새소식

🎮 Game Dev (게임개발)/PC (데스크탑, 노트북, 터치패널)

[3D 액션게임] 02.점프와 회피

  • -

🔔 유튜브 크리에이터 골든메탈님의 유니티강의 3D 쿼터뷰 액션게임 [BE5] 를 보고 공부하여 작성한 게시글입니다! 🔔

 

🧷 01.  코드 리팩토링

-  코드를 더 편리하게 만들어봅시다

    void Update()
    {
        GetInput();
        Move();
        Turn();

    }

    void GetInput()
    {
        // 키보드입력에 따라 0 ~ 1로 변환 left right up down
        hAxis = Input.GetAxisRaw("Horizontal");
        vAxis = Input.GetAxisRaw("Vertical");
        rDown = Input.GetButton("Run");
    }

    void Move()
    {
        // x y z
        moveVec = new Vector3(hAxis, 0, vAxis).normalized;

        // transform
        transform.position += moveVec * (rDown ? 1.3f : 1f) * speed * Time.deltaTime;

        // animator
        anim.SetBool("isWalk", moveVec != Vector3.zero);
        anim.SetBool("isRun", rDown);
    }

    void Turn()
    {
        // Rotation
        transform.LookAt(transform.position + moveVec);
    }
}
  • 기존의 코드들을 GetInput() , Move(), Turn() 함수로 정리하여 보기 쉽게 만들어 Update()에 넣어주었습니다.

 

🧷 02.  점프 및 회피 애니메이션

-  점프와 회피 모션 Animator 추가

  • 어떤 상황에서도 점프(Jump)와 회피(Dodge) 기능 애니메이션 모션으로 들어갈 수 있게 하였습니다.

 

  • 또한 점프 회피는 신호가 들어오면 모션을 실행하는 trigger로 parameter을 만들었고, 점프상황을 알리는 bool변수로 isJump를 추가하였습니다

 

  • 각 트랜지션 관계로는 아래와 같이 설정하였습니다.
  • doJump : Any State -> Jump
  • doDodge : Any State -> Dodge
  • isJump(false) : Jump -> Land
  • Has Exit Time(활성화시 해당 모션이 끝날때 까지 어떤 모션도 하지 않는다) : Land, Dodge -> Exit

 

 

 

🧷 03.  점프 및 회피 스크립트

-  플레이어 스크립트에 점프, 회피 기능 추가

 

코드 전체보기

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    public float speed;
    float hAxis;
    float vAxis;
    bool rDown;
    bool jDown;

    bool isJump;
    bool isDodge;

    Vector3 moveVec;
    Vector3 dodgeVec;
    Rigidbody rigid;

    Animator anim;

    void Awake()
    {
        rigid = GetComponent<Rigidbody>();
        anim = GetComponentInChildren<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        GetInput();
        Move();
        Turn();
        Jump();
        Dodge();
    }


    void GetInput()
    {
        // 키보드입력에 따라 0 ~ 1로 변환 left right up down
        hAxis = Input.GetAxisRaw("Horizontal");
        vAxis = Input.GetAxisRaw("Vertical");
        rDown = Input.GetButton("Run");
        jDown = Input.GetButtonDown("Jump");
    }

    void Move()
    {
        // x y z
        moveVec = new Vector3(hAxis, 0, vAxis).normalized;

        // 회피 시 업데이트 안되게
        if (isDodge)
            moveVec = dodgeVec;
      

        // transform
        transform.position += moveVec * (rDown ? 1.3f : 1f) * speed * Time.deltaTime;

        // animator
        anim.SetBool("isWalk", moveVec != Vector3.zero);
        anim.SetBool("isRun", rDown);
    }

    void Turn()
    {
        // Rotation
        transform.LookAt(transform.position + moveVec);
    }

    void Jump()
    {
        if(jDown && moveVec == Vector3.zero && !isJump && !isDodge) {
            // 물리엔진에 힘을 준다. 여기선 즉발적인 Impulse
            rigid.AddForce(Vector3.up * 15, ForceMode.Impulse);
            anim.SetBool("isJump", true);
            anim.SetTrigger("doJump");

            isJump = true;
        }
    }

    void Dodge()
    {
        // 이동하면서 점프할때, 
        if (jDown && moveVec != Vector3.zero && !isJump && !isDodge)
        {
            dodgeVec = moveVec;
            speed *= 2;
            anim.SetTrigger("doDodge");
            isDodge = true;

            Invoke("DodgeOut", 0.5f); // 시간지연 라이브러리 기능
        }
    }

    void DodgeOut()
    {
        speed *= 0.5f;
        isDodge = false;
    }



        // 충돌 시 이벤트 함수로 착지 구현
        void OnCollisionEnter(Collision collision)
    {
        if(collision.gameObject.tag == "Floor"){
            isJump = false;
            anim.SetBool("isJump", false);
        }
    }
}

 

-  점프 기능

    void Jump()
    {
        if(jDown && moveVec == Vector3.zero && !isJump && !isDodge) {
            // 물리엔진에 힘을 준다. 여기선 즉발적인 Impulse
            rigid.AddForce(Vector3.up * 15, ForceMode.Impulse);
            anim.SetBool("isJump", true);
            anim.SetTrigger("doJump");

            isJump = true;
        }
    }
  • jDown : 점프 키보드 입력값을 받는 변수 (누르는 상태가 아닌 한 번 누른 상황이기에 Input.GetButtonDown("Jump") 으로 입력받습니다 ) 
  • Jump() : 점프키를 누를때 , 움직이지 않고 가만히 있을때, 그리고 현재 점프, 회피 상황이 아닐때만 rigid에 힘을 가해줍니다. (Impulse : 즉발적으로) 
  • 애니메이션 prameter도 설정해줍니다.

 

-  점프 착지 시 

        void OnCollisionEnter(Collision collision)
    {
        if(collision.gameObject.tag == "Floor"){
            isJump = false;
            anim.SetBool("isJump", false);
        }
    }

 

새로 생성한 Floor 태그

 

 

  • OnCollisionEnter 이벤트 함수를 만들어 플레이어가 tag에 닿을때 마다 실행 하게 해줍니다.

 

 

-  회피 기능

    void Dodge()
    {
        // 이동하면서 점프할때, 
        if (jDown && moveVec != Vector3.zero && !isJump && !isDodge)
        {
            dodgeVec = moveVec;
            speed *= 2;
            anim.SetTrigger("doDodge");
            isDodge = true;

            Invoke("DodgeOut", 0.5f); // 시간지연 라이브러리 기능
        }
    }
    
    
    void DodgeOut()
    {
        speed *= 0.5f;
        isDodge = false;
    }
  • 점프키 누를때, 이동하는 경우, 또한 점프와 회피를 연속해서 사용하지 못하는 조건입니다.
  • 또한 함수 시간지연 효과가 있는 Invoke() 함수를 두어 Dodge 발동시간을 0.5초로 두었습니다.

 

-  회피 방향 고정기능

    void Move()
    {
        // x y z
        moveVec = new Vector3(hAxis, 0, vAxis).normalized;

        // 회피 시 업데이트 안되게
        if (isDodge)
            moveVec = dodgeVec;
      

        // transform
        transform.position += moveVec * (rDown ? 1.3f : 1f) * speed * Time.deltaTime;

        // animator
        anim.SetBool("isWalk", moveVec != Vector3.zero);
        anim.SetBool("isRun", rDown);
    }

 

  • 로운 벡터를 만들어 회피 상태시 방향이 고정되게 dodgeVec로 대체했습니다.

 

🧷 04.  중력설정

-  중력강화

Edit - Project Settings - Physics 에 Gravity를 높혀 점프 시 더 낮게 뛰도록 만들어줍시다.

 

 

 

 

 

 

 

 

 

출처: 골든메탈님 유튜브

https://www.youtube.com/watch?v=eZ8Dm809j4c&list=PLO-mt5Iu5TeYkrBzWKuTCl6IUm_bA6BKy&index=2 

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.