박건원

사용된 기술
1.
Player : FSM
사용 배경 PlayerController 하나에서 상태들을 관리하면 코드의 가독성이 떨어지고 상태가 많아 질수록 유지보수가 어려울 수 있다고 판단
이점 부모클래스인 StateMachine을 상속받은 PlayerStateMachine에서 플레이어에대한 각종 상태들을 관리하고 각종 상태에 대한 코드들을 분리하여 추가 상태의 확장이나 기존상태 제거가 원활하게 만듬
사용 후기 개발이 진행되면서 스테미나 시스템을 추가했다가 삭제하는 경우가 발생하였는데 이에대한 추가 및 삭제가 간단하였다.
2.
데이터 엑셀화 사용배경 ScriptableObject를 사용해 데이터를 저장하거나 Json을 이용하여 데이터를 직접 저장하는 것은 시간이 많이들고 추후 데이터를 수정할 경우의 복잡성을 생각하여 엑셀을 통해 전체적인 데이터를 관리하기로 결정
이점 팀원 모두에게 익숙한 엑셀파일을 사용함에따라 수정및 관리가 용이해 졌다
3.
SceneManager Custom
사용배경 3D게임 특성상 데이터가 큰 맵이 존재하며 데이터가 큰 맵과 큰 맵 사이에 이동이 있을경우 프레임 드랍현상이 발생할 위험이 크다는 것을 인지하여 이 부하현상을 해결해야 하여 자체적으로 SceneManagerEX라는 클래스에서 Scene이동을 관리하며 부하가 큰 Scene끼리의 이동이 있을때는 LoadingScene을 거치게 하였습니다.
//비동기 씬전환 목적 public class SceneManagerEx : MonoBehaviour { public BaseScene CurrentScene; public Scene NextScene; public void LoadSceneAsync(Scene sceneType) { NextScene = sceneType; SceneManager.LoadScene((int)Scene.Loading); } public void LoadScene(Scene sceneType) { NextScene = sceneType; SceneManager.LoadScene((int)sceneType); } public void Clear() { CurrentScene?.Clear(); } }
Plain Text
복사
이점 무겁지 않은 LoadingScene을 중간에 둠으로써 프레임의 분산효과를 주었으며 추가로 LoadingScene에서 비동기 씬로딩으로 무거운씬으로 가는 상황에서 렉이 발생하는 것을 방지 할 수 있었습니다.
트러블 슈팅
1.
플레이어 움직임 트러블 문제 : 플레이어가 조금만 움직였음에도 특정 굴곡진 공간에서 움직임 폭이 크거나 일반상태 걷기 달리기 상태로의 변화에서 속도가 즉각적으로 부자연스러운 움직임 발견
원인 : 문제된 코드에서는 speed의 값이 즉각적으로 변화하여 약간의 움직임에도 특정거리를 움직여 위의 문제 상황들이 발생하였다 (0.1,0.2 로 점점 증가하다가 2가 됐을 때 멈춤)
해결 : 스피드를 점점 증가하거나 감소하게 만듬으로써 움직임을 자연스럽게 만들어 주었다
private void Move() { if (stateMachine.MovementInput != Vector2.zero) moveDirection = MoveDirection_Ver_Camera();
float targetSpeed = GetMovementSpeed(); float currentHorizontalSpeed = new Vector3(stateMachine.Player.Controller.velocity.x, 0.0f, stateMachine.Player.Controller.velocity.z).magnitude; float speedOffset = 0.1f; if (currentHorizontalSpeed < targetSpeed - speedOffset || currentHorizontalSpeed > targetSpeed + speedOffset) { stateMachine.Player.speed = Mathf.Lerp(currentHorizontalSpeed, targetSpeed, Time.deltaTime * SpeedChangeRate); stateMachine.Player.speed = Mathf.Round(stateMachine.Player.speed * 1000f) / 1000f; } else { stateMachine.Player.speed = targetSpeed; } stateMachine.Player.Controller.Move(((moveDirection * stateMachine.Player.speed) + stateMachine.Player.ForceReceiver.Movement) * Time.deltaTime); if (stateMachine.MovementInput != Vector2.zero) Rotate(moveDirection);
Plain Text
복사
}
2.
애니메이션 문제 (에셋 애니메이션과의 연동이 잘 안되어서 플레이어가 애니메이션을 제대로 작동하지 않는 문제) 문제 : 애니메이션을 통한 이동을 제한하기 위해 applyroot를 해제하였음에도 앞으로 이동하거나 애니메이션이 기이하게 작동하는 문제가 발생하였다
원인 : applyroot을 전체를 꺼버려서 발생한 문제 개별적인 루트 모션의 적용이 필요하였다. 애니메이션 옵션을 수정하지 않아 플레이어에 애니메이션이 제대로 동작하지 않았다.
간략하게 살펴보면 Bake Into Pose 경우 애니메이션의 값을 적용할지 아님 고정할지에 대한 것이며
BasedUpon은 Original, Body Orientation, Center of Mass, Feet이 있는데
Original은 해당 애니메이션의 설정을 따르며
Body Orientation은 몸을 기준으로 앞 방향의 벡터를 기준으로 기준점을 잡고
Center Of Mass는 객체의 무게 중심을 기점으로 y좌표를 잡고
Feet은 발을 중심으로 y좌표를 잡는다
해결 : 문제가 생겼던 애니메이션 중 회전 슬래쉬인 경우 rootMotion을 끄면 애니메이션의 회전값이 적용이 안되어 기이하게 작동하였으므로 root transform rotation을 체크해 줌으로써 해결하였다