Created
May 22, 2018 07:12
-
-
Save michalbrzozowski/1c2ee6f9abcae055664847ad1e8e4365 to your computer and use it in GitHub Desktop.
Sample showing a potential way to start and run multiple worlds.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using UnityEngine; | |
using Unity.Entities; | |
public class WorldBootstrap | |
{ | |
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] | |
public static void Initialize() | |
{ | |
#if LOAD_SERVER | |
ServerWorldBootstrap.Initialize(); | |
#elif LOAD_CLIENT | |
ClientWorldBootstrap.Initialize(); | |
#else | |
LocalWorldBootstrap.Initialize(); | |
#endif | |
} | |
} | |
// Edit -> Project Settings -> Player: Scripting Define Symbols, add: UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP | |
#if LOAD_SERVER | |
#region ServerBootstrap | |
public class ServerWorldBootstrap | |
{ | |
public static World serverWorld; | |
public static void DomainUnloadShutdown() | |
{ | |
if (serverWorld != null) | |
{ | |
serverWorld.Dispose(); | |
ScriptBehaviourUpdateOrder.UpdatePlayerLoop(); | |
} | |
else | |
{ | |
Debug.LogError("World has already been destroyed"); | |
} | |
} | |
public static void Initialize() | |
{ | |
PlayerLoopManager.RegisterDomainUnload(DomainUnloadShutdown); | |
serverWorld = new World("Server"); | |
WorldCreator.FindAndCreateWorldFromNamespace(serverWorld, "Server"); | |
World.Active = null; | |
ScriptBehaviourUpdateOrder.UpdatePlayerLoop(serverWorld); | |
} | |
} | |
#endregion | |
#elif LOAD_CLIENT | |
#region ClientBootstrap | |
class ClientWorldBootstrap | |
{ | |
public static World clientWorld; | |
public static void DomainUnloadShutdown() | |
{ | |
if (clientWorld != null) | |
{ | |
clientWorld.Dispose(); | |
ScriptBehaviourUpdateOrder.UpdatePlayerLoop(); | |
} | |
else | |
{ | |
Debug.LogError("World has already been destroyed"); | |
} | |
} | |
public static void Initialize() | |
{ | |
PlayerLoopManager.RegisterDomainUnload(DomainUnloadShutdown); | |
clientWorld = new World("Client"); | |
WorldCreator.FindAndCreateWorldFromNamespace(clientWorld, "Client"); | |
World.Active = null; | |
ScriptBehaviourUpdateOrder.UpdatePlayerLoop(clientWorld); | |
} | |
} | |
#endregion | |
#else // Client + Server | |
#region LocalBootstrap | |
class LocalWorldBootstrap | |
{ | |
public static World clientWorld; | |
public static World serverWorld; | |
public static void DomainUnloadShutdown() | |
{ | |
if (clientWorld != null && serverWorld != null) | |
{ | |
serverWorld.Dispose(); | |
clientWorld.Dispose(); | |
ScriptBehaviourUpdateOrder.UpdatePlayerLoop(); | |
} | |
else | |
{ | |
Debug.LogError("World has already been destroyed"); | |
} | |
} | |
public static void Initialize() | |
{ | |
PlayerLoopManager.RegisterDomainUnload(DomainUnloadShutdown); | |
serverWorld = new World("Server"); | |
clientWorld = new World("Client"); | |
WorldCreator.FindAndCreateWorldFromNamespace(serverWorld, "Server"); | |
WorldCreator.FindAndCreateWorldFromNamespace(clientWorld, "Client"); | |
World.Active = null; | |
ScriptBehaviourUpdateOrder.UpdatePlayerLoop(serverWorld, clientWorld); | |
} | |
} | |
#endregion | |
#endif | |
#region WorldCreator | |
public class WorldCreator | |
{ | |
public static void FindAndCreateWorldFromNamespace(World world, string name) | |
{ | |
World.Active = world; | |
foreach (var ass in AppDomain.CurrentDomain.GetAssemblies()) | |
{ | |
if (ass.ManifestModule.ToString() == "Microsoft.CodeAnalysis.Scripting.dll") | |
continue; | |
var allTypes = ass.GetTypes(); | |
var systemTypes = allTypes.Where( | |
t => t.IsSubclassOf(typeof(ComponentSystemBase)) && | |
!t.IsAbstract && | |
!t.ContainsGenericParameters && | |
(t.Namespace != null && t.Namespace == name) && | |
t.GetCustomAttributes(typeof(DisableAutoCreationAttribute), true).Length == 0); | |
foreach (var type in systemTypes) | |
{ | |
GetBehaviourManagerAndLogException(world, type); | |
} | |
} | |
} | |
public static void GetBehaviourManagerAndLogException(World world, Type type) | |
{ | |
try | |
{ | |
Debug.Log("Found System" + type.FullName); | |
world.GetOrCreateManager(type); | |
} | |
catch (Exception e) | |
{ | |
Debug.LogException(e); | |
} | |
} | |
} | |
#endregion | |
namespace Server | |
{ | |
public class ServerSystem : ComponentSystem | |
{ | |
override protected void OnCreateManager(int capacity) | |
{ | |
Debug.Log("ServerSystem Created"); | |
} | |
override protected void OnUpdate() | |
{ | |
Debug.Log("ServerSystem Updating"); | |
} | |
override protected void OnDestroyManager() | |
{ | |
Debug.Log("ServerSystem Destroying"); | |
} | |
} | |
} | |
namespace Client | |
{ | |
public class ClientSystem : ComponentSystem | |
{ | |
override protected void OnCreateManager(int capacity) | |
{ | |
Debug.Log("ClientSystem Created"); | |
} | |
override protected void OnUpdate() | |
{ | |
Debug.Log("ClientSystem Updating"); | |
} | |
override protected void OnDestroyManager() | |
{ | |
Debug.Log("ClientSystem Destroying"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment