Protfolio-Emanuel-Polsky / Assets / _Project / Code / PathFinding / Systems / PathRigidbodyMovementSystem.cs
PathRigidbodyMovementSystem.cs
Raw
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics;
using Unity.Transforms;

namespace GarmentButton.PathFinding
{
    [BurstCompile]
    [UpdateAfter(typeof(CalculatePathSystem))]
    [UpdateAfter(typeof(UpdatePathBufferBasePosition))]
    public partial struct PathRigidbodyMovementSystem : ISystem
    {
        [BurstCompile]
        public void OnCreate(ref SystemState state)
        {
            var query = SystemAPI.QueryBuilder()
                .WithAll<PathRigidbodyMovement, PhysicsVelocity, LocalTransform, PathElement>()
                .Build();

            state.RequireForUpdate(query);
            state.RequireForUpdate<Grid>();
        }

        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            var grid = SystemAPI.GetSingleton<Grid>().Value;

            state.Dependency = new MoveAlongPathJob
            {
                Grid = grid,
            }.ScheduleParallel(state.Dependency);
        }

        [BurstCompile]
        public partial struct MoveAlongPathJob : IJobEntity
        {
            [ReadOnly] public BlobAssetReference<PointPathBlobAsset> Grid;

            public void Execute(
                ref PhysicsVelocity velocity,
                in PathRigidbodyMovement movement,
                in LocalTransform transform,
                in DynamicBuffer<PathElement> path)
            {
                var linearVelocity = velocity.Linear;

                if (path.Length == 0 || movement.MoveSpeed <= 0f)
                {
                    linearVelocity.x = 0f;
                    linearVelocity.z = 0f;
                    velocity.Linear = linearVelocity;
                    return;
                }

                var targetPoint = Grid.Value.Array[path[0].IndexGrid];
                var targetPosition = new float3(targetPoint.X, targetPoint.Y, targetPoint.Z) / 10f;
                var planarOffset = (targetPosition - transform.Position).xz;
                var stopDistance = math.max(0.01f, movement.StopDistance);

                if (math.lengthsq(planarOffset) <= stopDistance * stopDistance)
                {
                    linearVelocity.x = 0f;
                    linearVelocity.z = 0f;
                    velocity.Linear = linearVelocity;
                    return;
                }

                var direction = math.normalize(planarOffset);
                linearVelocity.x = direction.x * movement.MoveSpeed;
                linearVelocity.z = direction.y * movement.MoveSpeed;
                velocity.Linear = linearVelocity;
            }
        }
    }
}