오늘은 궁수의 전설 모작 프로젝트를 진행하며 플레이어가 멈췄을 때 가장 가까운 적을 자동으로 타겟팅하고 공격하는 것을 구현했다.
참고 영상을 보면 구현 코드를 직접적으로 보여주진 않지만, 구현하기 위한 아이디어를 제시해준다. 아이디어는 다음과 같다.
1. 맵에 존재하는 모든 적 오브젝트를 리스트에 저장한다.
2. 저장한 리스트를 토대로 모든 적 오브젝트에 Raycast를 쏜다.
3. Raycast의 길이가 가장 짧은 오브젝트를 바라보고 그 오브젝트를 타겟으로 지정한다.
이 아이디어를 토대로 아래와 같이 코드를 작성했다.
// Player가 가장 가까운 적을 바라보는 함수 void OnLook() { float minDistance = 999999f; foreach (var monster in monsterList) { direction = monster.transform.position - attackPivot.position; float distance = Vector3.Distance(monster.transform.position, attackPivot.position); RaycastHit2D hit = Physics2D.Raycast(attackPivot.position, direction.normalized, distance, LayerMask.GetMask("Enemy")); Debug.DrawRay(attackPivot.position, direction.normalized * distance, Color.red); if (hit.collider != null) { if (minDistance > distance) { minDistance = distance; target = hit.collider.gameObject; } } } Vector3 targetDirection = target.transform.position - attackPivot.position; float angle = Mathf.Atan2(targetDirection.x, -targetDirection.y) * Mathf.Rad2Deg - 90f; attackPivot.rotation = Quaternion.Euler(new Vector3(0, 0, angle)); }
위 코드에 대해서 설명하자면, 플레이어가 투사체를 발사하는 위치(attackPivot)에서 몬스터의 방향과 거리를 계산하고, 그 값들을 토대로 Raycast를 쏜다. 이후 Raycast가 적중한 몬스터 중 가장 가까운 거리에 있는 몬스터를 타겟으로 만드는 코드이다. 추가적으로 attackPivot을 몬스터 방향으로 돌려 몬스터를 공격할 준비를 한다.
여기서 추가 개발을 통해 장애물이 생기면 레이캐스트는 처음 적중한 오브젝트만 충돌판정을 내는 특성을 활용하여 오브젝트 뒤에 있는 몬스터가 가장 가까워도 타겟팅 하지 않는 코드로 발전 시킬 수 있다.
아래 이미지는 호박이 몬스터라고 가정했을 때 가장 가까이에 있는 호박에게 플레이어가 토마토를 던지는 모습이다.
