[UE4]Gameplay Dev Notes
keywords: UE4, Gameplay Development Notes
Switch Level
论坛上有不少资料说切换场景时使用GEngine->Browse()
:
if (FWorldContext* Context = GEngine->GetWorldContextFromWorld(GetWorld()))
{
FString Error;
FURL URL(TEXT("/Game/Demo/scecn_test/scecn_test02"));
EBrowseReturnVal::Type RS = GEngine->Browse(*Context, URL, Error);
if (EBrowseReturnVal::Type::Failure == RS)
{
WSI->ChangePlayerState(EPlayerState::EP_LoginFailed);
}
}
GEngine->Browse这种方式第一次打开场景时正常,如果第二次切换场景(比如从别的场景再切回原场景),则会导致程序崩溃。建议用:UGameplayStatics::OpenLevel(GetWorld(), TEXT("/Game/Map/TestMap")); 这种方式来回切场景不会出现崩溃问题。
Level Event
Level changed (switch level) event:
//只有Standalone和Client中触发,Server不触发。
FCoreUObjectDelegates::PreLoadMap.AddUObject(this, &UMySubsystem::OnPreLoadMap);
FCoreUObjectDelegates::PostLoadMapWithWorld.AddUObject(this, &UMySubsystem::OnPostLoadMap);
Level destroyed (e.g. exit game) event:
GetWorld()->GetLevel(0)->OnCleanupLevel.AddUObject(this, &UMySubsystem::OnCleanupLevel);
Actor spawned event:
FOnActorSpawned::FDelegate Delegate;
Delegate.BindUObject(this, &AMyActor::OnActorAdded);
GetWorld()->AddOnActorSpawnedHandler(Delegate);
or
GEngine->OnLevelActorAdded().AddUObject(this, &AMyActor::OnActorSpawned);
GEngine->OnLevelActorDeleted().AddUObject(this, &AMyActor::OnActorDeleted);
GEngine->OnLevelActorListChanged().AddUObject(this, &AMyActor::OnLevelActorListChanged);
How to get UWorld
if(UWorld* World = GEngine->GetCurrentPlayWorld(nullptr))
{
ULevel* Level = World->GetLevel(0);
}
Check if it’s server or client without WorldContext
Quoted from CoreMisc.h
bool IsRunningDedicatedServer();
bool IsRunningGame();
bool IsRunningClientOnly();
Subsystem (Unreal Stylized Singleton)
How to get customized Subsystem?
Quoted from GameInstance.h:
template <typename TSubsystemClass>
TSubsystemClass* GetSubsystem() const
{
return SubsystemCollection.GetSubsystem<TSubsystemClass>(TSubsystemClass::StaticClass());
}
Or:
header:
public:
static UMySubsystem* Get(const UObject* WorldContext);
cpp:
UMySubsystem* UMySubsystem::Get(const UObject* WorldContext)
{
return UGameInstance::GetSubsystem<UMySubsystem>(UGameplayStatics::GetGameInstance(WorldContext));
}
How to disable initialization of GameInstanceSubsystem
on dedicated server?
Quoted from:
Engine\Plugins\Experimental\CommonUI\Source\CommonUI\Private\CommonUISubsystemBase.cpp
bool UCommonUISubsystemBase::ShouldCreateSubsystem(UObject* Outer) const
{
return !CastChecked<UGameInstance>(Outer)->IsDedicatedServerInstance();
}
APIs
Interface
Define: ReactToTriggerInterface.h
#pragma once
#include "ReactToTriggerInterface.generated.h"
UINTERFACE(MinimalAPI, Blueprintable)
class UReactToTriggerInterface : public UInterface
{
GENERATED_BODY()
};
class IReactToTriggerInterface
{
GENERATED_BODY()
public:
/** Add interface function declarations here */
};
Usage: check if an actor implements an interface.
if(MyActor->GetClass()->ImplementsInterface(UMyInterface::StaticClass()))
{ }
if(IMyInterface* Interface = Cast<IMyInterface>(MyActor))
{
Interface->OnDamage(DamageValue, DamagePosition);
}
Reference: Unreal Interfaces
几时归去,作个闲人。对一张琴、一壶酒、一溪云。----宋·苏轼《行香子》