부캠에서 딱히 배운 거 없이 하루종일 포폴만 하다보니 정말 오랜만에 오게 되었다.
타워 디펜스 포폴을 만들던 중에 문제가 생겼다.
플레이어가 적과 충돌했을 경우 적이 밀려야 하는데 밀리지가 않는다.
보다시피 적의 x, z축 로테이션을 막아놔서 y축으로만 빙글 도는 모습을 볼 수 있다.
그렇다면 분명 서로 충돌은 하고 있다는건데.
구글링을 해보아도 밀림 방지만 나와있고 안 밀림 방지는 보이지 않는다.
밀림 방지 방법인 is Kinematic은 해제되어 있다.
Physics Material을 안 만들어서 그런가 싶어서 만들어 연결해봤는데 아무 변화도 없었다.
생각해보니 두 충돌체 모두 이동 중이니까 이동 구현을 transform으로 해서 그런 걸 수도 있다는 생각이 들었다.
이전 적 이동 코드
transform.position += _moveDir.normalized * (speed * Time.deltaTime);
transform.forward = Vector3.Slerp(transform.forward, _moveDir, Time.deltaTime * rotateSpeed);
바꾼 적 이동 코드
Vector3 movePos = transform.position + _moveDir.normalized * (speed * Time.deltaTime);
_rigid.MovePosition(movePos);
transform.forward = Vector3.Slerp(transform.forward, _moveDir, Time.deltaTime * rotateSpeed);
RigidBody를 이용한 이동으로 변경하였다.
아주 조금 밀리는 것 같기도 하고, 나의 염원에 의한 착각인 것 같기도 하고.
앗 다시 보니 오류가 있었다. 인스펙터 쳐다보느라 콘솔을 못 봤네
젭알 오류 때문에 안되는 거길 바라며 급하게 고쳤다.
오 충돌체끼리 서로 상호작용을 한다.
그런데 유령이 마치 고정좌표계 찍은 것 마냥 고정되어 있는 느낌이 든다.
그래서 코드로 시간마다 위치를 고정해놓은건가 싶어 코드를 살펴보았다.
변경 전 적 이동 코드
IEnumerator MoveAToB(Vector3 start, Vector3 end)
{
float percent = 0;
end = new Vector3(end.x, start.y, end.z);
float moveTime = Vector3.Distance(start, end) / unitPerSecond;
while (percent < 1)
{
percent += Time.deltaTime / moveTime;
var newPos = Vector3.Lerp(start, end, percent);
_rigid.MovePosition(newPos);
yield return null;
}
}
보다시피 Lerp를 사용하면서 특정 시간마다 percent 지점으로 움직이도록 코드를 짜놨다.
(transform에서 rigidBody로 바꾸면서 신경쓰지 못했던 부분이다.)
MoveTowards를 사용하여 방향만 설정해주고 알아서 이동하도록 수정하였다.
변경 후 적 이동 코드
IEnumerator MoveAToB(Vector3 start, Vector3 end)
{
end = new Vector3(end.x, start.y, end.z);
float speed = unitPerSecond;
while (Vector3.Distance(_rigid.position, end) > 0.01f)
{
var newPos = Vector3.MoveTowards(_rigid.position, end, speed * Time.deltaTime);
_rigid.MovePosition(newPos);
yield return null;
}
_rigid.MovePosition(end);
}
이렇게 하면,
짜잔~
아주 잘 밀린다.
너무 잘 밀려서 Physics Material의 Friction 값을 열심히 수정했는데,
알고보니 RigidBody 컴포넌트의 Drag 값을 높게 변경해주면 되는거였다.
(물론 Mass 값도 올리면 좋다)
결과
딱 내가 원했던 적당한 밀림이다.
결론적으로, 안 밀림 문제를 해결하기 위해서는
- is Kinematic 이 해제되어 있는지 확인
- tranform 이동 => rigidBody 이동으로 변경
- 코드로 특정 시간별 위치를 고정하고 있지는 않는지 확인
추가로 빙판길 마냥 너무 밀리면 RigidBody의 Drag 값을 올리자.
이 문제를 해결하면서 rigidBody와 transform 이동의 차이에 대해서 더 깊게 공부하고,
rigidBody로 움직이는 방법들도 다시 한 번 상기하게 되었다.
굿!
'문제 해결' 카테고리의 다른 글
모바일 이동 UI 문제(조이스틱 적용 안됨 + 부캠 대회 결과 후기) (4) | 2024.09.11 |
---|---|
발사체 캐릭터 에셋 적용 시 물리 적용 안됨 문제 해결 (1) | 2024.06.26 |