왜 Quaternion,Vector3 Angle 구현을 안했냐면 성능비용은 그렇게 큰 문제점은 안됐는데
0~180도 사이 즉, 음수 반환을 하지 않아서 상당한 커스터마이징 해야한다는게 싫었다
또 어떤 코드가 있긴 했는데 꼭 각도를 구하려고 식 계산을 해버리는게 있어서 좀 그랬다
내 코드에선 FSM의 특정한 Update에서 계속 적 시야각을 확인해야하는데 매번 계산을 한다라..
내가 하려는 코드 아님
public static float GetAngle (Vector3 vStart, Vector3 vEnd)
{
Vector3 v = vEnd - vStart;
return Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg;
}
private bool SeeingPlayer()
{
Vector3 enemyForwardDir = enemyManager.transform.forward;
enemyForwardDir.y = 0;
enemyForwardDir.Normalize();
Vector3 enemyPlayerDir = enemyManager.PlayerInteractHandler.transform.position - enemyManager.transform.position;
enemyPlayerDir.y = 0;
enemyPlayerDir.Normalize();
if(enemyForwardDir.z * enemyPlayerDir.z > 0 && enemyForwardDir.x * enemyPlayerDir.z > 0 )
{
return true;
}
else
{
return false;
}
}
현재 코드는 디테일한 각도 설정은 안된다는 점 주의
할려면 z가 음수,양수 x가 음수,양수 모든 경우의 수 추가해줘야 함
Vector3 enemyForwardDir = enemyManager.transform.forward;
enemyForwardDir.y = 0;
enemyForwardDir.Normalize();
Vector3 enemyPlayerDir = enemyManager.PlayerInteractHandler.transform.position - enemyManager.transform.position;
enemyPlayerDir.y = 0;
enemyPlayerDir.Normalize();
enemyForwardDir은 현재 enemy가 바라보고있는 정면이다
enemyPlayerDir은 현재 enemy Transform에서 player Transform을 보는 벡터이다
즉 실질적으로 적이 플레이어를 보려면 enemyPlayerDir의 대략적인 방향을 바라봐야 한다는 것
이러면 못본다는 것
Enemy가 바라보는 저 벡터는 x가 음수이고 z가 -0.1~0.1 정도 될 것
Player을 감지하려면 Player를 바라보는 벡터가 x가 양수이기 때문에 애당초 보지를 못함
바로 아래 부분도 각 벡터가 z의 부호가 다르기 때문에 확인 못함
즉, Enemy의 실질적인 정면 벡터와 가상으로 Player를 똑바로 바라보는 경우의 벡터. 두 벡터가 x,z 각각 부호가 같아야한다
if(enemyForwardDir.z * enemyPlayerDir.z > 0 && enemyForwardDir.x * enemyPlayerDir.x > 0 )
{
return true;
}
else
{
return false;
}
}
밑에 콘솔에 False, True는 Player를 감지 못했다, 했다를 나타낸다.
중간에는 NotMoving이라는 건데 무시해도 된다.
(전에 최적화 할때 확인용도로 Debug 해놓은 것)
public override void StateUpdate()
{
// 여기서 감지되면 Trancking으로 ChangeState 해주면 됨
Debug.Log(SeeingPlayer());
if (setRoamPos)
{
path = new NavMeshPath();
enemyManager.EnemyNavAgent.CalculatePath(roamPosition, path);
enemyManager.EnemyNavAgent.SetPath(path);
path = null;
setRoamPos = false;
enemyManager.Animator.SetBool(enemyManager.AnimIDWalk, true);
}
if (enemyManager.EnemyNavAgent.remainingDistance <= enemyManager.EnemyNavAgent.stoppingDistance)
{
enemyManager.Animator.SetBool(enemyManager.AnimIDWalk, false);
// 도착 했을때, Timer 시작
waitCounter += Time.deltaTime;
if (waitCounter >= enemyManager.WaitTime)
{
setRoamPos = true;
roamPosition = GetRoamingPosition();
waitCounter = 0;
}
}
}