-
내일배움캠프 32일차 TIL - 3D 게임 기초 개발 - 개인 과제2TIL/Unity 2024. 5. 30. 20:53
[한 줄 요약]
유니티 숙련 주차 3D 게임 기초 개발 과제를 진행하여 점프대, 3인칭 시점 변경, 움직이는 플랫폼, 벽타기 등을 구현했다.
그리고 Json을 주제로 수준별 특강을 수강하였다.
[학습 내용]
유니티 숙련 주차 과제
점프대
점프대 생성 및 스크립트 작성
- 플레이어 캐릭터가 닿으면 위로 강하게 점프하는 점프대
- ForceMode의 Impulse값을 사용하여 구현하였다.
rigidbody.AddForce(Vector3.up * 20f, ForceMode.Impulse); - 콜라이더에서 IsTrigger를 체크하여 트리거 형태로 구현하였다.
- IInteractable 인터페이스를 사용하여 상호작용도 가능하게 하였다.
3인칭 시점
카메라 작동방식 변경
- 기존 1인칭 시점이던 카메라를 3인칭으로 변경
- 삼각함수를 사용하여 카메라의 움직임을 구현하였다.
- 자연스러운 움직임을 위해 플레이어 캐릭터의 y축 길이와 회전 반지름 등을 고려하였다.
- 카메라가 멀어진 만큼 상호작용 레이캐스트 최대거리도 늘려주었다.
움직이는 플랫폼
플랫폼, 플랫폼 SO 생성
- 시간에 따라 정해진 구역을 이동하는 플랫폼
- Cube 오브젝트로 플랫폼 오브젝트 생성
- 스크립터블 오브젝트에 플랫폼이 이동해야 하는 목적지의 벡터값과 이동속도를 담아서 저장
- 현재 위치에서 다음 목적지로의 방향벡터를 구하고, 주어진 속도대로 이동 후, 도착했는지 체크하여 다음 목적지로 넘어갈지를 판단하는 로직
!! 문제 발생 !!
* 내용
목적지에 도착했을 때 간헐적으로 다음 목적지를 향하는 것이 아닌, 그 위치에서 오브젝트가 부들부들 떨리며 이동하지 못하는 현상 발생
* 탐색
Debug.Log로 이동에 관련된 값들을 찍어보았다.
목적지가 (5, 0, 27)이면 다음 목적지로 방향이 바뀌어야 하는데, 자꾸 0.01의 오차로 x값이 일치하지 않아서 계속 떨고 있던 것이었다.
그래서 Mathf의 Approximately 메서드처럼, 어느 정도의 오차를 허용하게 하는 기능이 벡터에도 있는지 찾아보았다.
공식 문서에서는 Equals 메서드를 쓰면 정확한 비교, == 연산자를 쓰면 대략적인 비교를 쓸 수 있다고 한다.
그런데 나는 이미 ==로 구현했는데도 오차를 해결하지 못하고 있는 상태였다.
그래서 그냥 오차값을 distanceThreshold 변수에 0.1f로 정의하고 목적지와의 거리가 이것보다 작으면 도착한 것으로 간주하기로 했다.
얼핏 해결되는 듯 보였으나 이동 속도를 크게 올리자 다시 현상이 나타났다.
* 해결
해결 방법은 의외로 간단했다. 목적지에 도착했는지 체크하는 메서드를 FixedUpdate가 아닌 그냥 Update에 두었더니 해결되었다.
물리적 이동이 일어나기 전에 계속 체크하면 해결되는 문제였다.
벽 타기 및 매달리기
벽타기
- 벽에 가까이 있을 경우 벽을 타고 오르게 구현
- 레이캐스트로 벽과의 거리를 측정한 뒤 충분히 가까우면 플레이어 캐릭터를 위로 올린다.
Json 특강
직렬화 (Serialization)
요약
- 객체 정보를 나열하는 게 직렬화
- 나열된 정보를 되돌리는 게 역직렬화
필요성
세상에는 여러 다양한 플랫폼이 존재하고, 사용하는 언어가 모두 다르기 때문에 서로 호환되기 어렵다. 객체 정보를 저장할 때 010010.. 같은 기계어로 저장한다면 호환성이 높아지겠지만, 개발자가 읽거나 알아보기 힘들다. 그래서 문자로 된 직렬화 기술이 필요하다.
직렬화는 프로그래밍에 있어서 중요하다. 유니티도 직렬화를 기반으로 한다.
직렬화를 사용하여 저장할 여러 방식들
PlayerPrefs
유니티에서는 PlayerPrefs라는 기능을 제공한다. 이를 이용해 문자열을 저장할 수 있다.
- void PlayerPrefs.SetString(string name, string info); // 저장
- string PlayerPrefs.GetString(string name); // 로드
이를 이용해 수동으로 직렬화, 역직렬화하여 객체 정보를 저장할 수 있다.
CSV
엑셀 등을 활용해 .csv(utf-8) 파일로 저장한다면 이것을 저장파일로 활용할 수 있다.
- var csvData = Resources.Load<TextAsset>("CSVData"); // 로드
이걸 읽어들이면 쉼표와 개행(\n)으로 구분된 데이터를 얻을 수 있다. 이 때 TrimEnd 메서드를 활용하여 나머지 공백이나 개행은 날려버릴 수 있다.
XML(eXtensible Markup Language)
<a> </a>의 형태로 쌍을 이루어 데이터를 표현함
XmlDocument xmlDoc = new XmlDocument; xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "yes")); XmlNode root = xmlDoc.CreateNode("XmlNodeType.Element, "GameData", string.Empty); xmlDoc.AppendChild(root); XmlNode child = xmlDoc.CreateNode(XmlNodeType.Element, "PlayerData", string.Empty); root.AppendChild(child); XmlElement nickname = xmlDoc.CreateElement("nickname"); nickname.InnerText = "myName"; child.AppendChild(nickname);
YAML (YAML Ain't Markup Language)
마크업이 아닌 데이터 중심의 언어로, 가벼운 마크업 언어로 사용할 수 있다.
JSON
JsonUtility
NewtonSoft보다 JsonUtility가 훨씬 빠르기 때문에 유니티에서는 JsonUtility를 사용하는 게 좋다. 다만 유니티가 지원하는 포맷만 사용할 수 있다는 단점이 있다.
- var json = JsonUtitlity.ToJson(Object data); // 직렬화
- Object data = JsonUtility.FromJson<Object>(jsonData); // 역직렬화
Json 직렬화 규칙
유니티와 C#에서 Json으로 직렬화를 할 때에는 일정한 규칙에 따라 코드를 작성해야 한다.
예) [Serializable] 사용 등
[결과물]
[회고]
오늘까지 해서 개인과제 제출일이 지났다. 특강이나 꾸준학습 등의 시간이 있어서 생각보다 시간이 모자랐다. 구현을 못한 다른 요구사항들도 되게 중요해보이는데 못해서 조금 아쉽다.
내일은 잠깐 쉬어가는 시간을 가지고 팀프로젝트에 관한 얘기도 좀 나눠봐야겠다.
'TIL > Unity' 카테고리의 다른 글
내일배움캠프 35일차 TIL - 3D 게임 기초 개발 - 팀 프로젝트 2 (0) 2024.06.04 내일배움캠프 34일차 TIL - 3D 게임 기초 개발 - 팀 프로젝트 1 (1) 2024.06.03 내일배움캠프 31일차 TIL - 3D 게임 기초 개발 - 개인 과제 1 (0) 2024.05.29 내일배움캠프 30일차 TIL - 3D 게임 기초 개발 3 (0) 2024.05.28 내일배움캠프 29일차 TIL - 3D 게임 기초 개발 2 (0) 2024.05.27