top of page

未発表パーティゲーム PlayerInputListener.cs

msandfrey3
Aug 12, 2024
2 min read
using UnityEngine;
using UnityEngine.InputSystem;
using Fusion;
using System;
using PartyGame.CameraManagement;
namespace PartyGame.Multiplayer.Inputs
{
    /// <summary>
    /// Listens to the PlayerInput actions and raises events when they are triggered.
    /// 
    /// This class acts as a wrapper for the PlayerInput and will convert actions to game-related terminology and events. 
    /// </summary>
    public class PlayerInputListener : NetworkBehaviour
    {
        private const string GrappleActionName = "Grapple";
        private const string UpdateGrappleAimDirectionActionName = "UpdateGrappleAimDirection"; // for gamepad
        private const string UpdateGrappleAimEndPointActionName = "UpdateGrappleAimEndPoint"; // for mouse
        private const string PauseActionName = "Pause";
        private const string ReadyActionName = "Ready";
        private readonly Plane _playPlane = new Plane(Vector3.up, Vector3.zero);
        [SerializeField] private PlayerInput _playerInput;
        [SerializeField, Tooltip("The transform where the grapple aim starts")] private Transform _aimTransform;
        private InputAction _grappleAction;
        private InputAction _controllerAimAction;
        private InputAction _mouseAimAction;
        private InputAction _pauseAction;
        private InputAction _readyAction;
        private bool _isGrapplePressed;
        private Gamepad _gamepad;
        private Camera _camera;
        private Ray? _aimRay;
        private Vector3 _aimPosition;
        private Vector3 _oldAimSourcePosition;
        private bool _isMouse = false;
        public event Action<Ray> OnGrapplePressed;
        public event Action OnGrappleReleased;
        public event Action<Ray> OnAimUpdated;
        public event Action OnAimCleared;
        public event Action OnPause;
        public event Action OnReady;
        public Gamepad Gamepad => _gamepad;
        public override void Spawned()
        {
            base.Spawned();
            PlayerCamera playerCamera = FindAnyObjectByType<PlayerCamera>();
            _camera = playerCamera.AimCamera;
            UnityEngine.Assertions.Assert.IsNotNull(_camera, "PlayerInputListener: Player Aim Camera is null");
        }
        public override void Despawned(NetworkRunner runner, bool hasState)
        {
            UnsubscribeInputs();
        }
        /// <summary>
        /// Sets the player camera used for aiming. 
        /// </summary>
        /// <param name="playerCamera"></param>
        public void SetPlayerCamera(PlayerCamera playerCamera)
        {
            _camera = playerCamera.AimCamera;
        }
        public void SetGamepadAndMouse(Gamepad gamepad)
        {
            _gamepad = gamepad;
            _playerInput.SwitchCurrentControlScheme(_playerInput.defaultControlScheme, _gamepad, Mouse.current, Keyboard.current);
        }
        public void SetMouse()
        {
            _playerInput.SwitchCurrentControlScheme(_playerInput.defaultControlScheme, Mouse.current, Keyboard.current);
        }
        public void SetGamepad(Gamepad gamepad)
        {
            _gamepad = gamepad;
            _playerInput.SwitchCurrentControlScheme(_playerInput.defaultControlScheme, _gamepad);
        }
        public void SetGameActionMap(string actionNamePrefix, string actionMap)
        {
            _playerInput.currentActionMap.Disable();
            _playerInput.defaultActionMap = actionMap;
            _playerInput.SwitchCurrentActionMap(actionMap);
            _playerInput.currentActionMap.Enable();
            _grappleAction = _playerInput.actions[actionNamePrefix + GrappleActionName];
            _controllerAimAction = _playerInput.actions[actionNamePrefix + UpdateGrappleAimDirectionActionName];
            _mouseAimAction = _playerInput.actions[actionNamePrefix + UpdateGrappleAimEndPointActionName];
            _pauseAction = _playerInput.actions[actionNamePrefix + PauseActionName];
            _readyAction = _playerInput.actions[actionNamePrefix + ReadyActionName];
            _grappleAction.performed += GrapplePressed;
            _grappleAction.canceled += GrappleReleased;
            _mouseAimAction.performed += MouseAimUpdated;
            _mouseAimAction.canceled += MouseAimCanceled;
            _controllerAimAction.performed += ControllerAimUpdated;
            _controllerAimAction.canceled += ControllerAimCanceled;
            _pauseAction.performed += PausePressed;
            _readyAction.performed += ReadyPressed;
        }
        private void PausePressed(InputAction.CallbackContext context)
        {
            OnPause?.Invoke();
        }
        private void ReadyPressed(InputAction.CallbackContext context)
        {
            OnReady?.Invoke();
        }
        private void ControllerAimCanceled(InputAction.CallbackContext context)
        {
            OnAimCleared?.Invoke();
        }
        private void ControllerAimUpdated(InputAction.CallbackContext context)
        {
            _isMouse = false;
            _aimRay = new Ray(_aimTransform.position, new Vector3(context.ReadValue<Vector2>().x, 0, context.ReadValue<Vector2>().y));
            OnAimUpdated?.Invoke(_aimRay.Value);
        }
        private void MouseAimCanceled(InputAction.CallbackContext context)
        {
            _isMouse = false;
            _aimRay = null;
            OnAimCleared?.Invoke();
        }
        private void MouseAimUpdated(InputAction.CallbackContext context)
        {
            _isMouse = true;
            _aimPosition = Vector3.zero;
            Ray mouseRay = _camera.ScreenPointToRay(context.ReadValue<Vector2>());
            if (_playPlane.Raycast(mouseRay, out float distanceToPlane))
            {
                _aimPosition = mouseRay.GetPoint(distanceToPlane);
            }
            Vector3 direction = _aimPosition - _aimTransform.position;
            _aimRay = new Ray(_aimTransform.position, new Vector3(direction.x, 0, direction.z));
            OnAimUpdated?.Invoke(_aimRay.Value);
        }
        public override void Render()
        {
            if (_oldAimSourcePosition != _aimTransform.position && _isMouse)
            {
                //update ray
                Vector3 direction = _aimPosition - _aimTransform.position;
                _aimRay = new Ray(_aimTransform.position, new Vector3(direction.x, 0, direction.z));
                OnAimUpdated?.Invoke(_aimRay.Value);
            }
            _oldAimSourcePosition = _aimTransform.position;
        }
        private void GrapplePressed(InputAction.CallbackContext ctx)
        {
            if (_aimRay != null)
            {
                _isGrapplePressed = true;
                OnGrapplePressed?.Invoke(_aimRay.Value);
            }
        }
        private void GrappleReleased(InputAction.CallbackContext ctx)
        {
            if (_isGrapplePressed)
            {
                _isGrapplePressed = false;
                OnGrappleReleased?.Invoke();
            }
        }
        private void UnsubscribeInputs()
        {
            if (_grappleAction != null)
            {
                _grappleAction.performed -= GrapplePressed;
                _grappleAction.canceled -= GrappleReleased;
            }
        }
        private void OnDestroy()
        {
            UnsubscribeInputs();
        }
    }
}

Recent Posts

See All

Comments


© 2024 by Matthew Sandfrey. Proudly created with Wix.com

bottom of page