Hi all. I’ve been working on a navmesh-based character controller based on this great video from Ciro Continisio. Here’s how I adapted his code to work with the old Input Manager:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class PlayerMovement : MonoBehaviour{
public float speed = 10f;
private Vector3 inputValue = Vector3.zero;
private float inputSqrMagnitude;
void Update(){
Step();
}
private void Step(){
inputValue = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
inputSqrMagnitude = inputValue.sqrMagnitude;
if(inputSqrMagnitude >= .01f){
Vector3 newPosition = transform.localPosition + inputValue * Time.deltaTime * speed;
NavMeshHit hit;
bool isValid = NavMesh.SamplePosition(newPosition, out hit, 1.0f, NavMesh.AllAreas);
if(isValid){
if((transform.localPosition - hit.position).magnitude >= .02f){
transform.localPosition = hit.position;
}else{
// movement stopped this frame
}
}
}else{
// no input from player
}
}
}
This has been helping me prototype levels very quickly, but I’ve noticed that diagonal movement is much faster than single-axis movement. Typically this can be controlled by normalizing or clamping the magnitude of the target vector, but I’m not sure how to do that here. I’ve tried the following:
-
transform.localPosition = Vector3.ClampMagnitude(hit.position, speed);
causes character to teleport diagonally and get stuck in the terrain after any WASD input -
transform.localPosition = hit.position.normalized;
does the same -
newPosition = Vector3.ClampMagnitude(newPosition, speed);
also causes the character to teleport, but they can still move within a small circular area in the level -
newPosition = newPosition.normalized;
, which leaves the character unable to move at all
Any ideas?