AiMovement 구조 작성
This commit is contained in:
parent
d930358fe5
commit
52881e4d75
26
Assets/_DDD/_Scripts/RestaurantCharacter/IAiMovement.cs
Normal file
26
Assets/_DDD/_Scripts/RestaurantCharacter/IAiMovement.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD
|
||||
{
|
||||
public interface IAiMovement
|
||||
{
|
||||
Vector3 CurrentPosition { get; }
|
||||
Vector3 Destination { get; }
|
||||
float CurrentSpeed { get; }
|
||||
bool IsMoving { get; }
|
||||
|
||||
void EnableMove();
|
||||
void DisableMove();
|
||||
void PlayMove();
|
||||
void StopMove();
|
||||
void SetMoveSpeed(float speed);
|
||||
|
||||
bool TryMoveToPosition(Vector3 position);
|
||||
bool TryMoveToTarget(Collider targetCollider);
|
||||
Vector3 GetRandomBetweenTwoPoints(Vector2? normalizedRange = null);
|
||||
bool TryTeleportToPosition(Vector3 position);
|
||||
bool HasReachedDestination();
|
||||
bool IsPositionMovable(Vector3 endPosition);
|
||||
bool TryMoveToRandomPositionInRange(float range, int graphIndex = 0);
|
||||
}
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -35,8 +35,10 @@ public class RestaurantPlayerMovement : RestaurantCharacterMovement
|
||||
|
||||
#region Unity Lifecycle
|
||||
|
||||
private void Awake()
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
InitializeComponents();
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ namespace DDD
|
||||
public class RestaurantCharacterMovement : MonoBehaviour
|
||||
{
|
||||
private RestaurantCharacterMovementConstraint _constraint;
|
||||
private void Awake()
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_constraint = gameObject.AddComponent<RestaurantCharacterMovementConstraint>();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user