유니티 기초

SimpleRPG

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

1. 방법 - Unity에서 만들기

변수에 메서드 설정한 거 .. On Click --> 대리자 100%


2. 방법 - 코드

익명 - 람다

이벤트 지우기

 

익명을 선호하는게 좋다고함..

명명을 사용하는 경우는 내부 구현이 길어질 때 [TestAttack] 사용한다고 함

 

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

namespace Test2
{
    public class Test_PlayerAttackSceneMain : MonoBehaviour
    {
        [SerializeField]
        private Button btnAttack;
        [SerializeField]
        private HeroController heroController;
        [SerializeField]
        private MonsterController monsterController;
        // Start is called before the first frame update
        void Start()
        {
            //이벤트 등록
            //익명 (람다)
            this.btnAttack.onClick.AddListener(() =>{
                //사거리 체크
                //두점과의 거리, 두 오브젝트의 radius의 합
                //B-A : C (방향벡터), magnitude (벡터의 길이)
                //MonsterController컴포넌트가 붙어있는 게임오브젝트의 Transform 컴포넌트의 Position속성 (Vector3)
                //Vector3 b = monsterController.gameObject.transform.position;
                //Vector3 b = monsterController.gameObject.GetComponent<Transform>().position;
                Vector3 b = this.monsterController.transform.position;
                Vector3 a = this.heroController.transform.position;
                Vector3 c = b - a; //방향벡터 [정규화되지 않은] , 방향과 크기 가지고있음, 크기 : 길이

                // --------------> (방향 -> , 크기 --------------)
                float distance = c.magnitude;
                Debug.LogFormat("distance: {0}", distance);
                Debug.DrawLine(a, b, Color.red, 5f);
                //단위벡터 (길이가 1인 벡터)
                //Vector3 normal = c.normalized; // 방향 의미
                //시작위치, 방향, 몇초, 색, 화살표타입
                //DrawArrow.ForDebug(a, c, 5f, Color.red, ArrowType.Solid);
                //DrawArrow.ForDebug(a, normal, 5f, Color.red, ArrowType.Solid);
                //Vector3.Distance

                //두 컴포넌트의 radius (반지름)의 합
                float sumRadius = this.heroController.Radius + this.monsterController.Radius;
                Debug.LogFormat("radius: {0}", sumRadius);

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

        }

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

        public void TestAttack()
        {
            Debug.Log("공격");
        }
    }
}


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Test2
{
    public class HeroController : MonoBehaviour
    {
        public enum eState
        {
            Idle, Attack
        }
        private Animator anim;
        [SerializeField]
        private float radius = 1f;
        private eState state;
        public float Radius
        {
            get
            {
                return this.radius;
            }
        }
        // Start is called before the first frame update
        void Start()
        {
            this.anim = GetComponent<Animator>();
        }

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

        }

        public void Attack(MonsterController target)
        {
            //공격 애니메이션을 1회 실행
            //애니메이터 컴포넌트가 필요함
            //this.anim.SetInteger("State", (int)eState.Attack); // 정수 -> enum
            this.PlayAnimation(eState.Attack);
        }

        private void PlayAnimation(eState state)
        {

            //중복막기
            if(this.state != state)
            {
                //this.state : 현재, state : 미래
                Debug.LogFormat("{0} -> {1}", this.state, state);
                this.state = state;
                this.anim.SetInteger("State", (int)state);

                switch(state)
                {
                    case eState.Attack:
                        this.StartCoroutine(this.CoWaitForCompleteAttackAnimation());
                        break;
                }
            }
            else
            {
                Debug.LogFormat("{0}은 현재상태와 같은 State입니다.", state);
            }

        }

        //코루틴
        //IEnumerator 반환타입을 갖는 1개 이상의 yield return을 포함하는 함수
        //Update와 동일하게 동작 가능
        private IEnumerator CoWaitForCompleteAttackAnimation()
        {
            yield return null; //다음 프레임의 시작

            Debug.Log("공격 애니메이션이 끝날때까지 기다림");
            //layerIndex : 0
            AnimatorStateInfo animStateInfo = this.anim.GetCurrentAnimatorStateInfo(0);
            bool isAttackState = animStateInfo.IsName("Attack01");
            Debug.LogFormat("IsAttackState: {0}", isAttackState);
            if (isAttackState)
            {
                Debug.LogFormat("animStateInfo.length: {0}", animStateInfo.length);
            }
            else
            {
                Debug.Log("Attack State가 아닙니다.");
            }
            //this.WaitForCompleteAnimation(0.833f);
            yield return new WaitForSeconds(animStateInfo.length);

            //Idle 애니메이션을 함
            this.PlayAnimation(eState.Idle);
        }
        private void OnDrawGizmos()
        {
            Gizmos.color = Color.yellow;
            Gizmos.DrawWireSphere(this.transform.position, this.radius);
        }
    }
}

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

Real SimpleRPG  (0) 2023.08.09
SimpleRPG Test  (0) 2023.08.09
이펙트  (0) 2023.08.08
몬스터 클릭해서 공격  (0) 2023.08.08
몬스터 클릭해서 몬스터 있는 위치로 이동  (0) 2023.08.08