유니티 기초

보스 MoveForward, MoveBack, Attack, 사거리 등 - MoveBack 오류

다모아 2023. 8. 14. 18:03

HeroController

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

namespace Test2_Boss
{
    public class Hero : MonoBehaviour
    {

        private Coroutine moveRoutine;
        private Vector3 position;
        // Start is called before the first frame update
        void Start()
        {

        }

        public void Move(Vector3 position)
        {
            this.position = position;
            if(moveRoutine != null)
            {
                this.StopCoroutine(this.moveRoutine);
            }
            this.moveRoutine = this.StartCoroutine(this.CoMove());
        }

        private IEnumerator CoMove()
        {
            while (true)
            {
                float dis = Vector3.Distance(this.transform.position, this.position);
                this.transform.LookAt(this.position);
                this.transform.Translate(Vector3.forward * 3f * Time.deltaTime);
                if(dis <= 0.1f)
                {
                    break;
                }
                yield return null;
            }

        }
    }
}

 

GameEnums

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

namespace Test2_Boss
{
    public class GameEnums
    {
        public enum eBossType
        {
            Idle, Run, Hit
        }

        public enum eHeroType
        {
            Idle, Run
        }

    }
}

 

Bull

using System.Collections;
using System.Collections.Generic;
using System.Net;
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;
        [SerializeField]
        private float back = 7f;

        private float distance;

        private Coroutine moveForwardRoutine;
        private Coroutine moveBackRoutine;
        private Coroutine attackRoutine;
        //public float Range
        //{
        //    get
        //    {
        //        return this.range;
        //    }
        //}
        public float Range => this.range;
        public float Sight => this.sight;

        private Animator anim;
        private void Start()
        {
            this.anim = GetComponent<Animator>();
        }

        public void MoveForward(Transform targetTrans)
        {
            this.targetTrans = targetTrans;
            if(this.moveForwardRoutine != null)
            {
                this.StopCoroutine(this.moveForwardRoutine);
            }
            this.moveForwardRoutine = this.StartCoroutine(this.CoMoveForward()); //문제없음
            //mono.StartCoroutine(this.CoMoeForward());
        }

        private IEnumerator CoMoveForward()
        {
            while (true)
            {
                var dis = Vector3.Distance(this.transform.position, this.targetTrans.position);
                this.distance = dis;

                //시야안에 있는지 확인
                if (this.distance <= this.sight)
                {
                    this.transform.LookAt(this.targetTrans);
                    this.PlayAnimation(GameEnums.eBossType.Run);
                    this.transform.Translate(Vector3.forward * 1f * Time.deltaTime);
                    this.sight = 7f;
                    if(this.distance <= this.range)
                    {
                        this.onMoveComplete();
                        break;
                    }
                }
                else
                {
                    //시야에 없음
                    this.MoveBack();
                }
                yield return null;
            }
        }

        public void MoveBack()
        {
            if(this.moveBackRoutine != null)
            {
                this.StopCoroutine(this.moveBackRoutine);
            }
            this.moveBackRoutine = this.StartCoroutine(this.CoMoveBack());
        }

        private IEnumerator CoMoveBack()
        {
            while(true)
            {
                Vector3 place = new Vector3(-7f, 0, 7f);
                float distance = Vector3.Distance(this.transform.position, place);
                this.transform.LookAt(place);
                this.PlayAnimation(GameEnums.eBossType.Run);
                this.transform.Translate(place * 1f * Time.deltaTime);
                if (distance <= 0.1f)
                {
                    this.PlayAnimation(GameEnums.eBossType.Idle);
                    this.sight = 3f;
                    break;
                }
                yield return null;
            }
            
        }
        public void Attack(Transform targetTrans)
        {
            this.targetTrans = targetTrans;
            
            if(this.attackRoutine != null)
            {
                this.StopCoroutine(this.attackRoutine);
            }
            this.attackRoutine = this.StartCoroutine(this.CoAttack());
        }

        private IEnumerator CoAttack()
        {
            var dis = Vector3.Distance(this.transform.position, this.targetTrans.position);

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

            yield return null;
        }

        private void PlayAnimation(GameEnums.eBossType state)
        {
            this.anim.SetInteger("State", (int)state);
        }
        private void OnDrawGizmos()
        {
            if (distance <= this.sight)
            {
                Gizmos.color = Color.red;
                GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, this.sight, 20);
            }
            else
            {
                //시야
                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_BossMain

using System.Collections;
using System.Collections.Generic;
using System.Net;
using UnityEngine;
using UnityEngine.UI;
 
namespace Test2_Boss
{
    public class Test_BossMain : MonoBehaviour
    {
        [SerializeField]
        private Bull bull;
        [SerializeField]
        private Transform targetTrans;
        [SerializeField]
        private Hero hero;

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

            this.bull.onMoveComplete = () => {
                this.BullMoveAndAttack();
            };
        }

        private void Update()
        {
            if(Input.GetMouseButtonDown(0))
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

                RaycastHit hit;

                if(Physics.Raycast(ray, out hit, 100f))
                {
                    this.hero.Move(hit.point);
                }
            }

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

 

Test_Mono

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

public class Test_Mono : MonoBehaviour
{
    [SerializeField]
    private Bull bull;
    // Start is called before the first frame update
    void Start()
    {

    }

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

 

MoveBack을 잘못했는지 혼자 빙빙 돌고있음..

 

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

[주말과제] 광복절 과제  (0) 2023.08.15
MonoBehavior 오류  (0) 2023.08.14
디자인패턴  (0) 2023.08.14
[주말과제] 복소수와 사원수  (1) 2023.08.14
[합치기] 이동, 공격, 피격  (0) 2023.08.11