
가장 기초적인 물체간의 상호작용 중 하나다. 충돌에 필요한 연산량을 어떻게 줄일 수 있나 알아보자
게임 오브젝트에 물리 엔진을 적용하는 컴포넌트. 질량, 공기저항, 중력과 같은 기본 요소와 함수를 사용해 물리처리. 물리 연산은 많은 연산량을 요구 하므로, 적절히 사용하는 것이 중요함
Mass : 물리량(Kg)Drag : 공기저항Angular Drag : 회전저항Automatic Center of Mass : 물체의 무게중심을 정중앙에 자동으로 해두기Automatic Tensor : 관성저항 자동세팅Use Gravity : 중력사용 여부Is Kinematic : 외부 충격에 영향을 받는지, 안받는지 설정 가능Interpolate : 보간. CCD와 관련있다. 키면 연산량이 증가한다Collision Detection : 중요한 물체의 충돌검사에 쓴다Constraints : 축에 대한 물리 연산 무시 여부를 체크할 수있다. 예를들어 Freeze Position Y에 체크하면, 낙하하지 않는다
프로젝트 세팅에서 물리 현상을 세팅할 수 있다. 중력또한 마찬가지. 2D 물리와, 3D 물리를 구분해서 사용한다
gameObject, transform 과 같이 기본적으로 있었던 기본 인스턴스였다. 그래서 사진과 같이 그 잔재가 남아있다
new 키워드를 붙여준다void FixedUpdate()
{
rigidbody.AddForce(Vector3.right * x * power,ForceMode.Force);
}rigidbody.velocity = Vector3.right * power * xInput;rigidbody.AddTorque(Vector3.up * xInput * power);rigidbody.angularVelocity = Vector3.up * xInput * power;게임을 제작하는 데 움직임은 매우 심혈을 기울여 만든다. 예시를 몇 개 조사해본다
버니합 : 버그로 탄생한 이동 기법. 벡터의 내적으로 구현하다보니 생긴 버그다
코요테 타임 :루니 툰의 전매특허인 허공에서 달리는 모션 후는 떨어지는 연출이 기원이며, 이는슈퍼 마리오,셀레스트,소닉등 플랫폼 게임에서 땅 끝부분에서 실제로는 떨어져야 하는 거리보다 더 가도 점프를 입력할 유예시간을 지칭한다


// 필수로 해당 컴포넌트는 가지고 있어야 한다 라는 의미
[RequireComponent(typeof(Rigidbody))]
public class Bullet : MonoBehaviour
{
[SerializeField] Rigidbody rigid;
private void Awake()
{
// 실수로 Rigidbody를 안 달았다면, 달아준다
// ?? : null 이면 오른쪽 GetComponent, 아니면 왼쪽 rigid 반환
rigid ??= GetComponent<Rigidbody>();
}
void Update()
{
if (rigid.velocity.magnitude > 3)
{
//포탄이 곡선을 그리며 날아간다
transform.forward = rigid.velocity;
// 오브젝트의 회전 방법 중 하나다
// transform.forward = 벡터
// 벡터 방향을 바라보도록(forward 앞이 그쪽을 향하도록) 회전함
}
}
}
// 충돌의 메시지(이벤트) 함수. FixedUpdate 이후에 호출된다
// 충돌 시작에 호출
private void OnCollisionEnter(Collision collision)
{
Debug.Log("Collision Enter");
}
// 충돌 중에 호출
private void OnCollisionStay(Collision collision)
{
Debug.Log("Collision Stay");
}
// 충돌이 끝나면 호출
private void OnCollisionExit(Collision collision)
{
Debug.Log("Collision Exit");
}

충돌은 두 개 이상의 물체가 만났을 때, 일어난다. 그래서 매개변수가 필요하다
private void OnCollisionEnter(Collision collision) 에서 Collision이 매개변수
private void OnCollisionEnter(Collision collision)
{
Debug.Log($"{collision.gameObject.name}과 충돌 시작");
}
private void OnCollisionStay(Collision collision)
{
Debug.Log($"{collision.gameObject.name}과 충돌 중");
}
private void OnCollisionExit(Collision collision)
{
Debug.Log($"{collision.gameObject.name}과 충돌 끝");
}

public class Bullet : MonoBehaviour
{
[Header("Components")]
[SerializeField] Rigidbody rigid;
[Header("Properties")]
[SerializeField] GameObject explosionPrefab;
private void OnCollisionEnter(Collision collision)
{
Destroy(gameObject);
Instantiate(explosionPrefab, transform.position, transform.rotation);
}
}
Destroy 이후에 position과 같은 정보를 사용할 수 있는 이유는, Destroy는 삭제 예정 함수이기 때문이다. 즉시 삭제는 DestroyImmediate가 있다(쓰는걸 추천하지 않음)Destroy된 게임 오브젝트는 가비지 컬렉터가 돌아갈 때 삭제된다Fake Null 조사

프로젝트 창에서 위와 같은 방법으로 만들 수 있다
Opaque : 불투명도를 설정한다 private void OnTriggerEnter(Collider other)
{
Debug.Log("OnTriggerEnter");
}
private void OnTriggerStay(Collider other)
{
Debug.Log("OnTriggerStay");
}
private void OnTriggerExit(Collider other)
{
Debug.Log("OnTriggerExit");
}

tag와 비슷함. 묶어서 관리 가능하다 보니 충돌/처리에 쓰임게임오브젝트의 레이어를 활용하여 충돌체간의 충돌가능 여부를 설정 가능
폴가이즈의 움직이는 장애물 들이 좋은 예시