쫑가 과정

쉬운 적 AI 만들기 (설정 범위 내 공격, 범위 밖 설정 자리로 돌아감) 본문

Unity 따라 배우기/Topdown 2D RPG In Unity

쉬운 적 AI 만들기 (설정 범위 내 공격, 범위 밖 설정 자리로 돌아감)

쫑가 2022. 2. 24. 20:46

오늘 결과

1. 적 애니메이션 설정

플레이어 설정과 똑같다. 이번 스프라이트는 Y축이 없어서 X축만 사용했다.

블렌드 트리 3개를 만든다.
float MoveX , Bool IsMoving , Trigger Attack

좌/우 애니메이션을 판정해줄 MoveX

움직임을 상시 표시할 IsMoving

공격 시 작동할 Attack

 

2. 적 Script

 1. 따라가기

private void Movement()
    {
    	// 타겟과 적의 거리가 followRange보다 작고 attackRange보다 크면 따라간다.
        if (Vector3.Distance(target.position, transform.position) <= followRange && Vector3.Distance(target.position, transform.position) >= attackRange)
        {
            speed = initialSpeed;
            transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
            // 좌 우 애니메이션 판단.
            anim.SetFloat("MoveX", target.position.x - transform.position.x);
            // 움직이는 애니메이션 실행.
            anim.SetBool("IsMoving", true);
        }
        // 공격 범위 안이라면 움직임을 멈추고 공격.
        else if (Vector3.Distance(target.position, transform.position) < attackRange)
        {
            anim.SetBool("IsMoving", false);
            anim.SetTrigger("Attack");
        }
        // 아니라면 되돌아가기.
        else
        {
            backHome();
        }                  
    }

Vector3.Distance를 이용해 타깃 위치와 적 위치 거리를 받아온다.

https://docs.unity3d.com/ScriptReference/Vector3.Distance.html

 

Unity - Scripting API: Vector3.Distance

Success! Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable. Close

docs.unity3d.com

위치를 Vector3.MoveToWards를 이용해서 다가간다.

https://docs.unity3d.com/ScriptReference/Vector3.MoveTowards.html

 

Unity - Scripting API: Vector3.MoveTowards

Use the MoveTowards member to move an object at the current position toward the target position. By updating an object’s position each frame using the position calculated by this function, you can move it towards the target smoothly. Control the speed of

docs.unity3d.com

 2. 되돌아가기

원리는 같다.

private void backHome()
    {
    	// 움직임
        anim.SetBool("IsMoving", true);
        // 돌아가는 위치 기준으로 좌 우 판단.
        anim.SetFloat("MoveX", homePos.position.x - transform.position.x);
        // 돌아가는 속도.
        speed = backSpeed;
        transform.position = Vector3.MoveTowards(transform.position, homePos.position, speed*Time.deltaTime);
        
        // 설정 위치로 돌아왔다면 멈추기.
        if(Vector3.Distance(homePos.position,transform.position) == 0)
        {
            anim.SetBool("IsMoving", false);
        }
    }

3. 완료

using UnityEngine;

public class EnemyController : MonoBehaviour
{
    [SerializeField] Transform target;
    // 따라가는 움직임 속도.
    [SerializeField] float speed = 3f;
    // 돌아가는 움직임 속도.
    [SerializeField] float backSpeed = 10f;
    // 공격하기 위해 따라가는 범위
    [SerializeField] float followRange = 5f;
    // 따라감을 멈추고 공격하는 범위 안.
    [SerializeField] float attackRange = 1.3f;
    // 적이 되돌아가는 위치.
    [SerializeField] Transform homePos;
    private Animator anim;
    private float initialSpeed;
    private void Awake()
    {
        anim = GetComponent<Animator>();
        target = FindObjectOfType<Movement>().transform;
    }
    private void Start()
    {
        initialSpeed = speed;
    }
    private void Update()
    {
        Movement();
    }

    private void Movement()
    {
    	// 타겟과 적의 거리가 followRange보다 작고 attackRange보다 크면 따라간다.
        if (Vector3.Distance(target.position, transform.position) <= followRange && Vector3.Distance(target.position, transform.position) >= attackRange)
        {
            speed = initialSpeed;
            transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
            // 좌 우 애니메이션 판단.
            anim.SetFloat("MoveX", target.position.x - transform.position.x);
            // 움직이는 애니메이션 실행.
            anim.SetBool("IsMoving", true);
        }
        // 공격 범위 안이라면 움직임을 멈추고 공격.
        else if (Vector3.Distance(target.position, transform.position) < attackRange)
        {
            anim.SetBool("IsMoving", false);
            anim.SetTrigger("Attack");
        }
        // 아니라면 되돌아가기.
        else
        {
            backHome();
        }                  
    }
    private void backHome()
    {
    	// 움직임
        anim.SetBool("IsMoving", true);
        // 돌아가는 위치 기준으로 좌 우 판단.
        anim.SetFloat("MoveX", homePos.position.x - transform.position.x);
        // 돌아가는 속도.
        speed = backSpeed;
        transform.position = Vector3.MoveTowards(transform.position, homePos.position, speed*Time.deltaTime);
        
        // 설정 위치로 돌아왔다면 멈추기.
        if(Vector3.Distance(homePos.position,transform.position) == 0)
        {
            anim.SetBool("IsMoving", false);
        }
    }
}
Comments