private void Update()
        {
            if (!m_isSpawning)
            {
                return;
            }

            m_startTime            += Time.deltaTime;
            m_gameState.score.Value = (int)m_startTime;

            m_timeToNextSpawn -= Time.deltaTime;
            if (m_isSpawning && (m_timeToNextSpawn <= 0.0f))
            {
                float distanceToNextPipe = Random.Range(minDistanceBetweenPipes, maxDistanceBetweenPipes);
                m_timeToNextSpawn = distanceToNextPipe / (m_obstacleSpawner.scroller.scrollSpeed * m_obstacleSpawner.scroller.scrollSpeedMultiplier);

                float      gapSize     = Random.Range(gapSizeLowerBound, gapSizeUpperBound);
                float      obstacleY   = Random.Range(bottomBorderTransform.localPosition.y + gapSize / 2.0f, topBorderTransform.localPosition.y - gapSize / 2.0f);
                GameObject obstacleObj = m_obstacleSpawner.SpawnObstacle(obstacleY, gapSize);

                ObstacleController obstacle       = obstacleObj.GetComponent <ObstacleController>();
                Vector3            upperPipeScale = obstacle.upperPipe.transform.localScale;
                Vector3            lowerPipeScale = obstacle.lowerPipe.transform.localScale;
                upperPipeScale.y = topBorderTransform.localPosition.y - obstacleObj.transform.localPosition.y - obstacle.gapSize / 2.0f;
                lowerPipeScale.y = obstacleObj.transform.localPosition.y - bottomBorderTransform.localPosition.y - obstacle.gapSize / 2.0f;
                obstacle.upperPipe.transform.localScale = upperPipeScale;
                obstacle.lowerPipe.transform.localScale = lowerPipeScale;

                NetOutMessage outMessage = new NetOutMessage();
                outMessage.WriteInt32((int)MessageType.Command.Control);
                outMessage.WriteInt32((int)MessageType.ControlType.SpawnObstacle);
                outMessage.WriteFloat(obstacleY);
                outMessage.WriteFloat(gapSize);
                outMessage.WriteVector3(upperPipeScale);
                outMessage.WriteVector3(lowerPipeScale);

                m_udpHelper.Send(outMessage, m_appState.HololensIP, Constants.NETWORK_PORT);
            }
        }
        private void UDPMessageReceivedHandler(NetInMessage message)
        {
            MessageType.Command command = (MessageType.Command)message.ReadInt32();
            if (command == MessageType.Command.Control)
            {
                MessageType.ControlType controlType = (MessageType.ControlType)message.ReadInt32();
                if (controlType == MessageType.ControlType.SpawnObstacle)
                {
                    float yPos    = message.ReadFloat();
                    float gapSize = message.ReadFloat();

                    GameObject obstacleObj = m_obstacleSpawner.SpawnObstacle(yPos, gapSize);

                    Vector3 upperPipeScale = message.ReadVector3();
                    Vector3 lowerPipeScale = message.ReadVector3();

                    ObstacleController obstacle = obstacleObj.GetComponent <ObstacleController>();
                    obstacle.upperPipe.transform.localScale = upperPipeScale;
                    obstacle.lowerPipe.transform.localScale = lowerPipeScale;
                }
                else if (controlType == MessageType.ControlType.PlayerPosition)
                {
                    Vector3 playerPosition = message.ReadVector3();

                    m_playerController.transform.localPosition = playerPosition;
                }
                else if (controlType == MessageType.ControlType.Start)
                {
                    m_gameState.isGameOver.Value = false;
                    m_gameState.score.Value      = 0;

                    m_obstacleSpawner.ResetState();
                }
                else if (controlType == MessageType.ControlType.TriggerGameOver)
                {
                    m_gameState.isGameOver.Value = true;
                }
                else if (controlType == MessageType.ControlType.UpdateScore)
                {
                    int score = message.ReadInt32();
                    m_gameState.score.Value = score;
                }
                else if (controlType == MessageType.ControlType.ChangeActiveFingers)
                {
                    int        numActiveFingers = message.ReadInt32();
                    List <int> activeFingers    = new List <int>();
                    for (int i = 0; i < numActiveFingers; i++)
                    {
                        int activeFingerIndex = message.ReadInt32();
                        activeFingers.Add(activeFingerIndex);
                    }

                    for (int i = 0; i < fingerIndicators.Count; i++)
                    {
                        bool isFingerActive = activeFingers.Contains(i);
                        fingerIndicators[i].IsVisible = isFingerActive;
                        if (isFingerActive)
                        {
                            fingerIndicators[i].SetIsOn(true);
                        }
                    }
                }
            }
        }