▼오늘 학습한 내용
애니메이션(Animation)
애니메이션
: 애니메이션을 실행하는 컴포넌트
- 하지만 Animation Component는 거의 쓰지 않으며, Animation에서 통합 관리하여 사용
애니메이션 윈도우 생성방법
- 단축키 : Ctrl + 6
애니메이션 생성
- 애니메이션을 만들 오브젝트 선택
- Create버튼 클릭
애니메이션 제작
- 녹화 버튼을 클릭
- Add Key 클릭
- 포인터를 원하는 시간만큼 이동
- 오브젝트를 움직여 원하는 동작으로 움직이기
- 녹화 종료
문이 0.30초 동안 transform.Rotation(0, -130, 0)만큼 회전하여 열리는 애니메이션 Door를 만들었다.
DoorEvent 스크립트를 작성한 후, Animatior가 추가된 오브젝트에 연결하고 확인해보자.
DoorEvent 스크립트
public class DoorEvent : MonoBehaviour
{
void AnimationEvent()
{
Debug.Log("문이 열리는 중");
}
}
결과 확인
문이 열리는 모션과 함께 "문이 열리는 중"이라는 멘트를 확인할 수 있다.
애니메이터(Animator)
애니메이터(Animator)
: 애니메이션 동작을 관리하는 컴포넌트
- 빈 State 만들기: Create State > Empty
- 기본 State로 변경: Set as Layer Default State
Layer설정
Animator의 Layer는 여러 애니메이션 동작을 관리하는 구조이다.
- Animator 창의 Layers 탭에서 + 버튼을 클릭하여 새 Layer 추가
파라미터설정
Animator의 Parameter는 애니메이션 상태 전환의 조건을 정의하는 값이다.
- Parameter 유형 4가지 (Float, Int, Bool, Trigger)등을 통해 제어한다.
- Animator 창의 Parameters 탭에서 + 버튼을 클릭해 원하는 유형의 Parameter를 추가
- Animator 창에서 두 상태(State) 간의 전환선을 클릭하여 Inspector에서 Transition 조건을 설정
애니메이터 윈도우 생성방법
[예제] 문 애니메이션 만들기
[예제] 문 애니메이션 만들기
1. Animator 설정
- Door 애니메이션의 트리거 파라미터 Open, Close 생성
- Any State에서 각각의 상태( Open, Close )로 전환하도록 연결
2. 스크립트 작성
public class DoorEvent : MonoBehaviour
{
public Animator anim; // Animator 컴포넌트 연결
// 플레이어가 문에 접근했을 때
public void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player")) // 태그가 "Player"인 경우
{
anim.SetTrigger("Open"); // "Open" 트리거 실행
}
}
// 플레이어가 문에서 멀어졌을 때
public void OnTriggerExit(Collider other)
{
if (other.CompareTag("Player")) // 태그가 "Player"인 경우
{
anim.SetTrigger("Close"); // "Close" 트리거 실행
}
}
}
- 플레이어가 문 근처 접근 -> OnTriggerEnter 호출 -> Open 트리거 실행 -> 문 열림
- 플레이어가 문에서 멀어짐 -> OnTriggerExit 호출 -> Close 트리거 실행 -> 문 닫힘
스크립트도 잘 작성하고 문 오브젝트에 필요한 컴포넌트도 추가했지만, 오류가 발생했다.
오류 발생
Animator가 제대로 연결되었는지도 확인하고, 코드도 다시 점검해봤지만 별다른 이상은 없었다.
마침 같은 오류 발생한 분이 질문을 하셔서 답변 내용을 하나씩 시도해본 결과, 문제의 원인은 Animation Event가 남아있어서 발생한 것이었다.
Event를 삭제하니 문제가 바로 해결되었다.
결과
[예제] 캐릭터 점프
[예제] 캐릭터 점프 구현
2단 점프 방지
캐릭터가 점프 기능을 하면 기본적으로 2단 점프가 되는 경우가 많다.
왜냐하면?
- 점프 중에도 다시 점프 입력을 처리하는 조건이 있음
- isGround와 같은 땅에 닿았는지 여부를 확인하는 로직이 없으면 공중에서도 점프가 계속 가능
그래서 isGround를 추가해야한다.
점프 기능 구현 준비
1. 스페이스바 입력
- 조건문: "스페이스바를 눌렀을 때"를 체크
2. 점프 힘 설정
- jumpPower 변수: 점프 시 캐릭터를 위로 밀어줄 힘
3. Rigidbody 활용
- 캐릭터가 점프할 때 `Rigidbody.AddForce()`를 사용하여 위쪽으로 힘을 가함
땅 체크 로직 (isGround) 구현
- Boolean 타입 변수 isGround로 캐릭터가 땅에 닿아 있는지 체크
- OnCollisionEnter / OnCollisionExit 이벤트 사용
최종 코드: GroundEvent 스크립트
public class GroundEvent : MonoBehaviour
{
void OnCollisionEnter(Collision collision)
{
if (collision.collider.CompareTag("Player"))
{
// Player 태그를 가진 오브젝트가 땅에 닿았음을 확인
GameObject characterObj = collision.gameObject;
// Player 오브젝트의 Movement 스크립트에서 isGround를 true로 변경
characterObj.GetComponent<Movement>().isGround = true;
}
}
void OnCollisionExit(Collision collision)
{
if (collision.collider.CompareTag("Player"))
{
GameObject characterObj = collision.gameObject;
// Player 오브젝트가 땅을 벗어났으므로 isGround를 false로 변경
characterObj.GetComponent<Movement>().isGround = false;
}
}
}
GroundEvent 스크립트와 함께 동작하도록 하기 위해
기존의 캐릭터 움직임을 구현한 MoveMent 스크립트에 다음과 같은 내용을 추가했다.
public float jumpPower = 10f;
public bool isGround = false; //true: 바닥에 닿은 상태일 때, false: 바닥에서 떨어졌을 때
void Update()
{
Jump();
}
void Jump()
{
// 스페이스바를 눌렀고, 캐릭터가 바닥에 있을 때만 점프 가능
if (Input.GetKeyDown(KeyCode.Space) && isGround)
{
// Rigidbody 컴포넌트를 가져와 AddForce를 사용해 위쪽으로 힘을 가함
GetComponent<Rigidbody>().AddForce(Vector3.up * jumpPower, ForceMode.Impulse);
// 점프 후 공중 상태로 변경
isGround = false;
}
}
}
결과
결과를 확인해보면, 기존에는 무한대로 점프하던 어몽이가 이제는 아무리 스페이스바를 눌러도 단 한 번만 점프할 수 있다.
▼마무리
애니메이션 구현 과정으로 넘어오니 조금 더 복잡하게 느껴지긴 했지만, 강사님이 설명을 차근차근 잘 해주셔서 이해가 잘 되고, 아직까지는 크게 어려운 부분 없이 따라가고 있는 것 같다.
오늘은 오류가 하나 발생해서 혼자 해결하려고 구글링도 해보고 여러 가지 시도를 해봤지만, 해결되지 않았다.
그런데 마침 다른 분들도 같은 오류를 겪고 있었고, 한 분이 알려주신 해결 방법 덕분에 문제를 해결할 수 있었다.
역시 함께 공부하니 혼자 하는 것보다 훨씬 수월하고 좋은 것 같다.