물리

김도익·2023년 5월 12일
0

Unity

목록 보기
21/23

23.05.11. 물리 수업

Mesh Render

Mesh Render을 off하면 물체가 사라짐

Mesh Render을 on하면 물체가 등장함

Collider

Collider은 여기에 있는 것을 사용하면 됩니다.

박스, 스피어, 캡슐 Collider를 많이 사용합니다.

교수님 의견은 하나에 오브젝트에 하나에 콜라이더를 붙이는 것이 더 좋다고 하셨다.

정적 콜라이더(리지드바디 부착x)끼리는 충돌 처리가 되지 않는다. 동적 콜라이더(리지드바디 부착o)가 하나는 있어야 충돌 처리가 된다.

Trigger

트리거(Trigger)는 충돌만 감지합니다.



CCD : 연속 충돌처리

속도가 너무 빠르면 서로 충돌을 감지하지 못하는 경우가 발생할 수 있습니다.
그래서 연속 충돌처리를 사용해서 충돌을 감지할 수 있도록 만들어줍니다.

Continuos - 정적 오브젝트만을 연속적으로 감시합니다.
Continuos Dynamic - 플레이어도 빠르고 총알도 빠르다고 했을 때, 충돌 처리를 할 수 있습니다.

만약 내가 게임을 만들 때 속도를 빠르게 만들었는데 내가 예상한 충돌 처리가 되지 않는다면 연속 충돌처리를 생각하자.

Collider 정리

콜라이더는 충돌 영역을 설정하고, 서로 겹치지 않도록 만들어주는 기능입니다.

  • 리직바디가 없으면 정적 콜라이더입니다.

  • 트리거를 사용하면 충돌 없이 서로 겹칠 수 있습니다.

    • 실질적인 충돌은 안나지만, 충돌은 처리되고 있습니다.

    • 정적 콜라이더와 정적 콜라이더가 부딪히면 충돌이 일어나지 않습니다.
      정적 콜라이더와 리지드바디 콜라이더가 부딪히면 충돌이 일어납니다.
      이때 정적 콜라이더에 트리거를 on하면 충돌 없이 서로 겹칠 수 있습니다.
      단, 충돌은 처리되고 있습니다.

키네마틱은 물리연산을 받지 않는다.

ObjectPool은 필수적으로 사용해야합니다.
Unity는 메모리 할당과 해제가 일어날 때 압축이 일어나지 않아 메모리 단편화가 발생하고, 빈 공간이 연속적이지 않아서 힙의 확장이 일어납니다.
이런 이슈를 해결하기 위해선 '재사용'을 해야하고 재사용하기 위해 ObjectPool을 사용해야합니다.

Layer

충돌을 설정할 때 Layers를 설정하는 것이 좋다.
연산이 절감되기 때문이다.

ex) 총알과 총알이 부딪혀도 신경쓰지 않도록 만들어주기



LayerMask를 사용하면 내가 원하는 오브젝트랑만 충돌처리가 가능하도록 만들어 줄 수 있다.
자세한건 Physics 파트에서 확인하자.

Rigidbody

개요

현실에서 강체(rigidbody)란 물리적인 힘에 의해 모양이 변형되지 않는 물체를 의미한다Unity에서 중력, 충돌 등과 같이 물리에 기반한 동작을 흉내내고 싶다면 게임오브젝트를 강체로 만들어야한다. 게임오브젝트를 강체로 만들고 싶다면 리지드바디 컴포넌트를 부착시키면 된다.

*물리 효과를 보고 싶다면 여기를 참고하자.

프로퍼티

리지드바디 컴포넌트를 추가하면 아래와 같은 프로퍼티를 확인할 수 있다.

  • Mass : 질량

  • Drag : 마찰력

  • Constraints : 제약 (힘을 받지 말아야 되는 곳에 사용하면 된다.)
    힘에 의해서 위치, 회전이 변화 되지 않도록 각 축마다 막을 수 있습니다.

리지드바디를 부착시킨 게임오브젝트는 Unity의 PhysX 시스템에 의해 트랜스폼이 계산되기 때문에 직접적으로 트랜스폼을 변경하지 말고 물리 엔진에 의해서 변경되게 해야 의도치 않은 동작을 막을 수 있다.

프로퍼티에 대한 설명은 여기여기를 참고하면 된다.

힘을 추가하기

AddForce(), AddExplosionForce(), AddTorque()등으로 게임오브젝트에 힘을 가할 수 있다. 아래 스크립트를 만들고 큐브를 만들어서 대입하고 힘을 Space를 눌러보자.



힘을 줄 때는 힘 모드가 있는데 아래와 같다.

  • Force : 질량을 고려하여 힘이 점진적으로 적용된다.

  • Acceleration : 일정한 비율로 증가하는 힘이 적용된다.

  • Impulse : 시간에 따라 점진적으로 형성되는 힘이 아닌 순간적인 힘이 적용된다.

  • VelocityChange : 다양한 방향으로 순간적인 힘을 가하며, 이때 질량은 무시 된다.

유연하게 Force모드 사용하기

물리 연산할때 시간 계산을 하기 때문에 Time.deltaTime을 곱하지 않아도 된다.
즉 Rigidbody를 사용하면 Time.deltaTime을 곱할 필요가 없다!

물리 연산할 때만 FixedUpdate에 작성하는거지, Rigidbody 사용한다고 FixedUpdate에 함수를 작성하는 것이 아니다. Rigidbody 자체가 물리 연산을 하기 때문에 Update 함수에 작성하면 된다.

키네마틱 리지드바디

프로퍼티 중 Is Kinematic에 체크를 하면 해당 리지드바디는 키네마틱 리지드바디가 된다.
키네마틱 리지드바디가 되면 오브젝트에 물리적인 영향을 줄 수 있지만, 그 자체는 영향을 받지 않는다.
아래의 스키립트처럼 힘을 가해도 전혀 움직이지 않는 것을 확인할 수 있다.

물리 설정

Edit -> Project Settings -> Physics에서 물리와 관련된 여러 가지를 설정 할 수 있다.
자세한 것은 여기를 참고하자.

상수 힘

일정 방향으로 힘이나 회전력을 계속 가하고 싶다면 ConstantForce컴포넌트를 추가하면 된다. API는 여기서 확인할 수 있다.

아래 스크립트를 입력하면 위쪽으로 날아가는 물체를 구현할 수 있다.

리지드바디 최적화

물리 연산은 꽤 무거운 편이다. 그렇기 때문에 Sleep Threshold보다 느린 속력을 가진 리지드바디는 Unity가 자동으로 잠자기 모드로 바꿔 물리 시뮬레이션에서 해당 물체를 제외시킨다.

만일 이를 직접적으로 제어하고 싶다면 Sleep()WakeUp()을 사용하면 된다.
아래의 스크립트를 만들고 게임오브젝트를 공중에 띄우면 중력이 바로 적용되지 않고, 시간이 좀 지난 후에 적용되는 것을 확인할 수 있다.

추가 내용

Physics

감지를 구현하는데 Physics를 사용하면 된다.

AI를 구현하고 싶다면 물리쪽 API를 잘 사용하면 된다.

Raycast는 마우스를 이용해서 게임을 만들 때 자주 사용한다.

Raycast는 bool타입이다.
하나의 물체만 충돌을 감지한다.


  • 다중의 물체 충돌을 감지하도록 만든다.





Overlap

  • 반경내에 겹쳐있는 콜라이더를 찾는 것이다.

  • radius 5의 크기는 아래 보이는 크기와 같다.
    OverlapSphere 크기에 포함되는 게임오브젝트들이 충돌처리 되었음을 알 수 있다.

LayerMask

내가 원하는 오브젝트랑만 충돌처리가 가능하도록 만들어줄 수 있다.



  • 갈색 공, 흰색공만 Enemy고 나머지는 Default값으로 처리한 상태이다.

<물리연산과 Update>

  • 물리연산은 어느 컴퓨터에서도 동일하게 산출되어야 합니다.
    그래서 시간으로 Update를 하는 것입니다.
    그래서 FixedUpdate는 물리 연산을 할 때 사용합니다.
    기본 값은 50프레임이며 수정할 수 있습니다.

  • Update는 무엇이 먼저 Update가 될지 모르기 때문에 Update안에 카메라를 넣는다면 카메라가 캐릭터를 따라가지 못해 화면이 깨질 우려가 있습니다.
    그래서 Update가 끝나고 LateUpdate가 되기 때문에 3D에선 카메라가 지속해서 카메라가 따라갈 수 있도록 만들어줍니다.

profile
고급 개발자가 되고 싶어요!

0개의 댓글