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
|
#region Unity Lifecycle
|
||||||
|
|
||||||
private void Awake()
|
protected override void Awake()
|
||||||
{
|
{
|
||||||
|
base.Awake();
|
||||||
|
|
||||||
InitializeComponents();
|
InitializeComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ namespace DDD
|
|||||||
public class RestaurantCharacterMovement : MonoBehaviour
|
public class RestaurantCharacterMovement : MonoBehaviour
|
||||||
{
|
{
|
||||||
private RestaurantCharacterMovementConstraint _constraint;
|
private RestaurantCharacterMovementConstraint _constraint;
|
||||||
private void Awake()
|
protected virtual void Awake()
|
||||||
{
|
{
|
||||||
_constraint = gameObject.AddComponent<RestaurantCharacterMovementConstraint>();
|
_constraint = gameObject.AddComponent<RestaurantCharacterMovementConstraint>();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user