Unreal Engine: Difference between revisions

From Andreida
Line 87: Line 87:
<pre>
<pre>
#pragma once
#pragma once
#include "CoreMinimal.h"


#include "Log.h"
#include "Engine.h"
</pre>

<pre>
// macros
// macros
// - LOG_LINE
// - LOG_LINE

Revision as of 23:14, 11 April 2024

Installation

 https://dotnet.microsoft.com/en-us/download/dotnet/3.1
 https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-3.1.32-windows-x64-installer
  • Visual Studio 2022: https://visualstudio.microsoft.com/downloads/
    • Workloads / Desktop development with C++ (was suggested by Visual Studio when I loaded a UE5 project)
    • Workloads / .NET desktop development (was suggested by Visual Studio when I loaded a UE5 project)
    • Workloads / Game Development with C++
      • don't unselect anything
      • Windows 10 SDK (1.0.20*)
      • Unreal Engine Test Adapter
      • Unreal Engine uproject support
    • Individual components / .NET 6.0 Runtime (Long Term Support) (was suggested by Visual Studio when I loaded a UE5 project)
    • Individual components / .NET Framework 4.8.1 SDK (or higher)
    • Individual components / .NET Framework 4.6.2 targeting pack (was suggested by Visual Studio when I loaded a UE5 project)
    • Individual components / MSVC 143 - VS 2022 C++ x64/x86 build tools (v14.36-17.6 or newer?) (was suggested by Visual Studio when I loaded a UE5 project)
    • After you install VS 2022, look in the VS Installer at the "Update" button. Enabled? Use it.
  • Unreal Engine Visual Studio Integration Tool plugin: https://aka.ms/vsituemarketplace (repeat after new engine installation)
  • naming convention checker: ".editorconfig" parallel to your .uproject file.
    Content: https://raw.githubusercontent.com/microsoft/vc-ue-extensions/main/Source/.editorconfig
  • HLS configuration file: "shadertoolsconfig.json" parallel to your .uproject file.
    Content: automatically created, defaults to:
{
  "hlsl.preprocessorDefinitions": {
  },
  " hlsl.additionalIncludeDirectories": [
  ],
  "hlsl.virtualDirectoryMappings": {
  }
}

Links

Unreal Engine

Blender

  • Export Options (so that the object is not lying on the side after Export/Import):
    • Forward: Y Forward
    • Up: Z up
  • Changing the object's origin to its bottom:
    • Switch to Edit Mode if needed (Tab). With vertex selection on, choose the center vertex in the bottom. Press Shift+S and choose Cursor to Selected. The 3D cursor will move to the selected vertex. Deselect all and switch to Object Mode (Tab).
    • In Tools choose Set Origin and then Origin to 3D Cursor.
    • Make sure the object's coordinates are set to 0,0,0. Now the object should be placed properly on the XY plane.

C++

Variable names

If you want to use real variable names but have nice names in the UE editor too, then use meta/DisplayName

UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, Meta = (DisplayName = "First Person Camera Component") )
    UCameraComponent* m_pFirstPersonCameraComponent;

owner / client /server

The instance that spawned the class is always ROLE_Authority. If an Actor is spawned on the client, the client is the authority. 
-- OmaManfred

OmaManfred::

 
And concerning the owner stuff:


When you spawn an instance of a class on the server FOR Client A, you have to set him as the owner.

FActorSpawnParameters params;
params.Owner = PlayerAPlayerController;

SpawnActor<Class>(Class:StaticClass(),params);

Then on Client B you can say IsOwner(PlayerBPlayerController), which should return false. 

Logging

The following is just a copy/paste/change from the UE4 wiki and was really done from different persons, I am just using the work of different people here. Put it in a Log.h and include it into your <your_project>.h file after the #include "Engine.h". Because <your_project>.h is in every of your files, you will now be able to use these macros in every .cpp file. If - like in certain newer UE projects - this is not working, put the include of your Log.h in the headers of the .cpps where you want to use it.


#pragma once
#include "CoreMinimal.h"

// macros
// - LOG_LINE
// - LOG -> output log
// -- LOG("text");
// -- LOG("text %s %f %d", "text", 1.2, 5);
// - PRINT -> screen
// -- PRINT("text");
// -- PRINT("text %s %f %d", "text", 1.2, 5);

#if _MSC_VER
#define FUNC_NAME    TEXT(__FUNCTION__)
#else // FIXME - GCC?
#define FUNC_NAME    TEXT(__func__)
#endif

#define LOG_LINE UE_LOG(LogTemp, Warning, TEXT("%s, file: %s, line %d"), FUNC_NAME, *FString(__FILE__), __LINE__);
//#define LOG_NULL(s, p) UE_LOG(LogTemp, Warning, TEXT("pointer %s %s"),s, (p?TEXT("ok"):TEXT("null") ) );

#define PRINT(format, ...) \
{ \
	const FString sFunc = FString::Printf(TEXT("%s"), FUNC_NAME); \
	const FString sText = FString::Printf(TEXT(format), ##__VA_ARGS__); \
	const FString sMsg = FString::Printf(TEXT("%s() : %s"), *sFunc, *sText); \
	if (GEngine) GEngine->AddOnScreenDebugMessage(-1, 5, FColor::White, sMsg); \
}

#define LOG(format, ...) \
{ \
    const FString sMsg = FString::Printf(TEXT(format), ##__VA_ARGS__); \
    UE_LOG(LogTemp, Warning, TEXT("%s() : %s"), FUNC_NAME, *sMsg);\
}

Am I client or server ?

https://answers.unrealengine.com/questions/416305/how-to-know-if-listenserverclient-owner-for-rpc.html

To answer questions 1 and 2: you can use AActor::GetNetMode() 
which returns whether you are a listen server, dedicated server or network client.

         if (GetNetMode() == ENetMode::NM_ListenServer)
         {
         }
         

The ENetMode values are:

    NM_Standalone = 0

    NM_DedicatedServer = 1

    NM_ListenServer = 2

    NM_Client = 3 // is only when you are actually connected to a server

The ordering of the ENetMode values allows you to check multiple things at once: 
GetNetMode() <= 2 means you are the server or standalone, so you have 'global authority'.

UMG with C++ base class

  • create a normal UMG widget
  • create a C++ class with base class UserWidget (UUserWidget)
  • build the project
  • set the parent class of the UMG widget to your C++ class
  • in <Project>.Build.cs add "UMG", "SLATE", "SLATECORE":
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });

		PrivateDependencyModuleNames.AddRange(new string[] {  });

		// Uncomment if you are using Slate UI
		 PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
  • put into <Project>.h
#include "Runtime/UMG/Public/UMG.h"
#include "Runtime/UMG/Public/UMGStyle.h"
#include "Runtime/UMG/Public/Slate/SObjectWidget.h"
#include "Runtime/UMG/Public/IUMGModule.h"
#include "Runtime/UMG/Public/Blueprint/UserWidget.h"

SLATE

https://wiki.unrealengine.com/Slate_Introduction_%E2%80%92_Basic_Menu_Part_1

The "canvas" in UMG is "SConstraintCanvas" in Slate.

Multiplayer / Sessions

Do not search for "multiplayer", search for "sessions". Good tutorial: https://wiki.unrealengine.com/How_To_Use_Sessions_In_C%2B%2B

String conversions

from: https://docs.unrealengine.com/en-us/Programming/UnrealArchitecture/StringHandling/FString

FString TestHUDString = FString(TEXT("This is my test FString."));
FName TestHUDName = FName(*TestHUDString);
FText TestHUDText = FText::FromString(TestHUDString);

Misc

Source control

Don't use Mercurial (or git) for game development. That would be just plain stupid.
Use Subversion or something like that.

The minimum you have to put under source control:

/Config
/Content
/Source
Project.uproject

Depending on your project:

/.editorconfig
/shadertoolsconfig.json


For ignores, have a look at ignoring files with svn.

Developer Folder

If you have the developer folder(s) enabled "Content / View Options / Show Developers Content" then make sure to not reference it from outside when cooking a project.

Other Licenses (examples)

not allowed

  • GNU General Public License (GPL),
  • Lesser GPL (LGPL) (unless you are merely dynamically linking a shared library), or
  • Creative Commons Attribution-ShareAlike License.

Code or content under the following licenses, for example, are allowed

  • BSD License,
  • MIT License,
  • Microsoft Public License, or
  • Apache License.

Other

Escape key stops simulation in editor

If you want to change this behavior, open "Edit/Editor Preferences" and search for "stop". Then change under "Play World/Stop" the shortcut "Escape" to whatever you want, for example shift-Escape.

Black Screens or flickering/invisible new action popup

Disable multiplane overlay

Details/Text/Line-Break

If you are shown a text in the Details tab, chances are you can use shift-return to create a line break.