[2025_11_20]3d에서 캐릭터의 물리 문제
2025. 11. 20. 21:18ㆍTIL
문제 상황
증상
플레이어가 장애물과 상호작용할 때 비정상적인 동작 발생:
- 장애물을 통과하거나 내부에 박힘
- 이동이 불안정함
- Y, Z축 속도가 의도치 않은 큰 음수 값으로 변경
csharp
// 문제가 발생한 코드 구조
private void FixedUpdate()
{
Slide(); // AddForce() 사용
Move(); // MovePosition() 사용
ApplyGravity(); // velocity 직접 수정
}
private void Slide()
{
// 슬라이드 시 힘 추가
rb.AddForce(slideDownSpeed * Vector3.down, ForceMode.Impulse);
}
private void Move()
{
// 계산된 속도로 이동
rb.MovePosition(rb.position + runSpeed * Time.fixedDeltaTime * Vector3.forward);
}
private void ApplyGravity()
{
if (IsFalling())
{
// velocity 직접 수정
rb.velocity += fallAccel * Time.fixedDeltaTime * Vector3.down;
}
}
원인 파악
핵심 문제: 물리 메서드 혼용
FixedUpdate()에서 여러 물리 메서드를 동시에 사용했기 때문:
- MovePosition() - 위치 기반 이동
- AddForce() - 힘 기반 이동
- velocity 직접 수정 - 속도 벡터 직접 변경
csharp
// 문제 코드
FixedUpdate()
{
rb.AddForce(...) // 1. 내부적으로 velocity 변경
rb.MovePosition(...) // 2. position 변경 (velocity는 무시)
rb.velocity += ... // 3. velocity 직접 덮어쓰기
}
// 세 메서드가 서로 충돌하며 Rigidbody의 속도 벡터가 예측 불가능하게 변경됨!
각 메서드가 하는 일:
메서드동작 방식내부 처리
| AddForce() | 힘을 가함 | velocity에 힘을 누적 |
| MovePosition() | 위치를 이동 | position 변경, velocity 계산 무시 |
| velocity = | 속도 직접 설정 | velocity를 덮어씀 |
충돌 과정:
1. AddForce() -> velocity = (5, -2, 0)
2. MovePosition() -> position 변경, velocity는 뭔지 모르게 됨
3. velocity += ... -> 이미 이상해진 velocity에 더함
4. 물리 엔진 혼란 -> 벽 통과, 버그 발생
해결 방안
핵심: Velocity 벡터 하나로 통일
모든 힘과 이동량을 velocity 벡터 하나에 누적한 뒤, 마지막에 한 번에 적용
csharp
private void FixedUpdate()
{
// 1. 현재 velocity 가져오기
Vector3 newVelocity = rb.velocity;
// 2. 모든 이동/힘을 velocity에 누적
if (IsSliding())
{
// AddForce 대신 velocity에 직접 추가
newVelocity += slideDownSpeed * Vector3.down;
}
if (IsMoving())
{
// MovePosition 대신 velocity로 계산
newVelocity = runSpeed * Vector3.forward;
}
if (IsFalling())
{
// 중력 가속도 추가
newVelocity += fallAccel * Time.fixedDeltaTime * Vector3.down;
}
// 3. 마지막에 한 번만 적용
rb.velocity = newVelocity;
}
배운 점
1. Rigidbody 물리 메서드는 혼용하면 안 됨
csharp
// 이렇게 섞어 쓰지 말기
rb.AddForce(...)
rb.MovePosition(...)
rb.velocity = ...
// 하나만 선택해서 사용
rb.velocity = ... // 추천: 직접적이고 예측 가능
2. 각 메서드의 용도
메서드언제 쓸까?
| velocity | 직접 속도를 제어하고 싶을 때 (추천) |
| AddForce() | 현실적인 힘 기반 물리가 필요할 때 |
| MovePosition() | 충돌 감지는 하되 물리 영향은 무시할 때 |
'TIL' 카테고리의 다른 글
| [2025_11_24]유니티 Batching을 이용한 최적화 및 Addressble (0) | 2025.11.25 |
|---|---|
| [2025_11_21] 프로젝트 마무리 (0) | 2025.11.21 |
| [2025_11_19]아이템 효과 플레이어와 연동 (0) | 2025.11.19 |
| [2025_11_18]ItemScriptableObject생성 및 Json과 연동 (0) | 2025.11.18 |
| [2025_11_17]장애물 충돌 관리(콜라이더 분리) (0) | 2025.11.17 |