improv: UnitMovementHandler.cs uses IUnitDirectionProvider.cs for direction instead of input direction directly

This commit is contained in:
Chris
2025-10-23 21:55:14 -04:00
parent 958c57bdc0
commit f1dee5c0e4
5 changed files with 91 additions and 11 deletions

View File

@@ -0,0 +1,74 @@
using Pathfinding;
using UnityEngine;
namespace Reset.Units{
public class EnemyPathfinding : MonoBehaviour, IUnitDirectionProvider{
public Vector2 Direction{ get; set; }
public Transform targetPosition;
private Seeker seeker;
public float nextWaypointDistance = 3;
private int currentWaypoint;
public Path path;
public bool reachedEndOfPath;
public void Start(){
seeker = GetComponent<Seeker>();
// If you are writing a 2D game you should remove this line
// and use the alternative way to move sugggested further below.
seeker.StartPath(transform.position, targetPosition.position, OnPathComplete);
}
public void OnPathComplete(Path p){
if (!p.error) {
path = p;
// Reset the waypoint counter so that we start to move towards the first point in the path
currentWaypoint = 0;
}
}
public void Update(){
if (path == null) {
// We have no path to follow yet, so don't do anything
return;
}
reachedEndOfPath = false;
// The distance to the next waypoint in the path
float distanceToWaypoint;
while (true) {
// If you want maximum performance you can check the squared distance instead to get rid of a
// square root calculation. But that is outside the scope of this tutorial.
distanceToWaypoint = Vector3.Distance(transform.position, path.vectorPath[currentWaypoint]);
if (distanceToWaypoint < nextWaypointDistance) {
// Check if there is another waypoint or if we have reached the end of the path
if (currentWaypoint + 1 < path.vectorPath.Count) {
currentWaypoint++;
} else {
// Set a status variable to indicate that the agent has reached the end of the path.
// You can use this to trigger some special code if your game requires that.
reachedEndOfPath = true;
break;
}
} else {
break;
}
}
// Slow down smoothly upon approaching the end of the path
// This value will smoothly go from 1 to 0 as the agent approaches the last waypoint in the path.
var speedFactor = reachedEndOfPath ? Mathf.Sqrt(distanceToWaypoint / nextWaypointDistance) : 1f;
// Direction to the next waypoint
// Normalize it so that it has a length of 1 world unit
Vector3 dirToPoint = (path.vectorPath[currentWaypoint] - transform.position).normalized * speedFactor;
Direction = dirToPoint.ToVector2();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1a67969fa2454c8f8b5c84c31c95d890
timeCreated: 1761268522

View File

@@ -2,6 +2,6 @@
namespace Reset.Units{ namespace Reset.Units{
public interface IUnitDirectionProvider{ public interface IUnitDirectionProvider{
public Vector2 direction{ get; set; } public Vector2 Direction{ get; }
} }
} }

View File

@@ -13,14 +13,17 @@ using Sirenix.OdinInspector;
using Unity.Cinemachine; using Unity.Cinemachine;
using Object = UnityEngine.Object; using Object = UnityEngine.Object;
public class PlayerControls : MonoBehaviour{ public class PlayerControls : MonoBehaviour, IUnitDirectionProvider{
// References // References
private Player thisPlayer; private Player thisPlayer;
private PlayerInput input; private PlayerInput input;
private SignalDefinition inputSignal; private SignalDefinition inputSignal;
private SignalDefinition blockSignal; private SignalDefinition blockSignal;
// IUnitDirectionProvider
public Vector2 Direction => rawMoveInput;
// TODO: Turn these into accessors // TODO: Turn these into accessors
public Vector2 rawMoveInput; public Vector2 rawMoveInput;
public Vector2 rawLookInput; public Vector2 rawLookInput;

View File

@@ -19,7 +19,7 @@ namespace Reset.Units{
// References // References
private CharacterController controller; private CharacterController controller;
private PlayerControls controls; private IUnitDirectionProvider directionProvider;
private IUnitTargetProvider targetProvider; private IUnitTargetProvider targetProvider;
// Movement Data // Movement Data
@@ -30,7 +30,7 @@ namespace Reset.Units{
void Awake(){ void Awake(){
controller = GetComponent<CharacterController>(); controller = GetComponent<CharacterController>();
controls = GetComponent<PlayerControls>(); directionProvider = GetComponent<IUnitDirectionProvider>();
targetProvider = GetComponent<IUnitTargetProvider>(); targetProvider = GetComponent<IUnitTargetProvider>();
InitAllSettings(); InitAllSettings();
@@ -59,7 +59,7 @@ namespace Reset.Units{
// Update the direction, called every frame // Update the direction, called every frame
private void UpdateCurrentDirection(){ private void UpdateCurrentDirection(){
// Get input value // Get input value
Vector2 targetDirection = new Vector2(controls.rawMoveInput.x, controls.rawMoveInput.y); Vector2 targetDirection = new Vector2(directionProvider.Direction.x, directionProvider.Direction.y);
// Rotate input by camera rotation (instead of rotating the output direction by camera rotation) // Rotate input by camera rotation (instead of rotating the output direction by camera rotation)
targetDirection = (Camera.main.transform.rotation * targetDirection.ToVector3()).ToVector2(); targetDirection = (Camera.main.transform.rotation * targetDirection.ToVector3()).ToVector2();
@@ -97,7 +97,7 @@ namespace Reset.Units{
newDirection = Vector2.SmoothDamp(currentDirection, targetDirection, ref refVelocityDirectionChangingHardness, data.directionChangingSoftness.Value * data.airDirectionDecay.Value * Time.deltaTime); newDirection = Vector2.SmoothDamp(currentDirection, targetDirection, ref refVelocityDirectionChangingHardness, data.directionChangingSoftness.Value * data.airDirectionDecay.Value * Time.deltaTime);
} }
newDirection = Vector3.Slerp(resolvedMovement.moveDirection.World, newDirection, controls.rawMoveInput.magnitude); newDirection = Vector3.Slerp(resolvedMovement.moveDirection.World, newDirection, directionProvider.Direction.magnitude);
// Commit the new direction // Commit the new direction
resolvedMovement.moveDirection.World = newDirection; resolvedMovement.moveDirection.World = newDirection;
@@ -108,7 +108,7 @@ namespace Reset.Units{
// ""Smooth"" the speed // ""Smooth"" the speed
float smoothedSpeed; float smoothedSpeed;
if (resolvedMovement.moveDirection.Local.magnitude < controls.rawMoveInput.magnitude) { if (resolvedMovement.moveDirection.Local.magnitude < directionProvider.Direction.magnitude) {
smoothedSpeed = Mathf.MoveTowards(resolvedMovement.moveSpeed, data.moveSpeed.Value, data.acceleration.Value * Time.deltaTime); smoothedSpeed = Mathf.MoveTowards(resolvedMovement.moveSpeed, data.moveSpeed.Value, data.acceleration.Value * Time.deltaTime);
} else { } else {
smoothedSpeed = Mathf.MoveTowards(resolvedMovement.moveSpeed, 0f, data.deacceleration.Value * Time.deltaTime); smoothedSpeed = Mathf.MoveTowards(resolvedMovement.moveSpeed, 0f, data.deacceleration.Value * Time.deltaTime);
@@ -135,7 +135,7 @@ namespace Reset.Units{
// Update the rotation, called every frame // Update the rotation, called every frame
private void UpdateCurrentRotation(){ private void UpdateCurrentRotation(){
// Get input value // Get input value
Vector3 inputMovement = new Vector3(controls.rawMoveInput.x, 0f, controls.rawMoveInput.y); Vector3 inputMovement = new Vector3(directionProvider.Direction.x, 0f, directionProvider.Direction.y);
Quaternion targetRotation = Quaternion.identity; Quaternion targetRotation = Quaternion.identity;
// Switch the desired rotation based on current movement setting // Switch the desired rotation based on current movement setting
@@ -162,7 +162,7 @@ namespace Reset.Units{
break; break;
case PlayerFacingDirection.MatchInput: case PlayerFacingDirection.MatchInput:
// Look towards the input direction- similar to Momentum but snappier // Look towards the input direction- similar to Momentum but snappier
if (controls.rawMoveInput.magnitude < 0.05f) { break; } if (directionProvider.Direction.magnitude < 0.05f) { break; }
targetRotation = Camera.main.transform.rotation * Quaternion.LookRotation(inputMovement); targetRotation = Camera.main.transform.rotation * Quaternion.LookRotation(inputMovement);
break; break;
@@ -181,7 +181,7 @@ namespace Reset.Units{
// Add the current input into the created rotation // Add the current input into the created rotation
if (data.facingDirection.Value == PlayerFacingDirection.MatchCamera || data.facingDirection.Value == PlayerFacingDirection.TowardsTarget) { if (data.facingDirection.Value == PlayerFacingDirection.MatchCamera || data.facingDirection.Value == PlayerFacingDirection.TowardsTarget) {
resolvedMovement.rotation = targetRotation; resolvedMovement.rotation = targetRotation;
} else if (controls.rawMoveInput.sqrMagnitude > .1){ } else if (directionProvider.Direction.sqrMagnitude > .1){
resolvedMovement.rotation = targetRotation; resolvedMovement.rotation = targetRotation;
} }