유니티 기초

MonoBehavior 오류

다모아 2023. 8. 14. 12:25

코루틴 참조할 때 제거하면 안됌


Bull

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

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

        [SerializeField]
        private float sight = 3f;
        [SerializeField]
        private float range = 1.1f;

        //public float Range
        //{
        //    get
        //    {
        //        return this.range;
        //    }
        //}
        public float Range => this.range;

        public void MoveForward(Transform targetTrans)
        {
            this.targetTrans = targetTrans;
            this.StartCoroutine(this.CoMoeForward()); //문제없음
            //mono.StartCoroutine(this.CoMoeForward());
        }

        private IEnumerator CoMoeForward()
        {
            while (true)
            {
                if (targetTrans == null)
                {
                    break;
                }
                var dis = Vector3.Distance(this.transform.position, this.targetTrans.position);

                //시야안에 있는지 확인
                if (dis > this.sight)
                {
                    yield return null; //한 프레임 건너뜀
                    continue;
                }
                this.transform.LookAt(this.targetTrans);
                this.transform.Translate(Vector3.forward * 1f * Time.deltaTime);
                Debug.Log(targetTrans);
                
                if( dis <= this.range)
                {
                    break;
                }
                Debug.Log(dis);
                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.yellow;
            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);
        }
    }
}

 

Test_Mono

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

public class Test_Mono : MonoBehaviour
{
    [SerializeField]
    private Bull bull;

    [SerializeField]
    private Test_Mono test_Mono;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

Test_BossMain

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

namespace Test2_Boss
{
    public class Test_BossMain : MonoBehaviour
    {
        [SerializeField]
        private Button btnMove;
        [SerializeField]
        private Button btnRemove;
        [SerializeField]
        private Bull bull;
        [SerializeField]
        private Transform targetTrans;
        // 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(() => {
                this.bull.MoveForward(targetTrans);
            });

            this.btnRemove.onClick.AddListener(() => {
                //Destroy(this.gameObject);
                //Destroy(this.bull.gameObject); //문제 없음
                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(this.targetTrans);
            }
        }
    }
}