private void OnRoomStateChanged(MapSchema <string> attributes)
    {
        if (_showCountdown && attributes.ContainsKey("countDown"))
        {
            _countDownString = attributes["countDown"];
            scoreboardController.CountDown(_countDownString);
        }

        if (attributes.ContainsKey("currentGameState"))
        {
            eGameState nextState = TranslateGameState(attributes["currentGameState"]);
            if (IsSafeStateTransition(currentGameState, nextState))
            {
                currentGameState = nextState;
            }
            else
            {
                LSLog.LogError($"CurrentGameState: Failed to transition from {currentGameState} to {nextState}");
            }
        }

        if (attributes.ContainsKey("lastGameState"))
        {
            eGameState nextState = TranslateGameState(attributes["lastGameState"]);
            if (IsSafeStateTransition(lastGameState, nextState))
            {
                lastGameState = nextState;
            }
            else
            {
                LSLog.LogError($"LastGameState: Failed to transition from {lastGameState} to {nextState}");
            }
        }
    }
        /// <summary>
        ///     Create a match making request
        /// </summary>
        /// <param name="method">The type of request we're making (join, create, etc)</param>
        /// <param name="roomName">The name of the room we're trying to match</param>
        /// <param name="options">Dictionary of options to use in the match making process</param>
        /// <param name="headers">Dictionary of headers to pass to the server</param>
        /// <typeparam name="T">Type of <see cref="ColyseusRoom{T}" /> we want to match with</typeparam>
        /// <returns><see cref="ColyseusRoom{T}" /> we have matched with via async task</returns>
        /// <exception cref="Exception">Thrown if there is a network related error</exception>
        /// <exception cref="CSAMatchMakeException">Thrown if there is an error in the match making process on the server side</exception>
        protected async Task <ColyseusRoom <T> > CreateMatchMakeRequest <T>(string method, string roomName,
                                                                            Dictionary <string, object> options, Dictionary <string, string> headers)
        {
            if (options == null)
            {
                options = new Dictionary <string, object>();
            }

            if (headers == null)
            {
                headers = new Dictionary <string, string>();
            }

            string json = await ColyseusRequest.Request("POST", $"matchmake/{method}/{roomName}", options, headers);

            LSLog.Log($"Server Response: {json}");
            ColyseusMatchMakeResponse response =
                JsonUtility.FromJson <ColyseusMatchMakeResponse>(json /*req.downloadHandler.text*/);

            if (response == null)
            {
                throw new Exception($"Error with request: {json}");
            }

            if (!string.IsNullOrEmpty(response.error))
            {
                throw new CSAMatchMakeException(response.code, response.error);
            }

            return(await ConsumeSeatReservation <T>(response, headers));
        }
示例#3
0
    /// <summary>
    /// Creates a new <see cref="ExampleNetworkedEntity"/> with the given prefab and attributes
    /// and places it at the provided position and rotation.
    /// </summary>
    /// <param name="room">The room the entity will be added to</param>
    /// <param name="prefab">Prefab you would like to use to create the entity</param>
    /// <param name="position">Position for the new entity</param>
    /// <param name="rotation">Position for the new entity</param>
    /// <param name="attributes">Position for the new entity</param>
    public void InstantiateNetworkedEntity(ColyseusRoom <ExampleRoomState> room, string prefab, Vector3 position, Quaternion rotation,
                                           Dictionary <string, object> attributes = null)
    {
        if (string.IsNullOrEmpty(prefab))
        {
            LSLog.LogError("No Prefab Declared");
            return;
        }

        if (attributes != null)
        {
            attributes.Add("creationPos", new object[3] {
                position.x, position.y, position.z
            });
            attributes.Add("creationRot", new object[4] {
                rotation.x, rotation.y, rotation.z, rotation.w
            });
        }
        else
        {
            attributes = new Dictionary <string, object>()
            {
                ["creationPos"] = new object[3] {
                    position.x, position.y, position.z
                },
                ["creationRot"] = new object[4] {
                    rotation.x, rotation.y, rotation.z, rotation.w
                }
            };
        }

        CreateNetworkedEntity(room, prefab, attributes);
    }
示例#4
0
    public void InitiView(ExampleNetworkedEntity entity)
    {
        try
        {
            state  = entity;
            IsMine = ExampleManager.Instance.CurrentUser != null && string.Equals(ExampleManager.Instance.CurrentUser.id, state.ownerId);
            state.attributes.OnChange += Attributes_OnChange;
            state.OnChange            += Entity_State_OnChange;

            OwnerId = state.ownerId;
            Id      = state.id;
            RefId   = state.__refId;

            //Syncs Transform on Initi
            SetStateStartPos();

            //set my transform
            if (myTransform == null)
            {
                myTransform = transform;
            }

            //Save lastLoc
            prevLocalPosition = myTransform.localPosition;

            HasInit = true;
        }
        catch (System.Exception e)
        {
            LSLog.LogError($"Error: {e.Message + e.StackTrace}");
        }
    }
    /// <summary>
    ///     Create a room with the given roomId.
    /// </summary>
    /// <param name="roomId">The ID for the room.</param>
    public async Task CreateSpecificRoom(ColyseusClient client, string roomName, string roomId)
    {
        LSLog.LogImportant($"Creating Room {roomId}");

        try
        {
            //Populate an options dictionary with custom options provided elsewhere as well as the critical option we need here, roomId
            Dictionary <string, object> options = new Dictionary <string, object> {
                ["roomId"] = roomId
            };
            foreach (KeyValuePair <string, object> option in roomOptionsDictionary)
            {
                options.Add(option.Key, option.Value);
            }

            _room = await client.Create <ExampleRoomState>(roomName, options);
        }
        catch (Exception ex)
        {
            LSLog.LogError($"Failed to create room {roomId} : {ex.Message}");
            return;
        }

        LSLog.LogImportant($"Created Room: {_room.Id}");
        _lastRoomId = roomId;
        RegisterRoomHandlers();
    }
    private void SpawnTargets(List <ShootingGalleryTargetModel> newTargets)
    {
        List <TargetBase> spawnedTargets = new List <TargetBase>(); //Pass this to whatever will handle the targets

        foreach (ShootingGalleryTargetModel target in newTargets)
        {
            GameObject prefab = null;
            foreach (TargetPrefabPair targetPair in potentialTargets)
            {
                if (targetPair.id.Equals(target.id))
                {
                    prefab = targetPair.prefab;
                }
            }

            if (prefab == null)
            {
                LSLog.LogError($"Could not find a prefab for target with an ID of {target.id}... will use default");
                prefab = defaultTarget;
            }

            GameObject newTarget  = Instantiate(prefab);
            TargetBase targetBase = newTarget.GetComponent <TargetBase>();
            targetBase.Init(target);
            targetObjectsSpawned.Add(targetBase);
            spawnedTargets.Add(targetBase);
        }

        targetHolder.Initialize(spawnedTargets);
        targetHolder.Reset();
    }
    public void GotNewTargetLineUp(ShootingGalleryNewTargetLineUpMessage targetLineUp)
    {
        if (targetLineUp == null || targetLineUp.targets == null)
        {
            LSLog.LogError("No targets came in");
            return;
        }

        targetCount = targetLineUp.targets.Length;
        newTargets  = new List <ShootingGalleryTargetModel>();
        for (int i = 0; i < targetLineUp.targets.Length; ++i)
        {
            if (!trackedTargets.Contains(targetLineUp.targets[i].uid))
            {
                newTargets.Add(targetLineUp.targets[i]);
                trackedTargets.Add(targetLineUp.targets[i].uid);
            }
        }

        SpawnTargets(newTargets);
        string userID = ExampleManager.Instance.CurrentUser.id;

        ExampleManager.NetSend("setAttribute",
                               new ExampleAttributeUpdateMessage
        {
            userId = userID, attributesToSet = new Dictionary <string, string> {
                { "readyState", "ready" }
            }
        });
    }
    /// <summary>
    ///     Join a room with the given <see cref="roomId" />.
    /// </summary>
    /// <param name="roomId">ID of the room to join.</param>
    public async Task JoinRoomId(string roomId)
    {
        LSLog.Log($"Joining Room ID {roomId}....");
        ClearRoomHandlers();

        try
        {
            while (_room == null || !_room.colyseusConnection.IsOpen)
            {
                _room = await _client.JoinById <ExampleRoomState>(roomId);

                if (_room == null || !_room.colyseusConnection.IsOpen)
                {
                    LSLog.LogImportant($"Failed to Connect to {roomId}.. Retrying in 5 Seconds...");
                    await Task.Delay(5000);
                }
            }
            LSLog.LogImportant($"Connected to {roomId}..");
            _lastRoomId = roomId;
            RegisterRoomHandlers();
        }
        catch (Exception ex)
        {
            LSLog.LogError(ex.Message);
            LSLog.LogError("Failed to join room");
            //await CreateSpecificRoom(_client, roomName, roomId, onJoin);
        }
    }
    /// <summary>
    ///     Sends "ping" message to current room to help measure latency to the server.
    /// </summary>
    /// <param name="roomToPing">The <see cref="ColyseusRoom{T}" /> to ping.</param>
    private void RunPingThread(object roomToPing)
    {
        ColyseusRoom <ExampleRoomState> currentRoom = (ColyseusRoom <ExampleRoomState>)roomToPing;

        const float pingInterval = 0.5f; // seconds
        const float pingTimeout  = 15f;  //seconds

        int timeoutMilliseconds  = Mathf.FloorToInt(pingTimeout * 1000);
        int intervalMilliseconds = Mathf.FloorToInt(pingInterval * 1000);

        DateTime pingStart;

        while (currentRoom != null)
        {
            _waitForPong = true;
            pingStart    = DateTime.Now;
            _lastPing    = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            _            = currentRoom.Send("ping");

            while (currentRoom != null && _waitForPong &&
                   DateTime.Now.Subtract(pingStart).TotalSeconds < timeoutMilliseconds)
            {
                Thread.Sleep(200);
            }

            if (_waitForPong)
            {
                LSLog.LogError("Ping Timed out");
            }

            Thread.Sleep(intervalMilliseconds);
        }
    }
示例#10
0
    private void CreateView(ExampleNetworkedEntity entity)
    {
        LSLog.LogImportant("print: " + JsonUtility.ToJson(entity));
        ColyseusNetworkedEntityView newView = Instantiate(prefab);

        ExampleManager.Instance.RegisterNetworkedEntityView(entity, newView);
        newView.gameObject.SetActive(true);
    }
示例#11
0
    /// <summary>
    ///     Subscribes the manager to <see cref="room" />'s networked events
    ///     and starts measuring latency to the server.
    /// </summary>
    public virtual void RegisterRoomHandlers()
    {
        LSLog.LogImportant($"sessionId: {_room.SessionId}");

        if (_pingThread != null)
        {
            _pingThread.Abort();
            _pingThread = null;
        }

        _pingThread = new Thread(RunPingThread);
        _pingThread.Start(_room);

        _room.OnLeave += OnLeaveRoom;

        _room.OnStateChange += OnStateChangeHandler;

        _room.OnMessage <ExampleNetworkedUser>("onJoin", currentNetworkedUser =>
        {
            Debug.Log($"Received 'ExampleNetworkedUser' after join/creation call {currentNetworkedUser.id}!");
            Debug.Log(Json.SerializeToString(currentNetworkedUser));

            _currentNetworkedUser = currentNetworkedUser;
        });

        _room.OnMessage <ExampleRFCMessage>("onRFC", _rfc =>
        {
            //Debug.Log($"Received 'onRFC' {_rfc.entityId}!");
            if (_entityViews.Keys.Contains(_rfc.entityId))
            {
                _entityViews[_rfc.entityId].RemoteFunctionCallHandler(_rfc);
            }
        });

        _room.OnMessage <ExamplePongMessage>(0, message =>
        {
            _lastPong    = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            _serverTime  = message.serverTime;
            _waitForPong = false;
        });

        //Custom game logic
        //_room.OnMessage<YOUR_CUSTOM_MESSAGE>("messageNameInCustomLogic", objectOfTypeYOUR_CUSTOM_MESSAGE => {  });

        //========================
        _room.State.networkedEntities.OnAdd    += OnEntityAdd;
        _room.State.networkedEntities.OnRemove += OnEntityRemoved;

        _room.State.networkedUsers.OnAdd    += OnUserAdd;
        _room.State.networkedUsers.OnRemove += OnUserRemove;

        _room.State.TriggerAll();
        //========================

        _room.colyseusConnection.OnError += Room_OnError;
        _room.colyseusConnection.OnClose += Room_OnClose;
    }
        public static async Task <string> Request(string uriMethod, string uriPath, Dictionary <string, object> options = null, Dictionary <string, string> headers = null)
        {
            UriBuilder uriBuilder = new UriBuilder(_serverSettings.WebRequestEndpoint);

            uriBuilder.Path = uriPath;

            UnityWebRequest req = new UnityWebRequest();

            req.method = uriMethod;
            req.url    = uriBuilder.Uri.ToString();
            LSLog.Log($"Requesting from URL: {req.url}");
            if (options != null)
            {
                // Send JSON options on request body
                MemoryStream jsonBodyStream = new MemoryStream();
                Json.Serialize(options, jsonBodyStream); //TODO: Replace GameDevWare serialization

                req.uploadHandler = new UploadHandlerRaw(jsonBodyStream.ToArray())
                {
                    contentType = "application/json"
                };
            }

            foreach (KeyValuePair <string, string> pair in _serverSettings.HeadersDictionary)
            {
                req.SetRequestHeader(pair.Key, pair.Value);
            }

            if (headers != null)
            {
                foreach (KeyValuePair <string, string> header in headers)
                {
                    req.SetRequestHeader(header.Key, header.Value);
                }
            }

            req.downloadHandler = new DownloadHandlerBuffer();
            await req.SendWebRequest();

            if (req.isNetworkError || req.isHttpError)
            {
                if (_serverSettings.useSecureProtocol)
                {
                    //We failed to make this call with a secure protocol, try with non-secure and if that works we'll stick with it
                    _serverSettings.useSecureProtocol = false;
                    LSLog.LogError($"Failed to make request to {req.url} with secure protocol, trying again without!");
                    return(await Request(uriMethod, uriPath, options, headers));
                }
                else
                {
                    throw new Exception(req.error);
                }
            }

            return(req.downloadHandler.text);
        }
    /// <summary>
    ///     Send an action and message object to the room.
    /// </summary>
    /// <param name="action">The action to take</param>
    /// <param name="message">The message object to pass along to the room</param>
    public static void NetSend(string action, object message = null)
    {
        if (Instance._roomController.Room == null)
        {
            LSLog.LogError($"Error: Not in room for action {action} msg {message}");
            return;
        }

        _ = message == null
            ? Instance._roomController.Room.Send(action)
            : Instance._roomController.Room.Send(action, message);
    }
示例#14
0
    private void OnLeaveRoom(WebSocketCloseCode code)
    {
        LSLog.Log("ROOM: ON LEAVE =- Reason: " + code);
        _pingThread.Abort();
        _pingThread = null;
        _room       = null;

        if (code != WebSocketCloseCode.Normal && !string.IsNullOrEmpty(_lastRoomId))
        {
            JoinRoomId(_lastRoomId);
        }
    }
示例#15
0
 private void OnNetworkAdd(ExampleNetworkedEntity entity)
 {
     if (ExampleManager.Instance.HasEntityView(entity.id))
     {
         LSLog.LogImportant("View found! For " + entity.id);
     }
     else
     {
         LSLog.LogImportant("No View found for " + entity.id);
         CreateView(entity);
     }
 }
    /// <summary>
    ///     Send an action and message object to the room.
    /// </summary>
    /// <param name="actionByte">The action to take</param>
    /// <param name="message">The message object to pass along to the room</param>
    public static void NetSend(byte actionByte, object message = null)
    {
        if (Instance._roomController.Room == null)
        {
            LSLog.LogError(
                $"Error: Not in room for action bytes msg {(message != null ? message.ToString() : "No Message")}");
            return;
        }

        _ = message == null
            ? Instance._roomController.Room.Send(actionByte)
            : Instance._roomController.Room.Send(actionByte, message);
    }
示例#17
0
    public void UnregisterNetworkedEntityView(ExampleNetworkedEntity model)
    {
        if (string.IsNullOrEmpty(model.id) || _entities.ContainsKey(model.id) == false)
        {
            LSLog.LogError("Cannot Find Entity in Room");
            return;
        }

        ExampleNetworkedEntityView view = _entityViews[model.id];

        _entityViews.Remove(model.id);
        view.SendMessage("OnEntityViewUnregistered", SendMessageOptions.DontRequireReceiver);
    }
 private void OnNetworkAdd(ExampleNetworkedEntity entity)
 {
     if (ExampleManager.Instance.HasEntityView(entity.id))
     {
         LSLog.LogImportant("View found! For " + entity.id);
         scoreboardController.EntityAdded(entity); //Already exists in scene which means it has been initialized
     }
     else
     {
         LSLog.LogImportant("No View found for " + entity.id);
         CreateView(entity);
     }
 }
        public static async Task <string> Request(string uriMethod, string uriPath, string uriQuery, string Token = "", UploadHandlerRaw data = null)
        {
            UriBuilder uriBuilder = new UriBuilder(_serverSettings.WebRequestEndpoint);

            uriBuilder.Path  = uriPath;
            uriBuilder.Query = uriQuery;

            UnityWebRequest req = new UnityWebRequest();

            req.method = uriMethod;

            req.url = uriBuilder.Uri.ToString();
            // Send JSON on request body
            if (data != null)
            {
                req.uploadHandler = data;
            }

            foreach (KeyValuePair <string, string> pair in _serverSettings.HeadersDictionary)
            {
                req.SetRequestHeader(pair.Key, pair.Value);
            }

            if (!string.IsNullOrEmpty(Token))
            {
                req.SetRequestHeader("Authorization", "Bearer " + Token);
            }

            // req.uploadHandler = new UploadHandlerRaw(bytes);
            req.downloadHandler = new DownloadHandlerBuffer();
            await req.SendWebRequest();

            if (req.isNetworkError || req.isHttpError)
            {
                if (_serverSettings.useSecureProtocol)
                {
                    //We failed to make this call with a secure protocol, try with non-secure and if that works we'll stick with it
                    _serverSettings.useSecureProtocol = false;
                    LSLog.LogError($"Failed to make request to {req.url} with secure protocol, trying again without!");
                    return(await Request(uriMethod, uriPath, uriQuery, Token, data));
                }
                else
                {
                    throw new Exception(req.error);
                }
            }

            string json = req.downloadHandler.text;

            return(json);
        }
    private void OnLeaveRoom(int code)
    {
        WebSocketCloseCode closeCode = WebSocketHelpers.ParseCloseCodeEnum(code);

        LSLog.Log(string.Format("ROOM: ON LEAVE =- Reason: {0} ({1})", closeCode, code));
        _pingThread.Abort();
        _pingThread = null;
        _room       = null;

        if (closeCode != WebSocketCloseCode.Normal && !string.IsNullOrEmpty(_lastRoomId))
        {
            JoinRoomId(_lastRoomId);
        }
    }
    public void RemoveView(ExampleNetworkedEntity entity)
    {
        ScoreboardEntry entryForView = GetEntryByID(entity.id);

        if (entryForView != null)
        {
            spawnedEntries.Remove(entryForView);
            Destroy(entryForView.gameObject);
        }
        else
        {
            LSLog.LogError("Player left game but we do not have a scoreboard entry for them!");
        }
    }
示例#22
0
    public void RemoteFunctionCallHandler(ExampleRFCMessage _rfc)
    {
        System.Type thisType = this.GetType();
        //LSLog.Log("got RFC call for " + _rfc.function);

        MethodInfo theMethod = thisType.GetMethod(_rfc.function);

        if (theMethod != null)
        {
            theMethod.Invoke(this, _rfc.param);
        }
        else
        {
            LSLog.LogError("Missing Fucntion: " + _rfc.function);
        }
    }
    public void UpdateScore(ShootingGalleryScoreUpdateMessage updateMessage, int remainingTargets)
    {
        ScoreboardEntry entryForView = GetEntryByID(updateMessage.entityID);

        if (entryForView != null)
        {
            entryForView.UpdateScore(updateMessage.score);
            UpdateEntryOrder();
        }
        else
        {
            LSLog.LogError("Tried to Update a score but couldn't find an entry!");
        }

        SetTargetsText(remainingTargets);
    }
示例#24
0
    IEnumerator Co_InitiWithServer()
    {
        while (ExampleManager.Instance.IsInRoom == false)
        {
            yield return(0);
        }

        if (autoInitEntity && HasInit == false && !string.IsNullOrEmpty(prefabName))
        {
            ExampleManager.CreateNetworkedEntity(prefabName, null, this);
        }
        else if (autoInitEntity && HasInit == false && string.IsNullOrEmpty(prefabName))
        {
            LSLog.LogError("Prefab Name / Location Must be set");
        }
    }
示例#25
0
    /// <summary>
    /// Registers the <see cref="ExampleNetworkedEntityView"/> with the manager for tracking.
    /// <para>Initializes the <see cref="ExampleNetworkedEntityView"/> if it has not yet been initialized.</para>
    /// </summary>
    /// <param name="model"></param>
    /// <param name="view"></param>
    public void RegisterNetworkedEntityView(ExampleNetworkedEntity model, ColyseusNetworkedEntityView view)
    {
        if (string.IsNullOrEmpty(model.id) || view == null || _entities.ContainsKey(model.id) == false)
        {
            LSLog.LogError("Cannot Find Entity in Room");
            return;
        }

        ExampleNetworkedEntityView entityView = (ExampleNetworkedEntityView)view;

        if (entityView && !entityView.HasInit)
        {
            entityView.InitiView(model);
        }

        _entityViews.Add(model.id, (ExampleNetworkedEntityView)view);
        view.SendMessage("OnEntityViewRegistered", SendMessageOptions.DontRequireReceiver);
    }
    IEnumerator WaitForConnect()
    {
        if (ExampleManager.Instance.CurrentUser != null && !IsMine)
        {
            yield break;
        }

        while (!ExampleManager.Instance.IsInRoom)
        {
            yield return(0);
        }
        LSLog.LogImportant("HAS JOINED ROOM - CREATING ENTITY");
        ExampleManager.CreateNetworkedEntityWithTransform(new Vector3(0f, 0f, 0f), Quaternion.identity, new Dictionary <string, object>()
        {
            ["prefab"] = "VMEViewPrefab"
        }, this, (entity) => {
            LSLog.LogImportant($"Network Entity Ready {entity.id}");
        });
    }
示例#27
0
    /// <summary>
    /// Creates a new <see cref="ExampleNetworkedEntity"/> attributes and <see cref="ColyseusNetworkedEntityView"/>.
    /// </summary>
    /// <param name="room">The room the entity will be added to</param>
    /// <param name="attributes">Position for the new entity</param>
    /// <param name="viewToAssign">The provided view that will be assigned to the new <see cref="ExampleNetworkedEntity"/></param>
    /// <param name="callback">Callback that will be invoked with the newly created <see cref="ExampleNetworkedEntity"/></param>
    public void CreateNetworkedEntity(ColyseusRoom <ExampleRoomState> room, Dictionary <string, object> attributes = null, ColyseusNetworkedEntityView viewToAssign = null, Action <ExampleNetworkedEntity> callback = null)
    {
        try
        {
            string creationId = null;

            if (viewToAssign != null || callback != null)
            {
                creationId = Guid.NewGuid().ToString();
                if (callback != null)
                {
                    if (viewToAssign != null)
                    {
                        _creationCallbacks.Add(creationId, (newEntity) =>
                        {
                            RegisterNetworkedEntityView(newEntity, viewToAssign);
                            callback.Invoke(newEntity);
                        });
                    }
                    else
                    {
                        _creationCallbacks.Add(creationId, callback);
                    }
                }
                else
                {
                    _creationCallbacks.Add(creationId,
                                           (newEntity) => { RegisterNetworkedEntityView(newEntity, viewToAssign); });
                }
            }

            _ = room.Send("createEntity",
                          new EntityCreationMessage()
            {
                creationId = creationId, attributes = attributes
            });
        }
        catch (System.Exception err)
        {
            LSLog.LogError(err.Message + err.StackTrace);
        }
    }
    /// <summary>
    ///     Callback for when a <see cref="ExampleNetworkedUser" /> is added to a room.
    /// </summary>
    /// <param name="user">The user object</param>
    /// <param name="key">The user key</param>
    private void OnUserAdd(string key, ExampleNetworkedUser user)
    {
        LSLog.LogImportant($"user [{user.__refId} | {user.id} | key {key}] Joined");

        // Add "player" to map of players
        _users.Add(key, user);

        // On entity update...
        user.OnChange += changes =>
        {
            user.updateHash = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();

            // If the change is for our current user then fire the event with the attributes that changed
            if (ExampleManager.Instance.CurrentUser != null &&
                string.Equals(ExampleManager.Instance.CurrentUser.sessionId, user.sessionId))
            {
                OnCurrentUserStateChanged?.Invoke(user.attributes);
            }
        };
    }
    /// <summary>
    ///     The callback for the event when a <see cref="ExampleNetworkedEntity" /> is added to a room.
    /// </summary>
    /// <param name="entity">The entity that was just added.</param>
    /// <param name="key">The entity's key</param>
    private async void OnEntityAdd(string key, ExampleNetworkedEntity entity)
    {
        LSLog.LogImportant(
            $"Entity [{entity.__refId} | {entity.id}] add: x => {entity.xPos}, y => {entity.yPos}, z => {entity.zPos}");

        _entities.Add(entity.id, entity);

        //Creation ID is only Registered with the owner so only owners callback will be triggered
        if (!string.IsNullOrEmpty(entity.creationId) && _creationCallbacks.ContainsKey(entity.creationId))
        {
            _creationCallbacks[entity.creationId].Invoke(entity);
            _creationCallbacks.Remove(entity.creationId);
        }

        onAddNetworkEntity?.Invoke(entity);

        if (_entityViews.ContainsKey(entity.id) == false && !string.IsNullOrEmpty(entity.attributes["prefab"]))
        {
            await _factory.CreateFromPrefab(entity);
        }
    }
示例#30
0
    /// <summary>
    /// Creates a GameObject using the <see cref="ExampleNetworkedEntityView"/>'s prefab.
    /// <para>Requires that the entity has a "prefab" attribute defined.</para>
    /// </summary>
    /// <param name="entity"></param>
    public async Task CreateFromPrefab(ExampleNetworkedEntity entity)
    {
        LSLog.LogError($"Factory - Create From Prefab - {entity.id}");

        ResourceRequest asyncItem = Resources.LoadAsync <ExampleNetworkedEntityView>(entity.attributes["prefab"]);

        while (asyncItem.isDone == false)
        {
            await Task.Yield();
        }

        ExampleNetworkedEntityView view = UnityEngine.Object.Instantiate((ExampleNetworkedEntityView)asyncItem.asset);

        if (view == null)
        {
            LSLog.LogError("Instantiated Object is not of VMENetworkedEntityView Type");
            asyncItem = null;
            return;
        }

        RegisterNetworkedEntityView(entity, view);
    }