몬스터 - 플레이어 사이에 장애물이 존재하면 플레이어를 인식하지 못하게 하기
- 수정 전 : Raycast에서 LayerMask를 설정하면 해당 Layer만 검출하고 나머지는 무시하기 때문에 Monster - Player - Obstacle(장애물) 순서로 있어도 몬스터가 플레이어를 인식하지 못함
- 이렇게 코드를 작성했던 이유 : Raycast의 return값을 검출된 대상이 LayerMask인지 아닌지로 생각했기 때문
- LayerMask를 설정하면 해당 Layer를 제외한 object는 무시하기 때문에 플레이어가 장애물보다 앞에(가까이) 있어도 플레이어를 무시하고 뒤에 있는 장애물만 검출해서 IsTargetInFieldOfView 메서드의 return 값이 계속 false가 됨
protected bool IsTargetInFieldOfView()
{
Vector3 directionToTarget = GetTargetDirection();
RaycastHit obstacleHit;
Vector3 offset = new Vector3(0, 1, 2);
if (!Physics.Raycast(
stateMachine.Monster.transform.position + offset,
directionToTarget,
out obstacleHit,
stateMachine.Monster.data.detectRange,
stateMachine.Monster.obstacleMask))
{
return true;
}
return false;
}
- 수정 후 : 장애물이 검출되면 RaycastHit.distance를 통해 장애물이 검출된 위치까지의 거리를 얻고, 이 거리를 플레이어와의 거리와 비교
플레이어와의 거리보다 짧으면 장애물이 더 가까이 있는 것 -> 플레이어와 몬스터 사이에 장애물이 있음
protected bool IsTargetInFieldOfView()
{
Vector3 directionToTarget = GetTargetDirection();
RaycastHit obstacleHit;
Vector3 offset = new Vector3(0, 1, 2);
if (!Physics.Raycast(
stateMachine.Monster.transform.position + offset,
directionToTarget,
out obstacleHit,
stateMachine.Monster.data.detectRange,
stateMachine.Monster.obstacleMask))
{
return true;
}
else
{
if (DistanceToTarget() < obstacleHit.distance * obstacleHit.distance) return true;
else return false;
}
}
protected Vector3 GetTargetDirection()
{
Vector3 directionToTarget = stateMachine.Target.transform.position - stateMachine.Monster.transform.position;
return directionToTarget;
}
private float DistanceToTarget()
{
return (stateMachine.Target.transform.position - stateMachine.Monster.transform.position).sqrMagnitude;
}