아카이브

보스 만들기/시야 안에 타겟이 있는지 검사 본문

유니티 기초

보스 만들기/시야 안에 타겟이 있는지 검사

timbercat 2023. 8. 14. 18:18

Test_BossMain

스크립트

Test_BossMain

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace Test_Boss
{
    public class Test_BossMain : MonoBehaviour
    {
        [SerializeField]
        private Button btnMove;

        [SerializeField]
        private Button btnRemove;

        [SerializeField]
        private Bull bull;

        [SerializeField]
        private Transform targetTrans;  //비활성화

        [SerializeField]
        private Hero hero;

        // Start is called before the first frame update
        void Start()
        {
            this.bull.onAttackCancel = () => {
                this.BullMoveAndAttack();
            };

            this.bull.onMoveComplete = () => {
                Debug.LogError("!");
                this.BullMoveAndAttack();
            };

            this.btnMove.onClick.AddListener(() => {
                Debug.Log("move");
                this.bull.MoveForward(targetTrans);
            });

            this.btnRemove.onClick.AddListener(() => {
                Debug.Log("remove");
                Destroy(this.targetTrans.gameObject);
            });
        }

        private void BullMoveAndAttack()
        {
            //사거리 계산 (공격하려고)
            Debug.Log("사거리 계산");
            var dis = Vector3.Distance(this.bull.transform.position, this.targetTrans.position);
            if (dis <= this.bull.Range)
            {
                //공격 
                Debug.Log("공격");
                this.bull.Attack(targetTrans);
            }
            else
            {
                //이동 
                Debug.Log("이동");
                this.bull.MoveForward(targetTrans);
            }
        }

        void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                //ray 만들기
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                //출력
                Debug.DrawRay(ray.origin, ray.direction * 1000f, Color.blue, 5f);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit, 1000f))
                {                                                                                   
                    this.hero.Move(hit.point); //Hero게임오브젝트를 이동
                }
            }

            //var dis = Vector3.Distance(this.bull.transform.position, this.hero.transform.position);

        }
    }
}

Bull

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Test_Boss
{
    public class Bull : MonoBehaviour
    {
        public System.Action onMoveComplete;
        public System.Action onAttackCancel;
        private Transform targetTrans;

        [SerializeField]
        private float sight = 25f;
        [SerializeField]
        private float range = 5f;

        public float Range => this.range;
        public void MoveForward(Transform targetTras)
        {
            this.targetTrans = targetTras;
            //코루틴 실행 
            this.StartCoroutine(this.CoMoveForward());    //문제없음
        }

        private IEnumerator CoMoveForward()
        {
            //매프레임마다 앞으로 이동 
            while (true)
            {
                if (targetTrans == null)
                    break;

                var dis = Vector3.Distance(this.transform.position, this.targetTrans.position);

                //시야안에 있는지확인 
                if (dis > 25)
                {
                    yield return null;  //한 프레임 건너뜀 
                    continue;
                }

                //방향을 바라보고 
                this.transform.LookAt(this.targetTrans);
                //이동 (relateTo : Self/지역좌표로 이동)
                this.transform.Translate(Vector3.forward * 3f * Time.deltaTime);
                //목표지점까지 오면 멈춤 

                if (dis <= this.range)
                {
                    break;
                }
                yield return null;
            }
            if (this.targetTrans == null)
            {
                Debug.Log("타겟을 잃었습니다.");
            }
            else
            {
                Debug.Log("이동을 완료함");
                this.onMoveComplete();
            }
        }

        public void Attack(Transform targetTrans)
        {
            this.targetTrans = targetTrans;
            this.StartCoroutine(this.CoAttack());
        }

        private IEnumerator CoAttack()
        {
            yield return null;

            var dis = Vector3.Distance(this.transform.position, this.targetTrans.position);

            //시야안에 있는지확인 
            if (dis <= this.range)
            {
                //사거리안에 있다면 공격 애니메이션 
            }
            else
            {
                this.onAttackCancel();  //공격 취소됨 
            }
        }

        private void OnDrawGizmos()
        {
            //시야 
            Gizmos.color = Color.green;
            GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, this.sight, 20);
            //공격사거리
            Gizmos.color = Color.red;
            GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, this.range, 20);
        }

    }
}

Hero

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Test_Boss
{
    public class Hero : MonoBehaviour
    {
        [SerializeField]
        private float range = 5f;

        private Vector3 targetPosition;
        private bool isMoveStart;
        // Start is called before the first frame update
        void Start()
        {

        }

        // Update is called once per frame
        void Update()
        {
            //이동시작이라면 
            if (this.isMoveStart)
            {
                //방향을 바라봄 
                this.transform.LookAt(this.targetPosition);
                //이미 바라봤으니깐 정면으로 이동 (relateTo : Self/지역좌표)
                this.transform.Translate(Vector3.forward * 6f * Time.deltaTime);
                //목표지점과 나와의 거리를 잼 
                float distance = Vector3.Distance(this.transform.position, this.targetPosition);                
                //0이 될수 없다 가까워질때 도착한것으로 판단 하자 
                if (distance <= 0.1f)
                {                   
                    this.isMoveStart = false;
                }
            }
        }

        public void Move(Vector3 targetPosition)
        {
            //이동할 목표지점을 저장 
            this.targetPosition = targetPosition;            
            //이동시작 
            this.isMoveStart = true;
        }

        private void OnDrawGizmos()
        {
            Gizmos.color = Color.red;
            GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, this.range, 20);
        }
    }
}

히어로 이동하면 보스가 따라오는 것 까지 구현

둘 사이 거리 표시하고 detect 연습해야함 

'유니티 기초' 카테고리의 다른 글

페이드인, 페이드 아웃 연습  (0) 2023.08.14
아이템 착용하기  (0) 2023.08.11
클릭한 위치에 몬스터 생성/삭제  (0) 2023.08.10
주말과제(Dog Knight)  (1) 2023.08.06
유니티짱 직선으로 움직이기  (0) 2023.08.04