ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 유니런 제작(1)
    실습/유니런 2024. 3. 6. 02:35

    땅으로 쓸 Ground 와 사망판정을 내릴 Deadzone에 각각 box Collider 컴포넌트를 넣고 만들어준다

    Deadzone 같은 경우 충돌판정도 있어야하니 IsTrigger에 체크해준다

    Deadzone 같은 경우 후에 있을 사망판정을 위해 Dead라는 태그를 따로 만들어 지정해준다

    1. Player를 배치한뒤 충돌판정, 중력적용을 위해 Circle Collider와 Rigidbody2D를 붙인다

     

    2. Conllision Detection을 Discrete에서 Continuous로 변경해준다

    Discrete : 충돌감지를 일정시간 간격으로 끊어서 실행

    Continuous : 움직이기 이전 위치와 움직인 다음 위치 사이에서 예상되는 충돌까지 함께 감지

    *상대적으로 Continuous가 더 정확하지만 성능을 더 요구

     

    3. 충돌이나 이동에따라 자연스럽게 Z축으로 휘어지는것을 방지하기 위해 Freeze Rotation에서 Z축을 고정시켜준다

     

    Audio Source도 추가해 점프할때 날 jump 사운드를 넣어준다

    그리고 게임 시작하자마자 점프소리를 재생할일은 없으니 Play On Awake는 해제한다

     

    Player를 선택한뒤 Window - Animation - Animation 을 선택.

    만약 Animation창에서 Create가 뜨지 않는다면 오브젝트를 선택하지 않고 들어갔을 확률이 크다

     

    Creat를 누르고 Animation 이름을 정하고 새폴더를 만들어 저장해준뒤 미리 잘라둔 이미지를 전부 드래그하여 넣어준다

     

    Multiple sprite

    아직 잘리지 않고 한 이미지에 이어져있는 이미지를 프레임에 따라 하나씩 일정하게 잘라주자 1. 우선 이미지를 선택후 Sprite Mode에서 Multiple로 선택해준다 그리고 밑에 있는 Sprite Editor를 눌러 Spr

    sangeun00.tistory.com

    *Run 이미지는 Multiple sprite로 일정하게 잘라주었다

     

    좀 더 고르게 퍼뜨리기 위해 Samples를 16으로 조절해준다

     

    만약 Samples가 보이지 않는다면 우측상단에서 Show Sample Rate를 클릭하여 보이게한다

    다른 애니메이션은 Create New Clip에서 바로 추가가 가능하다. 같은 방식으로 Run과 Jump도 만들어주자

    여기서 주의할건 Die 애니메이션은 Run이나 Jump와는 달리 딱 한번만 재생하고 멈출 예외의 상황이기에

    Loop Time을 체크해제한다

     

    이번엔 상황에 따른 애니메이션을 각각 다르게 설정해주도록 하기 위해 Player의 Animator를 열어준다

    Animator 창

    Animator 창을 여는 방법은 크게 두가지다. Player를 선택한뒤 Window에서 직접 열거나,

    아니면 따로 만든 Animation 관련 폴더에 들어가던가

     

    이번엔 애니메이션 간의 전이를 구성한다

    잇고 싶은곳에서 마우스 우클릭 후 Make Transition을 클릭한뒤 이어주기만 하면된다

     

    달리다가 점프를 할수 있고, 점프하다가도 달릴수 있기에 둘은 서로 이어질 수 있고,

    캐릭터가 죽는 순간 현재 상태가 무엇이든 상관없이 현재상태가 Die가 될수 있기에  Any State와 Die는 이어질 수 있다

     

    이번엔 파라미터. 조금 더 쉽게 풀어 설명하자면 애니메이션이 다른 애니메이션으로 넘어갈수 있는 조건을 설정해주자

    파라미터를 어디서 추가하는지 못찾고 헷갈린적이 많은데 파라미터는 Animator창에서 추가할 수 있다

    +를 눌러 타입을 정하고 이름을 지을 수 있다

    Player가 땅에 닿았냐, 안닿았냐를 결정할 bool 형식의 "Grounded"

    Player가 죽은 상태인지, 죽지 않은 상태인지를 결정할 Trigger 형식의 "Die"를 만들어주었다

     

    이제 파라미터도 만들어주었으니 전이설정을 해주자

    Run의 애니메이션에서 Jump의 애니메이션으로 갈때의 전이설정이다 

     

    1. 가장 먼저 Has Exit Time의 체크박스를 해제해주었다

     

    Has Exit Time : 종료 시점을 활성화하는 옵션.

    즉 이것이 활성화되면 종료 시점이 존재하게 되어 전이의 조건을 만족해도 다음 상태로 전이하지 않는다

    -은근히 많이 헷갈리고 신경을 안쓰는 부분이라고 한다

     

    2. Transition Duration을 0으로 설정

     

    Run 애니메이션으로 달리다가 점프를 하는순간 곧바로 Jump 애니메이션이 나오게 할 예정이니 

    그 밑에 보이는 그림으로 나오도록 변경해준다

     

    3. Conditions에 +를 눌러 추가를 해준뒤 Grounded - false로 설정해준다

     

    쉽게 말해 땅(Grounded)에 닿은 상태가 아니라면(false) 공중에 있는것이니 Jump 애니메이션으로 변경한다의 의미

     

    Jump => Run으로 돌아가는것도 마찬가지이다. 차이점이라면 Grounded - True일뿐

     

    Die 파라미터 같은 경우에는 Trigger 타입으로 추가했기에 Conditions에 Die만 들어가게 된다

    이는 Trigger 타입의 파라미터를 조건으로 사용한다면 수치를 검사하는것이 아닌

    Trigger의 '발동'을 감지하는 방식으로 전이가 실행되기 때문이다.

     

    이제 애니메이션 설정까지 모두 마쳤으니 Player를 움직이는 스크립트를 작성해보자

    <1. 기본준비단계 & 컴포넌트 가져오기>

    using UnityEngine;
    
    public class PlayerController : MonoBehaviour {
       public AudioClip deathClip;
       public float jumpForce = 700f;
    
       private int jumpCount = 0; 
        private bool isGrounded = false; 
       private bool isDead = false;
    
       private Rigidbody2D playerRigidbody; 
       private Animator animator; 
       private AudioSource playerAudio; 
    
       private void Start() {
            animator = GetComponent<Animator>();
            playerAudio = GetComponent<AudioSource>();
            playerRigidbody = GetComponent<Rigidbody2D>();
       }

    우선 사망시 나올 효과음 deathClip, 후에 스크립트에서 클릭하면 점프하게 만들텐데 그때 점프힘, 

    두번까지의 점프만 가능하게 만들예정이니 누적점프횟수,

    그리고 애니메이션을 바꿔줄 파라미터로 쓰일 isGrounded 와 isDead를 선언해준다

    이외에는 컴포넌트 사용을 위해 필요한것들이다. Player에 붙은 컴포넌트들을 보고 

    핵심적으로 필요한 Animator, Audio Source, Rigidbody2D를 불러온다

     

    <2. Player 점프시키기> 

       private void Update() {
          if(isDead) return;
          if(Input.GetMouseButtonDown(0) && jumpCount < 2)
            {
                jumpCount++;
                playerRigidbody.velocity = Vector2.zero;
                playerRigidbody.AddForce(new Vector2(0,jumpForce));
                playerAudio.Play();
            }
          else if(Input.GetMouseButtonUp(0) && playerRigidbody.velocity.y > 0)
            {
                playerRigidbody.velocity = playerRigidbody.velocity * 0.5f;
            }
            animator.SetBool("Grounded", isGrounded);
       }

     

          if(isDead) return;

    우선 가장 먼저 Trigger 타입인 isDead는 True처리 되자마자 곧바로 return으로 더이상 진행하지 않고 종료된다

     

     if(Input.GetMouseButtonDown(0) && jumpCount < 2)

    마우스 우측버튼을 누르고 누적점프횟수가 2번을 넘어가지 않을때, 즉 점프를 한번이라 하는순간 실행
            {
                jumpCount++;

                3번 점프를 방지하기 위해 점프횟수에 1을 더한다
                playerRigidbody.velocity = Vector2.zero;

                여기서 Player의 속도를 전부 Vector2(0,0)으로 초기화시켜버린다

                만약 점프를 연속두번 빠르게 눌렀을시 y축으로 힘이 가속되어 빠르게 나가버리는것을 방지하기 위함
                playerRigidbody.AddForce(new Vector2(0,jumpForce));

                점프하는 코드. 오로지 점프만 하면되니 x축으로는 0, y축으로는 jumpForce만큼 힘을준다
                playerAudio.Play();

                점프와 동시에 jump 효과음 재생

       

             else if(Input.GetMouseButtonUp(0) && playerRigidbody.velocity.y > 0)

            마우스 우측버튼을 떼고 Player의 y축 방향속도가 0보다 클때, 즉 점프를 한 상태라 공중에 있을때
                 {
                        playerRigidbody.velocity = playerRigidbody.velocity * 0.5f;

                        쉽게 말해 클릭을 오래하면 높이뛰고, 짧게 클릭하면 낮게 뛰는것을 구현하기 위한것

                        클릭을 떼는순간 속도를 절반으로 줄여준다
                 }
                 animator.SetBool("Grounded", isGrounded);

                 애니메이터의 컴포넌트를 나타내는 Animator 타입은 애니메이터의 파라미터값을 변경할수 있는

                Set 계열의 메서드를 제공한다. (SetBool, SetInt, SetFloat) 이것으로 애니메이션을 변경하는것
            }

     

    <3. 충돌판정>

    private void OnTriggerEnter2D(Collider2D other) {
           // 트리거 콜라이더를 가진 장애물과의 충돌을 감지
           // Player와 Trigger 타입인 Deadzone이 충돌
           if(other.tag == "Dead" && !isDead)
            {
                Die();
            }
       }
    
       private void OnCollisionEnter2D(Collision2D collision) {
            // 바닥에 닿았음을 감지하는 처리
            // Player와 바닥 Ground가 충돌
            if (collision.contacts[0].normal.y > 0.7f)
            {
                isGrounded = true;
                jumpCount = 0;
            }
       }
    
       private void OnCollisionExit2D(Collision2D collision) {
           // Player가 바닥에서 벗어났음을 감지하는 처리
           isGrounded = false;
       }

     

     private void OnTriggerEnter2D(Collider2D other) {
          Deadzone이 Trigger 타입이므로 OnTriggerEnter2D 사용
           if(other.tag == "Dead" && !isDead)

          충돌한 오브젝트의 태그가 "Dead" 이고 사망상태(isDead)가 아니라면(!isDead)
            {
                Die();

                Die() 메서드 실행
            }

     

     

    private void OnCollisionEnter2D(Collision2D collision) {

           Player가 벽이나 천장에 부딫혀도 OnCollisionEnter2D로 인정받아 점프횟수가 초기화되거나

           isGrounded가 True로 인정받는것을 방지하기위한 조건문      

               if (collision.contacts[0].normal.y > 0.7f)

              1. OnCollision 계열의 collision에는 각종 충돌정보들을 담고 있다. 

              2. 그리고 그 충돌정보는 contacts라는 배열변수로 제공한다 => "배열의 길이 = 충돌지점의 개수"

              2-1. contacts[0] = 첫번째 충돌 지점의 정보.

              3. 그리고 충돌지점에서 충돌표면의 방향(노말벡터)을 알려주는 변수가 normal

              4. normal.y값이 1.0일 경우 방향은 위쪽, 0은 아래, 0.7은 대충 45도 보다 위

              5. 즉 Player와 충돌한 바닥이 최소 45도 이상은 되야 충돌판정으로 인정해주겠다는 뜻

            {
                isGrounded = true;
                jumpCount = 0;

               땅바닥에 닿는순간 점프횟수 초기화, isGrounded는 true가 되어 Run 애니메이션으로 돌아온다
            }
       }

     

    private void OnCollisionExit2D(Collision2D collision) {
           isGrounded = false;

          바닥에서 벗어나는 순간 isGrounded는 false가 되어 Jump 애니메이션으로 전환
       }

     

    <4. 사망판정>

       private void Die() {
            animator.SetTrigger("Die");
            playerAudio.clip = deathClip;
            playerAudio.Play();
            playerRigidbody.velocity = Vector2.zero;
            isDead = true;
       }

    private void Die() {
            animator.SetTrigger("Die");

            가장 먼저 애니메이션은 Die로 재생
            playerAudio.clip = deathClip;
            playerAudio.Play();

            오디오클립 deathClip으로 갈아끼워준뒤 재생
            playerRigidbody.velocity = Vector2.zero;

            사망 즉시 모든 이동 멈추기
            isDead = true;

       }

     

    '실습 > 유니런' 카테고리의 다른 글

    유니런 제작(2)  (2) 2024.03.06
Designed by Tistory.