본문 바로가기

Project/전투 시스템

[전투 시스템] Unity: 적 컨트롤러 만들기 (1)

728x90

플레이어와는 다르게 적은 입력에 따라 움직임을 적용하지 않고, 시간에 따라서 움직임을 적용합니다. 원하는 패턴이 있다면 그 패턴을 명시해줘야 원하는 방법으로 움직이게 될 것입니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
 
public class EnemyController : CharacterStats
{
    public Transform attackTransform;
    public Image img;
 
    Vector2 prevPosition;
    Animator animator;
    Rigidbody2D rigid;
    SpriteRenderer sprite;
    IEnumerator enemyMove;
 
    void Start()
    {
        animator = GetComponent<Animator>();
        rigid = GetComponent<Rigidbody2D>();
        sprite = GetComponent<SpriteRenderer>();
 
        enemyMove = EnemyControl();
        StartCoroutine(enemyMove);
    }

 

attackTransform - 공격 유효 범위에 대한 정보를 가질 변수입니다.

img - 체력바 정보를 가질 변수입니다.

prevPosition - 적의 이전 위치를 저장할 변수입니다.

animator - 적의 애니메이터 정보를 저장할 변수입니다.

rigid - 적의 리지드바디 정보를 저장할 변수입니다.

sprite - 적의 스프라이트 정보를 저장할 변수입니다.

enemyMove - 적의 이동 코루틴을 저장할 변수입니다.

 

Start 함수를 통해서 변수들을 초기화 시켜주고, 코루틴을 재생시켜줍니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public override void TakeDamage(int damage)
    {
        base.TakeDamage(damage);
        animator.SetTrigger("onHit");
        img.fillAmount = health / maxHealth;
    }
 
    public override void Die()
    {
        animator.SetBool("isDeath"true);
        
        if(enemyMove != null)
        {
            StopCoroutine(enemyMove);
        }
 
        GetComponent<Collider2D>().enabled = false;
        this.enabled = false;
 
        GameManager.instance.GameOver(true);
    }
  
 

 

부모 스크립트에 있는 가상 함수들을 완성해줍니다. TakeDamage 함수는 피격 애니메이션을 재생시켜주고, img.fillAmount를 통해서 현재 체력을 UI를 통해서 볼 수 있게 설정해줍니다. Die 함수는 죽음 애니메이션을 재생시켜주고, 코루틴을 중단시켜준 다음에 적 스크립트와 콜라이더를 접근하지 못하게 해 줍니다.

 

체크 타겟 함수

 적의 위치를 임의로 계속 바꿔주게 된다면 적은 언젠가는 게임 화면 밖으로 나가게 될 것입니다. 그런 상황에 대비하여 CheckTarget 함수를 만들어줍니다.

 

 동작 원리는 limitPoint1의 좌표와 limitPoint2의 좌표를 사용하여 현재 위치에서 다음 위치로 적이 이동할 때 다음 위치가 limitPoint1, limitPoint2를 넘어가게 된다면 변수들을 다시 설정해주는 것으로 동작하게 해 줍니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    Vector2 CheckTarget(Vector2 target)
    {
        Vector2 temp = target;
 
        if (target.x < GameManager.instance.limitPoint1.x)
        {
            temp = new Vector2(target.x + 2, target.y);
        }
        else if (target.x > GameManager.instance.limitPoint2.x)
        {
            temp = new Vector2(target.x - 2, target.y);
        }
 
        if (target.y > GameManager.instance.limitPoint1.y)
        {
            temp = new Vector2(target.x, target.y - 1);
        }
        else if (target.y < GameManager.instance.limitPoint2.y)
        {
            temp = new Vector2(target.x, target.y + 1);
        }
 
        return temp;
    }

 

위의 설명한 방법을 코드로 구현하면 위와 같이 구현할 수 있습니다.

728x90