-
물리엔진, 애니메이션, 씬변환유니티/유니티 메인 2024. 2. 5. 03:02
<물리 엔진>
고양이를 올린뒤 rigidbody 2D와 box 콜라이더 추가
rigidbody 2D : 2D 한정 오브젝트에게 중력을 적용한다
Box Collider : 충돌판정을 위한 콜라이더
구름에게도 충돌판정을 위한 박스콜라이더를 입히면 게임 실행시 구름위에 고양이가 앉는걸 볼수있다
이렇게 Circle 콜라이더까지 추가해서 더 사실적으로 충돌판정을 만들수 있으나 정말 정교하게 만들지 않는다면
미끄러 넘어질수 있다
그럴땐 rigidbody의 Constrains로 들어가 축을 고정시킬수 있다
어느 축을 고정시키고 싶은지 알고 싶다면 3D 모드로 들어가 확인할수 있다
만약 구름에게도 rigidbody를 추가하지만 중력의 작용을 받고 싶지 않다면
Body Type에서 Kinematic을 선택하면 된다
이번에는 스페이스바를 누를때 고양이가 점프할수 있는 코딩을 짜볼 예정
예전처럼 transform.Translate 가 아닌 rigidbody 컴포넌트를 추가했기에 AddForce를 사용해보겠다
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Catcontrol : MonoBehaviour { Rigidbody2D rigid; float jumpforce = 600; void Start() { this.rigid = GetComponent<Rigidbody2D>(); } void Update() { if(Input.GetKey(KeyCode.Space)) { this.rigid.AddForce(transform.up * jumpforce); } } }
Catcontrol 스크립트를 만들어 Cat에게 삽입해주었다.
우선 Rigidbody 컴포넌트를 갖는 rigid이라는 변수를 만들어준뒤 Start 메서드에서 컴포넌트 추가
그리고 스페이스바를 눌렀을때, Rigidbody 컴포넌트에 들어있는 Addforce라는 메서드를 사용하여 점프하게 만든다
AddForce( 방향 * 힘);
근데 점프 힘이 너무 쎄서 Gravity Scale을 올리고 jumpforce를 200으로 낮췄다
처음엔 Gravity Scale만 주구장창 올렸는데 오히려 너무 중력이 쎄져 현실성이 떨어진다
둘다 적당히 줄이는게 중요하다
이제 플레이어를 좌우로 움직이게 만들건데 이것 역시 AddForce 메서드로
예전처럼 한번 누르면 일정거리만큼 순간이동하는것이 아닌, 키를 꾹 누르면 부드럽게 이동하도록 만들어보겠다
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { Rigidbody2D rigid; float jumpForce = 680.0f; float walkForce = 30.0f; float maxWalkSpeed = 2.0f; void Start() { this.rigid = GetComponent<Rigidbody2D>(); } void Update() { // 점프한다 if (Input.GetKeyDown(KeyCode.Space)) { this.rigid.AddForce(transform.up * this.jumpForce); } // 좌우 이동 int key = 0; if (Input.GetKey(KeyCode.RightArrow)) key = 1; if (Input.GetKey(KeyCode.LeftArrow)) key = -1; // 플레이어 속도 float speedx = Mathf.Abs(this.rigid.velocity.x); // 스피드 제한 if (speedx < this.maxWalkSpeed) { this.rigid.AddForce(transform.right * key * this.walkForce); } } }
k는 왼쪽과 오른쪽 방향을 결정하는 역할
speedx는 rigid이 어느쪽으로 향하던 그 속도의 절댓값을 저장할 변수
만약 speedx가 속도최댓값을 넘지 않는다면 AddForce로 힘을 줘 이동한다
그렇기에 버튼을 누르기만 해도 속도가 일정하고 부드럽게 쭉 나갈수 있는것이다
이제 방향에 따라 이미지가 반전되는 효과를 넣어보자
// 움직이는 방향에 맞춰 이미지 반전 if (key != 0) { transform.localScale = new Vector3(key, 1, 1); }
Update 메서드 맨밑에 이것만 추가해주면 된다
<애니메이션>
1. Cat을 선택하고 Window - Animation - Animation을 만든뒤 Creat를 눌러 이름을 지정하고 저장
*무조건 Cat을 선택한뒤 만들어야 한다. 그래야 Cat에 컴포넌트가 추가됨
2. Add Property 누른뒤 Sprite Renderer - Sprite 클릭
3. 오브젝트에서 프레임별 움직임을 끌어와 알맞게 배치한다
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { Rigidbody2D rigid; // 추가 Animator animator; float jumpForce = 680.0f; float walkForce = 30.0f; float maxWalkSpeed = 2.0f; void Start() { // 애니메이터 컴포넌트 추가 this.animator = GetComponent<Animator>(); this.rigid = GetComponent<Rigidbody2D>(); } void Update() { // 점프한다 if (Input.GetKeyDown(KeyCode.Space)) { this.rigid.AddForce(transform.up * this.jumpForce); } // 좌우 이동 int key = 0; if (Input.GetKey(KeyCode.RightArrow)) key = 1; if (Input.GetKey(KeyCode.LeftArrow)) key = -1; // 플레이어 속도 float speedx = Mathf.Abs(this.rigid.velocity.x); // 스피드 제한 if (speedx < this.maxWalkSpeed) { this.rigid.AddForce(transform.right * key * this.walkForce); } // 움직이는 방향에 맞춰 이미지 반전 if (key != 0) { transform.localScale = new Vector3(key, 1, 1); } //애니메이션 재생 속도 조절 this.animator.speed = speedx / 2; } }
4. Catcontrol에 애니메이터 컴포넌트를 추가한뒤 재생속도를 조절해준다
*Animation이 아니라 Animator이다. 헷갈리지 않게 조심
5. 애니메이터 컴포넌트가 잘 들어갔는지 확인한뒤에 실행하여 애니메이션이 정상작동하는것을 확인
<물리엔진을 이용한 충돌판정>
그동안은 Vector를 이용해 충돌판정을 해왔다면 지금부터는 물리엔진을 이용해보겠다
모드는 2개, 상태는 3개가 있다
상태 | Collision모드 | Trigger 모드
충돌한 순간 | OnCollisionEnter2D | OnTriggerEnter2D
충돌 중 | OnCollisionStay2D | OnTriggerStay2D
충돌이 끝난 순간 | OnCollisionExit2D | OnTriggerExit2D
이번에는 고양이가 깃발에 충돌하는 순간 충돌판정을 만들 예정이고 단계는 크게 2단계로
1. 깃발에 Collision2D 컴포넌트를 적용한뒤 Trigger모드(통과모드)로 설정
2. 플레이어와 깃발이 닿았을때 호출되는 OnTriggerEnter2D 메서드를 Playcontrol으로 구현한다
우선 깃발에 Box Collider 적용한뒤 IsTrigger에 체크를 해준다
void OnTriggerEnter(Collider2D other) { Debug.Log("골"); }
Update 메서드 밑에 OnTriggerEnter2D 메서드를 구현한다
이 메서드의 매개변수는 충돌 상태의 오브젝트에 적용한 Coillider가 전달된다
충돌 즉시 콘솔창에 골이 뜨는것을 확인
<씬변환>
씬 하나 더 만들고 Cloud - ClearScene으로 이름 붙여줌
그리고 여기엔 클리어씬으로 쓰일 이미지를 넣어준다
지금 왜 그런지는 모르겠는데 스위치 플랫폼이 안되서 우선 임의로 넣어준 상태이다
이제 두가지만 더 해주면 끝난다
1. 클리어 씬에서 클릭하면 다시 게임씬으로 전환하기
2. 게임씬에서 깃발과 충돌하는 순간 클리어씬으로 전환하기
<1. 클리어 씬에서 클릭하면 다시 게임씬으로 전환하기>
우선 클리어씬에서 ClearDirector라는 빈 오브젝트를 만든뒤 같은 이름의 스크립트를 제작하여 넣어준다
using System.Collections; using System.Collections.Generic; using UnityEngine; // 씬 변환을 위해서 필요 using UnityEngine.SceneManagement; public class ClearDirector : MonoBehaviour { void Update() { if(Input.GetMouseButton(0)) { SceneManager.LoadScene("CloudScene"); } } }
맨 위의 using 한줄 더 써주는것 잊지 않는다
LoadScene : 매개변수로 받은 씬 이름의 씬을 로드하는 메서드
하지만 이 상태로 스크립트를 적용해도 클릭을 하는 순간 오류가 발생한다. 바로 씬 등록을 하지 않았기 때문
Scene In Build에 CloudScene과 Cloud - ClearScene을 가져온다
Sample씬은 안쓸거니까 체크 해제한뒤 두 씬의 순서를 조정한다
클릭시 게임화면으로 돌아오는것을 확인
이번엔 게임씬에서 깃발과 충돌했을시 클리어씬으로 넘어갈 차례다
void OnTriggerEnter2D (Collider2D other) { Debug.Log("골"); SceneManager.LoadScene("Cloud - ClearScene"); }
이것도 간단하다. 아까처럼 맨 위에 using 한줄 추가해주고
playercontrol 충돌판정 메서드에 똑같이 씬 변경하는 한줄 추가해주면 끝
이제 깃발에 부딫히는 순간 클리어씬으로 넘어가는것까지 확인할수 있다
이번 주말안에 3D까지 나고 받은 과제까지 완료하는게 목표였는데 주말내내 알바하면서 이것까지 하기가 쉽지가 않다ㅠ
최대한 빨리 나머지 진도 하는걸로..
'유니티 > 유니티 메인' 카테고리의 다른 글
레벨 디자인, Debug.DrawRay, RayCast, RayCastHit (0) 2024.02.07 3D(Terrian, 파티클, Ray 클래스) (1) 2024.02.05 프리팹, 충돌판정 (2) 2024.02.04 Vector와 transform 응용, UI 표시, 효과음 삽입 (0) 2024.02.03 Vector2 클래스, transform, GetMouseButtonDown (0) 2024.02.03