![[2024 SWF] Project RM 개발일지 #2](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnnREd%2FbtsI5XUi3bl%2Fv1upS5fntgk1BzDJqBVYL1%2Fimg.png)
이번에는 전에 했던 적을 조금 다듬었고, 튜토리얼 씬 제작에 들어갔다.
튜토리얼 씬 개발
우선 내가 구상한 튜토리얼 씬에는, 외부 도시를 보여주는 배경이 원근감 효과를 주며 지나가고, NPC 하나가 말을 걸며 조작법과 게임의 컨셉을 알려주는 요소가 있었다. 구상이 얼추 끝나고 바로 개발에 들어갔다.
Parallax 배경 구현
내가 생각하고있던 원근감 있는 배경이 Parallax Background라는 용어로 존재하고있었다.
작년에는 Parallax말고 원근감을 달라고 구글을 잡고 흔들었는데 알고보니 같은 것이었다...
아무튼 그래서 Parallax Background는 간단하게 설명하면, 가까이 있는 배경사물은 빠르게 움직이고, 먼 배경사물일수록 천천히 움직이게 하여 원근감을 주는 기법이다.
이것을 코드로 해석하면, 메인 카메라가 움직이는 것에 맞춰 움직이지만 속도를 다르게 하여 가까이 있는 사물과 멀리 있는 사물을 구별할 수 있을 것이라고 생각했다.
그리고 이를 기반으로 구글에 있는 예제를 참고해 Parallax효과를 가진 배경을 구현했다.
void DoParallax()
{
Vector3 pos = MainCamera.transform.position;
float dist = pos.x * AmountOfParallax;
Vector3 newPos = new Vector3(startingPos + dist, transform.position.y, transform.position.z);
transform.position = newPos;
}
간단히 이 코드를 설명하면, 메인 카메라의 위치를 받아오고, 속도를 얼마나 느리게 할지를 정하는 변수인 AmountOfParallax 변수를 그 위치에 곱해 카메라와의 거리를 정해준다. 그리고 그것을 기반으로 위치를 재조정한다.
또한, 배경이 계속 움직여야 하므로 이를 Update 문에서 실행해주었다.
되게 거창할 줄 알았는데 코드 몇 줄로 끝나버리니 괜히 겁먹었던 내가 부끄러워졌다. 아잉 부끄러
그리고, 이것이 결과물이다.
뒤의 구름은 플레이어를 따라옴과 동시에 천천히 움직여야 하므로 AmountOfParallax를 1로 주어 속도를 똑같게 해 따라오게 했고, 별도의 스크립트로 천천히 움직이게 했다. 사실 저 구름이 복병이었지만 어떻게든 구현해낸 것을 보니 만족스러웠다.
대사 말하기 구현
튜토리얼 씬을 진행하면 빠지지 않는 것이 설명이다.
그런데 이 설명을 그냥 줄글로 쭉 써두면 플레이어가 보지도 않을 뿐더러 게임 특성상 전달도 잘 안될 것이기에 NPC를 하나 세워 설명하는 대사를 치도록 했다.
처음에는 UI로 화면의 하단에 대사창을 띄우려고 했으나, 다른 게임들과 비슷하기도 하고, 게임의 특색을 살리기 위해 직접 말풍선을 통해 말하는 것으로 구현하고자 했다.
public IEnumerator Chat(float chatSizeX, string text)
{
innerText.GetComponent<RectTransform>().sizeDelta = new Vector2(chatSizeX - 1f, 0.75f);
innerTextTMPro.text = "";
chatterSpriteRenderer.size = new Vector2 (chatSizeX, 0.75f);
for (int i = 0; i < text.Length; i++)
{
if (text[i] != ' ')
{
audioSource.Play();
}
innerTextTMPro.text += text[i];
yield return chatDelay;
}
}
말을 한번에 쭉 하면 너무 빨리 넘기거나 의도치 않게 다음 대사로 넘어가는 경우가 있을 것이라고 생각하여 한 글자씩 말하게 했다.
간단히 이 스크립트를 설명하면, 우선 말의 길이에 따라 말풍선의 크기를 조절해주고, 말하기 전에 대사에 해당하는 텍스트를 지워주고, 새 대사를 한글자씩 말하는 구조이다.
중간에 들어가있는 audioSource는 언더테일의 말하기 처럼 한 글자를 말 할때마다 아주 짧은 소리를 내는 연출을 주기 위해 넣어봤다. 띄어쓰기만 거르게 하여 말하게 해보니, 언더테일이 왜 그 연출을 채용했는지 알 것 같았다.
아래는 결과물이다.
이제 제법 게임 태가 나기 시작한 것 같다.
대사 진행 구현
대사 기능을 만들었으면, 이제 설명을 할 차례이다.
코루틴으로 짠 이유도 여기에 있는데, 어디선가 코루틴에서 다른 코루틴을 yield return으로 StartCoroutine 시키면 그 코루틴이 끝날 때 까지 대기한다는 것을 봤다. 그래서 대사가 다 끝난 후 다음 대사를 치도록 대사 코루틴을 yield return 시켰다.
하지만 바로 다음 대사를 치면 안된다. 대사 하나가 끝나고 사용자의 입력을 받아 다음 대사로 넘어가야 한다.
고민 끝에, 위의 개념을 응용했다. 사용자의 입력을 받았을 때 break되는 무한 반복문을 가진 코루틴을 하나 만들었고, 이를 대사가 끝난 후에 yield return 시켰다. 그렇게 되면 사용자의 입력을 기다리는 기능을 구현할 수 있을 것이라고 생각했고, 생각대로 됐다.
그리고 신이 난 나는 이걸 이용해 또 여러가지 기능을 만들어 튜토리얼을 쌈뽕멋지게 만들었다.
그리고 이것이 지금까지의 결과물이다.
카메라 무빙을 하여 앞으로 가야 함을 암시했고(사실 방향키로 움직이라고 하긴 하는데, 어디로 움직여야 할지 미리 보여주는 용도로 사용하고자 했다.), 상호작용 할 수 있는 물체(총) 근처에 가면 상호작용을 알려주도록 UI도 바꿔주었다. 그리고 대사 중에는 카메라가 따라오는 것을 잠시 꺼두어 카메라 무빙에 방해되는 것이 없게 하였다.
마지막으로, 상호작용이 완료되면 다시 대사를 치도록 하였다. 아직 이 부분의 대사는 짜두지 않아서 말풍선 밖으로 나간다.
이번에 개발을 하면서 크게 느낀 것이 있다.
바로... 코루틴은 신이다.
작년에 이런 류의 대사를 구현해야할 때가 있었는데, 코루틴의 개념을 잘 몰라서 어영부영 짜 버그도 많고 제대로 나오지도 않았었다.
이번에 다시 하면서 코루틴을 제대로 알고 가니 생각한대로 모두 병렬처리 하면서 순조롭게 짤 수 있었다.
그리고, 조금 성장한건지 코드 짜는 스타일이 바뀐건지 모르겠지만,
Update 문에서 사용자의 입력을 받는 코드와 배경 애니메이션 코드를 제외하면 코드가 아무것도 없다.
심지어 튜토리얼에서는 사용자의 입력을 Update에서 받지도 않는다.
다른 프로젝트에서 고수 선배가 Update문이 게임에서 드는 코스트가 커서 사용하지 않는 편이 좋다고 했었는데, 아무래도 그 프로젝트를 하며 짠 코드 스타일의 영향인 것 같다.
그런데 생각해보면, 적 오브젝트를 구현하면서 짠 코드에도 Update는 사용자 입력밖에 없었다. 아무래도 다른 사람이 개발하는 기능에 연결해야 하다보니 다 함수화를 했는데, 이 때문에 Update에 코드가 적어진 것 같다.
이 말은... 내가 모르는 새에 성장했다는 거겠지..?
아무튼, 이제 튜토리얼 씬에서 어떤 것을 알려줄지, 어떻게 알려줄지, 대사는 어떻게 칠지 등등을 모두 구상하여 튜토리얼 씬을 완성할 차례이다. 꾸미는건 나중에 하고, 우선 구현부터 해야겠다.

'팀 프로젝트 > Project RM' 카테고리의 다른 글
[2024 SWF] Project RM 개발일지 #4 (6) | 2024.09.02 |
---|---|
[2024 SWF] Project RM 개발일지 #3 (0) | 2024.08.17 |
[2024 SWF] Project RM 개발일지 #1 (0) | 2024.07.25 |
안녕하세요! 코드 짜는 농부입니다! 경희대학교 소프트웨어융합학과 23학번 재학중입니다. 문의 : dsblue_jun@khu.ac.kr
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!