'Unity3D'에 해당되는 글 52건
- 2017.03.10 [Unity3D] 조이스틱으로 캐릭터 조종하기. [Part 1] 6
- 2017.03.08 [Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 4] 3
- 2017.03.08 [Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 3] 3
- 2017.03.07 [Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 2]
- 2017.03.06 [Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 1]
- 2017.03.02 [Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 5]
- 2017.03.02 [Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 4]
- 2017.03.02 [Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 3] 1
- 2017.03.02 [Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 2]
- 2017.02.28 [Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 1]
[Unity3D] 조이스틱으로 캐릭터 조종하기. [Part 1]
※ 주의
이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.
Menu
1. 조이스틱 만들기.
2. 조이스틱의 벡터를 받아 캐릭터를 회전 및 이동 시키기.
완성작 미리보기
1. 조이스틱 만들기.
1). 이미지 준비.
- 조이스틱의 배경 이미지.
- 조이스틱 이미지.
2). 캔버스 준비.
UI이미지를 따로 관리해주는 객체가 있다.
하이러키창에서 마우스 오른쪽버튼을 클릭해 보면 UI라는 메뉴가 있는데,
이 메뉴안에 있는 여러가지 목록들을 선택하면 목록에 있는 객체가 생성된다.
만약 하이러키창에 캔버스가 없으면 캔버스를 자동으로 생성시키고 캔버스의 자식으로
우리가 선택한 목록을 생성시킨다.
더불어 EventSystem이라는 객체도 생성시키는데, 이 객체는 각종 UI이벤트에 필요한 객체이다.
이객체는 우리가 따로 건드릴 필요는 없다.
이미지를 2개 생성시킨다.
첫 번째 이미지의 이름은 JoyStickBackGround
두 번째 이미지의 이름은 JoyStick
그리고 객체를 하나씩 선택해서 이미지를 넣자.
2개의 이미지를 겹쳐 한쪽 구석에 이쁘게 정리하도록 하자.
정리가 끝났으면
JoyStick을 배경의 자식으로 넣는다.
하이러키창에 조이스틱 객체를 누르고 Add Componenet를 누른다.
그리고 Event Trigger라고 검색하면 하나의 컴포넌트가 나온다.
추가하도록 하자.
이 컴포넌트에는 UI에 대하여 여러가지 이벤트를 수행할 수 있다.
그 중에서 우리가 사용할 것은 드래그와 끝 드래그 이다.
이러한 컴포넌트를 조이스틱 객체에다 만든 이유는
조이스틱객체를 터치하여 움직이게 할 것이기 때문이다.
드래그와 드래그 끝 2개를 추가시켜주자.
다음은 스크립트를 작성하도록 하자.
스크립트의 이름은 JoyStick이다.
이 스크립트는 JoyStickBackGround에 넣도록 하자.
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 | using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class JoyStick : MonoBehaviour { // 공개 public Transform Stick; // 조이스틱. // 비공개 private Vector3 StickFirstPos; // 조이스틱의 처음 위치. private Vector3 JoyVec; // 조이스틱의 벡터(방향) private float Radius; // 조이스틱 배경의 반 지름. void Start() { Radius = GetComponent<RectTransform>().sizeDelta.y * 0.5f; StickFirstPos = Stick.transform.position; // 캔버스 크기에대한 반지름 조절. float Can = transform.parent.GetComponent<RectTransform>().localScale.x; Radius *= Can; } // 드래그 public void Drag(BaseEventData _Data) { PointerEventData Data = _Data as PointerEventData; Vector3 Pos = Data.position; // 조이스틱을 이동시킬 방향을 구함.(오른쪽,왼쪽,위,아래) JoyVec = (Pos - StickFirstPos).normalized; // 조이스틱의 처음 위치와 현재 내가 터치하고있는 위치의 거리를 구한다. float Dis = Vector3.Distance(Pos, StickFirstPos); // 거리가 반지름보다 작으면 조이스틱을 현재 터치하고 있는곳으로 이동. if (Dis < Radius) Stick.position = StickFirstPos + JoyVec * Dis; // 거리가 반지름보다 커지면 조이스틱을 반지름의 크기만큼만 이동. else Stick.position = StickFirstPos + JoyVec * Radius; } // 드래그 끝. public void DragEnd() { Stick.position = StickFirstPos; // 스틱을 원래의 위치로. JoyVec = Vector3.zero; // 방향을 0으로. } } | cs |
Stick변수는 조이스틱을 움직이기 위해 필요하다.
StickFirstPos변수는 조이스틱의 처음 위치가 들어가 있는데,
조이스틱을 움직이기 위해서는 처음 위치에다가 움직일 거리를 더해줄 필요가 있다.
처음위치 + 방향 * 거리 방식으로 움직여야 한다.
그리고, 드래그하다가 터치를 땠을 때 조이스틱은 원래의 위치로 돌아갈 필요가 있는데,
그 원래에 위치로 돌려주기위한 위치 값 저장 이기도 하다.
JoyVec은 현재 조이스틱에 대한 방향을 저장해줄 벡터 변수이다.
Radius는 배경 그림에 대한 반지름의 크기를 넣을 것이다.
조이스틱이 배경 이미지 바깥으로 넘어가지 못하게 하기 위함이다.
다음은 Drag함수이다.
모든 UI이벤트는 사실 레이캐스트로 작동하고 있다.
그렇기 때문에 이미지에 존재하는 Raycast Tartget을 해제하면 터치 이벤트가 작동하지 않는다.
아무튼, 터치에 대한 정보는 EventSystem에 저장되는데, UI메뉴중 아무거나 생성시키면 같이 생성되는 이유는 그 때문이다.
이 EventSystem에는 터치 정보 말고도 여러가지 정보가 저장되어있다.
그렇기 때문에 그 정보를 꺼내 쓰기 위해서 유징해줄 필요가 있는데,
스크립트에 맵 위에 보면 UnityEngine.EventSystems;이 유징되어 있는것을 볼 수 있다.
조이스틱을 움직이기 위해서는 현재 터치되는 위치가 어디인지 알 필요가 있다.
그 위치에 대한 정보는 BaseEventData에 들어있는데, 이 자료형을 사용하려면 EventSystems가 유징되어있어야 한다.
이벤트 트리거에서 잘 보면 BaseEventData을 인자로 받는것을 볼 수 있다.
베이스 이벤트 데이터를 인자로 받아
그 데이터를 PointerEventData 변수에 형변환 시킨뒤 저장한다.
※ PointerEventData : 마우스 및 터치에 대한 이벤트.
BaseEventData을 이용하고 있기 때문에 터치 포인트에 대해서는 따로 쓰게 된다.
무슨말이냐면 쉽게 말해서 이러한 조이스틱말고 또 다른 버튼이벤트 같은것이 있을 경우
터치 포인터를 공유해서 쓰지않고 따로따로 쓴다는 말이다.
한 줄로 요약해서 멀티터치가 가능하다는 소리다.
나머지 구문들은 스크립트에 주석으로 설명이 되어있기 때문이 생략하겠다.
결과
'Unity3D > Project' 카테고리의 다른 글
[Unity3D] UI - HP, MP 에너바 조절하기. [Part 0] (0) | 2017.03.15 |
---|---|
[Unity3D] 조이스틱으로 캐릭터 조종하기. [Part 2] (10) | 2017.03.13 |
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 4] (3) | 2017.03.08 |
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 3] (3) | 2017.03.08 |
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 2] (0) | 2017.03.07 |
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 4]
※ 주의
이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.
기능정리
1. 플레이어를 따라오는 카메라.
1.5. 플레이어의 움직임.
2. 마우스 휠 카메라 줌 인,아웃 기능.
3. 마우스 오른쪽 버튼 클릭 후 카메라 회전.
- x,y축 회전
- x축 회전의 한계치 설정.
3. 마우스 오른쪽 버튼 클릭 후 카메라 회전.
Input에는 마우스의 움직임에 대한 정보도 제공해 주고 있다.
"Mouse X" 는 마우스의 좌,우 움직임을,
"Mouse Y" 는 마우스의 상,항의 움직임에 대한 정보를 가지고있다.
마우스 오른쪽 버튼을 누르고 있을 때 카메라의 회전이 가능하게 만들어보자.
벡터변수 Gap을 만들어서 Gap.x값에 Mouse Y값을 축적해보도록 하자.
'Gap.x인데 Mouse X값이 아니냐?' 라고 묻는다면, 아니라고 답변해주고 싶다.
Mouse Y는 상,하에 대한 움직임을 감지한다. 즉, 마우스 오른쪽 버튼을 클릭한 채
위로 올리면 카메라는 밑을 바라보게 되고, 밑으로 내리면 위를 바라보게 해야한다.
이러한 경우를 봤을 때 회전을 이용하는건데, y축 회전이 아닌 x축으로 회전을 가하기 때문에
Gap.x에 Mouse Y값을 축적할 필요가 있다.
※ x축으로 회전하기 때문에 Gap.x에 Mouse Y를 축적시킬 필요가 있다.
Gap.x에 Mouse Y의 양수 값으로 축적하게 된다면 마우스를 위로 올려야지 카메라가 위에서 밑을 바라보는 상황이 될것이다.
그렇기 때문에 -1을 곱해주어 음수값으로 만든다면 마우스 오른쪽 버튼 클릭 후 밑으로 드래그 한다면 카메라가 위에서 밑을 바라보는 상활을 만들수 있다.
※ 반대로 Gap.y에는 Mouse X를 축적해야한다.
이 카메라도 마찬가지로 회전의 최소값과 최대값을 Mathf.Clamp함수를 이용하여 지정할 수 있다.
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 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class Axis : MonoBehaviour { public Quaternion TargetRotation; // 최종적으로 축적된 Gap이 이 변수에 저장됨. public Transform CameraVector; public float RotationSpeed; // 회전 스피드. public float ZoomSpeed; // 줌 스피드. public float Distance; // 카메라와의 거리. private Vector3 AxisVec; // 축의 벡터. private Vector3 Gap; // 회전 축적 값. private Transform MainCamera; // 카메라 컴포넌트. void Start() { MainCamera = Camera.main.transform; } void Update() { Zoom(); CameraRotation(); } // 카메라 줌. void Zoom() { Distance += Input.GetAxis("Mouse ScrollWheel") * ZoomSpeed * -1; Distance = Mathf.Clamp(Distance, 5f, 20f); AxisVec = transform.forward * -1; AxisVec *= Distance; MainCamera.position = transform.position + AxisVec; } // 카메라 회전. void CameraRotation() { if (transform.rotation != TargetRotation) transform.rotation = Quaternion.Slerp(transform.rotation, TargetRotation, RotationSpeed * Time.deltaTime); if (Input.GetMouseButton(1)) { // 값을 축적. Gap.x += Input.GetAxis("Mouse Y") * RotationSpeed * -1; Gap.y += Input.GetAxis("Mouse X") * RotationSpeed; // 카메라 회전범위 제한. Gap.x = Mathf.Clamp(Gap.x, -5f, 85f); // 회전 값을 변수에 저장. TargetRotation = Quaternion.Euler(Gap); // 카메라벡터 객체에 Axis객체의 x,z회전 값을 제외한 y값만을 넘긴다. Quaternion q = TargetRotation; q.x = q.z = 0; CameraVector.transform.rotation = q; } } } | cs |
Axis객체 인스펙터 정보.
Quternion.Euler(Gap);
오일러를 통해 축적된 Gap을 넣는다.
이 쿼터니언에는 얼만큼 회전하느냐에 대한 회전 값이 들어있다.
이러한 회전값을 TargetRotation에 초기화 시킨다.
그리고 transform.rotation(Axis객체 자신의 회전 값)에 저장된 회전값을 대입해줘도 되지만,
그렇게 되면 카메라가 서서히 회전하는 효과를 느낄수 없으므로, 쿼터니언의 슬러프 함수를 써서 목표회전을 사용하여
값을 대입 해준다.
Quternion.Slerp(현재 자신의 회전 값, 목표 회전 값, 회전 스피드);
정도로 보면 된다.
목표 회전을 하지 않았을 경우. (Slerp함수를 사용하지 않았을 경우.)
transform.rotation = TargetRotation;
목표회전을 사용한 경우. (Slerp함수를 사용한 경우.)
transform.rotation = Quaternion.Slerp(transform.rotation, TargetRotation, RotationSpeed * Time.deltaTime);
1 2 3 4 5 | Quaternion q = TargetRotation; q.x = q.z = 0; CameraVector.transform.rotation = q; | cs |
새롭게 쿼터니언 변수q를 만들어서 TargetRotation을 대입한 이유는
TargetRotation값을 회손하면 안되기 때문이다.
※ TargetRotation는 카메라를 x,y축을 회적시키는데 필요한 값이다.
쿼터니언변수 q에 x,z값을 0으로 초기화 시킨다.
y값만을 사용할 건데, 잘 생각해보면 현재 이 쿼터니언 값을 카메라의 회전값이다.
카메라의 x,z값을 0으로 초기화 시키고 y값만을 쓴다면 어떻게 될까?
바로 이렇게 된다.
x,z값을 0으로 고정시켰기 때문에 y축에대한 회전을 한다.
지금 회전하는 이 객체는 맨 처음에 만들어 두었던 CameraVector객체이다.
이 객체를 y회전만 시키는 이유는 카메라가 회전했을 때 카메라가 보는 방향에서 플레이어를 자유롭게 조종하기 위함이다.
플레이어는 이 객체(CameraVector)에 벡터값을 가져와서 이동한다.
완성.
'Unity3D > Project' 카테고리의 다른 글
[Unity3D] 조이스틱으로 캐릭터 조종하기. [Part 2] (10) | 2017.03.13 |
---|---|
[Unity3D] 조이스틱으로 캐릭터 조종하기. [Part 1] (6) | 2017.03.10 |
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 3] (3) | 2017.03.08 |
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 2] (0) | 2017.03.07 |
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 1] (0) | 2017.03.06 |
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 3]
※ 주의
이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.
기능정리
1. 플레이어를 따라오는 카메라.
1.5. 플레이어의 움직임.
2. 마우스 휠 카메라 줌 인,아웃 기능.
3. 마우스 오른쪽 버튼 클릭 후 카메라 회전.
- x,y축 회전
- x축 회전의 한계치 설정.
2. 마우스 휠 카메라 줌 인,아웃
Input에는 마우스 휠에대한 반환값도 제공해주고있다.
Input.GetAxis("Mouse ScrollWheel");
반환값은 float로 반환되며 휠을 위로 굴릴경우 양수의 값이,
밑으로 굴릴경우 음수의 값이 반환된다.
이를활용하여 줌 인,아웃 기능을 수행할 것이다.
카메라맨과 카메라의 거리를 유지해주는 Distance라는 변수에
휠을 위로 굴릴경우 Distance를 감소시켜주어 줌 인 기능을 수행하고,
휠을 밑으로 굴릴경우 Distance를 증가시켜주어 줌 아웃 기능을 수행하여 보자.
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 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class Axis : MonoBehaviour { public float ZoomSpeed; // 줌 스피드. public float Distance; // 카메라와의 거리. private Vector3 AxisVec; // 축의 벡터. private Transform MainCamera; // 카메라 컴포넌트. void Start() { MainCamera = Camera.main.transform; } void Update() { Zoom(); } // 카메라 줌. void Zoom() { Distance += Input.GetAxis("Mouse ScrollWheel") * ZoomSpeed * -1; Distance = Mathf.Clamp(Distance, 5f, 20f); AxisVec = transform.forward * -1; AxisVec *= Distance; MainCamera.position = transform.position + AxisVec; } } | cs |
휠을 위로 굴렸을 때 줌 인 효과를 내고 싶다면 Distance에 값을 그대로 더해주면 안된다.
휠을 위로 굴리면 반환값이 양수 값이기 때문에 Distance는 자연히 커지게 되고
줌 인 효과가 아닌 줌 아웃 효과가 나타나게 된다.
그렇기 때문에 Distance += 휠 값 * 줌 스피드 * -1;
-1을 곱해줌으로써 음수 값으로 만들고 휠을 위로 굴렸을 때 Distance값이 감소하게 된다.
Mathf.Clamp함수는 값을 제한해주는 함수이다.
Mathf.Clamp(Value, Min, Max);
Value는 값을 제한해줄 값을 집어넣고, Min은 그 값의 최소값, Max는 그 값의 최대 값을 지정해 준다.
결과
'Unity3D > Project' 카테고리의 다른 글
[Unity3D] 조이스틱으로 캐릭터 조종하기. [Part 1] (6) | 2017.03.10 |
---|---|
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 4] (3) | 2017.03.08 |
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 2] (0) | 2017.03.07 |
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 1] (0) | 2017.03.06 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 5] (0) | 2017.03.02 |
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 2]
※ 주의
이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.
기능정리
1. 플레이어를 따라오는 카메라.
1.5. 플레이어의 움직임.
2. 마우스 휠 카메라 줌 인,아웃 기능.
3. 마우스 오른쪽 버튼 클릭 후 카메라 회전.
- x,y축 회전
- x축 회전의 한계치 설정.
1.5 플레이어의 움직임.
플레이어부터 움직여 보도록 하자.
카메라가 잘 따라오는지 확인하려면 플레이어가 움직여야 되지 않는가?
Player스크립트를 하나 만들어준다.
이 스크립트에는 2가지 함수가 들어갈 것이다.
1. Run();
2. Rotation();
첫 번째 함수는 플레이어를 움직이게 만드는 함수이고,
두 번째 함수는 플레이어에게 회전을 주어서 원하는 방향으로 이동할수 있게 한다.
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 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { public float Speed; // 움직이는 스피드. private Transform Vec; // 카메라 벡터. private Vector3 MovePos; // 플레이어 움직임에 대한 변수. void Init() { MovePos = Vector3.zero; } void Start() { Vec = GameObject.Find("CameraVector").transform; Init(); } void Update () { Run(); } // 플레이어 움직임. void Run() { int ButtonDown = 0; if (Input.GetKey(KeyCode.LeftArrow)) ButtonDown = 1; if (Input.GetKey(KeyCode.RightArrow)) ButtonDown = 1; if (Input.GetKey(KeyCode.UpArrow)) ButtonDown = 1; if (Input.GetKey(KeyCode.DownArrow)) ButtonDown = 1; // 플레이어가 움직임. 버튼에서 손을 땠을 때 Horizontal, Vertical이 0으로 돌아감으로써 // 플레이어의 회전상태가 다시 원상태로 돌아가지 않게 하기 위해서. if (ButtonDown != 0) Rotation(); else return; transform.Translate(Vector3.forward * Time.deltaTime * Speed * ButtonDown); } // 플레이어 회전. void Rotation() { MovePos.Set(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); // 벡터 셋팅. Quaternion q = Quaternion.LookRotation(Vec.TransformDirection(MovePos)); // 회전 if (MovePos != Vector3.zero) transform.rotation = q; } } | cs |
1. float Speed; 플레이어가 움직이려면 힘이 필요하다. Speed변수를 하나 만들어준다.
2. Transform Vec; 카메라 벡터는, 카메라가 회전한다고 해서 플레이어의 벡터가 달라지는것이 아니므로, 카메라의 벡터를 이용하여 플레이어를 이동시켜주기 위한 변수이다.
3. Vector3 MovePos; 키의 입력을 받아서 플레이어의 벡터를 셋팅해줄 변수이다.
Run() 함수 안에 ButtonDown변수는 키 입력에 반응해 값을 대입 받는다.
키 입력을 받지 않으면 값이 0으로 들어가 플레이어는 움직일수 없게 된다.
반대로 키 입력을 받아 ButtonDown변수에 0이 아닌 값이 들어간다면 플레이어는 움직이게 된다.
그리고, 회전 함수도 함께 수행된다.
ButtonDown변수가 0이 아닐때에만 회전함수를 수행하는 이유는
MovePos에 Horizontal, Vertical로 값을 입력받기 때문이다.
Horizontal은 ←,→에 입력에 따라 -1 ~ +1 의 값이 들어간다.
(※ Vertical은 ↑,↓)
키(Horizontal)를 입력받지 않을 때에는 반환 값이 0으로 들어가는데, 이때 회전 함수가 키 입력(Input.GetKey)에 상관없이 수행된다면 Horizontal에 반환 값 0을 입력받아 플레이어가 다시 원래의 벡터 방향으로 회전하게 된다.
이것을 방지해 주기 위한 처리이다.
1 2 3 4 5 6 7 8 9 10 11 12 | void Run() { int ButtonDown = 0; if (Input.GetKey(KeyCode.LeftArrow)) ButtonDown = 1; if (Input.GetKey(KeyCode.RightArrow)) ButtonDown = 1; if (Input.GetKey(KeyCode.UpArrow)) ButtonDown = 1; if (Input.GetKey(KeyCode.DownArrow)) ButtonDown = 1; Rotation(); transform.Translate(Vector3.forward * Time.deltaTime * Speed * ButtonDown); } | cs |
회전 함수를 예외처리 없이 수행했을 경우.
대각선으로 이동하다가 키에 손을 때면 게속 정면을 바라보게 된다.
다음은 회전함수를 살펴보도록 하자.
MovePos.Set을 활용하여 Horizontal과 Vertical의 입력 값을 셋팅한다.
그리고 쿼터니언(Quaternion)을 활용하여 플레이어에게 회전값을 줄것이다.
Quaternion.LookRotation( Vector3 ); - 이 함수는 인자에 들어온 벡터의 방향으로 물체를 회전시켜준다.
만약 A라는 물체가 B라는 물체를 바라보고 싶을때 B까지의 벡터를 구해 이 함수의 인자로 넣어주면
A는 B를 바라보도록 회전시켜준다.
TransformDirection( Vector3 ); - 이 함수는 인자로 들어온 값을 로컬공간에서 월드공간으로 방향을 변환해준다.
인자로 MovePos를 넣어, CameraVector오브젝트의 벡터를 현재 플레이어의 벡터로 활용하는 것이다.
그뒤 transform.rotation에 회전 값 q를 넣어서 적용시켜주면 적절히 회전하게 된다.
'Unity3D > Project' 카테고리의 다른 글
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 4] (3) | 2017.03.08 |
---|---|
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 3] (3) | 2017.03.08 |
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 1] (0) | 2017.03.06 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 5] (0) | 2017.03.02 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 4] (0) | 2017.03.02 |
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 1]
※ 주의
이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.
기능정리
1. 플레이어를 따라오는 카메라.
1.5. 플레이어의 움직임.
2. 마우스 휠 카메라 줌 인,아웃 기능.
3. 마우스 오른쪽 버튼 클릭 후 카메라 회전.
- x,y축 회전
- x축 회전의 한계치 설정.
완성작 미리보기.
1. 플레이어를 따라오는 카메라.
카메라가 플레이어와 아에 멀리 떨어져 있어도 따라오는 카메라를 만들어야 한다.
카메라가 직접 플레이어를 따라가게 만들지 않을것이다.
카메라맨이라는 빈 객체를 만들어서 이 객체가 플레이어를 직접적으로 따라갈 것이고,
카메라는 카메라맨과 일정 거리를 유지한체 따라다닐 것이다.
이러한 번거로운 작업을 할 필요 없이 '카메라를 플레이어의 자식으로 두면 되는거 아닌가요?' 라고 묻는다면
그냥 따라다니기만 할거라면 그렇게 해도 되지만, 우리는 줌 인/아웃 또는 카메라를 회전시킬 것이기 때문에
이러한 과정이 필요하다고 말해두겠다.
물론 이렇게 넣는다고 해서 이러한 과정이 불 가능해 지는것은 아니지만, 매우 귀찮은 코딩이 필요해 지기 때문에
그러한 과정은 피하도록 하겠다.
1. 빈 오브젝트를 만든다. - 이름은 CameraMan
2. 또다시 빈 오브젝트를 만든다. - 이름은 CameraVector
3. 또다시 빈 오브젝트를 만든다. - 이름은 Axis
4. CameraMan에 자식으로 CameraVector를 넣는다.
5. CameraMan에 자식으로 Axis를 넣는다.
6. Axis의 자식으로 Camera를 넣는다. (이 카메라는 메인카메라이다.)
재료를 만들었으니 이제 스크립트를 작성해 보자.
스크립트의 이름은 CameraMan이다.
이 스크립트는 CameraMan오브젝트에 넣으면 된다.
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
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraMan : MonoBehaviour {
// 공개
public float MoveSpeed; // 플레이어를 따라오는 카메라 맨의 스피드.
// 비공개
private Transform Target; // 플레이어의 트랜스 폼.
private Vector3 Pos; // 자신의 위치.
void Start()
{
// Player라는 태그를 가진 오브젝트의 transform을 가져온다.
Target = GameObject.FindGameObjectWithTag("Player").transform;
}
// 플레이어를 따라다님.
void Update ()
{
Pos = transform.position;
transform.position += (Target.position - Pos) * MoveSpeed;
}
}
|
cs |
(플레이어의 위치 - 자신의 위치)를 빼주면 현재 카메라맨의 위치에서 플레이어의 벡터(방향)가 구해진다.
그 벡터를 향해 값을 플러스(+) 해주면 카메라맨은 플레이어를 쫓아가게 된다.
* MoveSpeed는 카메라맨이 플레이어를 쫓아가는 스피드다.
※ 플레이어의 Transform을 가져오기위한 설정.
플레이어는 그냥 큐브를 하나 만들어주고 이름을 Player로 바꿔주고,
태그를 Player로 바꿔주면 된다.
그 뒤 실행을 해보면
※ CameraMan스크립트 컴포넌트에서 MoveSpeed를 설정해주지 않으면 카메라맨이 움직이지 않는다.
카메라맨이 플레이어를 따라가지만, 카메라에 비치지 않는것을 확인 할 수 있다.
이것은 당연한 것이다. 우리는 아직 카메라맨과 카메라와의 유지거리를 설정해주지 않았기 때문이다!
카메라의 유지거리를 설정하기 위한 스크립트를 짜보도록 하자.
Axis스크립트.
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
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Axis : MonoBehaviour {
// 공개
public float Distance; // 카메라와의 거리.
// 비공개
private Vector3 AxisVec; // 축의 벡터.
private Transform MainCamera; // 카메라 컴포넌트.
void Start()
{
MainCamera = Camera.main.transform;
}
void Update()
{
DisCamera();
}
void DisCamera()
{
AxisVec = transform.forward * -1;
AxisVec *= Distance;
MainCamera.position = transform.position + AxisVec;
}
}
|
cs |
현재 플레이어의 Position == CameraMan의 Position == Axis의 Position은 같다.
왜냐하면 CameraMan이 플레이어를 추적하기 때문이다.
Axis가 같은 이유는 CameraMan의 자식이기 때문이다.
그렇기 때문에 Axis의 전방벡터 (transform.forward)는 플레이어의 전방벡터 이기도 하다.
이러한 전방벡터에 -1을 곱한다는것은 플레이어의 후방벡터의 방향을 뜻한다.
플레이어가 보고있는 방향의 반대 방향으로 Distance 변수의 거리만큼 카메라를 벌려주면
카메라가 멀리서 플레이어를 바라보는것처럼 만들수 있다.
결과
'Unity3D > Project' 카테고리의 다른 글
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 3] (3) | 2017.03.08 |
---|---|
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 2] (0) | 2017.03.07 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 5] (0) | 2017.03.02 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 4] (0) | 2017.03.02 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 3] (1) | 2017.03.02 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 5]
※ 주의
이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.
메뉴
1. 움직임 적용.
- Horizontal을 이용한 움직임.
2. 중력 적용.
- 점프에 의한 중력.
- 낙하에 의한 중력.
3. 충돌 적용. (레이 캐스트로 충돌체크.)
- 점프로 인한 위쪽블록과의 충돌.
- 낙하로 인한 블록과의 충돌.
- 오른쪽, 혹은 왼쪽으로 움직일때에 벽과 충돌.
4. 점프
- 점프로 인한 충돌체크 및 중력적용.
5. 좌,우 충돌체크.
4. 좌,우 충돌체크.
별로 어려운건 없다.
기존에 만들어두었던 RayCastFire함수를 이용하면 된다.
하지만 몇 가지 추가하거나 바꿔줄 필요는 있다.
현재 x방향으로 레이캐스트를 3개를 쏘고있다.
그리고 이제 할 좌,우 충돌에 대해서도 마찬가지로 3개의 레이캐스트를 쏠 것이다.
for문을 하나 더 만들어서 함수를 호출해버리면 아무래도 프로그램에 부담이걸려 돌아오는 반응에 공백이 생길수
있으므로, for문을 RayCastFire함수 안으로 넣으려고 한다.
그리고 전체적인 구성을 조금 바꿀 것이다.
결과
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
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour {
// 공개
public float Speed; // 좌, 우로 움직이는 스피드.
public float JumpSpeed; // 점프 할때에 힘.
public float Gravity; // 작용하는 중력.
// 디버그
public float RayTime; // 그려준 레이 지속시간.
public bool isDrawX; // 좌,우 쏘는 레이캐스트 보기.
public bool isDrawY; // 위,아래로 쏘는 레이캐스트 보기.
public Color ColorX; // 레이의 색깔.
public Color ColorY; // 레이의 색깔.
// 비공개
private Vector2 Pos; // 플레이어가 실직적으로 움직일 좌, 우 벡터.
private Vector2 Dir; // 점프 및 낙하 여부의 벡터.
private Vector2 Radius; // 플레이어의 x,y의 반지름.
private float H; // Horizontal.
private bool isGround; // 현재 땅이냐? true 땅이 아니냐? false
// 각종 값 초기화.
void Init()
{
ColorX = Color.blue;
ColorY = Color.red;
Pos = Vector2.zero;
Dir = Vector2.down;
Radius = new Vector2(transform.localScale.x * 0.5f, transform.localScale.y * 0.5f);
H = 0;
isGround = false;
}
void Start()
{
Init();
}
void Update()
{
H = Input.GetAxis("Horizontal");
if (Input.GetButtonDown("Jump") && isGround)
{
Pos.y = JumpSpeed;
Dir = Vector2.up;
}
CollisionCheck();
Move();
}
// 좌, 우 움직임.
void Move()
{
Pos.Set(H * Speed, Pos.y);
transform.Translate(Pos * Time.deltaTime);
}
// 충돌 체크를 위한 레이 캐스트.
void CollisionCheck()
{
RayCastFire(Dir, Radius.y + 0.1f, Color.blue); // 위,아래
RayCastFire(DirX(), Radius.x + 0.1f, Color.yellow); // 좌, 우.
}
// 플레이어 방향 벡터를 결정해 준다. (좌, 우)
Vector2 DirX()
{
if (H < 0)
return Vector2.left;
else if (H > 0)
return Vector2.right;
return Vector2.zero;
}
// 레이캐스트를 발사한다.
void RayCastFire(Vector2 _Dir, float _length, Color _color )
{
if (_Dir == Vector2.zero)
return;
RaycastHit Hit;
for (int i = -1; i < 2; i++)
{
Vector2 MyPos = transform.position;
// 레이 발사위치를 정하는 구문.
if (_Dir == Vector2.right || _Dir == Vector2.left)
MyPos = new Vector2(MyPos.x, MyPos.y + (Radius.y * i)); // 좌,우 충돌 레이.
else
MyPos = new Vector2(MyPos.x + (Radius.x * i), MyPos.y); // 위,아래 충돌 레이.
// 레이를 그려주는 함수.
DrawRay(MyPos, _Dir, _length, _color);
if (Physics.Raycast(MyPos, _Dir, out Hit, _length))
{
// Ray를 발사 했는데 땅에 맞았음.
if (Hit.transform.gameObject.layer == 8)
{
if (_Dir == Vector2.right || _Dir == Vector2.left)
{
H = 0;
return;
}
// 플레이어가 땅에 있으면 함수 종료.
if (isGround)
return;
Transform Target = Hit.transform;
if (_Dir == Vector2.down)
{
// 충돌한 블럭의 위에 정착.
transform.position = new Vector2(transform.position.x, Target.position.y + (Target.localScale.y * 0.5f) + _length);
Pos.y = 0; // 중력이 작용했던 값에 대해 0으로 초기화.
isGround = true; // 이제 땅에 있다고 표시.
return;
}
// 충돌한 블럭 밑으로 이동.
transform.position = new Vector2(transform.position.x, Target.position.y - (Target.localScale.y * 0.5f) - _length);
Pos.y = 0;
break;
}
}
}
if (_Dir == Vector2.right || _Dir == Vector2.left)
return;
// Ray를 발사 했는데 땅에 맞지 않았음.
isGround = false;
Pos.y -= Gravity * Time.deltaTime;
if (Pos.y <= 0)
Dir = Vector2.down;
}
// 레이를 그려준다.
void DrawRay(Vector2 _MyPos, Vector2 _Dir, float _length, Color _color)
{
if (_Dir == Vector2.left || _Dir == Vector2.right)
{
if (isDrawX)
Debug.DrawRay(_MyPos, _Dir * _length, ColorX, RayTime);
}
else
{
if (isDrawY)
Debug.DrawRay(_MyPos, _Dir * _length, ColorY, RayTime);
}
}
}
|
cs |
'Unity3D > Project' 카테고리의 다른 글
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 2] (0) | 2017.03.07 |
---|---|
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 1] (0) | 2017.03.06 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 4] (0) | 2017.03.02 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 3] (1) | 2017.03.02 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 2] (0) | 2017.03.02 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 4]
※ 주의
이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.
메뉴
1. 움직임 적용.
- Horizontal을 이용한 움직임.
2. 중력 적용.
- 점프에 의한 중력.
- 낙하에 의한 중력.
3. 충돌 적용. (레이 캐스트로 충돌체크.)
- 점프로 인한 위쪽블록과의 충돌.
- 낙하로 인한 블록과의 충돌.
- 오른쪽, 혹은 왼쪽으로 움직일때에 벽과 충돌.
4. 점프
- 점프로 인한 충돌체크 및 중력적용.
5. 좌,우 충돌체크.
4. 점프
이번에 구현해야 할 것은 3가지다.
1. 점프.
2. 플레이어가 점프 했을 때 점프경로에 블럭이 있고 충돌하게 된다면 떨어지게 하는 것.
3. 점프경로에 블럭이 없고 중력에 의해 떨어지는 것.
플레이어 인스펙터 정보
이것은 그렇게 어렵지 않기 때문에 바로 소스코드를 보도록 하자.
다음은 좌,우 이동에 대한 충돌체크를 해보도록 하자.
'Unity3D > Project' 카테고리의 다른 글
[Unity3D] RPG게임 카메라 - 줌 인/아웃, 카메라 회전. [Part 1] (0) | 2017.03.06 |
---|---|
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 5] (0) | 2017.03.02 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 3] (1) | 2017.03.02 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 2] (0) | 2017.03.02 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 1] (0) | 2017.02.28 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 3]
※ 주의
이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.
메뉴
1. 움직임 적용.
- Horizontal을 이용한 움직임.
2. 중력 적용.
- 점프에 의한 중력.
- 낙하에 의한 중력.
3. 충돌 적용. (레이 캐스트로 충돌체크.)
- 점프로 인한 위쪽블록과의 충돌.
- 낙하로 인한 블록과의 충돌.
- 오른쪽, 혹은 왼쪽으로 움직일때에 벽과 충돌.
4. 점프
- 점프로 인한 충돌체크 및 중력적용.
5. 좌,우 충돌체크.
3. 레이 캐스트 충돌체크
이번엔 충돌을 적용시켜 보도록 하자.
Ray를 플레이어의 아래쪽으로 쏴서 땅에 맞는다면 플레이어는 땅에 존재하는 것이므로,
중력을 적용하지 않으면 된다.
반대로 Ray를 쐈을 때 아무것도 맞지 않는다면 플레이어의 발 밑에 발판이 존재하지 않는다는 말이므로,
중력을 적용하면 된다.
Ray를 이용하여 충돌여부를 미리 체크하므로써 효율적인 연산을 수행할 수 있다.
Ray를 맞은 객체가 땅이라고 판별하기 위해서는 한 가지 작업이 필요하다.
Layer에 Ground라는 요소를 추가하여 설정하면 된다.
설정이 끝난 뒤 Ray에 맞으면 그 객체가 땅인지 아닌지 판별할 수 있게 된다.
아무 객체를 선택한 후, 인스펙터창 우측 상단에 Layer를 클릭하여 Ground를 추가 한 후
발판 객체들을 선택하여 Layer를 Ground로 설정 하도록 하자.
1.
2.
3.
※ Radius변수 설명에 대해서는 밑을 참고.
※
isGround == true : 현재 플레이어가 땅에 존재함.
isGround == false : 현재 플레이어가 땅에 존재하지 않음.
RaycastHit Hit;
Hit 변수에는 Ray에 맞은 객체에 대한 정보가 들어있다.
현재 사용한 레이캐스트의 인자들을 살펴보면,
Physics.Raycast(Ray가 발사되는 위치,
Ray가 발사되는 방향,
Ray를 맞을 객체에 대한 정보를 저장할 변수,
Ray의 길이 );
이렇게 되어있다.
Ray에 맞은 객체에 대한 정보가 Hit에 존재하기 때문에 Hit.transform.gameObject.laye의 경로로
그 객체의 레이어를 체크한다.
체크된 레이어가 8번 레이어(Ground)라면
플레이어의 위치를 발판 위에 올려놔야 되는데,
플레이어의 x값에 대해서는 변환할 필요가 없기 때문에,
y값만 바꿔주면 된다.
보통 어떤 객체의 기준점은 객체의 정 가운데 있다.
그림으로 살펴보면 이렇다.
그래서 Ray가 발판에 닿았을 때 플레이어의 위치를 발판의 위치로 대입해 버리면
밑에의 그림과 같은 상황이 일어난다.
transform.position = 객체.position;
그렇기 때문에 밑에 그림과 같이 계산해야 한다.
플레이어의 위치를 발판 위에 올려다 놓고.
플레이어에게 작용하는 y의 벡터 값을 0으로 줘버린다.
그리고 isGround의 값을 true로 줌으로써 현재 자신은 땅에 존재한다고 명시해준다.
다음 Ray를 쐈을 때 Ray가 발판에 닿았고 또 위의 구문을 수행하기전에
의 구문에 의해서 밑의 구문을 수행하지 않고 함수를 종료해 버린다.
결과.
※파란색 선이 Ray이다.
Ray를 쏴서 충돌을 체크하는데, Ray가 나오지 않는 부분은 충돌이 될까?
※ Ray가 닿지 않는 부분은 충돌이 되지 않는것을 볼 수 있다.
당연히 충돌이 되지 않는다.
그러면 어떻게 해야할까? 플레이어의 크기 만큼 Ray를 쏴주면 된다.
Ray를 플레이어의 크기만큼 쏴주기 위해 새로운 변수를 선언한다.
Vector2 Radius;
자료형을 벡터로 선언한 이유는 이렇다.
벡터는 2가지 정보를 가지고 있다.
바로 x값과 y값인데, 플레이어의 x만큼의 반지름과 y만큼의 반지름 크기가 필요하다.
그럼 float형으로 x값과 y값 따로 선언해 주면 되지 않냐고 묻는다면, 그렇게 해도 아무 문제도 없다.
아무튼 원래 Ray를 쏘았던 위치에서 플레이어의 반지름을 더해주거나 빼주면 플레이어의 크기만큼 Ray를
발사할 수 있다.
다음은 점프를 구현해 보도록 하자.
'Unity3D > Project' 카테고리의 다른 글
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 5] (0) | 2017.03.02 |
---|---|
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 4] (0) | 2017.03.02 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 2] (0) | 2017.03.02 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 1] (0) | 2017.02.28 |
[Unity3D] Character Controller를 이용한 캐릭터 움직임. (0) | 2017.02.25 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 2]
※ 주의
이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.
메뉴
1. 움직임 적용.
- Horizontal을 이용한 움직임.
2. 중력 적용.
- 점프에 의한 중력.
- 낙하에 의한 중력.
3. 충돌 적용. (레이 캐스트로 충돌체크.)
- 점프로 인한 위쪽블록과의 충돌.
- 낙하로 인한 블록과의 충돌.
- 오른쪽, 혹은 왼쪽으로 움직일때에 벽과 충돌.
4. 점프
- 점프로 인한 충돌체크 및 중력적용.
5. 좌,우 충돌체크.
2. 중력적용
다음으로 해야할 것은 플레이어에게 중력을 적용 해야한다.
여기서 한 가지 생각해야할 것이 있는데, '언제 어떤 상황에서 중력을 적용할것 인가?' 이다.
궁금히 생각해 보도록 하자.
플레이어가 땅에 가만히 있는데도 중력이 적용된다면 굉장한 연산 낭비가 아닌가?
그렇다면 2가지 경우에만 중력을 적용시키면 된다.
첫 번째, 플레이어가 점프 후 떨어질 때.
두 번째, 좌,우 이동 중 높은곳에서 낮은 곳으로 떨어졌을 때.
이 중 첫 번째에 경우 점프가 구현되어있지 않았기 때문에 두 번째에 경우를 우선하여 적용 하도록 하자.
우선적으로 중력만 적용시켜보자.
중력만 적용시키는것은 매우 간단한 일이다.
플레이어에게 가할 중력 값을 만들고, y값에 중력값을 게속하여 가중시키면 된다.
플레이어 인스펙터창 정보.
결과
중력은 적용되었지만, 블록에 충돌하지 않고 지나가는것이 보일 것이다.
위에서 말했던 첫 번째, 두 번째 경우에만 중력을 적용 시키기 위해서는 레이 캐스트를 사용하여
충돌체크 부터 해야 한다.
다음은 충돌을 적용시켜 보도록 하자.
'Unity3D > Project' 카테고리의 다른 글
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 4] (0) | 2017.03.02 |
---|---|
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 3] (1) | 2017.03.02 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 1] (0) | 2017.02.28 |
[Unity3D] Character Controller를 이용한 캐릭터 움직임. (0) | 2017.02.25 |
유니티란? (0) | 2017.02.25 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 1]
※ 주의
이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.
메뉴
1. 움직임 적용.
- Horizontal을 이용한 움직임.
2. 중력 적용.
- 점프에 의한 중력.
- 낙하에 의한 중력.
3. 충돌 적용. (레이 캐스트로 충돌체크.)
- 점프로 인한 위쪽블록과의 충돌.
- 낙하로 인한 블록과의 충돌.
- 오른쪽, 혹은 왼쪽으로 움직일때에 벽과 충돌.
4. 점프
- 점프로 인한 충돌체크 및 중력적용.
5. 좌,우 충돌체크.
1. 움직임
처음은 플레이어의 움직임을 구현해야 한다.
플레이어는 좌, 우로만 움직일 것이다.
메뉴탭에Edit - Project Settings - Input - Axes 에는 키 입력에 대한 여러가지 정보가 들어있는데,
그 중 Horizontal은 x값 / 좌, 우(←,→) 키 입력에 대한 정보가 들어있다.
이 정보를 받아서 현재 입력 받은 키가 무엇이며, 어떤 방향인지 정보를 가져와 플레이어 움직임에 적용할 것이다.
※ 다른 키 입력 정보
- Vertical : y값 / 위, 아래(↑,↓)에 대한 정보.
- Jump : Spacebar(스페이스바)
Horizontal을 가져오는 방법은
Input.GetAxis("Horizontal");을 통해 가져올수 있다.
이 값은 반환하는 값이 있는데, 눌리는 키에 방향에따라 다른 값을 반환한다.
왼쪽 키(←) : 0 ~ -1
오른쪽 키(→) : 0 ~ 1
입력 X : 0
을 반환한다.
움직이려는 방향(벡터)을 알아내었다면 어떤 속력으로 움직일지 정해야 한다.
float Speed 변수를 하나 만들어주어 어떤 속력으로 움직일지 임의로 정하면 된다.
그리고 마지막으로 프레임당 호출 횟수를 고려하여 Time.deltatime을 곱해 시간을 보정해준다.
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 UnityEngine;
public class Player : MonoBehaviour {
// 공개
public float Speed; // 좌, 우로 움직이는 스피드.
// 비공개
private Vector2 Pos; // 플레이어가 실직적으로 움직일 좌, 우 벡터를 저장할 변수.
private float H; // Horizontal.
// 각종 값 초기화.
void Init()
{
Pos = Vector2.zero;
H = 0;
}
void Start()
{
Init();
}
void Update()
{
H = Input.GetAxis("Horizontal");
Move();
}
// 좌, 우 움직임.
void Move()
{
Pos.Set(H * Speed, Pos.y);
transform.Translate(Pos * Time.deltaTime);
}
}
|
cs |
플레이어에 대한 인스펙터 정보
결과.
다음은 중력적용을 시켜보도록 하자.
'Unity3D > Project' 카테고리의 다른 글
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 4] (0) | 2017.03.02 |
---|---|
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 3] (1) | 2017.03.02 |
[Unity3D] 캐릭터 움직임, 충돌체크, 물리엔진사용 X [Part 2] (0) | 2017.03.02 |
[Unity3D] Character Controller를 이용한 캐릭터 움직임. (0) | 2017.02.25 |
유니티란? (0) | 2017.02.25 |