# 虚幻三消
* actor获取gamemode
```
Cast<AMatch3GameMode>(UGameplayStatics::GetGameMode(WorldContextObject))
这个WorldContextObject传AActor this就行了
```
* spawned actor获取spawn自己的actor
```
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
SpawnParams.Instigator = GetInstigator();
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
// Tiles never rotate
FRotator SpawnRotation(0.0f, 0.0f, 0.0f);
// Spawn the tile.
ATile* const NewTile = World->SpawnActor<ATile>(TileToSpawn, SpawnLocation, SpawnRotation, SpawnParams);
然后spawned actor:
Grid = Cast<AGrid>(GetOwner());
```
* GameInstance使用
* 在Edit->Project Settings->Project->Maps & Modes里配置用自己的GameInstance类
* GameInstance复写父类方法:
```
// Called by the game at startup.
void Init() override;
// Called by the game as it shuts down.
void Shutdown() override;
```
在这两个函数实现中,先写自己的自定义实现,最后再调用父类实现Super::F()
* GameInstance有个USaveGame作为成员变量,在其他地方不操作USaveGame,所有有关的操作都通过GameInstance直接或间接进行。
* 每个level的slotname都是关卡名
* 有个【TMap FString, int32】记录一些东西,如分数,是否播放音乐(将int32转为bool)
* GameInstance的init里面,注册了一些事件
```
LoginChangedHandle = FCoreDelegates::OnUserLoginChangedEvent.AddUObject(this, &UMatch3GameInstance::OnLoginChanged);
EnteringForegroundHandle = FCoreDelegates::ApplicationHasEnteredForegroundDelegate.AddUObject(this, &UMatch3GameInstance::OnEnteringForeground);
EnteringBackgroundHandle = FCoreDelegates::ApplicationWillEnterBackgroundDelegate.AddUObject(this, &UMatch3GameInstance::OnEnteringBackground);
ViewportHandle = FViewport::ViewportResizedEvent.AddUObject(this, &UMatch3GameInstance::OnViewportResize_Internal);
```
* 获取GameInstance
```
UGameInstance* GameplayStatics::GetGameInstance(const UObject* WorldContextObject);
```
* 游戏的设置(是否播放声音、是否播放音乐等设置)也作为成员变量记录在GameInstance里,接着在对应情况时检查GameInstance的设置。
* 获取当前Level的名字
```
/**
* Get the name of the currently-open level.
*
* @param bRemovePrefixString remove any streaming- or editor- added prefixes from the level name.
*/
UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", AdvancedDisplay = "1"), Category = "Game")
static FString GameplayStatics::GetCurrentLevelName(const UObject* WorldContextObject, bool bRemovePrefixString = true);
```
* 棋盘生成算法
以当前Actor为中心,左下角为0
```
FVector AGrid::GetLocationFromGridAddress(int32 GridAddress) const
{
FVector Center = GetActorLocation();
FVector OutLocation = FVector(-(GridWidth * 0.5f) * TileSize.X + (TileSize.X * 0.5f), 0.0f, -(GridHeight * 0.5f) * TileSize.Y + (TileSize.Y * 0.5f));
check(GridWidth > 0);
OutLocation.X += TileSize.X * (float)(GridAddress % GridWidth);
OutLocation.Z += TileSize.Y * (float)(GridAddress / GridWidth);
OutLocation += Center;
return OutLocation;
}
```
* GameMode
* 重启当前关卡
```
FName LevelName(*UGameplayStatics::GetCurrentLevelName(this, true));
UGameplayStatics::OpenLevel(this, LevelName);
```
* 实现UserWidget的切换
```
void AMatch3GameMode::ChangeMenuWidget(TSubclassOf<UUserWidget> NewWidgetClass)
{
if (CurrentWidget)
{
CurrentWidget->RemoveFromViewport();
CurrentWidget = nullptr;
}
if (NewWidgetClass)
{
if (AMatch3PlayerController* PC = Cast<AMatch3PlayerController>(UMatch3BlueprintFunctionLibrary::GetLocalPlayerController(this)))
{
CurrentWidget = CreateWidget<UUserWidget>(PC, NewWidgetClass);
if (CurrentWidget)
{
CurrentWidget->AddToViewport();
}
}
}
```
* IsGameActive()
```
bool AMatch3GameMode::IsGameActive() const
{
// Game is active whenever time hasn't run out or the timer is paused.
FTimerManager& WorldTimerManager = GetWorldTimerManager();
return (WorldTimerManager.IsTimerActive(GameOverTimer) || WorldTimerManager.IsTimerPaused(GameOverTimer));
}
```
* GetRemainingTime
```
GetWorldTimerManager().GetTimerRemaining(GameOverTimer)
```
* 给计时器加时间
```
重新设置下timer就好
GetWorldTimerManager().SetTimer(GameOverTimer, this, &AMatch3GameMode::GameOver, StartingTimeValue + (ScoreAwardCount * Reward.TimeAwarded), false);
```
* GameMode一般和PlayerController打交道
* PlayerController->IsLocalController()
* the network to uniquely identify a player:
```
PlayerController->PlayerState->GetUniqueId()->GetHexEncodedString()
```
* 交换宝石时那种位置移动的动画,通过节点Timeline在两个位置中lerp实现