2022. 2. 19. 21:55ㆍProjects/Amnyang
게임 하다가 한 번씩은 그래도 깜짝(?)놀랄만한 공포 이벤트를 저번 시간에 만들었다. 이번에는 적(무당)의 집 평상 밑에서 숨기 버튼('F키')를 눌렀을 때, 숨도록 하는 기능을 만들어야 한다.
1. 시작하자마자 버그 마주치기
평상 부분이 레이어가 나뉘어져 있지 않아서, 유니티에서 오브젝트로 존재하지 않는 상황이다. 그래서 발판으로 사용하기 위한 빈 오브젝트를 생성하고, 콜라이더를 부착해줬다.
그리고 테스트를 위해, 캐릭터를 조작하여 달리면서 점프하여 평상 위로 올라가게 하려했다. 근데 만약 점프 중간에 평상 측면 콜라이더 부분에 닿이게 되면 아래와 같이 낀 것처럼 된다.
정상적인 상황이라면, 위와 같이 끼었다면 방향 조작이 있다 하더라도 중력에 의해 자연스럽게 아래로 미끄러져 내려와야 한다. 뭐가 문제일지 여러가지 생각을 해봤다.
- Rigidbody 2D의 velocity를 통해 이동을 제어하는데, 평상 측면에 막히니 속도 값이 0으로 된다.
- 물론 position을 이동하는 방법을 택했어도 물리 연산에 의해 밀려나긴 할 거다.
- 이 부분은 상관 없는 것 같다.
- 점프 중에는 이동 키 입력과 바라보는 방향 전환을 하지 못하도록 막아놨기 때문이다.
- 기능을 수정하고 테스트해봤지만, 근본적으로 해결하지는 못했다.
그리고 이 버그에 시선을 빼앗겨서, 미처 생각치 못했던 부분도 있었는데 평상 밑에 숨을 수 있어야 하니, 당연히 평상 밑을 캐릭터가 지나다니며 왔다갔다 할 수 있어야 한다. 내 얕은 지식의 머리로는 도저히 모르겠어서 질문하고 구글링을 해봤다. 문제는 평상 측면의 마찰력 때문이었다. 평상에 붙여놓은 콜라이더의 측면 부분에도 마찰력이 적용되기 때문에 캐릭터가 박혀서 미끄러져 내려오지 못한 것이었다.
또한, 구글링하면서 위에 해결해야할 두 문제를 한 번에 해결할 수 있는 것도 알아냈다. 바로, Platform Effector 2D 컴포넌트였다. 이걸 사용하여 문제를 해결해보자!
2. Platform Effector 2D 적용하기
간단하게 이 컴포넌트가 어떤 기능을 수행해주는지 설명하자면, 콜라이더의 일방향 충돌 처리와 측면 마찰 및 반발력 설정을 할 수 있는 녀석이다. 아무튼 평상에 이 컴포넌트를 부착해줬다.
콜라이더가 이 플랫폼 이펙터에 영향을 받도록, 콜라이더의 Used By Effector 옵션을 활성화 해줘야 한다. 평상 위에서는 충돌 처리가 되고, 아래에서는 충돌 처리가 되지 않도록 해야 한다. 이렇게 해야, 평상 밑을 캐릭터가 돌아다닐 수 있고 밑에서 점프하여 평상 위로 올라갈 수도 있다.
그러니, 플랫폼 이펙터의 Use One Way 옵션을 활성화 해줬다. 주인공 캐릭터의 콜라이더가 하나 밖에 없으므로 Use One Way Grouping은 비활성화했다.
Surface Arc을 160도 정도로 줬다. 이 각도를 벗어난 곳에서 들어오는 건 충돌 처리하지 않는다. 기본값이 180도인데, 이러면 평상의 측면까지 막히니 조금 각도를 작게 준 것이다.
마지막으로 측면에서 미끄러지지 못했던 버그를 수정해줘야 한다. 플랫폼 이펙터의 Use Side Friction 옵션을 비활성화 해줬다. 이로써, 골머리를 아프게 했던 버그를 해결할 수 있었다.
테스트 영상을 찍으면서 또 다른 버그를 하나 발견했지만, 이건 시간이 남으면 수정해야겠다. 사실 버그라기 보단, 유저의 스킬로도 인정해줄 수도 있는 영역이긴 하다.
3. 평상 밑에 숨기 구현하기
평상 윗 부분 콜라이더는 말 그대로 발판 역할을 수행하는 오브젝트이기 때문에, 캐릭터가 숨을 수 있는 영역에 들어왔는지를 탐지하는 것 또한 필요하다. 새 빈 오브젝트를 생성하고, is Trigger를 활성화한 콜라이더를 하나 부착해서 배치해줬다.
그리고 또, 새로운 빈 오브젝트를 만들어서 스프라이트 렌더러(Sprite Renderer) 컴포넌트를 달아줬다. 숨어있는 모습의 스프라이트를 넣어줬다. 그리고 이 오브젝트는 비활성화 해두면 된다.
그리고 저번에 만들었던 상호작용 가능한 오브젝트에 붙일 "InteractiveObject" 스크립트를 붙여줬다. "IsDynamicHiddenSpace"란 항목도 새롭게 추가된 걸 볼 수 있는데, 이따가 설명하도록 하겠다. 숨을 수 있는 오브젝트이므로, ObjectType을 "eCanHideObject"로 설정해줬다.
그리고, "InteractiveObject" 스크립트를 약간 수정해줬다. 숨은 모습의 스프라이트 이미지를 담고 있을 변수와 캐릭터가 있는 그 위치에서 숨은 모습을 보이게 할 건지에 대한 "IsDynamicHiddenSpace" bool 변수를 추가해줬다.
InteractiveObject 스크립트
public SpriteRenderer hidingSprite; // 추가
public bool isDynamicHiddenSpace; // 추가
public ObjectType objectType;
private SujiController suji;
private string objectTag;
...
public void Interaction()
{
...
if (objectType == ObjectType.eCanHideObject)
{
suji.Hide(hidingSprite, isDynamicHiddenSpace); // 매개변수 추가
}
}
SujiController 스크립트
숨을 이미지가 담긴 변수와 정적 공간인지 동적 공간인지에 대한 정보를 Hide() 함수에 매개변수에서 받았다.
public void Hide(SpriteRenderer hidingSprite, bool isDynamicHiddenSpace)
{
if (isJumping)
return;
if (!isHiding)
{
isHiding = true;
ControlEnableMyBody(false);
}
else
{
isHiding = false;
ControlEnableMyBody(true);
}
OnOffHiddenSpritePlayer(hidingSprite, isDynamicHiddenSpace); // 추가
}
private void OnOffHiddenSpritePlayer(SpriteRenderer hidingSprite, bool isDynamicHiddenSpace)
{
if (isDynamicHiddenSpace)
{
hidingSprite.transform.position = new Vector3(this.transform.position.x,
hidingSprite.transform.position.y,
this.transform.position.z);
}
hidingSprite.gameObject.SetActive(IsHiding);
}
OnOffHiddenSpritePlayer()란 함수를 새로 만들어서 사용해줬다. 이렇게 하면, 간단하게 숨는 것을 만들 수 있다.
완성 및 후기
초기 계획에는 숨는 애니메이션 동작까지 넣어서 구현할 생각이었는데, 그것까지는 빠듯할 듯 해보였다. 그래서 위와 같은 방식으로 숨는 것을 구현했다.
점점 구현하는 게 하나 둘씩 많이 생기다보니, 이제 버그가 자주 출몰하는 것 같다. 게임은 항상 버그가 나오는구나...라는 생각이 들었고, 그걸 해결하는 과정에서 또 하나 배우게 된 것 같다.
다음에는 무당 집과 사당문이 열리는 모션, 일지에는 한 번도 나오지 않았지만 이제 적(경관, 무당)도 나타날 예정이다. 먼저 무당 집까지 가는 길목에서 플레이어를 방해할 경관을 손 볼 생각이다.
'Projects > Amnyang' 카테고리의 다른 글
[압량(Amnyang)] #Final. 새로운 적, 무당(Shaman)과 게임 시작 씬, 로딩씬, 인트로씬 제작 (2) | 2022.03.05 |
---|---|
[압량(Amnyang)] #13. 2D 게임 적(Enemy) 패턴 구현하기 (0) | 2022.02.21 |
[압량(Amnyang)] #11. 2D 공포 분위기 조성용 이벤트 만들기 (0) | 2022.02.15 |
[압량(Amnyang)] #10. 2D 게임 상호작용 시스템(숨기) 만들기 + 수많은 버그 수정 (0) | 2022.02.14 |
[압량(Amnyang)] #9. 2D 게임 배경 간단히 배치 및 카메라 추적 이동 구현하기 (0) | 2022.02.13 |