본문 바로가기
Unity Portfolio/TinySwordDefense

2. 적 캐릭터 타일맵 이동, 애니메이션

by 첨부엉. 2024. 7. 23.
반응형

[Unity 2D Game] Tower Defense #01 - 맵 배치, 적 생성 및 이동 (youtube.com)

 

고박사의 유니티 노트 영상을 참고하여 작성하였습니다.

 

스크립트

EnemyCtrl.cs

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyCtrl : MonoBehaviour
{
    private int         wayPointCount;      // 이동 경로 개수
    [SerializeField]
    private Transform[] wayPoints;          // 이동 경로 정보
    private int         currentIndex = 0;   // 현재 목표지점 인덱스
    private Movement2D  movement2D;         // 오브젝트 이동 제어

    public void Setup(Transform[] wayPoints)
    {
        movement2D = GetComponent<Movement2D>();

        // 적 이동 경로 wayPoint 정보 저장
        wayPointCount = wayPoints.Length;
        this.wayPoints = new Transform[wayPointCount];
        this.wayPoints = wayPoints;

        // 적의 위치를 첫번째 wayPoint 위치로 설정
        transform.position = wayPoints[currentIndex].position;

        StartCoroutine(OnMove());
    }

    /// <summary>
    /// 적 이동/목표지점 설정 코루틴
    /// </summary>
    /// <returns></returns>
    private IEnumerator OnMove()
    {
        NextMoveTo();

        while(true)
        {
            // 적의 현재위치와 목표위치의 거리가 MoveSpeed 보다 적을 때 if 조건문 실행
            // Tip. MoveSpeed 를 곱해주는 이유는 속도가 빠르면 전 프레임에 0.02보다 크게 움직이기 때문에
            // if 조건문에 걸리지 않고 경로를 탈주하는 오브젝트가 발생할 수 있음
            if(Vector3.Distance(transform.position,wayPoints[currentIndex].position)<0.02f * movement2D.MoveSpeed)
            {
                NextMoveTo();
            }
            yield return null;
        }
    }

    /// <summary>
    /// 다음 이동 방향 설정
    /// </summary>
    private void NextMoveTo()
    {
        // 아직 이동할 wayPoints 가 남아있다면
        if(currentIndex < wayPointCount - 1)
        {
            // 적의 위치를 정확하게 목표 위치로 설정
            transform.position = wayPoints[currentIndex].position;
            Debug.Log(transform.position);
            // 이동 방향 설정 => 다음 목표지점(wayPoints)
            currentIndex++;
            Vector3 direction = (wayPoints[currentIndex].position - transform.position).normalized;
            movement2D.MoveTo(direction);
        }
        // 현재 위치가 마지막 wayPoints 라면
        else
        {
            // 적 오브젝트 삭제
            Destroy(gameObject);
        }
    }
}

 

EnemySpawner.cs

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemySpawner : MonoBehaviour
{
    [SerializeField]
    private GameObject enemyPrefab;
    [SerializeField]
    private float spawnTime;
    [SerializeField]
    private Transform[] myPoints;

    private void Awake()
    {
        // 적 생성 코루틴 함수 호출
        StartCoroutine(SpawnEnemy());
    }

    /// <summary>
    /// 적 스폰 코루틴 함수
    /// </summary>
    /// <returns></returns>
    private IEnumerator SpawnEnemy()
    {
        while(true)
        {
            GameObject clone = Instantiate(enemyPrefab);
            EnemyCtrl enemy = clone.GetComponent<EnemyCtrl>();

            enemy.Setup(myPoints);

            yield return new WaitForSeconds(spawnTime);
        }
    }
}

 

Movement2D.cs

더보기
using UnityEngine;

public class Movement2D : MonoBehaviour
{
    [SerializeField]
    private float moveSpeed = 0.0f;
    [SerializeField]
    private Vector3 moveDirection = Vector3.zero;

    public float MoveSpeed => moveSpeed;    // moveSpeed 변수의 프로퍼티

    private void Update()
    {
        transform.position += moveDirection * moveSpeed * Time.deltaTime;
    }
    public void MoveTo(Vector3 direction)
    {
        moveDirection = direction;
    }
}

 

적 캐릭터의 애니메이션

에셋 파일에 포함되어 있는 애니메이션과 애니메이터는 정비율로 잘린 이미지가 아니라 작업하기가 어렵다. 예를 들면 아래와 같이 경로를 이탈하는 사태가 생기기 때문에 애니메이션을 새로 생성해줘야된다.

 

 

픽셀 유닛은 줄일수록 화면 내에서 이미지가 커지기 때문에 적당히 조절하고 스프라이트만 Multiple 로 변경한 후 Sprite Editor 뷰로 들어간다.

여백이 많이 남더라도 저렇게 잘라준다.

 

idle 이 될 첫번째 이미지를 누르고 Shift 키를 누른뒤 맨 마지막 이미지를 눌러 다중 선택한다. 

오른쪽 마우스를 클릭하고 Create - Animation 을 선택하여 Idle 애니메이션을 생성한다. 

idle과 Attack 밖에 쓰지 않을거니까 애니메이션을 두개만 생성한다.

 

자른 이미지중 idle 상태의 이미지 하나를 하이러키뷰에 드래그앤 드롭하고 Animator 컴포넌트를 연결한다음 "Torch_Red"라는 이름의 Animator 를 생성한다.

프로젝트 창에 드래그 앤 드롭하여 프리팹으로 생성하고 

방금 만들었던 Animator 와 MoveMent2D, EnemyCtrl 스크립트를 연결한뒤 

속성은 위와 같이 설정한다.

Torch_Red 의 애니메이터

 

스포너

빈 오브젝트에 EnemySpawner 를 연결

방금 만든  Torch_Red프리팹을 연결

MyPoints에 WayPoint 다중선택 후 드래그앤 드롭하여 연결한다

 

그럼 정상 작동되는 모습을 확인 가능

 

 

 

반응형