toppers / hakoniwa-base

5 stars 1 forks source link

Unreal Engine対応をしたい #14

Open tmori opened 9 months ago

tmori commented 9 months ago

最小構成でのタスクリスト

考え方

タスクリスト

以降は、こちらで対応します。

https://github.com/toppers/hakoniwa-unreal-simasset-plugin/issues/1

tmori commented 9 months ago

Unreal Engine をインストールする

https://docs.unrealengine.com/4.27/ja/Basics/InstallingUnrealEngine/

version

スクリーンショット 2024-01-14 15 36 35

起動方法

Epic GamesというアプリがUnity Hubに対応していると思われる。

起動ボタンをクリック(バージョン選択できる)

スクリーンショット 2024-01-15 6 08 26

起動ボタンを押下すると、Epic Gamesアプリが落ちて、プロジェクトブラウザが開く。

スクリーンショット 2024-01-15 6 09 52
tmori commented 9 months ago

Unreal Engineエディタを起動して、保存できるようになる

ゴール

プリミティブなオブジェクトをシーンに配置して、シミュレーション実行できるようになる

新規プロジェクト作成方法

プロジェクトブラウザで、ゲーム タブを選択して、「ブランク」を選んで、プロジェクトデフォルトを C++ にする。 スターターコンテンツのチェックは外す。

カテゴリは、「シミュレーション」にすること!

スクリーンショット 2024-01-15 6 26 47

XCodeが起動し、コンパイルが走り出す。

スクリーンショット 2024-01-15 6 15 50

起動した!

スクリーンショット 2024-01-15 6 18 29

保存方法

画面左上のタブの名前が、最初、「名称未設定」とあったが、保存ボタンをクリックして、名前を入れたら変わった。 初期プロジェクトでは、マップの新規作成まではやってくれるけれど、永続化されない状態なんだな。

スクリーンショット 2024-01-15 6 31 31

tmori commented 9 months ago

スクリプトのイロハ

https://docs.unrealengine.com/4.27/ja/ProgrammingAndScripting/ProgrammingWithCPP/CPPProgrammingQuickStart/

tmori commented 9 months ago

シミュレーションの状態遷移の把握

image

追加の注意点:

tmori commented 9 months ago

Q

シミュレーションを停止させた場合、UE側のシミュレーションも一時停止させて時間も進まなくしたいのですが、可能でしょうか

A

はい、Unreal Engineでシミュレーションを一時停止させることは可能です。一時停止中は、ゲームの時間も進行しなくなります。これを実現するには、主にゲームの世界(UWorldオブジェクト)を操作することになります。

シミュレーションの一時停止方法

  1. SetPause関数の使用:

    • UWorldクラスのSetPause関数を使用してゲームを一時停止させることができます。
    • 一時停止を有効にするには、以下のようにコードを記述します:
      GetWorld()->SetPause(true);
    • シミュレーションを再開するには、falseを引数として渡します:
      GetWorld()->SetPause(false);
  2. ブループリントでの実装:

    • ブループリントでも同様の機能を使用してゲームを一時停止および再開することができます。
    • 「Set Game Paused」というノードを使用して一時停止の状態を切り替えます。

シミュレーション時間の挙動

注意点

これにより、外部シミュレーションの状態に応じてUnreal Engineのシミュレーションを一時停止および再開することが可能になります。また、この機能を使って、ユーザーによる手動の一時停止/再開操作も実装できます。

tmori commented 9 months ago

Q

シミュレーション時間として適切なのは、GetTimeSecondsですね。シミュレーション停止させたときに、連動して時間が停止するので。

A

はい、正確にはその通りです。GetTimeSeconds関数は、Unreal EngineのUWorldクラスが提供するメソッドで、ゲームが開始してからの総経過時間(秒)を返します。この関数はゲームが一時停止された際にも時間の進行を停止するため、シミュレーション時間として適切です。

GetTimeSeconds関数の特徴

シミュレーションの一時停止と再開

注意点

GetTimeSecondsを使用することで、ゲーム内のシミュレーション時間を正確に追跡し、外部シミュレーションシステムとの時間同期を行うことが可能になります。これにより、ゲームのビジュアライズと外部シミュレーションのデータを効果的に組み合わせることができます。

tmori commented 9 months ago

Q

シミュレーション再開させるには、独立して駆動するスレッドかイベントコールバックが必要ですよね。

A

シミュレーションを再開させるためには、確かに独立して駆動するスレッドやイベントコールバックが必要になる場合があります。Unreal Engineにおけるシミュレーションの一時停止と再開の実装は、ゲームの具体的な要件や設計によって異なりますが、以下の方法が考えられます。

スレッドによる実装

イベントコールバックによる実装

カスタムコントローラーまたはマネージャーの使用

注意点

ゲームの具体的な要件に応じて、これらの方法を組み合わせることで、シミュレーションの一時停止と再開を効果的に制御できます。また、Unreal Engineの機能を最大限に活用し、パフォーマンスと安定性を確保することが重要です。

tmori commented 9 months ago

つぶやき

うーん、外部から不定期にくるイベントを監視するとなると、スレッドしかないですね。

A

外部から不定期に来るイベントを監視する場合、確かに独立したスレッドを使用するのが一つの有効な解決策です。Unreal Engineでマルチスレッディングを実装する際には、特に同期やデータ共有における安全性に注意を払う必要があります。

スレッドを使用したイベント監視の実装

  1. 独立した監視スレッドの作成:

    • 外部イベントをリッスンするために専用のスレッドを作成します。
    • このスレッドは、外部ソースからのイベントやデータを継続的に監視し、それに応じてゲームエンジン内でのアクションをトリガーします。
  2. スレッド間通信:

    • Unreal Engineのメインゲームスレッドと監視スレッド間で適切にデータを共有し、コマンドを伝達するための安全なスレッド間通信メカニズムを実装します。
    • 例えば、スレッドセーフなキューやイベント通知システムを利用できます。
  3. エラーハンドリングと同期:

    • マルチスレッディングでは、エラーハンドリングとデータの競合を防ぐための適切な同期メカニズムが必要です。
    • Unreal Engineにはスレッドセーフなクラスや機能が提供されていますが、それらを正確に理解し使用する必要があります。

注意点

マルチスレッディングは強力なツールですが、複雑さとリスクも伴います。実装には慎重さと適切なプログラミング手法が求められます。Unreal Engineのドキュメントやコミュニティのリソースを活用して、最適な実装方法を探求してください。

tmori commented 9 months ago

Q

UEは、マルチスレッド対応に特化した適切なライブラリ群を用意しているのではないでしょうか?

A

はい、Unreal Engineはマルチスレッディングに関連するいくつかの特化したライブラリやフレームワークを提供しています。これらは、マルチスレッド処理のための安全で効率的な機能を開発者に提供することを目的としています。

Unreal Engineのマルチスレッディング関連の主な機能

  1. タスクベースのマルチスレッディング:

    • Unreal Engineでは、FTaskGraphInterfaceを使用してタスクベースのマルチスレッディングがサポートされています。
    • これにより、開発者は個々のタスクを定義し、エンジンによって管理されるスレッドプールで実行させることができます。
  2. スレッドセーフなコンテナ:

    • Unreal Engineにはスレッドセーフなコンテナクラス(例:TQueue, TArray, etc.)があります。
    • これらのコンテナは、データのスレッド間共有時に発生する競合を防ぐために設計されています。
  3. スレッドセーフなプリミティブ:

    • スレッド間の同期や排他制御のために、FCriticalSection, FEvent, FMutex などのスレッドセーフなプリミティブが提供されています。
  4. 非同期処理:

    • FAsyncTaskFRunnableインターフェイスを使用することで、独立したスレッドでの非同期処理が可能です。
  5. AsyncFuture の使用:

    • C++11のstd::futurestd::asyncのような、非同期タスクを管理するための機能も提供されています。

パフォーマンスと安全性

注意点

これらのマルチスレッド機能を適切に使用することで、効率的かつ安全なマルチスレッド処理をUnreal Engine内で実現できるでしょう。Linuxカーネル開発のご経験を活かして、これらの高度な機能を効果的に利用されることをお勧めします。

tmori commented 9 months ago

箱庭のUE対応設計について

大体、全体設計が見えてきました。

UEでは、各アクターが独立してTickタイミングで動作します。 箱庭としては、箱庭管理のアクターをちゃんと管理したいので、 ルートアクターを用意します。そして、ルートアクターのtickから、各アクターの制御を行います。

各アクターは、箱庭の外部データ通信をします。

そして、箱庭のシミュレーションイベント監視は、専用スレッドを用意して、イベント監視させます。箱庭からのシミュレーション開始や停止イベントです。これらのイベント通知を受けたら、UE側のシミュレーションの開始や停止させます。

こんな感じで行けますか?

A

お考えの設計はUnreal Engineのフレームワーク内で実現可能であり、効率的なアプローチのようです。以下は、提案された設計の各要素に関するいくつかの具体的な考慮事項です。

ルートアクターの使用

各アクターの外部データ通信

専用イベント監視スレッド

UEのシミュレーション制御

総合的な考慮事項

全体的に、ご提案された設計は、シミュレーションの中央集権的な制御と各アクターの分散型の動作を適切に組み合わせています。これにより、複雑なシミュレーションを効果的に管理し、Unreal Engineの強力な

ビジュアライゼーション機能を活用することができるでしょう。また、専用のイベント監視スレッドを使用することで、シミュレーションの状態管理をより効果的に行えます。

ただし、各アクターが外部データと通信する際や、専用イベント監視スレッドを使用する際には、スレッドセーフなプログラミングや効率的なリソース管理に注意を払う必要があります。また、シミュレーションの一時停止や再開に関連するUnreal EngineのAPIを適切に利用することで、シミュレーションの制御を柔軟に行うことができます。

全体的な設計がUnreal Engineのフレームワーク内で実装可能であることを考えると、プロジェクトの目的に合わせた効率的で柔軟なシミュレーション環境を構築することができそうです。