Unity/수업내용
2020-05-26 유니티 코루틴
J월드
2020. 5. 26. 11:59
코루틴... 진도는 너무나도 빠르고, 그때그때마다 사용만하고, 이해하지않고 그냥 넘어갔던 것들이 산더미만큼 쌓여서
머릿속이 뿌옇다.
아무것도 모르겠어서 코드읽기밖에 못하겠다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
#region(문제)
/*
* 코루틴 사용
공격 이펙트(Hit Slashes Vol1)
데미지 텍스트(DoTween)
Test1
└Hero
└Hero(Enmey)
└Fx
UITest1
└HudText
*/
#endregion
public class Hero : MonoBehaviour
{
public GameObject model; //프리팹 손으로넣음
public Transform targetPoint; //타겟포인트 지정
public Hero target; //타겟이 누구인지 알기 위해
public UnityAction OnHitComplete; //대리자
public float attackRange = 0.5f; //공격범위
public bool isEnemy; //적이 있는지 없는지
private UnityAction OnMoveComplete; //대리자
private System.Action OnOnceAttackComplete; //대리자
private Animation anim; //애니메이션가져옴
private void Start()
{
this.anim = this.model.gameObject.GetComponent<Animation>(); //애니메이션가져옴
this.OnHitComplete = () => //공격이 끝났을때 실행되는 대리자
{
this.Idle();
};
if (isEnemy) return; //true값일때 리턴
this.target = this.targetPoint.GetComponent<Hero>(); //타겟에 타겟포인트의 Hero 컴포넌트 가져옴
Debug.LogFormat("target : {0}", this.target);
this.OnOnceAttackComplete = () => //한번 공격후 실행되는 대리자
{
this.Idle();
this.StartCoroutine(this.Attack(0.5f)); //공격 코루틴, 매개변수로 딜레이시간을 보냄
};
this.OnMoveComplete = () => //이동이 끝난뒤 실행되는 대리자
{
this.Idle();
this.StartCoroutine(this.Attack()); //공격 코루틴 실행
};
this.StartCoroutine(this.Move()); //이동 코루틴 실행
}
#region(내가 짠 Attack)
//IEnumerator Attack(float deley = 0)
//{
// this.anim.Play("attack_sword_01");
// float elapsedTime = 0; //공격애니메이션 경과시간 담기.
// //float elapsedTimeForHit = 0; //히트애니메이션 경과시간 담기
// elapsedTime += Time.deltaTime;
// Debug.Log("공격실행");
// string animName = "attack_sword_01";
// var length = this.anim[animName].length;
// if (elapsedTime >= length)
// {
// Debug.Log("히트다 히트");
// elapsedTime = 0;
// }
// yield return new WaitForSeconds(1f);
//}
#endregion
private void Idle() //Idle 함수
{
this.anim.Play("idle@loop"); //그저 애니메이션만 플레이함
}
IEnumerator Hit() { //Hit 코루틴 정의
this.anim.Play("damage"); //히트 애니메이션 실행
//히트애니메이션의 길이만큼 기다렸다가 다음프레임 실행
yield return new WaitForSeconds(this.anim["damage"].length);
this.OnHitComplete(); //OnHitComplete 대리자 호출
}
IEnumerator Attack(float delay = 0) //Attack 코루틴 정의
{
//매개변수로 받아온 delay값만큼 기다림
//애니메이션 씹히는 것을 방지하기 위해
yield return new WaitForSeconds(delay);
var animName = "attack_sword_01"; //변수하나 선언해서 애니메이션 이름 넣어둠
var length = this.anim[animName].length; //변수하나 선언해서 애니메이션의 길이저장
var isImpact = false; //공격 모션 이펙트 판정
this.anim.Play(animName); //animName의 애니메이션 실행
float elapsedTime = 0; //공격 애니메이션 경과시간을 계산하기 위해
while (true) {
elapsedTime += Time.deltaTime;
if (elapsedTime >= 0.2665f)
{ //이펙트가 나오는시점의 공격 모션시간이 0.2665f
if (!isImpact) {
isImpact = true;
Debug.Log("Impact"); //공격 모션시점에서 Impact를 출력
StartCoroutine(this.target.Hit()); //target의 Hit 코루틴을 실행
}
}
if (elapsedTime >= length) //공격애니메이션이 다끝나면 break문으로 조건식 탈출
{
break;
}
yield return null; //다음프레임실행
}
Debug.Log("once attack complete");
this.OnOnceAttackComplete(); //코루틴이 한바퀴 돌았을때 대리자 실행
}
IEnumerator Move()
{
this.anim.Play("run@loop"); //run 루프 애니메이션 실행
while (true)
{
//position 변경
this.transform.Translate(Vector3.forward * 1f * Time.deltaTime); //계속 앞으로 이동
//타겟포인트와 영웅의 거리 계산
var dis = Vector3.Distance(this.targetPoint.position, this.transform.position);
if (dis <= this.attackRange) {
//도착
break; //조건식 탈출
}
//다음 프레임 이동
yield return null;
}
Debug.Log("이동완료");
this.anim.Play("idle@loop");
this.OnMoveComplete(); //OnMoveComplete 대리자 호출
}
}
|
cs |