**2D로 만들 때 카메라 Projection 꼭 ortho로 해주기
Rigidbody
- 보통 중력의 영향을 주기 위해서 사용(Use Gravity 활성화)
- 물리적인 제어를 구현
- Rigidbody를 사용하거나 Tranform을 쓰거나 둘중 하나를 선택해야함
- Rigidbody 2D를 쓰면 Collider도 2D로 맞춰서 써야함
Collider
-물리 충돌 처리를 위한 오브젝트 형태
-보이지 않음
-Mesh : 형태
-한 객체에 Collider를 여러개 적용시킬 수 있음
ex) 캐릭터에 콜라이더를 여러가지 붙여놓고
박스 콜라이더는 인식범위, 캡슐 콜라이더는 공격범위 등으로 설정할 수 있음
-쉬어 변환 : 회전을 하다보면(쉬어 변환이 되면) 제대로 동작하지 않는다
->반드시 제대로 동작하지 않는다는 것을 의미함
-동적 콜라이더 : rigidbody가 있는거
-정적 콜라이더 : 벽, 바닥 등 고정물체에 있는 것
-트리거 : 충돌이 일어나는 시점을 감지, OnCollisionEnter 함수를 사용하여 액션
OnCollisionEnter (lifeCycle의 Physics의 OnCollisionXXX 중 하나)
XXX에는 Enter, Exit, Stay 가 있음
Enter : 충돌지점에 들어갈 때 한번 호출
Stay : 충돌지점에 머무를 때 매 프레임마다 호출
Exit : 충돌지점에서 벗어날 때 한번 호출
-Collision : 충돌을 나타내는 클래스 -> OnColliderXXX를 통해 전달되는 값의 데이터 형식
-Collider의 isTrigger가 활성화되면 물리적인 충돌을 무시
-OnTriggerXXX (Enter, Exit, Stay) 메서드 이용시 Collision 타입의 other값을 전달하게 됨
올라갈 때 속도변화
S=(v+at)t
초속이 1이라고 치면
현재 속도 = (초속 + 가속도 * 시간) * 시간
현재 속도 = (1+9.8 *Time.deltaTime) * Time.deltaTime;
this.transform.translate(현재 속도);
내려갈 때 속도 변화
S=(v-at)t
현재 속도 = (초속 - 가속도 * 시간) * 시간
현재 속도 = (1-9.8 *Time.deltaTime) * Time.deltaTime;
this.transform.translate(현재 속도);
1. Test1
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
|
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class Test1 : MonoBehaviour
{
public Button btn;
public GameObject heroPrefabs;
public GameObject flagGo;
private Hero hero;
private bool isHeroDown;
private bool isHeroExis;
void Start()
{
this.btn.onClick.AddListener(() =>
{
if(!this.isHeroExis)
{
GameObject heroGo = Instantiate<GameObject>(this.heroPrefabs);
heroGo.transform.position = new Vector3(0, 5, 0);
this.hero = heroGo.GetComponent<Hero>();
this.hero.Init(heroGo);
this.isHeroExis = true;
}
this.hero.OnDownComplete = () =>
{
this.isHeroDown = true;
};
});
}
void Update()
{
if(this.isHeroDown)
{
//캐릭터 생성 후 버튼을 또 눌렀을 때
//버튼 x 위치로 캐릭터가 달려가는 걸 방지
if (!EventSystem.current.IsPointerOverGameObject())
{
if (Input.GetMouseButtonDown(0))
{
//2D면 카메라 Projection을 꼭 ortho로 맞추기
//안하면 값이 말도 안되게 작게나옴
//레이캐스트 쓰면 뒤에 게임오브젝트 빈거라도 만들고 콜라이더 2D를 넣어줌
//콜라이더 스케일을 1920 * 1080으로 맞춰주기
//SpriteRenderer 컴포넌트 붙여주고 Order in layer 게임 오브젝트보다 작게 주기
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction);
if (hit)
{
this.flagGo.transform.position = hit.point;
this.hero.Move(hit.point.x);
}
}
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("스페이스 버튼 누름");
this.hero.Jump();
}
}
}
}
}
|
2. 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
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
|
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
public class Hero : MonoBehaviour
{
private Animator anim;
private bool isGround;
private float g = 9.8f;
private Coroutine moveRoutine;
private float maxHeight = 1.5f;
private Coroutine jumpRoutine;
private bool isJump;
private bool isMove;
private float delayTime;
private bool isJumpDown;
private float colliderHalfSize;
public UnityAction OnDownComplete;
public UnityAction OnMoveComplete;
public UnityAction OnJumpComplete;
void Start()
{
this.OnMoveComplete = () =>
{
this.Idle();
};
this.OnJumpComplete = () =>
{
if(this.isMove)
{
//실행하려면 스테이트머신에서 Run의 transitions 을 다 끊거나
//Run을 지우고 새로 노드를 만들어서
//Run애니메이션을 할당하고 이름을 Run으로 지어준다.
//안그럼 Idle만 함
//이름을 제대로 안적었을 땐 invalid layer index '-1' 이라는 문구가 나오면서 안됨
this.anim.Play("Run");
}
else
{
this.Idle();
}
};
}
public void Init(GameObject model)
{
this.anim = model.GetComponent<Animator>();
var ground = GameObject.Find("ground");
this.colliderHalfSize = ground.GetComponent<BoxCollider>().size.x / 2;
this.StartCoroutine(this.DownIE());
}
public void Idle()
{
this.anim.Play("Idle");
}
public void Move(float tposX)
{
float heroX = this.transform.position.x;
Vector2 dir = Vector2.zero;
if (heroX > tposX)
{
dir = Vector2.left;
this.transform.localScale = new Vector3(5, 5, 5);
}
if (heroX < tposX)
{
dir = Vector2.right;
this.transform.localScale = new Vector3(-5, 5, 5);
}
if(this.moveRoutine!=null)
{
this.StopCoroutine(this.moveRoutine);
}
this.moveRoutine = this.StartCoroutine(this.MoveIE(tposX, dir));
}
public void Jump()
{
this.anim.Play("Jump");
if (this.transform.position.y < this.maxHeight)
{
this.isJump = false;
}
if(this.jumpRoutine!=null)
{
this.StopCoroutine(this.jumpRoutine);
}
this.jumpRoutine = this.StartCoroutine(this.JumpIE());
}
IEnumerator JumpIE()
{
while(true)
{
if (!this.isJump)
{
Debug.Log("올라감");
float currentSpeed = (3.5f + this.g * Time.deltaTime) * Time.deltaTime;
this.transform.Translate(Vector3.up * currentSpeed);
}
if (this.transform.position.y >= this.maxHeight)
{
Debug.Log("정점");
//더 자연스럽게 보이기 위해 체공시간을 넣어봤는데
//좀 더 떠있긴 함
this.delayTime += Time.deltaTime;
if(this.delayTime>=0.15f)
{
this.isJumpDown = true;
this.delayTime = 0;
}
this.isJump = true;
}
if(this.isJumpDown)
{
Debug.Log("내려감");
float currentSpeed = (3.5f - this.g * Time.deltaTime) * Time.deltaTime;
this.transform.Translate(Vector3.down * currentSpeed);
}
if(this.isGround)
{
this.isGround = false;
this.transform.position = new Vector3(this.transform.position.x, 0.5f, 0);
this.OnJumpComplete();
this.isJumpDown = false;
break;
}
yield return null;
}
}
IEnumerator MoveIE(float tposX, Vector2 dir)
{
this.anim.Play("Run");
this.isMove = true;
float distance = 0;
while(true)
{
this.transform.Translate(dir * 2f * Time.deltaTime);
distance = this.transform.position.x - tposX;
if(distance<0)
{
distance *= -1;
}
if(distance<0.02f)
{
this.OnMoveComplete();
this.isMove = false;
break;
}
if(this.transform.position.x >= colliderHalfSize || this.transform.position.x <=-colliderHalfSize)
{
this.OnMoveComplete();
this.isMove = false;
break;
}
yield return null;
}
}
IEnumerator DownIE()
{
Debug.Log(this.isGround);
while (true)
{
this.transform.Translate(Vector3.down * g * Time.deltaTime);
if (this.isGround)
{
this.transform.position = new Vector3(0, 0.5f, 0);
this.OnDownComplete();
this.isGround = false;
break;
}
yield return null;
}
}
//콜라이더가 붙어있는 게임오브젝트가 가장 상위에 있어야 제대로 적용됨
//모델에 콜라이더가 있는데 hero껍데기를 만들어서 껍데기를 부모로 설정하면
//콜라이더 적용이 안되고 프리패스함
//히어로 껍데기에 콜라이더가 붙어있던가
//히어로 껍데기를 씌우지 않고 모델에 붙어있던가 해야함
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("ground"))
{
this.isGround = true;
}
}
}
|
'C# > 수업내용' 카테고리의 다른 글
2020.06.23. 수업내용 - Shader2 (Range, lerp) (0) | 2020.06.24 |
---|---|
2020.06.22. 수업내용 - Shader (0) | 2020.06.22 |
2020.05.26. 수업내용 - Coroutine 으로 애니메이션 실행하기 (0) | 2020.05.26 |
2020.05.26. 수업내용 - 2D animator/ 2D 오브젝트 움직이기 (0) | 2020.05.26 |
2020.05.25. 수업내용 - world 좌표 -> Screen좌표, hudText효과 연출하기/ 적 어그로 끌기 (0) | 2020.05.26 |