C#/수업내용

2020.05.25. 수업내용 - world 좌표 -> Screen좌표, hudText효과 연출하기/ 적 어그로 끌기

dev_sr 2020. 5. 26. 00:16

 

카페에 있는 요구사항을 대부분 충족시키려고 했습니다

적이 공격당했을 때 데미지 모션을 실행하는 부분이 잘 안됐습니다

히어로의 체력에 데미지를 주고 게이지에 반영하는 부분은 데미지 모션 구현이 해결되면 같이 구현해보려고 합니다.

 

더 공부해볼 것

 

1. Test

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
167
168
169
170
171
172
using DG.Tweening;
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
 
public class Test : MonoBehaviour
{
    public UITest uiTest;
    public Hero hero;
    public Enemy enemy;
    public GameObject flagGo;
    public GameObject notiPrefab;
    public GameObject uiHudTextPrefab;
    public GameObject fx01Prefab;
 
 
    private bool isStart;
    private GameObject notiGo;
    private void Awake()
    {
        
    }
 
    void Start()
    {
        this.uiTest.Init();
        this.hero.Init();
        this.enemy.Init();
 
        this.uiTest.OnClickStartBtn = () =>
        {
            this.isStart = true;
        };
 
        this.enemy.OnAlert = () =>
        {
            this.notiGo = Instantiate<GameObject>(this.notiPrefab);
            this.notiGo.transform.SetParent(this.uiTest.transform, false);
 
            Vector3 screenPos = Camera.main.WorldToScreenPoint(this.enemy.iconPivot.transform.position);
            var screenPosX = screenPos.x - 1920 / 2;
            var screenPosY = screenPos.y - 1080 / 2;
 
            //Debug.LogFormat("{0}, {1}", screenPosX, screenPosY);
 
            this.notiGo.transform.localPosition = new Vector2(screenPosX, screenPosY);
 
            this.uiTest.heroState.ShowTargetUI();
            this.uiTest.enemyState.ShowTargetUI();
 
        };
 
        this.enemy.OnReturnNormal = () =>
        {
            Object.Destroy(this.notiGo);
            this.uiTest.heroState.HideTargetUI();
            this.uiTest.enemyState.HideTargetUI();
        };
 
        this.hero.OnImpact = () =>
        {
            //hud
            GameObject uiHudTextGo = Instantiate<GameObject>(this.uiHudTextPrefab);
            uiHudTextGo.transform.SetParent(this.uiTest.transform, false);
 
            Vector3 screenPos = Camera.main.WorldToScreenPoint(this.hero.hudPivot.transform.position);
            var screenPosX = screenPos.x - 1920 / 2;
            var screenPosY = screenPos.y - 1080 / 2;
 
            Vector2 targetLocalPos = new Vector2(screenPosX, screenPosY);
            UIHudText uiHudText = uiHudTextGo.GetComponent<UIHudText>();
            uiHudText.Init("100", targetLocalPos);
 
            //스케일 조절하기 위해 처음에 0으로 맞춤
            uiHudTextGo.transform.localScale = Vector3.zero;
 
            //연출
            var targetPosY = uiHudTextGo.transform.localPosition.y + 100;
 
            uiHudTextGo.transform.DOScale(2f, 0.5f).OnComplete(() =>
            {
                uiHudTextGo.transform.DOScale(0f, 0.5f).OnComplete(() =>
                {
 
                });
 
            });
 
            uiHudTextGo.transform.DOLocalMoveY(targetPosY, 0.5f).SetEase(Ease.OutCirc).OnComplete(() =>
            {
                Debug.Log("move complete");
                Object.Destroy(uiHudTextGo);
            });
 
 
 
            //이펙트
            GameObject fx01Go = Instantiate(this.fx01Prefab) as GameObject;
            Transform heroTrans = this.hero.gameObject.transform;
            fx01Go.transform.position = new Vector3(heroTrans.position.x, heroTrans.position.y + 0.3f, heroTrans.position.z + 0.3f);
            
        };
 
        this.enemy.OnChaseRemoveNoti = () =>
          {
              Object.Destroy(this.notiGo);
          };
 
        this.hero.OnAttack=(float enemyHp,float enemyMaxhp) =>
        {
            this.uiTest.heroState.ChangeGauge(enemyHp, enemyMaxhp);
            this.uiTest.enemyState.ChangeGauge(enemyHp, enemyMaxhp);
        };
 
        this.enemy.OnReturnToOriginalPos = (float hp, float maxHp) =>
         {
             this.uiTest.heroState.ChangeGauge(hp, maxHp);
             this.uiTest.enemyState.ChangeGauge(hp, maxHp);
         };
 
    }
 
    void Update()
    {
 
        if (Input.GetMouseButtonDown(0))
        {
            if (!EventSystem.current.IsPointerOverGameObject())
            {
                if(this.isStart)
                {
 
                    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                    Debug.DrawRay(ray.origin, ray.direction * 1000f, Color.red, 1f);
 
                    RaycastHit hit;
 
                    if (Physics.Raycast(ray, out hit, 1000))
                    {
                        //Debug.Log(hit.point);
                        this.flagGo.transform.position = hit.point;
                        var target = hit.collider;
                        Debug.Log(target.gameObject.name);
 
                        this.hero.Move(this.flagGo.transform);
 
                        //this.uiTest.Hide();
 
                        if (target.gameObject.transform.root.name == "Enemy")
                        {
                            //this.uiTest.Show();
                            this.hero.Move(target.gameObject.transform.root.transform);
 
                        }
 
                    }
 
                   
                }
                
            }
 
        }
 
        
 
    }
}
 

 

2. UITest 

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class UITest : MonoBehaviour
{
    public Image thumb;
    public GameObject emptyThumb;
    public Button startBtn;
    public HeroState heroState;
    public EnemyState enemyState;
    public System.Action OnClickStartBtn;
 
    public void Init()
    {
        this.startBtn.onClick.AddListener(() =>
        {
            this.OnClickStartBtn();
        });
    }
 
    // 바닥 클릭하면 ui가 empty 썸넬로 바뀌는 코드
    //public void Show()
    //{
    //    this.emptyThumb.SetActive(false);
    //    this.thumb.gameObject.SetActive(true);
    //}
   
    //public void Hide()
    //{
    //    this.emptyThumb.SetActive(true);
    //    this.thumb.gameObject.SetActive(false);
    //}
}
 

 

 

3. HeroState 

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
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.UI;
 
public class HeroState : MonoBehaviour
{
    public Slider heroSlider;
    public Slider targetSlider;
    public Image heroThumb;
    public Image targetImage;
 
    private void Start()
    {
        //시작은 만땅
        this.heroSlider.value = 1f;
        this.targetSlider.value = 1f;
    }
 
    public void ShowTargetUI()
    {
        this.targetImage.gameObject.SetActive(true);
        this.targetSlider.gameObject.SetActive(true);
    }
 
    public void HideTargetUI()
    {
        this.targetImage.gameObject.SetActive(false);
        this.targetSlider.gameObject.SetActive(false);
    }
 
    public void ChangeGauge(float targetCurrnetHp, float targetMaxHp)
    {
        this.targetSlider.value = targetCurrnetHp / targetMaxHp;
        Debug.LogFormat("{0} {1} {2}", targetCurrnetHp, targetMaxHp, targetCurrnetHp/targetMaxHp);
    }
}
 

 

4. EnemyState 

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class EnemyState : MonoBehaviour
{
    public Slider enemySlider;
    public Slider targetSlider;
    public Image enemyImage;
    public Image targetImage;
 
    public void ShowTargetUI()
    {
        this.targetImage.gameObject.SetActive(true);
        this.targetSlider.gameObject.SetActive(true);
    }
 
    public void HideTargetUI()
    {
        this.targetImage.gameObject.SetActive(false);
        this.targetSlider.gameObject.SetActive(false);
 
    }
 
    public void ChangeGauge(float currnetHp, float maxHp)
    {
        this.enemySlider.value = currnetHp / maxHp;
        Debug.LogFormat("{0} {1} {2}", currnetHp, maxHp, currnetHp / maxHp);
    }
}
 

 

5. UIHudText 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class UIHudText : MonoBehaviour
{
    public Text text;
 
    public void Init(string strNum, Vector2 targetLocalPos)
    {
        this.text.text = strNum;
        this.transform.localPosition = targetLocalPos;
    }
    // Update is called once per frame
    void Update()
    {
        
    }
}
 

 

6.Hero 

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
 
public class Hero : MonoBehaviour
{
    private float speed;
    private Transform targetTrans;
    private Animation anim;
    private AnimationState animStateAttack;
    private bool isMove;
    private float elapsedTimeMove;
    private bool isAttack;
    private float elapsedTimeAttack;
    private float impactTime;
    private bool isImpact;
    private float elapsedTimeImpact;
    private Enemy enemy;
    private float damage = 100f;
 
    public float targetRange = 3f;
    public UnityAction OnImpact;
    public GameObject hudPivot;
    public System.Action<float,float> OnAttack;
 
    public void Init()
    {
        this.speed = 1f;
        GameObject model = GameObject.Find("ch_04_01");
        this.anim = model.GetComponent<Animation>();
 
        this.animStateAttack = this.anim["attack_sword_01"];
        float impactFrame = 6;
        float totalFrame = this.animStateAttack.length * this.animStateAttack.clip.frameRate;
        this.impactTime = this.animStateAttack.length * impactFrame / totalFrame;
        this.isImpact = true;
 
        this.enemy = GameObject.Find("Enemy").GetComponent<Enemy>();
 
    }
 
    public void Move(Transform targetTrans)
    {
        this.anim.Play("run@loop");
        this.targetTrans = targetTrans;
        this.transform.LookAt(this.targetTrans);
        this.isMove = true;
 
    }
 
    public void Stop()
    {
        this.anim.Play("idle@loop");
    }
 
    public void Attack()
    {
        this.anim.Play("attack_sword_01");
 
        this.enemy.hp -= this.damage;
        Debug.LogFormat("{0} {1}"this.enemy.hp, this.enemy.maxHp);
        this.OnAttack(this.enemy.hp, this.enemy.maxHp);
 
        if(this.enemy.hp<=0)
        {
            this.enemy.Die();
        }
 
 
        this.isAttack = true;
        this.isImpact = false;
        this.isMove = false;
    }
 
    void Update()
    {
        if(this.isMove)
        {
            this.elapsedTimeMove = Time.deltaTime;
 
            float distance = Vector3.Distance(this.transform.position, this.targetTrans.position);
            this.transform.Translate(this.speed * this.elapsedTimeMove * Vector3.forward);
 
 
            if(distance<0.5f)
            {
                this.Stop();
                this.isMove = false;
 
                if (this.targetTrans.gameObject.name == "Enemy")
                {
                    this.Attack();
                }
            }
            
        }
 
        if(this.isAttack)
        {
            this.elapsedTimeAttack += Time.deltaTime;
 
            if(this.elapsedTimeAttack >= this.animStateAttack.length)
            {
                this.elapsedTimeAttack = 0;
                this.Stop();
                this.isAttack = false;
 
            }
        }
 
        if(!this.isImpact)
        {
            this.elapsedTimeImpact += Time.deltaTime;
 
            if(this.elapsedTimeImpact>=this.impactTime)
            {
                this.elapsedTimeImpact = 0;
                this.isImpact = true;
 
                if(this.OnImpact !=null)
                {
                    this.OnImpact();
                }
            }
        }
    }
}
 

 

7. Enemy 

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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Build;
using UnityEngine;
using UnityEngine.Events;
 
public class Enemy : MonoBehaviour
{
    private Hero hero;
    private float targetRange;
    private bool isTargetIn;
    private Transform targetTrans;
    private float distanceAlert;
    private bool isKnowTarget;
    private bool isLookAtTarget;
    private float attackRange;
    private Animation anim;
    private AnimationState animStateAttack;
    private bool isAttack;
    private float elapsedTimeAttack;
    private float chaseRange;
    private bool isChase;
    private float elapsedTimeChase;
    private float distanceBetweenOriginalPos;
    private Vector3 originalPos;
    private bool isReturnToOriginalPos;
    private float elapsedTimeReturn;
    private float speed = 0.7f;
    private bool didAttack;
    private float delayTime;
 
    public float hp;
    public float maxHp;
 
    public GameObject iconPivot;
    public UnityAction OnAlert;
    public UnityAction OnReturnNormal;
    public UnityAction OnChaseRemoveNoti;
    public UnityAction<float,float> OnReturnToOriginalPos;
    
    public void Init()
    {
        this.chaseRange = 4;
        this.targetRange = 3f;
        this.attackRange = 1f;
        this.hero = GameObject.Find("Hero").GetComponent<Hero>();
        this.targetTrans = this.hero.transform;
        this.isKnowTarget = false;
        this.isLookAtTarget = false;
 
 
        GameObject model = GameObject.Find("ch_02_01");
        this.anim = model.GetComponent<Animation>();
        this.animStateAttack = this.anim["attack_sword_01"];
 
        this.originalPos = new Vector3(002);
        
 
        Debug.LogFormat("원래 위치 {0}"this.originalPos);
 
        this.hp = 1000f;
        this.maxHp = 1000f;
 
    }
 
    public void Alert()
    {
        Debug.Log("적이 알아챔");
        this.OnAlert();
 
        this.isLookAtTarget = true;
    }
 
    public void ReturnNormal()
    {
       
        this.OnReturnNormal();
 
        this.isLookAtTarget = false;
        this.isAttack = false;
        this.isChase = false;
    }
 
    public void Attack()
    {
        this.anim.Play("attack_sword_01");
        this.isAttack=true;
    }
 
    public void Stop()
    {
        this.anim.Play("idle@loop");
        this.isAttack = false;
        //this.isChase = false;
    }
 
    public void Chase()
    {
        this.anim.Play("run@loop");
        this.isChase = true;
    }
 
    public void ReturnToOriginalPos()
    {
        this.anim.Play("run@loop");
        this.transform.LookAt(this.originalPos);
        this.isReturnToOriginalPos = true;
        
    }
 
    public void Damage()
    {
        this.anim["damage"].time = 0;
        this.anim.Play("damage");
    }
 
    public void Die()
    {
        this.anim.Play("die");
        this.isKnowTarget = true;
        this.isLookAtTarget = false;
        this.didAttack = false;
        this.isChase = false;
        this.isReturnToOriginalPos = false;
        this.isAttack = false;
    }
 
    void Update()
    {
        this.distanceAlert = Vector3.Distance(this.targetTrans.position, this.transform.position);
       
 
        if (!this.isKnowTarget)
        {
            
            if (this.distanceAlert <= this.targetRange)
            {
                this.isKnowTarget = true;
                this.Alert();
            }
        }
 
        if (this.isKnowTarget)
        {
            if (this.distanceAlert > this.targetRange)
            {
                this.isKnowTarget = false;
                this.ReturnNormal();
            }
 
        }
 
        if(this.isLookAtTarget)
        {
            this.transform.LookAt(this.targetTrans);
 
            if (this.distanceAlert <= this.attackRange)
            {
                this.Attack();
                this.didAttack = true;  //공격했었어?
            }
 
        }
 
        if(this.didAttack)
        {
            //다시 범위를 벗어나면 쫓아가기
            if (this.distanceAlert >= this.attackRange)
            {
                this.Chase();
                this.didAttack = false;
            }
        }
 
 
        if (this.isChase)
        {
            
            //느낌표 지우기
            if (this.OnChaseRemoveNoti != null)
            {
                this.OnChaseRemoveNoti();
            }
 
            if (this.distanceAlert <= attackRange)
            {
               
                this.delayTime += Time.deltaTime;
 
                if(this.delayTime>=2f)
                {
                    this.Attack();
                    this.delayTime = 0;
                }
            }
 
            else 
            {
                this.Chase();
            
                this.elapsedTimeChase = Time.deltaTime;
                this.distanceBetweenOriginalPos = Vector3.Distance(this.originalPos, this.transform.position);
                this.transform.Translate(this.speed * this.elapsedTimeChase * Vector3.forward);
 
                //Debug.LogFormat("원래 위치와의 차 {0}",this.distanceBetweenOriginalPos);
 
                if(this.distanceBetweenOriginalPos>=this.chaseRange)
                {
                    this.ReturnToOriginalPos();
                    this.isChase = false;
                    this.isLookAtTarget = false;
                }
 
            }
 
        }
 
        if(this.isReturnToOriginalPos)
        {
            this.elapsedTimeReturn = Time.deltaTime;
            this.distanceBetweenOriginalPos = Vector3.Distance(this.originalPos, this.transform.position);
            this.transform.Translate(this.speed * this.elapsedTimeReturn * Vector3.forward);
 
            if(this.distanceBetweenOriginalPos <=0.02f)
            {
                this.Stop();
                this.isReturnToOriginalPos = false;
                this.hp = 1000f;
                if(this.OnReturnToOriginalPos!=null)
                {
                    this.OnReturnToOriginalPos(this.hp,this.maxHp);
                }
            }
        }
 
        if (this.isAttack)
        {
            this.elapsedTimeAttack += Time.deltaTime;
 
            if (this.elapsedTimeAttack >= this.animStateAttack.length)
            {
                this.elapsedTimeAttack = 0;
                //this.Stop();
                this.isAttack = false;
                
            }
 
        }
    }
}
 

 

 

 

 

 

 

 

 

HudTextTest 코드

 

 

1.HudTextTest 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class HudTextTest : MonoBehaviour
{
    public UIHudTextTest uiHudTextTest;
    public Transform pivotTrans;
 
    void Start()
    {
        this.uiHudTextTest.btn.onClick.AddListener(() =>
        {
            this.uiHudTextTest.ShowHud(this.pivotTrans.position,5890);
        });
    }
 
    // Update is called once per frame
    void Update()
    {
        
    }
}
 

 

2.UIHudTextTest 

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
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using UnityEngine;
using UnityEngine.UI;
 
public class UIHudTextTest : MonoBehaviour
{
    public Button btn;
    public GameObject uiHudTextPrefab;
    void Start()
    {
        
    }
 
    //targetPos : world position
 
    public void ShowHud(Vector3 targetPos,int num)
    {
        //세자리 수 , 찍기
        var strNum = string.Format("{0:#,0}", num);
        Debug.LogFormat("{0}", strNum);
        var hudTextgo = Instantiate<GameObject>(this.uiHudTextPrefab);
 
        hudTextgo.transform.SetParent(this.transform, false);
 
        var pos = Camera.main.WorldToScreenPoint(targetPos);
        var canvasX = pos.x - 1920 / 2;
        var canvasY = pos.y - 1080 / 2;
        //초기위치
        var targetLocalPos= new Vector2(canvasX, canvasY);
        var uiHudText = hudTextgo.GetComponent<UIHudText>();
        uiHudText.Init(strNum, targetLocalPos);
        hudTextgo.transform.localScale = Vector3.zero;
 
        //연출할때 사용
        var targetPosY = hudTextgo.transform.localPosition.y + 100;
 
        hudTextgo.transform.DOScale(2f, 0.5f).OnComplete(() =>
         {
             hudTextgo.transform.DOScale(0f, 0.5f).OnComplete(() =>
             {
 
             });
 
         });
 
        hudTextgo.transform.DOLocalMoveY(targetPosY, 1f).SetEase(Ease.OutQuint).OnComplete(() =>
        {
            Debug.Log("move complete");
            Object.Destroy(hudTextgo);
        });
    }
 
    // Update is called once per frame
    void Update()
    {
        
    }
}
 

 

3.UIHudText 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class UIHudText : MonoBehaviour
{
    public Text text;
 
    public void Init(string strNum, Vector2 targetLocalPos)
    {
        this.text.text = strNum;
        this.transform.localPosition = targetLocalPos;
    }
    // Update is called once per frame
    void Update()
    {
        
    }
}