ãUnity2018ãEntity Component System(ECS)ã¨UniRx.Asyncãå解ããã
åé¡ç¹
ECSã使ã£ã¦ããããã¸ã§ã¯ãã«UniRxãã¶ã¡ããã¨ãECSã¨UniRxã®PlayerLoopãå§å©ãã¦UniRxãåã¡ã¾ãï¼ECSãåããªããªãã¾ãï¼
ãã¯ãECSã§ãï¼ç¸æ§ãè¯ããã¯ã¨ãããï¼Rxãããã®ã§ãUniRxã使ãæ¹æ³ãæ¢ã£ã¦ã¿ã¾ããã
å é¨ã®ã³ã¼ããèªã
PlayerLoopã«GetCurrentããªããããUniRxã¨ECSãããããåæåæã«new PlayerLoopSystem
ããä¸ã§ãPlayerLoop.SetPlayerLoop(playerLoop)
ãã¦ãã¾ãã
ã©ã¡ããRuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)
ã®ã¿ã¤ãã³ã°ã§å¼ã°ãã¦ãã¾ããããã¾ãã¾UniRxãå¾ã«å¼ã°ãã¦ããããããã¡ãã®PlayerLoopãåªå
ããã¦ããããã§ãã
ECSé£å¶
GameBootstrap.cs
using UnityEngine; namespace Unity.Entities { #if !UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP static class AutomaticWorldBootstrap { [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] static void Initialize() { DefaultWorldInitialization.Initialize("Default World", false); } } #endif }
ScriptBehaviourUpdateOrder.cs
private static void SetPlayerLoop(PlayerLoopSystem playerLoop) { PlayerLoop.SetPlayerLoop(playerLoop); currentPlayerLoop = playerLoop; }
public static void UpdatePlayerLoop(params World[] worlds) { var defaultLoop = PlayerLoop.GetDefaultPlayerLoop(); if (worlds?.Length > 0) { var ecsLoop = InsertWorldManagersInPlayerLoop(defaultLoop, worlds.Where(x => x != null).ToArray()); SetPlayerLoop(ecsLoop); } else { SetPlayerLoop(defaultLoop); } }
UniRxé£å¶
PlayerLoopHelper.cs
public static void Initialize(ref PlayerLoopSystem playerLoop) { yielders = new ContinuationQueue[7]; runners = new PlayerLoopRunner[7]; var copyList = playerLoop.subSystemList.ToArray(); copyList[0].subSystemList = InsertRunner(copyList[0], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldInitialization), yielders[0] = new ContinuationQueue(), typeof(UniTaskLoopRunners.UniTaskLoopRunnerInitialization), runners[0] = new PlayerLoopRunner()); copyList[1].subSystemList = InsertRunner(copyList[1], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldEarlyUpdate), yielders[1] = new ContinuationQueue(), typeof(UniTaskLoopRunners.UniTaskLoopRunnerEarlyUpdate), runners[1] = new PlayerLoopRunner()); copyList[2].subSystemList = InsertRunner(copyList[2], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldFixedUpdate), yielders[2] = new ContinuationQueue(), typeof(UniTaskLoopRunners.UniTaskLoopRunnerFixedUpdate), runners[2] = new PlayerLoopRunner()); copyList[3].subSystemList = InsertRunner(copyList[3], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPreUpdate), yielders[3] = new ContinuationQueue(), typeof(UniTaskLoopRunners.UniTaskLoopRunnerPreUpdate), runners[3] = new PlayerLoopRunner()); copyList[4].subSystemList = InsertRunner(copyList[4], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldUpdate), yielders[4] = new ContinuationQueue(), typeof(UniTaskLoopRunners.UniTaskLoopRunnerUpdate), runners[4] = new PlayerLoopRunner()); copyList[5].subSystemList = InsertRunner(copyList[5], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPreLateUpdate), yielders[5] = new ContinuationQueue(), typeof(UniTaskLoopRunners.UniTaskLoopRunnerPreLateUpdate), runners[5] = new PlayerLoopRunner()); copyList[6].subSystemList = InsertRunner(copyList[6], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPostLateUpdate), yielders[6] = new ContinuationQueue(), typeof(UniTaskLoopRunners.UniTaskLoopRunnerPostLateUpdate), runners[6] = new PlayerLoopRunner()); playerLoop.subSystemList = copyList; PlayerLoop.SetPlayerLoop(playerLoop); }
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] static void Init() { // capture default(unity) sync-context. unitySynchronizationContetext = SynchronizationContext.Current; mainThreadId = Thread.CurrentThread.ManagedThreadId; if (runners != null) return; // already initialized var playerLoop = PlayerLoop.GetDefaultPlayerLoop(); Initialize(ref playerLoop); }
解決æ¹æ³
ã²ã¼ã ã®åæåãè¡ãRuntimeInitializeLoadType.BeforeSceneLoad
ããå¾ã®ã¿ã¤ãã³ã°ã§ãä¸è¨ã®ããã«ãScriptBehaviourUpdateOrder.CurrentPlayerLoop
ã§ECSå´ã®PlayerLoopãåå¾ããPlayerLoopHelper.Initialize
ã§UniRxå´ã®PlayerLoopãåæåããªããã¦ããããã¨ã§å
±åããããã¾ãã
éå»·ï¼ï¼ï¼
var playerLoop = ScriptBehaviourUpdateOrder.CurrentPlayerLoop;
PlayerLoopHelper.Initialize(ref playerLoop);