Enemy AI가 플레이어를 인식해야
순찰 혹은 IDLE 상태에서 chasing 상태 혹은 attack 상태로 변화할 수 있다.
따라서 적군이 플레이어를 인식하는 것은
가장 필요한 기초적인 단계이다.
이러한 단계는 다음과 같이 접근할 수 있다.
protected virtual void OnDrawGizmos()
{
Gizmos.DrawLine(groundCheck.position, groundCheck.position + new Vector3(0, -groundCheckDistance));
Gizmos.DrawLine(primaryWallCheck.position, primaryWallCheck.position + new Vector3(wallCheckDistance * facingDir, 0));
if (secondaryWallCheck != null)
{
Gizmos.DrawLine(secondaryWallCheck.position, secondaryWallCheck.position + new Vector3(wallCheckDistance * facingDir, 0));
}
}
에디터(Scene 뷰) 상에 디버그용 선(Gizmos) 을 그려서
캐릭터의 바닥 체크(Ground Check) 와 벽 체크(Wall Check) 범위를 시각화하는 함수이다.
실질적으로는 다음과 같은 레이캐스트를 통하여 충돌을 체크하고 있다.
private void HandleCollisionDetection()
{
groundDetected = Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckDistance, whatIsGround);
if (secondaryWallCheck != null)
{
wallDetected = Physics2D.Raycast(primaryWallCheck.position, Vector2.right * facingDir, wallCheckDistance, whatIsGround)
&& Physics2D.Raycast(secondaryWallCheck.position, Vector2.right * facingDir, wallCheckDistance, whatIsGround);
}
else
{
wallDetected = Physics2D.Raycast(primaryWallCheck.position, Vector2.right * facingDir, wallCheckDistance, whatIsGround);
}
}
이제 플레이어를 인식하는 enemy ai를 생성하려면
위와 같은 레이 캐스트를 통하여 제작할 수 있다.
또한 레이 캐스트 범위를 기즈모를 이용하여 시각화하여 가시적으로 확인할 수 있다.
1.Gizmos 함수 overriding 하기
기존의 기즈모 함수를 통하여 가시화한 것과 더불어
플레이어를 체크할 수 있는 거리에 대한 변수를 에디터에서 수정할 수 있도록
아래와 같이 작성한다.
[Header("Player detection")]
[SerializeField] private LayerMask whatIsPlayer;
[SerializeField] private Transform playerCheck;
[SerializeField] private float playerCheckDistance = 10;
public RaycastHit2D PlayerDetection()
{
RaycastHit2D hit = Physics2D.Raycast(playerCheck.position, Vector2.right * facingDir, playerCheckDistance, whatIsPlayer | whatIsGround);
if (hit.collider == null || hit.collider.gameObject.layer != LayerMask.NameToLayer("Player"))
return default;
return hit;
}
protected override void OnDrawGizmos()
{
base.OnDrawGizmos();
Gizmos.color = Color.yellow;
Gizmos.DrawLine(playerCheck.position,
new Vector3(playerCheck.position.x + (facingDir * playerCheckDistance),
playerCheck.position.y));
2. 플레이어 방향 바라보게 하기
public class Enemy_BattleState : EnemyState
{
private Transform player;
public Enemy_BattleState(Enemy enemy, StateMachine stateMachine, string animBoolName) : base(enemy, stateMachine, animBoolName)
{
}
public override void Enter()
{
base.Enter();
if(player == null)
player = enemy.PlayerDetection().transform;
}
public override void Update()
{
base.Update();
if (WithinAttackRange())
stateMachine.ChangeState(enemy.attackState);
else
enemy.SetVelocity(enemy.battleMoveSpeed * DirectionToPlayer(), rb.linearVelocity.y);
}
private bool WithinAttackRange() => DistanceToPlayer() < enemy.attackDistance;
private float DistanceToPlayer()
{
if(player == null)
return float.MaxValue;
return Mathf.Abs(player.position.x - enemy.transform.position.x);
}
private int DirectionToPlayer()
{
if(player == null)
return 0;
return player.position.x > enemy.transform.position.x ? 1 : -1;
}
}'DevLog > 유니티 프로젝트' 카테고리의 다른 글
| 2DRPG 타겟 탐지 기능 - ComBatSystem (1) | 2026.01.14 |
|---|---|
| 몬스터 ai의 ground checking (0) | 2026.01.13 |
| 유니티 구글 스프레드 시트 연동 툴 (4) | 2025.06.29 |
| DT 기능 에디터 만들기 GoogleSheetURLParser Class 설명 (2) | 2025.06.08 |
| 구글 엑셀 연동 DT 관리 - GoogleDTTemplate 클래스 정리 (1) | 2025.05.27 |