플레이어가 범위(반지름이 detectDistance인 원)안에 있다면 undefinedPlayer(미정)에 플레이어의 Transform을 할당한다.
좀비에서 undefinedPlayer까지의 거리와 방향을 distanceToTarget에 할당한다.
Ray를 좀비에서 distanceToTarget방향으로 distanceToTarget거리만큼 쏴서 Obstacle Layer에 걸리지 않는다면 _dectedPlayer에 undefinedPlayer를 할당시켜 실제 감지됨을 인지한다.
private INode.E_NodeState CheckDetectPlayer()
{
var overlapColliders =
Physics.OverlapSphere(transform.position, _detectDistance, _PLAYER_LAYER_MASK);
if (overlapColliders != null & overlapColliders.Length> 0)
{
Transform undefinedPlayer = overlapColliders[0].transform;
Vector3 directionToPlayer = (undefinedPlayer.position - transform.position).normalized;
/*===========================================================================================*/
if (Vector3.Dot(transform.forward, directionToPlayer) > 0.9f)
{
float distanceToTarget = Vector3.Distance(undefinedPlayer.position ,transform.position);
if (!Physics.Raycast(transform.position, directionToPlayer, distanceToTarget, _ENEMY_LAYER_MASK))
{
// 순찰 노드 최초확인 bool값 초기화.
_patrolRandomPosCheck = true;
_idleWaitCheck = true;
_detectedPlayer = undefinedPlayer;
}
}
/*===========================================================================================*/
return INode.E_NodeState.ENS_Success;
}
// 추후 범위 밖으로 나가면 한번만 비우게 변경
_detectedPlayer = null;
return INode.E_NodeState.ENS_Failure;
}
[CustomEditor (typeof(EnemyBasicBT))]
public class FieldOfViewEditor : Editor
{
private void OnSceneGUI()
{
#if DEBUG_MODE
EnemyBasicBT enemyFOV = (EnemyBasicBT)target;
Vector3 enemyForward = enemyFOV.transform.forward;
Handles.color = Color.black;
Handles.DrawWireArc // Radius = _detectDistance 인 원을 그린다.
(enemyFOV.transform.position, Vector3.up, Vector3.forward, 360, enemyFOV._detectDistance);
float vie = Mathf.Acos(0.9f) * Mathf.Rad2Deg;
Vector3 leftViewDirection = Quaternion.Euler(0f, -vie, 0) * enemyForward;
Vector3 rightViewDirection = Quaternion.Euler(0f, vie, 0f) * enemyForward;
Handles.DrawLine // 좀비 정면으로부터 내적 0.9에 해당하는 선
(enemyFOV.transform.position, enemyFOV.transform.position + leftViewDirection * enemyFOV._detectDistance);
Handles.DrawLine
(enemyFOV.transform.position, enemyFOV.transform.position + rightViewDirection * enemyFOV._detectDistance);
if (enemyFOV._detectedPlayer != null)
{
Handles.color = Color.red;
Handles.DrawLine(enemyFOV.transform.position, enemyFOV._detectedPlayer.position);
}
#endif
}
}
현재 EnemyBasicBT.cs 안에 액션노드들이 모두 구현되어 작동중이다. (Func를 사용해서)
코드가 길어지다 보니 시인성이 좋지 않기도 하고, 확인이 힘들어져 튜터님의 피드백대로 각 액션노드들을 SO와 클래스로 모듈화 할 예정이다.
현재 좀비가 시야각 안에서만 감지가 가능한데 그러면 가까이 와서 총을 쏘거나 뛰어다녀도 인식을 하지 못할것이다.
그것은 매우 부자연스럽다. 그래서 사운드감지 범위를 만들고 그 범위 안에서 소리가 나는 행동을 이벤트로 받아서 감지하도록 할 예정이다.
좀비가 공격을 하는 "도중"에 플레이어가 감지범위 밖으로 갑자기 나가버리면 그 자리에서 그대로 계속 허공에 공격을 하는 버그
위 버그를 고친 뒤에 니온 버그로, 위와 똑같은 상황이 왔을 때 최초 한번은 괜찮지만 그 다음부터는 좀비가 그 이전 상황으로 순간이동을 하는 버그
private void NavMeshAgentAttackSetting()
{
IsAnimationAttackCheck();
_animator.applyRootMotion = false;
_agent.isStopped = true;
_agent.updatePosition = false;
_agent.updateRotation = false;
_agent.velocity = Vector3.zero;
}
private void NavMeshAgentPatrolSetting()
{
IsAnimationWalkCheck();
_animator.applyRootMotion = true;
_agent.speed = _agentSpeed;
_agent.SetDestination(_correctPos);
_patrolRandomPosCheck = false;
_agent.isStopped = false;
_agent.updatePosition = true;
_agent.updateRotation = true;
}