어제자의 플레이어와의 상호작용 연결 과정에서 문과 책상은 같이 작업을 하여 수정했지만, SwitchController는 내가 따로 수정하기로 했다.
우선은 플레이어와 상호작용 기능을 연결해 주기 위해 설정을 해 주었으며, 또한 버튼이 눌렸는지 안 눌렸는지 확인하기 위해 눌렸을 경우 버튼이 빨간색으로 색이 변하게 했다.
그래서 아래와 같이 코드를 수정하였다.
using System.Collections.Generic;
using UnityEngine;
public class SwitchController : MonoBehaviour, IInteractable
{
[SerializeField] List<Animator> m_objectAnimator;
[SerializeField] GameObject m_button;
private bool m_isPressed = false;
public void Interact()
{
for (int i = 0; i < m_objectAnimator.Count; i++)
{
boolAnimator(m_objectAnimator[i]);
}
m_isPressed = !m_isPressed;
if (m_isPressed)
{
m_button.GetComponent<MeshRenderer>().material.color = Color.red;
}
else
{
m_button.GetComponent<MeshRenderer>().material.color = Color.white;
}
}
private void boolAnimator(Animator animator)
{
bool isOpen = animator.GetBool("IsOpen");
isOpen = !isOpen;
animator.SetBool("IsOpen", isOpen);
}
}
이와 같이 작성하여 팀장님과 함께 테스팅을 진행했고, 정상 작동하는 것을 확인하였다.
크로스헤어는 흔히 FPS 게임에서의 조준점을 말한다.
우리가 만드는 GwisinRun 또한 1인칭 게임이다 보니 조준점이 있는 편이 좋아 보였다.
팀장님의 요청으로 만든 기능이면서도 내 나름대로 필요한 조건을 추가하였다.
이걸 위해선 내 코드만 보는 것이 아니고 게임 매니저 코드가 어떻게 되어 있는지 살펴봐야만 했다. 그래서 게임매니저를 통해 게임의 진행 여부를 판단하고 출력 조건을 설정하였다.
using UnityEngine;
public class CrossHairController : MonoBehaviour
{
[SerializeField] GameObject m_crosshair;
[SerializeField] GameObject m_itemPanel;
private void Update()
{
if (GameManager.Instance.IsPaused == true)
{
m_crosshair.SetActive(false);
}
else
{
if (m_itemPanel.activeSelf == false)
{
m_crosshair.SetActive(true);
}
else
{
m_crosshair.SetActive(false);
}
}
}
}
이와 같이 작성하여 출력은 아래와 같이 나왔다.
어제자 UI에서의 흔들림 현상의 연장선으로, 이번에는 Raycast 흔들림 문제가 발생했다. 플레이어 담당자는 내가 아니지만, UI출력 쪽에서도 문제가 생기는 부분이다 보니 버그의 원인을 찾아보기로 했다.
Debug.Log()로 출력되는 좌표를 일일히 찍어보기 시작했다.
문제가 생긴 좌표는 아래와 같았다.
- Debug.Log(ray.origin) // 좌표가 튄다
- Debug.Log(Camera.main.transform.position) // 좌표기 튄다
- Debug.Log(Camera.main.transform.localPosition) // 좌표가 튀지 않는다
즉 이 말은 카메라 자체의 좌표는 잘 고정되어 있는데 카메라의 포지션의 좌표가 계속 튀고 있다는 소리이다.
우리는 카메라가 플레이어의 자식 오브젝트로 들어가 있는 상황이다 보니 즉 이 상황은 플레이어가 튀고 있다는 것이다. 플레이어가 튀고 있다는 걸 전혀 알아차리지 못했는데 말이다.
그래서 플레이어의 좌표도 찍어보았다. (gameObject.transform.position)
그 결과 플레이어도 좌표가 튀고 있다는 것을 알게 되었다.
아직까지는 익숙하지 않아서 강사님의 도움을 통해 해당 디버거를 사용해 문제가 어떻게 발생하는지 확인했다.
해당 디버거를 실행한 후 Collision Geometry를 실행해서 어떻게 되는지 살펴보았다.
지금은 문제가 해결된 상태이지만, 일정 간격으로 플레이어의 저 빨간색 영역이 올라갔다 내려가기를 반복했다. 그 현상을 바탕으로 내용을 확인한 결과 문제가 발생하는 건 아무래도 플레이어 구조에 문제가 있었던 것으로 보였다.
플레이어를 내가 직접 만든 것이 아니라서 잘 모르는 상태였으나, 원래 Character Controller와 Rigidbody를 같이 쓰는 경우는 잘 없다고 한다. 어차피 캐릭터가 점프를 하는 것 또한 Character Controller에서 처리하면 되므로, 둘 중 하나만 쓰는 방식을 사용한단 것이다.
또한 캐릭터가 이렇게 튀는 현상이 발생하는 것은 결국 이 Rigidbody에서 문제가 생긴 것으로 보이고, Rigidbody와 Capsule Collider 영역이 일치하지 않아 떨어졌다가 올라오기를 반복하는 형태로 흔들림이 발생한단 사실을 알게 되었다.
해당 내용을 팀원에게 전달하여 Rigidbody를 삭제하는 것으로 수정사항이 적용되었고 캐릭터의 흔들림은 수정되었다.
이 부분이 오늘자에서 상당히 고전했던 부분이 아니지 싶다.
현재 몬스터 담당자가 몬스터 움직임 로직을 아직 개발 중에 있으며, 나는 거기에 부차적으로 몬스터가 문을 열고 들어올 수 있도록 문 스크립트를 수정해야 했다.
하지만 이상하게도 이와 같은 문제가 발생했다.
생각할 수 있는 오류의 부분을 다 고려해 보았다. 태그를 안 붙였나? 태그를 불러오다가 오타를 냈나? 그런 세세한 부분을 다 확인해도 안 잡혀서 결국 팀장님과 같이 회의를 했다.
결국엔 해결 방법을 찾았지만 몬스터에 Rigidbody가 붙어 있지 않아서 Trigger 이벤트가 발생하지 않았다. 분명 트리거 이벤트에서는 딱히 Rigidbody가 있어야 한다는 조건이 있었던 것 같지는 않았는데 막상 사용해 보니 Rigidbody가 있어야 하는 것 같았다.
생각해보면 충돌체의 Rigidbody 여부 관계 없이 트리거 이벤트가 발생하게 되면 맵에 배치된 오브젝트는 인접한 모든 오브젝트와 트리거 이벤트를 발생시킬 것이다.
해당 사실을 염두에 두고, 코드는 트리거 영역에 몬스터 탐지 여부 판정을 하고 아래와 같이 작성했다.
public class DoorController : MonoBehaviour, IInteractable
{
...
public void Awake()
{
m_doorAnimator.SetBool("Close", true);
}
public void Update()
{
m_isClosed = m_doorAnimator.GetBool("Close");
if(m_doortrigger1.MonsterDetected() && m_isClosed)
{
OpenDoorCounterClockwise();
}
else if (m_doortrigger2.MonsterDetected() && m_isClosed)
{
OpenDoorClockwise();
}
else if (m_doortrigger1.MonsterDetected() || m_doortrigger2.MonsterDetected())
{
return;
}
}
...
사실 몬스터가 완성된 상태가 아니라서 아직 완전한 테스트를 진행하지 못한 상태이다. 그래서 우선은 문이 정상적으로 열리는 것만 확인했으나 몬스터가 완성되고 나면 본격적으로 테스트를 진행해야 할 것 같다.