유니티 기초

보스 추적 및 돌아가기

송현호 2023. 8. 14. 02:45
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MonsterController : MonoBehaviour
{
    public float radius = 1f;
    public float attackRange = 3f;
    public float chaseDistance = 8f;
    private Vector3 originalPosition;
    private bool isChasing = false;
    private bool isAttacking = false;
    [SerializeField]
    private GameObject target;
    private Animator anim;
    private float moveSpeed = 1f;
    // Start is called before the first frame update
    void Start()
    {
        this.anim = GetComponent<Animator>();
        originalPosition = this.transform.position;
    }

    // Update is called once per frame
    void Update()
    {
        float distance = Vector3.Distance(this.transform.position, target.transform.position);
        
        if (distance < chaseDistance && distance > attackRange)
        {
            isChasing = true;
            isAttacking = false;
            
            this.anim.SetInteger("State", 1);
            
            this.transform.LookAt(target.transform);
            transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);

            
        }
        else if (distance <= attackRange)
        {
             isAttacking = true;
             isChasing = false;
             StartCoroutine(Attack());
        }
        else if (isChasing && distance >= chaseDistance)
        {
            this.transform.LookAt(originalPosition);
            transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
            if (Vector3.Distance(originalPosition, this.transform.position) < 0.2f)
            {
                isChasing = false;
                this.anim.SetInteger("State", 0);
            }
            

        }
    }

    private IEnumerator Attack()
    {

        this.anim.SetInteger("State", 2);
        Debug.Log(123);
        yield return new WaitForSeconds(2.5f);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HeroController : MonoBehaviour
{
    private Animator anim;
    private MonsterController target;
    private Vector3 targetPosition;
    private Coroutine moveRoutine;
    public float radius = 1f;
    public System.Action<MonsterController> onMoveComplete;
    // Start is called before the first frame update
    void Start()
    {
        this.anim = this.GetComponent<Animator>();
    }

    public void Move(MonsterController target)
    {
        this.target = target;
        this.targetPosition = this.target.gameObject.transform.position;
        this.anim.SetInteger("State", 1);
        if (this.moveRoutine != null)
        {
            this.StopCoroutine(this.moveRoutine);
        }
        this.moveRoutine = this.StartCoroutine(this.CoMove());
    }

    public void Move(Vector3 targetPosition)
    {
        this.target = null;

        this.targetPosition = targetPosition;

        this.anim.SetInteger("State", 1);

        if (this.moveRoutine != null)
        {
            this.StopCoroutine(this.moveRoutine);

        }
        this.moveRoutine = this.StartCoroutine(this.CoMove());
    }

    public IEnumerator CoMove()
    {
        while (true)
        {

            this.transform.LookAt(this.targetPosition);

            this.transform.Translate(Vector3.forward * 2f * Time.deltaTime);

            float distance = Vector3.Distance(this.transform.position, this.targetPosition);

            if (this.target != null)
            {
                if (distance <= (1f + 1f))
                {
                    break;
                }
            }
            else
            {
                if (distance <= 0.1f)
                {
                    break;
                }
            }

            yield return null;
        }
        this.anim.SetInteger("State", 0);
        this.onMoveComplete(this.target);
    }

    public void Attack(MonsterController target)
    {
        this.anim.SetInteger("State", 2);
        this.StartCoroutine(this.CoAttack());
    }

    private IEnumerator CoAttack()
    {
        yield return new WaitForSeconds(0.1f);
        yield return new WaitForSeconds(0.73f);
        this.anim.SetInteger("State", 0);  
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BossRoomMain : MonoBehaviour
{
    [SerializeField]
    private HeroController heroController;

    void Start()
    {
        this.heroController.onMoveComplete = (target) =>
        {
            Debug.LogFormat("<color=cyan>이동을 완료 했습니다. : {0}</color>", target);
            //타겟이 있다면 공격 애니메이션 실행
            if (target != null)
            {
                this.heroController.Attack(target);
            }
        };
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Debug.Log("down");
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            float maxDistance = 100f;
            Debug.DrawRay(ray.origin, ray.direction * maxDistance, Color.red, 3f);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, maxDistance))
            {
                //클릭한 오브젝트가 몬스터라면 
                if (hit.collider.tag == "Monster")
                {
                    //거리를 구한다 
                    float distance = Vector3.Distance(this.heroController.gameObject.transform.position,
                        hit.collider.gameObject.transform.position);

                    MonsterController monsterController = hit.collider.gameObject.GetComponent<MonsterController>();

                    //각 반지름더한거와 비교 
                    float sumRadius = this.heroController.radius + monsterController.radius;

                    Debug.LogFormat("{0}, {1}", distance, sumRadius);

                    //사거리 안에 들어옴 
                    if (distance <= sumRadius)
                    {
                        //공격 
                    }
                    else
                    {
                        //이동 
                        this.heroController.Move(monsterController);
                        //this.heroController.Move(hit.point);
                    }

                }
                else if (hit.collider.tag == "Ground")
                {
                    this.heroController.Move(hit.point);
                }
            }
        }
    }
}