본문 바로가기
Unity Portfolio/ZombieShooter

2. Player 움직임 보정하기, 맵 구상, Camera 벽 충돌 보정, Volume, Skybox 추가

by 첨부엉. 2024. 7. 10.
반응형

PlayerCtrl.cs 수정

더보기
#pragma warning disable IDE0051

using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerCtrl : MonoBehaviour
{
    // Component
    private Animator anim;
    private new Transform transform;
    private Camera cam;

    private Plane plane;
    private Ray ray;

    private Vector3 moveDir;
    private Vector3 hitPoint;
    private float tmpSprint;
    private float isSprint; // 1 : true , 0 : false

    public float moveSpeed = 2.0f;
    public float turnSpeed = 2.0f;
    
    

    private void Start()
    {
        anim = GetComponent<Animator>();
        transform = GetComponent<Transform>();
        cam = Camera.main;


        plane = new Plane(transform.up, transform.position);
    }

    private void Update()
    {
        if (moveDir != Vector3.zero)
            transform.Translate(Vector3.forward * Time.deltaTime * moveSpeed);
        SprintLerp();
        Turn();
    }
    /// <summary>
    /// 커서 위치에 따른 회전
    /// </summary>
    void Turn()
    {
        // 마우스의 2차원 좌푯값을 이용해 3차원 광선을 생성
        ray = cam.ScreenPointToRay(Input.mousePosition);

        float enter = 0.0f;

        // 가상의 바닥에 레이를 발사해 충돌한 지점의 거리를 enter 변수로 반환
        plane.Raycast(ray, out enter);
        // 가상의 바닥에 레이가 충돌한 좌푯값 추출
        hitPoint = ray.GetPoint(enter);

        // 회전해야 할 방향의 벡터를 계산
        Vector3 lookDir = hitPoint - transform.position;
        lookDir.y = 0;
        // 주인공 캐릭터의 회전값 지정
        transform.localRotation = Quaternion.Slerp(transform.localRotation, Quaternion.LookRotation(lookDir), Time.deltaTime * turnSpeed);
    }
    /// <summary>
    /// 자연스러운 sprint 사용을 위한 보간
    /// </summary>
    void SprintLerp()
    {
        tmpSprint = Mathf.Lerp(tmpSprint, isSprint, Time.deltaTime * 10);
        anim.SetFloat("Sprint", tmpSprint);
    }

    #region UNITY_EVENTS
    public void OnMove(InputAction.CallbackContext ctx)
    {
        Vector2 dir = ctx.ReadValue<Vector2>();
        
        // 2차원 좌표를 3차원 좌표로 변환
        moveDir = new Vector3(dir.x, 0, dir.y);

        anim.SetFloat("Horizontal", moveDir.x);
        anim.SetFloat("Vertical", moveDir.z);

    }
    public void OnFire(InputAction.CallbackContext ctx)
    {
        if (ctx.performed)
        {
            anim.SetTrigger("Attack");
        }
    }
    public void OnSprint(InputAction.CallbackContext ctx)
    {
        if(ctx.performed)
            isSprint = 1;
        else
            isSprint = 0;
    }
    #endregion
}

회전속도와 이동속도가 느린거 같아서 원래는 애니메이션에 포함되어 있는 이동모션만 사용했는데

코드로도 추가해주었다.

 

Player 오브젝트를 프리팹으로 만들고 Character Controller 컴포넌트도 추가하였다.

 

맵 구상

원하는 맵이 없어서 직접 제작하고

맵에 포함되어 있는 오브젝트는 모두 Environment 하위에 넣어준다.

Environment 부터 하위의 모든 오브젝트들은 Navigation Static 플래그를 체크한다.

Window - AI - Navigation - Bake 탭에 들어가서 Bake 해주기

 

맵의 이곳 저곳을 돌아보며 못가는 곳이 있는지 확인하고 조절하기

가끔 계단이나 벽을 뚫고 지나가는 경우가 있는데 보통 Mesh Collider컴포넌트가 붙어있지 않아서 그럼

Camera 벽 충돌 보정

Cinemachine을 사용하다보면 벽이 좁은 곳이나 천장이 낮은 곳은 보통 카메라가 벽을 뚫거나 충돌로 어지러운 경우가 있는데 

이는 보통 Camera Collider 를 씌어주지 않았기 때문이다

 

여기서 가장 중요한 속성은 Ignore Tag인데 아까 위에 있는 사진에서

하이러키 뷰의 Environment와 하위 오브젝트들에게 모두 태그를 생성해서 달아주고 Cinemachine Collider의 Ignore Tag에 달아주어야 한다. 

저렇게 설정하지 않으면 아무리 Cinemachine Collider 를 생성해도 벽뚫는 모습을 확인 할 수 있기 때문에 꼭꼭 설정해주기

 

Smoothing Time, Damping 도 적절히 설정해서 부드럽게 이동할 수 있게 하기

 

Volume

URP 프로젝트이기에 Post Processing 이 내장되어 있는데 하이러키뷰에 .Global Volume 을 생성하고 아래와 같이 적절히 설정해준다.

 

Shadows MidtonesHighlights, ToneMapping, Vignette, White Balance 를 Add Override 로 추가하였다.

 

 

Skybox 추가 에셋 임포트

Simple Sky - Cartoon assets | 3D Environments | Unity Asset Store

 

Simple Sky - Cartoon assets | 3D 주변환경 | Unity Asset Store

Elevate your workflow with the Simple Sky - Cartoon assets asset from Synty Studios. Find this & other 주변환경 options on the Unity Asset Store.

assetstore.unity.com

 

이 에셋을 임포트 하고 SimpleSky - Prefabs - SkyDome을 하이러키뷰에 드래그하고 Material 의 Offset 값을 조정하면 적절한 하늘로 변경할 수 있음

반응형