/// <summary>
        /// Switches to a scene with a given name. Can only be called from Server
        /// </summary>
        /// <param name="sceneName">The name of the scene to switch to</param>
        public static void SwitchScene(string sceneName)
        {
            if (!NetworkingManager.singleton.NetworkConfig.EnableSceneSwitching)
            {
                Debug.LogWarning("MLAPI: Scene switching is not enabled");
                return;
            }
            else if (isSwitching)
            {
                Debug.LogWarning("MLAPI: Scene switch already in progress");
                return;
            }
            else if (!registeredSceneNames.Contains(sceneName))
            {
                Debug.LogWarning("MLAPI: The scene " + sceneName + " is not registered as a switchable scene.");
                return;
            }
            SpawnManager.DestroySceneObjects(); //Destroy current scene objects before switching.
            CurrentSceneIndex = sceneNameToIndex[sceneName];
            isSwitching       = true;
            lastScene         = SceneManager.GetActiveScene();
            AsyncOperation sceneLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);

            sceneLoad.completed += OnSceneLoaded;

            using (BitWriter writer = new BitWriter())
            {
                writer.WriteUInt(sceneNameToIndex[sceneName]);

                InternalMessageHandler.Send("MLAPI_SWITCH_SCENE", "MLAPI_INTERNAL", writer.Finalize(), null);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Spawns a object from the pool at a given position and rotation. Can only be called from server.
        /// </summary>
        /// <param name="poolName">The name of the pool</param>
        /// <param name="position">The position to spawn the object at</param>
        /// <param name="rotation">The rotation to spawn the object at</param>
        /// <returns></returns>
        public static GameObject SpawnPoolObject(string poolName, Vector3 position, Quaternion rotation)
        {
            if (!NetworkingManager.singleton.isServer)
            {
                Debug.LogWarning("MLAPI: Object spawning can only occur on server");
                return(null);
            }
            GameObject go = Pools[PoolNamesToIndexes[poolName]].SpawnObject(position, rotation);

            using (BitWriter writer = new BitWriter())
            {
                writer.WriteUInt(go.GetComponent <NetworkedObject>().NetworkId);

                writer.WriteFloat(position.x);
                writer.WriteFloat(position.y);
                writer.WriteFloat(position.z);

                writer.WriteFloat(rotation.eulerAngles.x);
                writer.WriteFloat(rotation.eulerAngles.y);
                writer.WriteFloat(rotation.eulerAngles.z);

                InternalMessageHandler.Send("MLAPI_SPAWN_POOL_OBJECT", "MLAPI_INTERNAL", writer.Finalize(), null);
            }
            return(go);
        }
Beispiel #3
0
        internal static void OnDestroyObject(uint networkId, bool destroyGameObject)
        {
            if (!spawnedObjects.ContainsKey(networkId) || (netManager != null && !netManager.NetworkConfig.HandleObjectSpawning))
            {
                return;
            }
            if (spawnedObjects[networkId].OwnerClientId != NetworkingManager.singleton.NetworkConfig.NetworkTransport.InvalidDummyId && !spawnedObjects[networkId].isPlayerObject)
            {
                //Someone owns it.
                NetworkingManager.singleton.connectedClients[spawnedObjects[networkId].OwnerClientId].OwnedObjects.RemoveAll(x => x.NetworkId == networkId);
            }
            GameObject go = spawnedObjects[networkId].gameObject;

            if (netManager != null && netManager.isServer)
            {
                releasedNetworkObjectIds.Push(networkId);
                if (spawnedObjects[networkId] != null)
                {
                    using (BitWriter writer = new BitWriter())
                    {
                        writer.WriteUInt(networkId);

                        InternalMessageHandler.Send("MLAPI_DESTROY_OBJECT", "MLAPI_INTERNAL", writer.Finalize(), null);
                    }
                }
            }
            if (destroyGameObject && go != null)
            {
                MonoBehaviour.Destroy(go);
            }
            spawnedObjects.Remove(networkId);
        }
Beispiel #4
0
        /// <summary>
        /// Spawns a object from the pool at a given position and rotation. Can only be called from server.
        /// </summary>
        /// <param name="poolName">The name of the pool</param>
        /// <param name="position">The position to spawn the object at</param>
        /// <param name="rotation">The rotation to spawn the object at</param>
        /// <returns></returns>
        public static NetworkedObject SpawnPoolObject(string poolName, Vector3 position, Quaternion rotation)
        {
            if (!NetworkingManager.singleton.isServer)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Object spawning can only occur on server");
                }
                return(null);
            }
            NetworkedObject netObject = Pools[PoolNamesToIndexes[poolName]].SpawnObject(position, rotation);

            using (BitWriter writer = BitWriter.Get())
            {
                writer.WriteUInt(netObject.NetworkId);

                writer.WriteFloat(position.x);
                writer.WriteFloat(position.y);
                writer.WriteFloat(position.z);

                writer.WriteFloat(rotation.eulerAngles.x);
                writer.WriteFloat(rotation.eulerAngles.y);
                writer.WriteFloat(rotation.eulerAngles.z);

                InternalMessageHandler.Send("MLAPI_SPAWN_POOL_OBJECT", "MLAPI_INTERNAL", writer, null);
            }
            return(netObject);
        }
Beispiel #5
0
        internal static void SpawnPrefabIndexServer(NetworkedObject netObject, uint?clientOwnerId = null)
        {
            if (netObject.isSpawned)
            {
                Debug.LogWarning("MLAPI: Object already spawned");
                return;
            }
            else if (!netManager.isServer)
            {
                Debug.LogWarning("MLAPI: Only server can spawn objects");
                return;
            }
            else if (!netManager.NetworkConfig.NetworkPrefabIds.ContainsKey(netObject.NetworkedPrefabName))
            {
                Debug.LogWarning("MLAPI: The prefab name " + netObject.NetworkedPrefabName + " does not exist as a networkedPrefab");
                return;
            }
            else if (!netManager.NetworkConfig.HandleObjectSpawning)
            {
                Debug.LogWarning("MLAPI: NetworkConfig is set to not handle object spawning");
                return;
            }
            uint netId = GetNetworkObjectId();

            netObject.networkId = netId;
            spawnedObjects.Add(netId, netObject);
            netObject._isSpawned  = true;
            netObject.sceneObject = false;
            netObject.InvokeBehaviourNetworkSpawn();
            if (clientOwnerId != null)
            {
                netObject.ownerClientId = clientOwnerId.Value;
                NetworkingManager.singleton.connectedClients[clientOwnerId.Value].OwnedObjects.Add(netObject);
            }
            using (BitWriter writer = new BitWriter())
            {
                writer.WriteBool(false);
                writer.WriteUInt(netObject.NetworkId);
                writer.WriteUInt(netObject.OwnerClientId);
                writer.WriteInt(netManager.NetworkConfig.NetworkPrefabIds[netObject.NetworkedPrefabName]);
                writer.WriteBool(netObject.sceneObject == null ? true : netObject.sceneObject.Value);

                writer.WriteFloat(netObject.transform.position.x);
                writer.WriteFloat(netObject.transform.position.y);
                writer.WriteFloat(netObject.transform.position.z);

                writer.WriteFloat(netObject.transform.rotation.eulerAngles.x);
                writer.WriteFloat(netObject.transform.rotation.eulerAngles.y);
                writer.WriteFloat(netObject.transform.rotation.eulerAngles.z);


                InternalMessageHandler.Send("MLAPI_ADD_OBJECT", "MLAPI_INTERNAL", writer.Finalize(), null);
            }
        }
Beispiel #6
0
        internal static void FlushSceneObjects()
        {
            if (!NetworkingManager.singleton.isServer)
            {
                return;
            }

            //This loop is bad. For each client, we loop over every object twice.
            foreach (KeyValuePair <uint, NetworkedClient> client in netManager.connectedClients)
            {
                int sceneObjects = 0;
                foreach (var netObject in SpawnManager.spawnedObjects)
                {
                    if (netObject.Value.sceneObject == null || netObject.Value.sceneObject == true)
                    {
                        sceneObjects++;
                    }
                }

                using (BitWriter writer = BitWriter.Get())
                {
                    writer.WriteUShort((ushort)sceneObjects);
                    foreach (var netObject in SpawnManager.spawnedObjects)
                    {
                        if (netObject.Value.sceneObject == null || netObject.Value.sceneObject == true)
                        {
                            writer.WriteBool(false); //isLocalPlayer
                            writer.WriteUInt(netObject.Value.NetworkId);
                            writer.WriteUInt(netObject.Value.OwnerClientId);
                            writer.WriteInt(NetworkingManager.singleton.NetworkConfig.NetworkPrefabIds[netObject.Value.NetworkedPrefabName]);
                            writer.WriteBool(netObject.Value.sceneObject == null ? true : netObject.Value.sceneObject.Value);
                            writer.WriteBool(netObject.Value.observers.Contains(client.Key));

                            writer.WriteFloat(netObject.Value.transform.position.x);
                            writer.WriteFloat(netObject.Value.transform.position.y);
                            writer.WriteFloat(netObject.Value.transform.position.z);

                            writer.WriteFloat(netObject.Value.transform.rotation.eulerAngles.x);
                            writer.WriteFloat(netObject.Value.transform.rotation.eulerAngles.y);
                            writer.WriteFloat(netObject.Value.transform.rotation.eulerAngles.z);

                            if (netObject.Value.observers.Contains(client.Key))
                            {
                                netObject.Value.WriteFormattedSyncedVarData(writer);
                            }
                        }
                    }
                    InternalMessageHandler.Send(client.Key, "MLAPI_ADD_OBJECTS", "MLAPI_INTERNAL", writer, null);
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Destroys a NetworkedObject if it's part of a pool. Use this instead of the MonoBehaviour Destroy method. Can only be called from Server.
        /// </summary>
        /// <param name="netObject">The NetworkedObject instance to destroy</param>
        public static void DestroyPoolObject(NetworkedObject netObject)
        {
            if (!NetworkingManager.singleton.isServer)
            {
                Debug.LogWarning("MLAPI: Objects can only be destroyed on the server");
                return;
            }
            netObject.gameObject.SetActive(false);
            using (BitWriter writer = new BitWriter())
            {
                writer.WriteUInt(netObject.NetworkId);

                InternalMessageHandler.Send("MLAPI_DESTROY_POOL_OBJECT", "MLAPI_INTERNAL", writer.Finalize(), null);
            }
        }
Beispiel #8
0
        internal static void RemoveOwnership(uint netId)
        {
            NetworkedObject netObject = SpawnManager.spawnedObjects[netId];

            NetworkingManager.singleton.connectedClients[netObject.OwnerClientId].OwnedObjects.RemoveAll(x => x.NetworkId == netId);
            netObject.ownerClientId = NetworkingManager.singleton.NetworkConfig.NetworkTransport.InvalidDummyId;

            using (BitWriter writer = new BitWriter())
            {
                writer.WriteUInt(netId);
                writer.WriteUInt(netObject.ownerClientId);

                InternalMessageHandler.Send("MLAPI_CHANGE_OWNER", "MLAPI_INTERNAL", writer.Finalize(), null);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Destroys a NetworkedObject if it's part of a pool. Use this instead of the MonoBehaviour Destroy method. Can only be called from Server.
        /// </summary>
        /// <param name="netObject">The NetworkedObject instance to destroy</param>
        public static void DestroyPoolObject(NetworkedObject netObject)
        {
            if (!NetworkingManager.singleton.isServer)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Objects can only be destroyed on the server");
                }
                return;
            }
            netObject.gameObject.SetActive(false);
            using (BitWriter writer = BitWriter.Get())
            {
                writer.WriteUInt(netObject.NetworkId);

                InternalMessageHandler.Send("MLAPI_DESTROY_POOL_OBJECT", "MLAPI_INTERNAL", writer, null);
            }
        }
Beispiel #10
0
        internal static void FlushSceneObjects()
        {
            if (!NetworkingManager.singleton.isServer)
            {
                return;
            }

            List <NetworkedObject> sceneObjectsToSync = new List <NetworkedObject>();

            foreach (KeyValuePair <uint, NetworkedObject> pair in SpawnManager.spawnedObjects)
            {
                if (pair.Value.sceneObject == null || pair.Value.sceneObject == true)
                {
                    sceneObjectsToSync.Add(pair.Value);
                }
            }

            using (BitWriter writer = new BitWriter())
            {
                writer.WriteUShort((ushort)sceneObjectsToSync.Count);
                for (int i = 0; i < sceneObjectsToSync.Count; i++)
                {
                    writer.WriteBool(false); //isLocalPlayer
                    writer.WriteUInt(sceneObjectsToSync[i].NetworkId);
                    writer.WriteUInt(sceneObjectsToSync[i].OwnerClientId);
                    writer.WriteInt(NetworkingManager.singleton.NetworkConfig.NetworkPrefabIds[sceneObjectsToSync[i].NetworkedPrefabName]);
                    writer.WriteBool(sceneObjectsToSync[i].sceneObject == null ? true : sceneObjectsToSync[i].sceneObject.Value);

                    writer.WriteFloat(sceneObjectsToSync[i].transform.position.x);
                    writer.WriteFloat(sceneObjectsToSync[i].transform.position.y);
                    writer.WriteFloat(sceneObjectsToSync[i].transform.position.z);

                    writer.WriteFloat(sceneObjectsToSync[i].transform.rotation.eulerAngles.x);
                    writer.WriteFloat(sceneObjectsToSync[i].transform.rotation.eulerAngles.y);
                    writer.WriteFloat(sceneObjectsToSync[i].transform.rotation.eulerAngles.z);
                }

                InternalMessageHandler.Send("MLAPI_ADD_OBJECTS", "MLAPI_INTERNAL", writer.Finalize(), null);
            }
        }
Beispiel #11
0
        internal static void RemoveOwnership(uint netId)
        {
            if (!netManager.isServer)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("You can only remove ownership from Server");
                }
                return;
            }
            NetworkedObject netObject = SpawnManager.spawnedObjects[netId];

            NetworkingManager.singleton.connectedClients[netObject.OwnerClientId].OwnedObjects.RemoveAll(x => x.NetworkId == netId);
            netObject.ownerClientId = NetworkingManager.singleton.NetworkConfig.NetworkTransport.InvalidDummyId;

            using (BitWriter writer = BitWriter.Get())
            {
                writer.WriteUInt(netId);
                writer.WriteUInt(netObject.ownerClientId);

                InternalMessageHandler.Send("MLAPI_CHANGE_OWNER", "MLAPI_INTERNAL", writer, null);
            }
        }
Beispiel #12
0
        internal static void SpawnObject(NetworkedObject netObject, uint?clientOwnerId = null, BitWriter payload = null)
        {
            if (netObject.isSpawned)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Object already spawned");
                }
                return;
            }
            else if (!netManager.isServer)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Only server can spawn objects");
                }
                return;
            }
            else if (!netManager.NetworkConfig.NetworkPrefabIds.ContainsKey(netObject.NetworkedPrefabName))
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("The prefab name " + netObject.NetworkedPrefabName + " does not exist as a networkedPrefab");
                }
                return;
            }
            else if (!netManager.NetworkConfig.HandleObjectSpawning)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("NetworkConfig is set to not handle object spawning");
                }
                return;
            }
            uint netId = GetNetworkObjectId();

            netObject.networkId = netId;
            spawnedObjects.Add(netId, netObject);
            netObject._isSpawned  = true;
            netObject.sceneObject = false;

            if (clientOwnerId != null)
            {
                netObject.ownerClientId = clientOwnerId.Value;
                NetworkingManager.singleton.connectedClients[clientOwnerId.Value].OwnedObjects.Add(netObject);
            }

            if (payload == null)
            {
                netObject.InvokeBehaviourNetworkSpawn(null);
            }
            else
            {
                using (BitReader payloadReader = BitReader.Get(payload.Finalize())) netObject.InvokeBehaviourNetworkSpawn(payloadReader);
            }

            foreach (var client in netManager.connectedClients)
            {
                netObject.RebuildObservers(client.Key);
                using (BitWriter writer = BitWriter.Get())
                {
                    writer.WriteBool(false);
                    writer.WriteUInt(netObject.NetworkId);
                    writer.WriteUInt(netObject.OwnerClientId);
                    writer.WriteInt(netManager.NetworkConfig.NetworkPrefabIds[netObject.NetworkedPrefabName]);
                    writer.WriteBool(netObject.sceneObject == null ? true : netObject.sceneObject.Value);
                    writer.WriteBool(netObject.observers.Contains(client.Key));

                    writer.WriteFloat(netObject.transform.position.x);
                    writer.WriteFloat(netObject.transform.position.y);
                    writer.WriteFloat(netObject.transform.position.z);

                    writer.WriteFloat(netObject.transform.rotation.eulerAngles.x);
                    writer.WriteFloat(netObject.transform.rotation.eulerAngles.y);
                    writer.WriteFloat(netObject.transform.rotation.eulerAngles.z);

                    writer.WriteBool(payload != null);

                    if (netObject.observers.Contains(client.Key))
                    {
                        netObject.WriteFormattedSyncedVarData(writer);
                    }

                    if (payload != null)
                    {
                        writer.WriteWriter(payload);
                    }

                    InternalMessageHandler.Send(client.Key, "MLAPI_ADD_OBJECT", "MLAPI_INTERNAL", writer, null);
                }
            }
        }