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 |