- 이번 프로젝트에서는 다양한 플레이어 조작, 상호작용, 환경 요소를 구현한 3D 액션 어드벤처 스타일 게임을 개발했다.
- Unity 엔진과 C#을 활용하여 기본 이동, 시점 전환, 상호작용 시스템, 아이템 사용 시스템 등을 구현했다.
🔗 깃허브 링크
🎥 게임 영상
📅 개발 기간
- 2025.08.08 ~ 2025.08.13 (주말 제외 4일)
✨ 구현 기능
1. 기본 이동 및 점프
- WASD로 이동하고 Spacebar로 점프한다. 대쉬(Shift)를 통해 가속 이동을 할 수 있도록 구현했다.
2. 플레이어 상태바 UI
- 플레이어의 체력, 스태미나, 버프 지속 시간을 UI로 실시간 표시했다.
3. 동적 환경 조사 - 상호작용 가능한 오브젝트 표시
- Raycast를 사용해 플레이어 시선 방향의 오브젝트를 탐지한다.
- 탐지된 오브젝트의 이름과 설명을 UI에 표시하며, 상호작용 가능한 경우에는 해당 UI가 활성화되도록 했다.
4. 점프대
- 밟으면 캐릭터가 위로 튀어 오르는 점프대를 구현했다.
5. 다양한 아이템 구현
- 아이템 데이터는 ScriptableObject로 관리한다. 이름, 설명, 속성 등을 개별 정의할 수 있도록 했다.
6. 아이템 사용 시스템
- 특정 아이템을 사용하면 무적, 더블 점프, 스피드 부스트 등 효과가 일정 시간 동안 지속된다.
- 효과의 남은 시간은 우측 상단에 아이콘으로 표시한다.
7. 시점 전환
- 1인칭 ↔ 3인칭 시점을 전환할 수 있도록 구현했다.
8. 움직이는 플랫폼
- 시간에 따라 이동하는 발판을 구현했다. 플레이어가 발판 위에서 이동하면 자연스럽게 함께 이동한다.
9. 벽 타기 및 매달리기
- 플레이어가 벽을 타고 오르거나 매달릴 수 있도록 구현했다.
10. 레이저 트랩 (플랫폼 발사기)
- Raycast로 특정 구간을 감시하고, 플레이어가 일정 시간 닿으면 특정 방향으로 발사되도록 구현했다.
🛠️ 트러블 슈팅 - 플레이어에 AddForce 적용
문제 상황
- 플레이어에 AddForce를 적용했지만 X, Z 축 방향의 힘이 적용되지 않는 문제가 발생했다.
- 원인은 플레이어 이동을 Rigidbody.velocity로 제어하는 로직에 있었다.
- 매 프레임 이동 입력 시 velocity를 직접 덮어쓰는 방식 때문에 외부에서 가하는 힘이 무시되는 현상이 있었다.
해결 방법
- 이동 제어 방식을 변경했다. 입력이 있을 때만 AddForce로 이동을 처리하도록 했다.
- 입력이 없을 경우 OnMoveStop()을 호출해 강제로 이동을 멈추도록 했다.
- 또한 벽에서 자연스럽게 떨어지지 않는 문제를 해결하기 위해 Physic Material의 마찰을 0으로 설정했다.
- 마찰이 0이면 미끄러지는 현상이 발생하므로 강제 정지 로직이 필요했다.
// FixedUpdate() 내 이동 처리
void Move()
{
if (curMovementInput == Vector3.zero) return; // 입력 없으면 작동 안 함
Vector3 dir = Vector3.zero;
Vector3 velocityChange = Vector3.zero;
// 플레이어 상태에 따라 이동 방향과 속도 결정
if (player.IsClimbing)
{
dir = transform.up * curMovementInput.z + transform.right * curMovementInput.x;
dir = dir.normalized;
float climbRunSpeed = player.WalkSpeed / player.RunSpeed * climb.ClimbSpeed;
dir *= player.IsDashing ? climbRunSpeed : climb.ClimbSpeed;
velocityChange = dir - _rigidbody.velocity;
}
else
{
dir = transform.forward * curMovementInput.z + transform.right * curMovementInput.x;
dir = dir.normalized;
dir *= player.IsDashing ? player.RunSpeed : player.WalkSpeed;
velocityChange = dir - new Vector3(_rigidbody.velocity.x, 0, _rigidbody.velocity.z);
}
_rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
}
// 인풋 액션 처리
// 입력시(performed)
void OnMove(InputAction.CallbackContext context)
{
curMovementInput = context.ReadValue<Vector3>();
}
// 입력이 없으면(cancel) 정지
void OnMoveStop()
{
curMovementInput = Vector3.zero;
_rigidbody.velocity = new Vector3(0f, _rigidbody.velocity.y, 0f)
}
결과
- 이 방식을 적용한 뒤, 외부 힘(트랩, 폭발 등)에 자연스럽게 반응할 수 있게 됐다.
- 또한 벽이나 오브젝트에 끼이지 않고 부드럽게 미끄러지는 움직임을 구현했다.
- 플레이어 조작과 물리 반응이 모두 자연스러운 상태로 유지된다.
⚙️ 기술 스택
- Engine: Unity 2022.3.17f1
- Language: C#
- Version Control: GitHub
'Programming > Unity 구현' 카테고리의 다른 글
| Unity 3D 미니 프로젝트 - 🕹️ Project_3D_IdleRPG (1) | 2025.09.09 |
|---|---|
| Unity 3D 팀 미니 프로젝트 - 🕹️ Followers_Project_Survival (4) | 2025.08.22 |
| Unity 2D 미니 팀 프로젝트 - 🕹️ SilverTown Utopia (6) | 2025.08.06 |
| Unity 2D 미니 프로젝트 - 🕹️ Sparta Metaverse (3) | 2025.07.28 |
| Unity 2D 미니 프로젝트 - 팀원 카드 매칭 게임 (3) | 2025.07.07 |
