새소식

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

[3D 액션게임] 08. 플레이어 물리엔진 고치기

  • -

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

🧷 1. 플레이어 자동 회전 방지

-  플레이어 스크립트 자동 회전 방지 추가

/* Player script, 추가된 부분을 작성하였습니다. */

public class Player : MonoBehaviour
{
	void FreezeRotation()
    {
        rigid.angularVelocity = Vector3.zero;  
    }

    void FixedUpdate()
    {
        FreezeRotation();
    }
}
  • rigid 의 회전력을 없애버려서 회전방지를 해줍니다.

 

-  오브젝트 Layer Collision Matrix 설정

  • 우선 오브젝트의 Layer 에 Player, PlayerBullet, BulletCase, Wall을 추가해줍니다.

 

 

  • 각 레이어 별로 설정해줍시다.

 

 

Edit - Project Setting - Physics - Layer Collision Matrix 의 설정을 해줍시다.

  • BulletCase는 Floor, BulletCase 빼고 다 제외시켜줍니다
  • PlayerBullet은 Player 제외시켜줍니다.

 

🧷 2. 벽 관통 방지

-  벽 쪽으로 이동하지 못하는 기능 추가

/* Player script, 추가된 부분을 작성하였습니다. */

public class Player : MonoBehaviour
{
    void StopToWall()
    {
        // DrawRay() : Scene내에 Ray를 보여주는 함수
        Debug.DrawRay(transform.position, transform.forward * 5, Color.green);
    }

    void FixedUpdate()
    {
        StopToWall();
    }
}

  • DrawRay() 함수를 이용해, 대략적인 레이의 크기를 가늠해 봅니다.

 

/* Player script, 추가된 부분을 작성하였습니다. */

public class Player : MonoBehaviour
{
    bool isBorder;

    void Move()
    {
        // transform + 벽뚫방지
        if (!isBorder)
            transform.position += moveVec * (rDown ? 1.3f : 1f) * speed * Time.deltaTime;
	}
    
    void StopToWall()
    {
        // DrawRay() : Scene내에 Ray를 보여주는 함수
        //Debug.DrawRay(transform.position, transform.forward * 5, Color.green);
        isBorder = Physics.Raycast(transform.position, transform.forward, 3, LayerMask.GetMask("Wall"));
    }

    void FixedUpdate()
    {
        StopToWall();    
    }
}
  • 그 다음 isBorder 변수를 만들어, 레이캐스트로 플레이어의 충돌 여부를 파악해줍니다.
  • 이후 Move의 움직임 기능에, 충돌하지 않을때만 움직 일 수 있도록 조건식을 써주었습니다.

 

 

🧷 3. 아이템 충돌 방지

-  플레이어가 아이템 충돌 시  아이템들 움직임 못하게 하기

/* Item script, 추가된 부분을 작성하였습니다. */

public class Item : MonoBehaviour
{
    Rigidbody rigid;
    SphereCollider sphereCollider;

    void Awake()
    {
        rigid = GetComponent<Rigidbody>();
        sphereCollider = GetComponent<SphereCollider>(); // 같은이름 첫번째 컴포넌트만 가져옴
    }

    private void OnCollisionEnter(Collision collision)
    {
        if(collision.gameObject.tag == "Floor"){
            rigid.isKinematic = true;
            sphereCollider.enabled = false;
        }
    }

}
  • 아이템 스크립트에 rigid와, collider를 접근하기위해 불러들여 왔습니다.
  • OnCollisionEnter 메서드를 이용해, 아이템이 바닥에 닿을때 isKinematic이 활성화되고, Collider이 비활성화 되도록 만들어 줍시다
  • 이때, 주의사항으로는 각 아이템마다 sphereCollider를 2개 넣어놨는데 유니티 컴포넌트상 가장 위에 있는 컴포넌트가 불어들여오기에 유니티에서 컴포넌트의 위치를 바꿔줘야합니다.

 

 

-  아이템 컴포넌트 위치 바꿔주기

  • 무조건 내가 만든 prefabs 상에서 진행하는데, 플레이어가 아이템을 먹기위한 콜라이더가 아닌, 물리효과의 범위를 위해서 만든 콜라이더를 위로 올려주었습니다.

 

이제는 벽도 뚫지 못하고 아이템을 밟고서 플레이어가 회전하지도 않으며, 아이템이 제 멋대로 움직이는 일도 없어졌습니다.!! 와우~!! 

 

 

출처: 골든메탈님 유튜브

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

 

Contents

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

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