/// <summary> /// Constructor. /// </summary> /// <param name="netManager">Network manager owning this network world.</param> public NetWorld(NetManager netManager) { this.netManager = netManager; Instance = this; GameCallbacks.onWorldUnload += () => { OnGameWorldUnload(); }; GameCallbacks.onWorldLoad += () => { OnGameWorldLoad(); }; GameCallbacks.onPlayMakerObjectCreate += (GameObject instance, GameObject prefab) => { if (!Game.GamePickupableDatabase.IsPickupable(instance)) { return; } var metaData = prefab.GetComponent <Game.Components.PickupableMetaDataComponent>(); Client.Assert(metaData != null, "Tried to spawn pickupable that has no meta data assigned."); RegisterPickupable(instance); Messages.PickupableSpawnMessage msg = new Messages.PickupableSpawnMessage(); msg.prefabId = metaData.prefabId; msg.transform.position = Utils.GameVec3ToNet(instance.transform.position); msg.transform.rotation = Utils.GameQuatToNet(instance.transform.rotation); msg.active = instance.activeSelf; // Check for multiple sync components from prefab ObjectSyncComponent oscOld = prefab.GetComponent <ObjectSyncComponent>(); if (instance.GetComponents <ObjectSyncComponent>().Length > 1) { foreach (ObjectSyncComponent osc in instance .GetComponents <ObjectSyncComponent>()) { if (osc.ObjectID == oscOld.ObjectID) { GameObject.Destroy(osc); } else { msg.id = osc.ObjectID; } } } else { msg.id = instance.GetComponent <ObjectSyncComponent>().ObjectID; } // Determine if object should be spawned on remote client. // (Helps to avoid duplicate objects spawning) bool sendToRemote = false; if (NetManager.Instance.IsHost) { Logger.Debug("Sending new object data to client!"); sendToRemote = true; } else { if (instance.name.StartsWith("BottleBeerFly")) { sendToRemote = true; } } if (sendToRemote) { netManager.BroadcastMessage(msg, Steamworks.EP2PSend.k_EP2PSendReliable); Logger.Debug("Sending new object data to client!"); } }; GameCallbacks.onPlayMakerObjectActivate += (GameObject instance, bool activate) => { if (playerIsLoading) { return; } if (activate == instance.activeSelf) { return; } if (!GamePickupableDatabase.IsPickupable(instance)) { return; } ObjectSyncComponent pickupable = GetPickupableByGameObject(instance); if (pickupable == null) { return; } if (activate) { var metaData = pickupable.gameObject.GetComponent <PickupableMetaDataComponent>(); Messages.PickupableSpawnMessage msg = new Messages.PickupableSpawnMessage(); msg.id = pickupable.ObjectID; msg.prefabId = metaData.prefabId; msg.transform.position = Utils.GameVec3ToNet(instance.transform.position); msg.transform.rotation = Utils.GameQuatToNet(instance.transform.rotation); netManager.BroadcastMessage(msg, Steamworks.EP2PSend.k_EP2PSendReliable); } else { Messages.PickupableActivateMessage msg = new Messages.PickupableActivateMessage(); msg.id = pickupable.ObjectID; msg.activate = false; netManager.BroadcastMessage(msg, Steamworks.EP2PSend.k_EP2PSendReliable); } }; GameCallbacks.onPlayMakerObjectDestroy += (GameObject instance) => { if (!Game.GamePickupableDatabase.IsPickupable(instance)) { return; } ObjectSyncComponent pickupable = GetPickupableByGameObject(instance); if (pickupable == null) { Logger.Debug( $"Pickupable {instance.name} has been destroyed however it is not registered, skipping removal."); return; } HandlePickupableDestroy(instance); }; GameCallbacks.onPlayMakerSetPosition += (GameObject gameObject, Vector3 position, Space space) => { if (!Game.GamePickupableDatabase.IsPickupable(gameObject)) { return; } ObjectSyncComponent pickupable = GetPickupableByGameObject(gameObject); if (pickupable == null) { return; } if (space == Space.Self) { position += gameObject.transform.position; } Messages.PickupableSetPositionMessage msg = new Messages.PickupableSetPositionMessage(); msg.id = pickupable.ObjectID; msg.position = Utils.GameVec3ToNet(position); netManager.BroadcastMessage(msg, Steamworks.EP2PSend.k_EP2PSendReliable); }; RegisterNetworkMessagesHandlers(netManager.MessageHandler); }
/// <summary> /// Constructor. /// </summary> /// <param name="netManager">Network manager owning this network world.</param> public NetWorld(NetManager netManager) { this.netManager = netManager; Instance = this; GameCallbacks.onWorldUnload += () => { OnGameWorldUnload(); }; GameCallbacks.onWorldLoad += () => { OnGameWorldLoad(); }; GameCallbacks.onPlayMakerObjectCreate += (GameObject instance, GameObject prefab) => { if (!GamePickupableDatabase.IsPickupable(instance)) { return; } var metaData = prefab.GetComponent <PickupableMetaDataComponent>(); Client.Assert(metaData != null, "Tried to spawn pickupable that has no meta data assigned."); Messages.PickupableSpawnMessage msg = new Messages.PickupableSpawnMessage(); msg.prefabId = metaData.prefabId; msg.transform.position = Utils.GameVec3ToNet(instance.transform.position); msg.transform.rotation = Utils.GameQuatToNet(instance.transform.rotation); msg.active = instance.activeSelf; // Setup sync component on object. Client.Assert(instance.GetComponent <ObjectSyncComponent>(), $"Object created but no ObjectSyncComponent could be found! Object name: {instance.name}"); ObjectSyncComponent osc = instance.GetComponent <ObjectSyncComponent>(); msg.id = osc.Setup(osc.ObjectType, ObjectSyncManager.AUTOMATIC_ID); // Determine if object should be spawned on remote client. // (Helps to avoid duplicate objects spawning) bool sendToRemote = false; if (NetManager.Instance.IsHost) { Logger.Debug("Sending new object data to client!"); sendToRemote = true; } else { // This is a hack to workout beer bottles not spawning on the remote client due to items only spawning on the host. // This will be replaced in the future. if (instance.name.StartsWith("BottleBeerFly")) { sendToRemote = true; } } if (sendToRemote) { netManager.BroadcastMessage(msg, Steamworks.EP2PSend.k_EP2PSendReliable); Logger.Debug("Sending new object data to client!"); } }; GameCallbacks.onPlayMakerObjectActivate += (GameObject instance, bool activate) => { if (playerIsLoading) { return; } if (activate == instance.activeSelf) { return; } if (!GamePickupableDatabase.IsPickupable(instance)) { return; } ObjectSyncComponent pickupable = GetPickupableByGameObject(instance); if (pickupable == null) { return; } if (activate) { var metaData = pickupable.gameObject.GetComponent <PickupableMetaDataComponent>(); Messages.PickupableSpawnMessage msg = new Messages.PickupableSpawnMessage(); msg.id = pickupable.ObjectID; msg.prefabId = metaData.prefabId; msg.transform.position = Utils.GameVec3ToNet(instance.transform.position); msg.transform.rotation = Utils.GameQuatToNet(instance.transform.rotation); netManager.BroadcastMessage(msg, Steamworks.EP2PSend.k_EP2PSendReliable); } else { Messages.PickupableActivateMessage msg = new Messages.PickupableActivateMessage(); msg.id = pickupable.ObjectID; msg.activate = false; netManager.BroadcastMessage(msg, Steamworks.EP2PSend.k_EP2PSendReliable); } }; GameCallbacks.onPlayMakerObjectDestroy += (GameObject instance) => { if (!GamePickupableDatabase.IsPickupable(instance)) { return; } ObjectSyncComponent pickupable = GetPickupableByGameObject(instance); if (pickupable == null) { Logger.Debug($"Pickupable {instance.name} has been destroyed however it is not registered, skipping removal."); return; } HandlePickupableDestroy(instance); }; GameCallbacks.onPlayMakerSetPosition += (GameObject gameObject, Vector3 position, Space space) => { if (!GamePickupableDatabase.IsPickupable(gameObject)) { return; } ObjectSyncComponent pickupable = GetPickupableByGameObject(gameObject); if (pickupable == null) { return; } if (space == Space.Self) { position += gameObject.transform.position; } Messages.PickupableSetPositionMessage msg = new Messages.PickupableSetPositionMessage(); msg.id = pickupable.ObjectID; msg.position = Utils.GameVec3ToNet(position); netManager.BroadcastMessage(msg, Steamworks.EP2PSend.k_EP2PSendReliable); }; RegisterNetworkMessagesHandlers(netManager.MessageHandler); }