jpnMini Map - B477042/GraduationProject GitHub Wiki
初期には簡単にSceneをキャプチャーして得たTextureを利用しました。
このように作ると早く作ることはできますが、きちんとした表現ができませんでした。
よく表現するために、ワールドの適切な高さにPlaneを作って、そのPlaneをCaputreしました。
そして、Playerの高さの位置情報を視覚的に伝えるために地形を表すPlaneのOpacityを調節します。
しかし、この演算をTickで処理するにはコストが惜しかったですが、Tickと表現するしかありませんでした。
解決策として、Multi-Threadingを適用させ、この演算を新しいThreadで処理するようにしました。
Back to Planning & Implementation
class CalcMiniMapTileAsyncTask :public FNonAbandonableTask
{
AMiniMapTileManager* Manager;
const AActor* Player;
public:
CalcMiniMapTileAsyncTask(AMiniMapTileManager* Manager, const AActor* Player)
{
this->Manager = Manager;
this->Player = Player;
}
FORCEINLINE TStatId GetStatId() const
{
RETURN_QUICK_DECLARE_CYCLE_STAT(PrimeCalculationAsyncTask, STATGROUP_ThreadPoolAsyncTasks);
}
void DoWork();
};
ThreadのFactorでManagerとPlayerをもらいました。
void CalcMiniMapTileAsyncTask::DoWork()
{
//Task Parameter Check
if (Manager && Player)
{
//#1 Set Opacity to 0
Thread_CalcOpacity::SetAllOpacityToZero(Manager);
Thread_CalcOpacity::CalcOpacityOfStruct(Manager, Player);
}
}
void Thread_CalcOpacity::CalcOpacityOfStruct( AMiniMapTileManager* Manager, const AActor* Player)
{
while (Player->IsValidLowLevel()&& UGameplayStatics::GetGameInstance(Manager))
{
Manager->CalculateStructsOpacity(Player->GetActorLocation());
FPlatformProcess::Sleep(0.01);
}
}
ManagerとPlayerが有効になっているかチェックし、Opacity を計算しました。
Multi-Threadingを適用させるのが最も困難でした。 最初からThreadの同期を入れるべきかについて深く考えるようになりました。
「構造物に対する相互作用を作らないため、ゲーム中に破壊される問題がないため、入れなくてもいい」と判断しました。
次に、問題はThreadの生成と消滅時点が問題でした。Thread内部にwhileやforによって無限ループを生成し、終了条件がない場合、ゲームが終了してもEditorに戻り続ける問題を確認しました。 このThreadはPlayerがあってこそ意味のあるThreadだという点が浮かびました。
ですから、Playerが有効な間にThreadが駆動されるようになりました。
Multi-Threadingを適用させた後、希望する通りに駆動されることを確認したら、言葉では表現できないけど、本当に良かったです。
Multi-Threadingに焦点を合わせました。