Exemple #1
0
        /// <summary>
        /// The OpenXR plug-in uses extensions to expose all possible data, which might be surfaced through multiple input devices.
        /// This method is overridden to account for multiple input devices and reuse MRTK controllers if a match is found.
        /// </summary>
        protected override GenericXRSDKController GetOrAddController(InputDevice inputDevice)
        {
            using (GetOrAddControllerPerfMarker.Auto())
            {
                // If this is a new input device, search if an existing input device has matching characteristics
                if (!ActiveControllers.ContainsKey(inputDevice))
                {
                    foreach (InputDevice device in ActiveControllers.Keys)
                    {
                        if (((device.characteristics.HasFlag(InputDeviceCharacteristics.Controller) && inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.Controller)) ||
                             (device.characteristics.HasFlag(InputDeviceCharacteristics.HandTracking) && inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.HandTracking))) &&
                            ((device.characteristics.HasFlag(InputDeviceCharacteristics.Left) && inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.Left)) ||
                             (device.characteristics.HasFlag(InputDeviceCharacteristics.Right) && inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.Right))))
                        {
                            ActiveControllers.Add(inputDevice, ActiveControllers[device]);
                            break;
                        }
                    }
                }

                if (inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.HandTracking) &&
                    inputDevice.TryGetFeatureValue(CommonUsages.isTracked, out bool isTracked) &&
                    !isTracked)
                {
                    // If this is an input device from the Microsoft Hand Interaction profile, it doesn't go invalid but instead goes untracked. Ignore it if untracked.
                    return(null);
                }

                return(base.GetOrAddController(inputDevice));
            }
        }
Exemple #2
0
        /// <summary>
        /// The OpenXR plug-in uses extensions to expose all possible data, which might be surfaced through multiple input devices.
        /// This method is overridden to account for multiple input devices and reuse MRTK controllers if a match is found.
        /// </summary>
        protected override void RemoveController(InputDevice inputDevice)
        {
            using (RemoveControllerPerfMarker.Auto())
            {
                foreach (InputDevice device in ActiveControllers.Keys)
                {
                    if (device != inputDevice &&
                        ((device.characteristics.HasFlag(InputDeviceCharacteristics.Controller) && inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.Controller)) ||
                         (device.characteristics.HasFlag(InputDeviceCharacteristics.HandTracking) && inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.HandTracking))) &&
                        ((device.characteristics.HasFlag(InputDeviceCharacteristics.Left) && inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.Left)) ||
                         (device.characteristics.HasFlag(InputDeviceCharacteristics.Right) && inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.Right))))
                    {
                        ActiveControllers.Remove(inputDevice);
                        // Since an additional device exists, return so a lost source isn't reported
                        return;
                    }
                }

                base.RemoveController(inputDevice);
            }
        }
Exemple #3
0
        public void HandleMessage(object sender, Message message)
        {
            if (message.Kind == Message.MessageType.InputMessage)
            {
                // Pass input messages to the respective ball controllers
                InputMessage msg = (InputMessage)message;

                // When using turn mode in hot-seat, direct all input messages to the active player
                if (Session.UsePlayerTurns && msg.Player != null && msg.Player.IsLocal && Session.ActivePlayer != null && ActiveControllers.ContainsKey(Session.ActivePlayer))
                {
                    ActiveControllers[Session.ActivePlayer]?.HandleMessage(sender, msg);
                }
                // Otherwise, redirect input messages to the player given by msg.Player
                else if (msg.Player != null && msg.Player.IsLocal && ActiveControllers.ContainsKey(msg.Player) && ActiveControllers.ContainsKey(msg.Player))
                {
                    ActiveControllers[msg.Player]?.HandleMessage(sender, msg);
                }
            }

            if (message.Kind == Message.MessageType.LogicMessage)
            {
                LogicMessage msg = (LogicMessage)message;

                if (msg.Kind == LogicMessage.MessageType.GameMessage)
                {
                    Enabled = !Enabled;
                    if (Enabled && Game.Match.State != SessionState.Finished)
                    {
                        Game.Match.State = SessionState.Running;
                    }
                    else
                    {
                        Ballz.The().Services.GetService <SoundControl>().PlaySound(SoundControl.DeclineSound);
                        Game.Match.State = SessionState.Paused;
                    }
                }
            }
        }
Exemple #4
0
        /// <inheritdoc />
        protected override GenericUnityController GetOrAddController(string joystickName)
        {
            // If a device is already registered with the ID provided, just return it.
            if (ActiveControllers.ContainsKey(joystickName))
            {
                var controller = ActiveControllers[joystickName];
                Debug.Assert(controller != null);
                return(controller);
            }

            Handedness controllingHand;

            if (joystickName.Contains("Left"))
            {
                controllingHand = Handedness.Left;
            }
            else if (joystickName.Contains("Right"))
            {
                controllingHand = Handedness.Right;
            }
            else
            {
                controllingHand = Handedness.None;
            }

            var  currentControllerType = GetCurrentControllerType(joystickName);
            Type controllerType;

            switch (currentControllerType)
            {
            case SupportedControllerType.GenericOpenVR:
                controllerType = typeof(GenericOpenVRController);
                break;

            case SupportedControllerType.ViveWand:
                controllerType = typeof(ViveWandController);
                break;

            case SupportedControllerType.ViveKnuckles:
                controllerType = typeof(ViveKnucklesController);
                break;

            case SupportedControllerType.OculusTouch:
                controllerType = typeof(OculusTouchController);
                break;

            case SupportedControllerType.OculusRemote:
                controllerType = typeof(OculusRemoteController);
                break;

            case SupportedControllerType.WindowsMixedReality:
                controllerType = typeof(WindowsMixedRealityOpenVRMotionController);
                break;

            default:
                return(null);
            }

            var pointers           = RequestPointers(controllerType, controllingHand);
            var inputSource        = InputSystem?.RequestNewGenericInputSource($"{currentControllerType} Controller {controllingHand}", pointers);
            var detectedController = Activator.CreateInstance(controllerType, TrackingState.NotTracked, controllingHand, inputSource, null) as GenericOpenVRController;

            if (detectedController == null)
            {
                Debug.LogError($"Failed to create {controllerType.Name} controller");
                return(null);
            }

            if (!detectedController.SetupConfiguration(controllerType))
            {
                // Controller failed to be setup correctly.
                Debug.LogError($"Failed to Setup {controllerType.Name} controller");
                // Return null so we don't raise the source detected.
                return(null);
            }

            for (int i = 0; i < detectedController.InputSource?.Pointers?.Length; i++)
            {
                detectedController.InputSource.Pointers[i].Controller = detectedController;
            }

            ActiveControllers.Add(joystickName, detectedController);
            return(detectedController);
        }
Exemple #5
0
        public override void Update(GameTime time)
        {
            var elapsedSeconds = (float)time.ElapsedGameTime.TotalSeconds;

            Session.GameTime += elapsedSeconds;

            Session.FocussedEntity = null;

            // Remove finished graphics events
            var graphicsEffects = Session.World.GraphicsEvents.Where(e => e.End < Session.GameTime).ToArray();

            foreach (var e in graphicsEffects)
            {
                Session.World.GraphicsEvents.Remove(e);
            }

            if (Session.UsePlayerTurns)
            {
                if (Session.ActivePlayer == null)
                {
                    Session.ActivePlayer = Session.Players[0];
                }

                Session.TurnTime += elapsedSeconds;
                if (Session.TurnTime > Session.SecondsPerTurn && Session.TurnState == TurnState.Running)
                {
                    EndTurn();
                }

                // End the turn if the turn is over and MinSecondsBetweenTurns have passed.
                // Wait for all entities to stand still, but at most MaxSecondsBetweenTurns.
                if (Session.TurnState == TurnState.WaitingForEnd &&
                    (Session.TurnTime > Session.MaxSecondsBetweenTurns ||
                     (Session.TurnTime > Session.MinSecondsBetweenTurns && !Session.World.IsSomethingMoving))
                    )
                {
                    StartNextTurn();
                }
            }

            var worldState = Session.World;

            if (Game.Match.State == SessionState.Running && !Session.IsRemoteControlled)
            {
                // Update all active balls
                var currentControllers = ActiveControllers.Values.ToArray();
                foreach (var controller in currentControllers)
                {
                    if (controller != null && controller.Ball.Player.IsLocal && (controller.Ball.Player == Session.ActivePlayer || !Session.UsePlayerTurns))
                    {
                        var playerMadeAction = controller.Update(elapsedSeconds, worldState);
                        if (playerMadeAction)
                        {
                            EndTurn();
                        }
                    }
                }

                // Check for dead balls
                List <Player> alivePlayers    = new List <Player>();
                Player        winner          = null;
                var           ballControllers = BallControllers.Values.ToArray();
                foreach (var controller in ballControllers)
                {
                    if (controller.Ball.Disposed || !controller.Ball.IsAlive)
                    {
                        controller.Ball.Player.OwnedBalls.Remove(controller.Ball);

                        if (controller.Ball.Player == Session.ActivePlayer)
                        {
                            StartNextTurn();
                        }

                        ActiveControllers.Remove(controller.Ball.Player);
                        BallControllers.Remove(controller.Ball);
                    }
                    else if (controller.Ball.IsAlive)
                    {
                        if (!alivePlayers.Contains(controller.Ball.Player))
                        {
                            alivePlayers.Add(controller.Ball.Player);
                        }
                        winner = controller.Ball.Player;
                    }
                }

                //TODO: find proper game finished condition, this one is not always correct
                if (alivePlayers.Count < 2)
                {
                    Game.Match.State = SessionState.Finished;
                    //TODO: find proper condition to determine the winner, this one is not always correct
                    if (alivePlayers.Count == 1)
                    {
                        Game.Match.Winner = winner;
                        Game.Services.GetService <Sound.SoundControl>().PlaySound(Sound.SoundControl.WinnerSounds[winner.TeamName]);
                    }
                }
            }
        }