Hello everyone!
I want to share the results of my work with A*.
I managed to make my character search for the ground around itself, and when it found it, change the direction of movement. Additionally, I redesigned the mesh of my level and regenerated the navmesh, which significantly improved the situation, but it’s still far from perfect. What bothers me the most is why my character sometimes detaches from the ground and starts moving in the air. Shouldn’t it always stay grounded?
I have questions regarding ray optimization. Perhaps someone has recommendations for optimization? Because right now, I’m doing it rather blindly.
Here’s an example of my code for the character and a small video of what I’ve achieved. I like the result, it looks cool. What do you think?
using System.Collections.Generic;
using UnityEngine;
namespace Pathfinding {
public class AIPathAlignedToSurfaceExtremeDegrees : AIPathAlignedToSurface {
[SerializeField]
private float additionalRayDistance = 1f;
[SerializeField]
private float horizontalRaysCount = 10f;
[SerializeField]
private float verticalRaysCount = 10f;
[SerializeField]
private float maxVerticalAngle = 10f;
protected override void UpdateMovementPlane() {
base.UpdateMovementPlane();
var lAverageNormal = lastRaycastHit.normal;
var lValidHits = 1;
foreach (var aRayDirection in GetRayDirections())
{
if (!TryGetSurfaceNormalAtDirection(aRayDirection, out var aNormal)) continue;
lAverageNormal += aNormal;
lValidHits++;
}
if (lValidHits > 1) {
SetInterpolatedNormal(lAverageNormal / lValidHits);
}
}
private bool TryGetSurfaceNormalAtDirection(Vector3 aDirection, out Vector3 aNormal) {
var lRayOrigin = transform.position;
var lHitSomething = Physics.Raycast(lRayOrigin, aDirection, out var aHit, additionalRayDistance);
aNormal = lHitSomething ? aHit.normal : Vector3.zero;
return lHitSomething;
}
private IEnumerable<Vector3> GetRayDirections() {
for (var i = 0; i < horizontalRaysCount; i++) {
var lHorizontalAngle = (i / horizontalRaysCount) * 360f;
for (var j = 0; j < verticalRaysCount; j++) {
var lVerticalAngle = -maxVerticalAngle + (j / (verticalRaysCount - 1)) * (2 * maxVerticalAngle);
var lHorizontalRotation = Quaternion.Euler(0, lHorizontalAngle, 0);
var lVerticalRotation = Quaternion.Euler(lVerticalAngle, 0, 0);
var lRayDirection = lHorizontalRotation * lVerticalRotation * Vector3.forward;
yield return lRayDirection;
}
}
}
protected override void OnDrawGizmosSelected() {
foreach (var aRayDirection in GetRayDirections()) {
Gizmos.color = Color.red;
Gizmos.DrawRay(transform.position, aRayDirection * additionalRayDistance);
}
}
}
}
Useful links on the forum that can help. Thank you to all the authors, I found useful information.