146 lines
4.5 KiB
C#
146 lines
4.5 KiB
C#
![]() |
using Pathfinding;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace DDD
|
||
|
{
|
||
|
public class RestaurantNpcMovement : RestaurantCharacterMovement, IAiMovement
|
||
|
{
|
||
|
private IAstarAI _iAstarAi;
|
||
|
|
||
|
protected override void Awake()
|
||
|
{
|
||
|
base.Awake();
|
||
|
|
||
|
_iAstarAi = GetComponent<IAstarAI>();
|
||
|
Debug.Assert(_iAstarAi != null, "_iAstarAi is null");
|
||
|
}
|
||
|
|
||
|
private const int MaxRandomMoveAttempts = 1000;
|
||
|
|
||
|
public Vector3 CurrentPosition => _iAstarAi.position;
|
||
|
public Vector3 Destination => _iAstarAi.destination;
|
||
|
public float CurrentSpeed => _iAstarAi.velocity.magnitude;
|
||
|
public bool IsMoving => !_iAstarAi.isStopped && _iAstarAi.hasPath;
|
||
|
|
||
|
public void EnableMove()
|
||
|
{
|
||
|
_iAstarAi.canMove = true;
|
||
|
}
|
||
|
|
||
|
public void DisableMove()
|
||
|
{
|
||
|
_iAstarAi.canMove = false;
|
||
|
}
|
||
|
|
||
|
public void PlayMove()
|
||
|
{
|
||
|
_iAstarAi.isStopped = false;
|
||
|
}
|
||
|
|
||
|
public void StopMove()
|
||
|
{
|
||
|
_iAstarAi.isStopped = true;
|
||
|
_iAstarAi.SetPath(null);
|
||
|
}
|
||
|
|
||
|
public void SetMoveSpeed(float speed)
|
||
|
{
|
||
|
_iAstarAi.maxSpeed = speed;
|
||
|
}
|
||
|
|
||
|
public bool TryMoveToPosition(Vector3 position)
|
||
|
{
|
||
|
if (IsPositionMovable(position) == false)
|
||
|
{
|
||
|
Debug.LogWarning($"{gameObject.name}이 이동 불가능한 위치를 대상으로 이동을 시도함");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
_iAstarAi.destination = position;
|
||
|
PlayMove();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public bool TryMoveToTarget(Collider targetCollider)
|
||
|
{
|
||
|
if (targetCollider == null)
|
||
|
{
|
||
|
Debug.LogWarning($"{gameObject.name}이 이동하려는 타겟을 찾지 못함");
|
||
|
StopMove();
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return TryMoveToPosition(targetCollider.transform.position);
|
||
|
}
|
||
|
|
||
|
public Vector3 GetRandomBetweenTwoPoints(Vector2? normalizedRange = null)
|
||
|
{
|
||
|
var range = normalizedRange ?? new Vector2(0.2f, 0.8f);
|
||
|
var randomFactor = Random.Range(range.x, range.y);
|
||
|
return Vector3.Lerp(_iAstarAi.position, _iAstarAi.destination, randomFactor);
|
||
|
}
|
||
|
|
||
|
public bool TryTeleportToPosition(Vector3 position)
|
||
|
{
|
||
|
if (IsPositionMovable(position) == false)
|
||
|
{
|
||
|
Debug.LogWarning($"{gameObject.name}오브젝트가 이동 불가능한 위치로 텔레포트 시도됨");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
_iAstarAi.Teleport(position);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public bool HasReachedDestination()
|
||
|
{
|
||
|
return _iAstarAi.pathPending == false && _iAstarAi.reachedEndOfPath;
|
||
|
}
|
||
|
|
||
|
public bool IsPositionMovable(Vector3 endPosition)
|
||
|
{
|
||
|
var nearestNode = AstarPath.active.GetNearest(endPosition).node;
|
||
|
return nearestNode != null && nearestNode.Walkable;
|
||
|
}
|
||
|
|
||
|
public bool TryMoveToRandomPositionInRange(float range, int graphIndex = 0)
|
||
|
{
|
||
|
if (graphIndex < 0 || graphIndex >= AstarPath.active.graphs.Length)
|
||
|
{
|
||
|
Debug.LogWarning($"{gameObject.name} - 유효하지 않은 그래프 인덱스: {graphIndex}");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
int attempts = 0;
|
||
|
Vector3 randomPosition;
|
||
|
var isMovable = false;
|
||
|
var graphBounds = AstarPath.active.graphs[graphIndex].bounds;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
var randomDirection = Random.insideUnitCircle.normalized;
|
||
|
var randomOffset = new Vector3(randomDirection.x, 0, randomDirection.y) * Random.Range(0, range);
|
||
|
|
||
|
randomPosition = _iAstarAi.position + randomOffset;
|
||
|
if (!graphBounds.Contains(randomPosition))
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
isMovable = IsPositionMovable(randomPosition);
|
||
|
|
||
|
attempts++;
|
||
|
} while (!isMovable && attempts < MaxRandomMoveAttempts);
|
||
|
|
||
|
if (isMovable == false)
|
||
|
{
|
||
|
Debug.LogWarning($"{gameObject.name}오브젝트의 랜덤 위치 탐색 실패");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
_iAstarAi.destination = randomPosition;
|
||
|
PlayMove();
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|