1. 유니티의 생명주기
docs.unity3d.com/kr/current/Manual/ExecutionOrder.html
이벤트 함수의 실행 순서 - Unity 매뉴얼
Unity 스크립트를 실행하면 사전에 지정한 순서대로 여러 개의 이벤트 함수가 실행됩니다. 이 페이지에서는 이러한 이벤트 함수를 소개하고 실행 시퀀스에 어떻게 포함되는지 설명합니다.
docs.unity3d.com
Awake() 프로그램이 시작하면 딱 한 번만 실행. 항상 Start함수 앞에서 실행된다. 만약 해당 오브젝트가 비활성화 상태라면 활성화되기 전까지 호출되지 않는다.
Start() 스크립트 인스턴스가 활성화된 경우에만 첫 프레임 업데이트 이전에 호출된다.
OnEnable() Insfector뷰에서 체크를 통해 오브젝트가 활성화 될 때마다 호출된다.
OnDisable() 동작이 비활성화되거나 비활성 상태일 때 이 함수가 호출된다.
Update() 프레임마다 호출되는 함수로 게임의 핵심 로직에 관여한다. 스크립트가 활성화되어 있어야 사용 가능하고 주기가 일정하지 않다.
FixedUpdate() 일정한 주기로 호출되는 함수이다. 프레임 속도가 낮을경우 프레임보다 더 자주 호출될 수 있으며 프레임 속도가 높을 경우 프레임 사이에 호출되지 않을 수도 있다. 주로 물리 엔진을 사용할 때 일정 시간으로 힘을 가하기 위해 사용된다.
OnDestroy() 오브젝트 생존기간 중 모든 프레임 업데이트를 마친 후 호출된다.
2. 프리팹
이미 컴포넌트로 구성이 완료된 재사용 가능한 게임 오브젝트(GameObject)를 일컫는다. 추후 게임 오브젝트의 내용을 수정할 필요가 생겼을 때 프리팹 파일만 바꿔주면 되기 때문에 관리에 있어 용이하다.
3. 똥 피하기 게임 만들기
유니티 에셋 폴더에 Sprites폴더를 만들고 그 안에 아무거나 피하고 싶게 생긴 이미지를 넣는다. 그 다음 Hierachy탭에서 우클릭 -> UI -> Image 로 이미지 오브젝트를 하나 만들고 소스 이미지에 아까 구한 이미지 파일을 끌어다 넣는다.
이걸 프리팹으로 만들건데 에셋 폴더에 Prefab폴더를 만들고 방금 만든 이미지 게임 오브젝트를 프리팹 폴더에 드래그 앤 드롭 한다.
그럼 이렇게 게임오브젝트가 프리팹화 되는걸 볼 수 있다. 이 똥(프리팹)에 중력을 줄 건데 프리팹을 누르고 Inspector 창에서 Rigidbody2D 컴포넌트를 추가하자. 그 다음 gravity scale을 10으로 주고 simulated의 체크를 해제한다.
이제 원하는 플레이어 하나를 가져오자. 아까 똥 만들던것처럼 UI -> Image 로 오브젝트 하나를 만든 다음 소스 이미지를 넣어준다.
크기와 위치는 적당히 조정해주자.
다음은 빈 게임 오브젝트를 하나 만들고 GameController로 이름을 바꾼다. 게임을 컨트롤할 스크립트를 컴포넌트할 녀석이다.
Scripts 폴더를 하나 만들고 거기에 GameController라는 C#스크립트 파일을 하나 만들자. 그 다음 GameController 오브젝트에 Add Component 시킨다.
똥 오브젝트(프리팹)를 받을 게임오브젝트 변수, 이들을 그려주는 캔버스(부모 오브젝트의 역할로써 캔버스 산하로 똥 프리팹을 생성할 예정이다.), 플레이어 오브젝트를 받을 게임오브젝트 변수, 마지막으로 똥 리스트를 하나 만든다.(이 리스트에 똥을 생성할 예정이다. 즉 리스트의 길이가 똥 갯수가 되는 셈.)
그 다음 플레이어의 이동 속도를 받을 변수를 하나 만들자.
똥 피하기 게임이니까 당연히 떨어지는 똥을 소환해야 할 것이다. Awake함수에서 똥을 생성하자.
그리고 코루틴 함수를 넣고 중력의 영향을 받게 simulated 부분을 여기서 켜주자. 코루틴 함수는 딜레이를 주기 위해 사용하는 형식이다.
Start함수에서는 그냥 코루틴 함수 DelayGravity를 불러오면 된다.
이제 플레이어 이동에 관한 함수 MoveControl을 만들자.
X좌표에서만 움직일 것이니 Input의 GetAxis에서 Horizontal영역만 불러오면 된다.(좌 우 방향키만 입력받을 예정이기 때문)
moveSpeed에서 100을 곱해준 이유는 해상도가 커 이동 속도에 굉장히 큰 수를 입력해야 하기에 처음부터 코드에서 100을 곱해준 값을 사용하는 것이다.
goPlayer에서 RectTransform(이미지 출력 부분) 컴포넌트를 가져와서 X값 부분에 moveX 변수를 넣자.
맨 아래 print는 Input.GetAxis의 값이 키보드를 누름에 따라 어떻게 바뀌는지 알아보기 위해 로그로 찍어본 것이다. 한번 찍어보면 1과 -1이 나오는 것을 볼 수 있을 것이다.
Update함수에서는 똥이 -620좌표 밑으로 떨어지면 똥을 다시 올려주며 가속도를 초기화 해줄 예정이다.
이하는 스크립트 전문이다.
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
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour
{
public GameObject goDungPrefab;
public GameObject goParent;
public GameObject goPlayer;
List<GameObject> list_Dung = new List<GameObject>();
public float moveSpeed; //public으로 선언해서 유니티 내에서 변경 가능
private void Awake()
{
GameObject goPrefab;
for(int i=0; i<30; i++) { //똥 30개 만들기
goPrefab = Instantiate(goDungPrefab);
//Instantiate(a) a 오브젝트 생성
list_Dung.Add(goPrefab);
list_Dung[i].transform.parent = goParent.transform;
list_Dung[i].transform.GetComponent<RectTransform>().anchoredPosition = new Vector2(Random.Range(-900, 900), 620);
//Random Range(a,b) a b 사이에서 랜덤값 생성
}
}
IEnumerator DelayGravity() { //코루틴, 시작부터 중력이 적용되지 않도록 하기 위해 사용함
//딜레이를 주고 함수를 실행시킬 때 사용하는 형식이다.
for (int i = 0; i < list_Dung.Count; i++) {
yield return new WaitForSeconds(1f);
list_Dung[i].GetComponent<Rigidbody2D>().simulated = true;
}
}
// Start is called before the first frame update
void Start()
{
StartCoroutine("DelayGravity"); //코루틴함수 실행
}
void MoveControl() //player의 이동에 관련하는 함수
{
float moveX = moveSpeed*100 * Time.deltaTime * Input.GetAxis("Horizontal");
//moveSpeed에 Time.deltaTime 을 곱함으로써 매 프레임마다 움직이게 설정 (해상도가 커서 moveSpeed값을 크게 입력해야 하기에 처음부터 코드에서 100을 곱해줌)
//Input의 GetAxis에서 Horizonta 부분을 가져온다는 뜻이다. 키보드 입력받는 부분(1or-1값이 됨, 1:우측방향키/-1:좌측방향키)
//Input.GetAxis부분에서 1or-1값이 나오는데 이 값이 곱해져 플레이어가 움직이는 방향이 바뀜.
goPlayer.transform.GetComponent<RectTransform>().Translate(moveX, 0, 0); //인자는 x,y,z 값을 받는 것이다.
//지금 상황에선 x값을 moveX값에 따라 움직이게 설정했으므로 x값이 계속 키보드에 의해 움직임.
//만약 (0, moveX, 0) 이라고 설정하면 y값이 키보드에 의해 움직임.
print(Input.GetAxis("Horizontal")); //Input매니저에서 Horizontal값을 가져와서 console에 값을 출력한다.
}
// Update is called once per frame
void Update()
{
/*if (Input.GetKeyDown(KeyCode.LeftArrow)) //교수님이 알려주신 이동 방식
{
goPlayer.GetComponent<RectTransform>().Translate(-5, 0, 0);
}
else if (Input.GetKeyDown(KeyCode.RightArrow))
{
goPlayer.GetComponent<RectTransform>().Translate(5, 0, 0);
}*/
MoveControl(); //MoveControl을 매 프레임마다 호출
for (int i = 0; i < list_Dung.Count; i++) { //똥 리스트의 요소 개수만큼 반복한다. (30개 똥 전부 간섭)
if (list_Dung[i].GetComponent<RectTransform>().anchoredPosition.y < -620) //리스트의 요소 중 하나가 y좌표 -620밑으로 떨어지면
{
list_Dung[i].transform.GetComponent<RectTransform>().anchoredPosition = new Vector2(Random.Range(-900, 900), 620);
//X는 -900에서 900좌표 사이 랜덤으로 y는 620위치에 해당 요소를 다시 올림
list_Dung[i].transform.GetComponent<Rigidbody2D>().velocity = new Vector2(1, 1); //가속도 초기화
}
}
}
}
|
cs |
참고로 이 스크립트가 정상적으로 작동하기 위해서는 Input Manager와 맞춰줄 필요가 있는데 상단 탭에서 Edit -> Project Settings를 들어가면 Input Manager를 볼 수 있다.
다른건 필요없고 Name 부분이 아까 소스에서 입력한 Horizontal인지, Negative Button 이 left인지, Positive Button이 right인지만 확인하면 된다. 저 Negative Button과 Positive Button다른 키로 바꾸면 그 키 눌렀을 때 플레이어가 좌우 이동을 할 것이다.
마지막으로 유니티로 돌아와 오브젝트를 넣고 수치를 입력하자.
여기까지 잘 따라왔다면 문제 없이 실행될 것이다.
'수업 복습 > 유니티 복습 노트' 카테고리의 다른 글
[유니티] 유니티 수업 10차시 (0) | 2021.05.20 |
---|---|
[유니티] 유니티 수업 8차시 (0) | 2021.05.06 |
[유니티] 유니티 수업 5, 6차시 (0) | 2021.04.15 |
[유니티] 유니티 수업 4차시 (0) | 2021.04.02 |
[유니티] 유니티 수업 2차시 (0) | 2021.03.18 |
댓글