Just thought I would share. I implemented the click to move and click and hold to move using the new input system.
First I defined a ClickToMove action in an Input Action Asset named Player Controls as follows:
Next here is my Mover script:
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.InputSystem;
public class Mover : MonoBehaviour
{
private NavMeshAgent _navAgent;
private PlayerControls _controls;
private Animator _anim;
private Camera _cam;
private bool _moveShouldContinue;
private bool _moveHasStarted;
private void Awake() {
_controls = new PlayerControls();
_navAgent = GetComponent<NavMeshAgent>();
_anim = GetComponent<Animator>();
_cam = Camera.main;
}
private void OnEnable() {
_controls.Enable();
}
private void OnDisable() {
_controls.Disable();
}
private void Start() {
_controls.Player.ClickToMove.started += OnClickToMoveStarted;
_controls.Player.ClickToMove.performed += OnClickToMove;
_controls.Player.ClickToMove.canceled += OnClickToMoveCanceled;
}
private void LateUpdate() {
// check if we are holding the mouse button down so we
// should keep moving
if (_moveShouldContinue && _moveHasStarted) {
MoveToRay();
}
}
private void OnClickToMoveStarted(InputAction.CallbackContext context) {
// set the boolean flags when we click the mouse
_moveShouldContinue = true;
_moveHasStarted = false;
}
private void OnClickToMove(InputAction.CallbackContext context) {
// started to actually move
_moveHasStarted = true;
MoveToRay();
}
private void OnClickToMoveCanceled(InputAction.CallbackContext context) {
// we have released the mouse, so we should not continue movement
_moveShouldContinue = false;
}
// move us to the ray defined by the mouse's current position
private void MoveToRay() {
var ray = _cam.ScreenPointToRay(Mouse.current.position.ReadValue());
var hasHit = Physics.Raycast(ray, out var hit);
if (hasHit) {
_navAgent.destination = hit.point;
}
UpdateAnimator();
}
// update the animator
private void UpdateAnimator() {
var vel = _navAgent.velocity;
var localVel = transform.InverseTransformDirection(vel);
_anim.SetFloat("forwardSpeed", localVel.z);
}
}
The two booleans _moveShouldContinue and _moveHasStarted work together to let the mover know if we just clicked the mouse or are holding down the mouse. The three methods the ClickToMove action is subscribed to take care of setting those booleans as well as moving the player.
For click and hold I am using LateUpdate which checks for both flags to be true and if so continue moving to where the mouse is pointing to. This is needed because, as I understand it, the input system not yet has implemented continuous callbacks.
Hope this helps!