유니티 기초

Real SimpleRPG

다모아 2023. 8. 9. 18:21

 

HeroController

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

namespace Real
{
    public class HeroController : MonoBehaviour
    {
        public enum eState
        {
            Idle, Run, Attack
        }
        private float moveSpeed = 2f;
        [SerializeField]
        private float radius = 1f;
        public float Radius
        {
            get
            {
                return this.radius;
            }
        }
        private Vector3 targetPosition;
        private MonsterController attackTarget;
        private MonsterController target;
        private Animator anim;
        private Coroutine moveRoutine;
        private Coroutine attackRoutine;
        // Start is called before the first frame update
        void Start()
        {
            this.anim = GetComponent<Animator>();
        }

        public void Move(MonsterController target)
        {
            this.target = target;
            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;
            if(this.moveRoutine != null)
            {
                this.StopCoroutine(this.moveRoutine);
            }
            this.moveRoutine = this.StartCoroutine(this.CoMove());
        }

        private IEnumerator CoMove()
        {
            while (true)
            {
                if(this.target != null)
                {
                    float distance = Vector3.Distance(this.transform.position, this.target.transform.position);
                    this.transform.LookAt(this.target.transform);
                    this.PlayAnimation(eState.Run);
                    this.transform.Translate(Vector3.forward * this.moveSpeed * Time.deltaTime);
                    if(distance <= 2f)
                    {
                        this.PlayAnimation(eState.Idle);
                        break;
                    }
                }
                else
                {
                    float distance = Vector3.Distance(this.transform.position, this.targetPosition);
                    this.transform.LookAt(targetPosition);
                    this.PlayAnimation(eState.Run);
                    this.transform.Translate(Vector3.forward * this.moveSpeed * Time.deltaTime);
                    if (distance <= 0.1f)
                    {
                        this.transform.position = this.targetPosition;
                        this.PlayAnimation(eState.Idle);
                        break;
                    }
                }
                yield return null;
            }

        }

        public void Attack(MonsterController target)
        {
            this.attackTarget = target;
            if(this.attackRoutine != null)
            {
                this.StopCoroutine(this.CoAttack());
            }
            this.attackRoutine = this.StartCoroutine(this.CoAttack());
        }

        private IEnumerator CoAttack()
        {
            while(true)
            {
                this.PlayAnimation(eState.Attack);
                yield return null;
            }
        }

        private void PlayAnimation(eState state)
        {
            this.anim.SetInteger("State", (int)state);
        }
        private void OnDrawGizmos()
        {
            GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, 1, 40);
        }
    }
}

 

Real_SimpleRpgSceneMain

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

namespace Real
{
    public class Real_SimpleRpgSceneMain : MonoBehaviour
    {
        [SerializeField]
        private HeroController heroController;
        [SerializeField]
        private MonsterController monsterController1;
        [SerializeField]
        private MonsterController monsterController2;
        // Start is called before the first frame update
        void Start()
        {

        }

        // Update is called once per frame
        void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red, 2f);

                RaycastHit hit;
                if(Physics.Raycast(ray, out hit, 100f))
                {
                    //두 원점사이의 거리
                    float distance = Vector3.Distance(this.transform.position, hit.collider.gameObject.transform.position);
                    //반지름의 합
                    float sumRadius = this.heroController.Radius + this.monsterController1.Radius;
                    Debug.LogFormat("sumRadius: {0}", sumRadius);
                    //몬스터라면
                    if(hit.collider.tag == "Monster")
                    {
                        Debug.LogFormat("hit.collider.tag : {0}", hit.collider.tag);
                        if (distance <= sumRadius)
                        {
                            //this.heroController.Attack(monsterController1);
                        }
                        else
                        {
                            this.heroController.Move(monsterController1);
                        }
                    }
                    else if(hit.collider.tag == "Monster2")
                    {
                        Debug.LogFormat("hit.collider.tag : {0}", hit.collider.tag);
                        if (distance <= sumRadius)
                        {
                            //this.heroController.Attack(monsterController2);
                        }
                        else
                        {
                            this.heroController.Move(monsterController2);
                        }
                    }
                    //땅이라면
                    else if(hit.collider.tag == "Ground")
                    {
                        Debug.LogFormat("hit.collider.tag : {0}", hit.collider.tag);
                        this.heroController.Move(hit.point);
                    }

                }
            }
        }
        private bool IsWithinRange(float distance, float sumRadius)
        {
            return distance <= sumRadius;
        }
    }
}

 

MonsterController

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

namespace Real
{
    public class MonsterController : MonoBehaviour
    {
        [SerializeField]
        private float radius = 1f;
        public float Radius
        {
            get
            {
                return this.radius;
            }
        }

        // Start is called before the first frame update
        void Start()
        {

        }

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

        }
        private void OnDrawGizmos()
        {
            GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, 1, 40);
        }
    }
}

 

Move(monsterController)로 받고 HeroController의 CoMove에서 Vector3의 targetPosition으로만 받아와서 마우스로 몬스터를 찍어도 Vector로 받지 않아서 움직이지 않았는데 MonsterController 변수인 target을 받고 if(target != null)로 distance등 전부 다 따로 받았더니 움직이게 되었다.

 

 

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

몬스터를 죽이면 리스트에서 없애고 임의 위치에 포탈생성  (0) 2023.08.10
몬스터 동적으로 데이터관리 생성  (0) 2023.08.10
SimpleRPG Test  (0) 2023.08.09
SimpleRPG  (0) 2023.08.09
이펙트  (0) 2023.08.08