SELF RESOLVED (roughly speaking. See own reply)
Good morning,
I’m relatively new to coding, making a 1st-person game for fun. I’ve spent the past 4 days trying to implement Input System, without good knowledge of the older Input schema before this. Using Unity 2020.3.2f1 with Input System v1.0.2.
I have an Input asset, action map, and various actions set up with two schemes, Keyboard+Mouse and Gamepad. A sample of current bindings so you can see how I’m handling things:
Move [Val V2] - WASD [2D Vec], Left Stick
Look Gamepad [Val V2] - Right Stick
Look Mouse [Val V2] - Delta [Mouse] ← Currently handle differently in code
Crouch Toggle [Button] - C Key, Left Stick Button
Crouch Hold [Button] - Ctrl Key, Button West
Other inputs include Sprint hold/toggle, Zoom hold/toggle, actions like interact/jump.
Right now I have a player object with character controller on it, main camera child to that, and a monolithic PlayerController script, which I plan to refactor when I’ve got everything working (and when I’ve learnt some best practices for how to refactor!).
Some problems I have:
-
I don’t know if I’m doing any of this right in any way. I could be using completely wrong methodologies and wouldn’t have a clue. I don’t know how to fix or improve it.
-
Mouse sensitivity is still too high, despite the fact I’m
-
modifying incoming vec2 by 1.1f, then by 0.01f, then even by 0.1f if zooming. Even when I remove that 1.1f, it’s still too high.
-
Contrast with input from the gamepad, which is too slow even when being multiplied by 2.0f.
-
When I manage to slow down the mouse, it jitters across the screen; even the smallest mouse movement can jump many pixels on screen, but it seems inconsistent
-
When I tried combining the two Look actions,
-
I had no easy way to apply a different sensitivity for the mouse (except ctx.control.device.name),
-
Meant that the mouse was being called in FixedUpdate, which made it janky
-
When I tried pulling the LookUpdate method out of FixedUpdate (so it would be only used from the registered Awake statements for both Mouse and Gamepad) the Gamepad look stopped working (would move a tiny amount for only the frame of input).
-
All the tutorials I can find is for the old input get axis stuff, and the few tutorials which do use the new input system either don’t demonstrate both mouse and gamepad, or are for non-FPS type games/controls
-
Documentation is too hard to understand
Relevant code:
I’m attaching the cs file as well, but putting the relevant code here. The cs file has other unfinished code in it like sprinting and zooming, but I’m including anyway. Some of the methods and variables have different names in there, because I changed some things to make the relevant code below clearer.
//There is other code in this class for things like sprinting, zooming, crouching
//So I've cut those bits out and commented where relevant
//All the comments in this class aren't indicative of how I actually comment my code, they're there because I've stripped out some of the context. Also put some simple things on one line instead of 2.
(using UnityEngine and UnityEngine.InputSystem)
namespace ProjectAlpha.Player
{
public class PlayerController : MonoBehaviour
{ // ---References
private CharacterController _characterController;
private InputMap _inputMap;
private InputMap.AMGameplayActions _imgmap;
public Transform playerCamera;
// ---Movement variables
private const float gravity = -13.0f;
private float _playerVelocityY, _playerSpeed;
private const float MoveSmoothTime = 0.1f;
private Vector2 _targetMoveDirection = Vector2.zero;
private Vector2 _currentDirection = Vector2.zero;
private Vector2 _currentDirectionVelocity = Vector2.zero;
// ---General Look variables
private float _calculateSensitivity;
private Vector2 _currentLookDelta = Vector2.zero;
private Vector2 _currentLookDeltaVelocity = Vector2.zero;
private const float LookSmoothTime = 0.03f;
private float _cameraPitch;
private Vector2 _look = Vector2.zero;
// ---Mouselook variables
[Range(0.0f, 5.0f)] private float mouseLookSpeed = 1.1f;
private const float MouseSpeedMagicModifier = 0.01f;
private float _conditionalMouseZoomSpeedModifier; //switches between 0.1 or 1f
private float _conditionalNonMouseZoomSpeedModifier = 1.0f; //same but 0.4 or 1f
private float _totalMouseSensitivity;
// ---Gamepadlook variables - generically named for future
private float nonMouseLookSpeed = 2f;
private void Awake()
{
_characterController = GetComponent<CharacterController>();
_inputMap = new InputMap();
_imgmap = _inputMap.AMGameplay;
_totalMouseSensitivity = mouseLookSpeed * MouseSpeedMagicModifier;
_imgmap.Move.performed += ctx => _targetMoveDirection = ctx.ReadValue<Vector2>();
_imgmap.Move.canceled += ctx => _targetMoveDirection = Vector2.zero;
//If mouse, pass context to LookUpdate and say yes am a mouse
_imgmap.MouseLook.performed += ctx => LookUpdate(ctx.ReadValue<Vector2>(), true);
//If not a mouse, set _look (which gets handled in FixedUpdate)
_imgmap.Look.performed += ctx => _look = ctx.ReadValue<Vector2>();
_imgmap.Look.canceled += ctx => _look = Vector2.zero;
}
private void FixedUpdate()
{
MovementUpdate();
LookUpdate(_look, false); //Updating using _look, tell method not a mouse
}
private void MovementUpdate()
{ //Some code here modifies _playerSpeed if sprinting,zooming,crouching bools are set
//Handling gravity
if (_characterController.isGrounded) { _playerVelocityY = 0.0f; }
_playerVelocityY += gravity * Time.deltaTime;
_targetMoveDirection.Normalize();
_currentDirection = Vector2.SmoothDamp(_currentDirection, _targetMoveDirection, ref _currentDirectionVelocity, MoveSmoothTime);
var velocity = (transform.forward * _currentDirection.y + transform.right * _currentDirection.x) * _playerSpeed + (Vector3.up * _playerVelocityY);
_characterController.Move(velocity * Time.deltaTime);
}
private void LookUpdate(Vector2 targetDelta, bool isMouse)
{
_calculateSensitivity = isMouse switch
{
//The _conditional floats get modified by a zoom method (not included)
true => _totalMouseSensitivity * _conditionalMouseZoomSpeedModifier,
false => nonMouseLookSpeed * _conditionalNonMouseZoomSpeedModifier
};
_currentLookDelta = Vector2.SmoothDamp(_currentLookDelta, targetDelta, ref _currentLookDeltaVelocity,
LookSmoothTime);
_cameraPitch -= _currentLookDelta.y * _calculateSensitivity;
_cameraPitch = Mathf.Clamp(_cameraPitch, -90.0f, 90.0f);
playerCamera.localEulerAngles = Vector3.right * _cameraPitch;
transform.Rotate(Vector3.up * (_currentLookDelta.x * _calculateSensitivity));
}
}
}
Videos
The first shows gamepad look first, then mouse look after.
The second shows changing the mouse speed mid-game, and the jitter is more noticeable.
Requesting
Any advice, corrections, suggestions, anything to help me improve this. My main goal is to have functioning move and look with both Gamepads and Keyboard+Mouse. I want to continue using the InputSystem rather than switching back to the old system, because that seems to be the future for Unity, and because I’d like the benefits of being able to extend controller support later as the project progresses.
Any advice would be greatly appreciated. Thanks!
7003106–827828–PlayerController.cs (13.2 KB)