Rigidbody2D.velocity
객체가 이동하는 속도와 방향을 Vector2 형태로 설정하거나 가져올 수 있다.
Vector2 currentVelocity = rb.velocity; // 현재 속도 저장 (혹시 나중에 복원할 수도 있음)
rb.velocity = new Vector2(5f, 0f); // 새로운 속도로 덮어씀 (오른쪽으로 이동)
x 방향으로 초당 5 유닛의 속도로 이동
*Vector2는 값 타입(struct)
Mathf.Clamp(값, min, max)
값을 특정 범위 내로 제한하는 함수
float angle = Mathf.Clamp((_rigidbody.velocity.y * 10f), -90, 90);
transform.rotation = Quaternion.Euler(0, 0, angle);
_rigidbody.velocity.y:
Rigidbody2D의 속도(velocity)는 Vector2 타입이다.
velocity.y는 물체의 수직 속도를 나타낸다.
_rigidbody.velocity.y * 10f:
물체의 수직 속도를 10배로 확대한다.
y축 속도가 회전 각도에 더 큰 영향을 미치도록 하기 위해.
Mathf.Clamp():
(_rigidbody.velocity.y * 10f) 값이 -90과 90 사이로 제한되도록 한다.
즉, 회전 각도가 -90도에서 90도 사이로 고정되게 된다.
Quaternion.Euler(0, 0, angle):
3D 공간에서 객체의 회전을 설정하는 함수
Quaternion.Euler(0, 0, angle)는 z축을 기준으로 angle만큼 회전하도록 설정한다.
Quaternion.identity
회전이 전혀 없는 기본 상태
(x: 0, y: 0, z: 0) 방향을 바라보는 회전값.
transform.rotation
transform.rotation은 게임 오브젝트의 회전을 설정하는 속성.
Quaternion.Euler(0, 0, angle)를 이용해 z축 회전값을 설정하여 물체가 회전하도록 만든다.
=> 결과적으로 이 코드는 물체가 수직 속도에 따라 회전하는 동작을 구현합니다. 예를 들어, 물체가 위로 빠르게 올라가면 양의 속도를 갖고, 아래로 내려가면 음의 속도를 갖게 되어, 물체가 그에 맞게 회전하도록 한다.
그냥 transform.rotation 값을 변경하면 안되나?
transform.rotation의 타입을 보면 이렇게 돼 있다.
public Quaternion rotation;
즉, 회전을 바꾸려면 Quaternion 값을 넣어줘야만 동작한다.
transform.rotation = new Vector3(0, 0, angle); // ❌ 오류!
각도를 직접 집어넣으면 오류가 난다.
왜냐면 Vector3는 회전값으로 쓸 수 없고,
Unity는 Quaternion 형식으로 회전을 저장하기 때문.
transform.eulerAngles = new Vector3(0, 0, angle); // ✅ 이건 가능
transform.eulerAngles를 이용해 각도를 직접 제어할 수 있지만
정확도 문제가 생길 수 있으므로 quaternion을 쓰는 것이 좋다.
어느 방향으로 회전해야 할지 모르겠다면?
Scene 뷰의 2D를 끄면
3차원으로 표시된다.
화살표를 움직여보며 회전 방향을 찾아보자.
public void OnCollisionEnter2D()
2D 물리 엔진에서 두 오브젝트가 충돌했을 때 호출되는 이벤트 함수
public void OnCollisionEnter2D(Collision2D collision)
{
Debug.Log("충돌한 2D 객체: " + collision.gameObject.name);
}
⚙️ 작동 조건
- 충돌한 두 오브젝트 모두 Collider2D가 있어야 한다.
- 최소한 하나는 Rigidbody2D를 가지고 있어야 한다.
- Trigger 모드가 꺼져 있어야 (isTrigger == false) OnCollisionEnter2D가 호출된다.
- 만약 isTrigger == true이면 OnTriggerEnter2D()를 사용해야 한다.
속성 | 설명 |
collision.gameObject | 충돌한 상대 오브젝트 |
collision.contacts | 충돌 지점 정보 (배열) |
collision.relativeVelocity | 두 오브젝트 간 상대 속도 |
이벤트 함수(Event Function)란?
특정 상황이나 동작이 발생할 때 자동으로 호출되는 함수.
이벤트함수 | 언제 호출됨? |
Start() | 오브젝트가 생성되고 게임 시작할 때 1번 실행 |
Update() | 매 프레임마다 실행 (계속 반복됨) |
OnCollisionEnter2D() | 다른 물체와 처음 충돌했을 때 |
OnTriggerEnter2D() | 트리거에 들어갔을 때 |
OnMouseDown() | 오브젝트를 마우스로 클릭했을 때 |
https://docs.unity3d.com/kr/2019.4/Manual/ExecutionOrder.html
이벤트 함수의 실행 순서 - Unity 매뉴얼
Unity 스크립트를 실행하면 사전에 지정한 순서대로 여러 개의 이벤트 함수가 실행됩니다. 이 페이지에서는 이러한 이벤트 함수를 소개하고 실행 시퀀스에 어떻게 포함되는지 설명합니다.
docs.unity3d.com
충돌 처리 함수
- OnCollisionEnter: 충돌 시작 시 호출
- OnCollisionStay: 충돌이 유지되는 동안 호출
- OnCollisionExit: 충돌이 끝났을 때 호출
- OnTriggerEnter/Stay/Exit: Trigger Collider와의 상호작용을 처리
라이프사이클(Lifecycle)
Unity에서 라이프사이클(Lifecycle)은 게임 오브젝트와 스크립트가 실행되는 순서를 정의한다.
함수 이름 | 언제 실행되는가? | 설명 |
Awake() | 오브젝트가 생성되자마자 1번만 실행됨 | 초기 설정 (다른 스크립트보다 먼저 실행됨) |
OnEnable() | 오브젝트가 활성화될 때 실행됨 | 꺼져있다 켜졌을 때 다시 실행됨 |
Start() | Awake 이후, 첫 프레임 전에 1번 실행됨 | 게임 시작 직전에 설정할 때 |
Update() | 매 프레임마다 실행됨 | 실시간 입력, 움직임 처리 |
FixedUpdate() | 일정 시간마다 실행됨 (물리 연산에 적합) | Rigidbody 움직임 |
LateUpdate() | Update가 모두 끝난 후 실행됨 | 카메라 따라가기 등에 사용 |
OnDisable() | 오브젝트가 비활성화될 때 실행됨 | 일시 정지 시 처리 등 |
OnDestroy() | 오브젝트가 삭제되기 직전 실행됨 | 정리 작업에 사용 |
각 단계가 명확히 구분되어 있어, 적절한 함수에 코드를 배치하면 효율적인 게임 로직을 구현 가능하다
Time.deltaTime
Time.deltaTime은 이전 프레임과 현재 프레임 사이의 시간을 반환한다.
예: speed * Time.deltaTime으로 일정 속도로 이동 가능
animator.SetInteger("파라미터이름", 값);
Animator animator = GetComponent<Animator>();
animator.SetInteger("IsDie", 1);
SetInteger("IsDie", 1):
Animator 안에 있는 정수형(int) 파라미터 "IsDie"의 값을 1로 설정한다.
로컬 좌표와 월드 좌표
Unity에서 로컬 좌표(Local Position)와 월드 좌표(World Position)는 오브젝트의 위치를 측정하는 기준이다.
- 로컬 좌표(Local Position)
- 부모 오브젝트를 기준으로 한 오브젝트의 위치
- 오브젝트가 부모 오브젝트 내에서 얼마나 떨어져 있는지를 나타낸다.
- 부모 오브젝트의 위치나 회전이 변경되면, 로컬 좌표가 반영되어 상대적인 위치를 유지한다.
- 월드 좌표(World Position)
- 게임의 전체 월드(전역 공간)에서의 위치
- 부모 오브젝트와 관계없이, Unity의 전역 좌표계(0, 0, 0)를 기준으로 계산된다.
따라오는 카메라 구현
offsetX = transform.position.x - target.position.x;
void Update()
{
Vector3 pos = transform.position;
pos.x = target.position.x + offsetX;
transform.position = pos;
}
offsetX(타겟과의 간격)을 유지한 position값을 계속해서 Update한다.
현재 씬을 다시 로드 -> 게임 재시작 하는 법
public void RestartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
SceneManager.GetActiveScene()
현재 실행 중인 씬 정보를 가져온다.
예: 현재 Level1 씬이라면, 그 정보를 객체로 리턴함.
.name
위에서 가져온 씬 객체의 이름만 추출한다.
예: "Level1"
SceneManager.LoadScene(...)
씬을 로드하는 함수.
=> 이름을 넣어주면 그 씬을 다시 불러오게 되어 게임을 초기 상태로 리셋한다.
Polygon Collider
형태에 맞춰 충돌영역이 생긴다.
복잡한 다각형은 성능에 영향을 줄 수 있으니 꼭 필요한 경우만 사용!
배경, 장애물 무한 생성하기
메인 카메라에 빈 오브젝트 BgLooper을 만든다.
=> 카메라의 움직임에 맞춰 BgLooper도 움직인다.
배경, 장애물과 충돌할 수 있게 Box Collider 영역을 설정해준다.
Rigidbody Type을 Kinematic 으로 설정한다.
Rigidbody 2D Type
타입 이름 | 설명 |
Dynamic | ✅ 기본값. 중력, 힘, 충돌 모두 적용됨. 움직이는 물리 오브젝트에 사용 |
Kinematic | 중력&충돌 영향 x. 직접 위치를 스크립트로 제어할 때 사용 (ex: 움직이는 발판) |
Static | 🧱 절대 안 움직임. 벽이나 바닥처럼 고정된 물체에 사용 |
BgLooper 스크립트에서 충돌 처리 함수를 작성해주면 된다.
void Start()
{
Obstacle[] obstacles= GameObject.FindObjectsOfType<Obstacle>();
obstacleLastPosition = obstacles[0].transform.position;
obstacleCount = obstacles.Length;
for (int i = 0; i < obstacleCount; i++)
{
obstacleLastPosition = obstacles[i].SetRandomPlace(obstacleLastPosition, obstacleCount);
}
}
public void OnTriggerEnter2D(Collider2D collision)
{
Debug.Log("Triggered: " + collision.name);
if (collision.CompareTag("BackGround"))
{
float widthOfBgObject = ((BoxCollider2D)collision).size.x;
Vector3 pos = collision.transform.position;
pos.x += widthOfBgObject * numBgCount;
collision.transform.position = pos;
return;
}
Obstacle obstacle = collision.GetComponent<Obstacle>();
if(obstacle)
{
obstacleLastPosition = obstacle.SetRandomPlace(obstacleLastPosition, obstacleCount);
}
'내일배움캠프 Unity 9기 > TIL' 카테고리의 다른 글
[Unity/TIL] - 4주차 Unity입문 트러블슈팅 (1) | 2025.05.07 |
---|---|
[Unity/TIL] - 맵 그리기(타일맵) (0) | 2025.05.02 |
[Unity/TIL] - 애니메이션, 트랜지션 추가하기 / GetComponent (1) | 2025.04.29 |
[Unity/TIL] - new로 생성한 객체는 클래스와 동기화 되나요? (1) | 2025.04.23 |
[Unity/TIL] - static (0) | 2025.04.22 |