본문 바로가기
공부/Unity 기초

3D FPS - 13 / 사다리 이동

by svcbn 2022. 5. 24.

 

 

cube로 길쭉하고 납작한 형태로 만들어주고 Box Collider의 Trigger를 켜준다.

 

 

 

 

Ladder에서는 부딪힌 대상을 판별하여 PlayerMove에서 상태를 전환하도록 설정

사다리를 탈출하면 정상적인 이동으로 전환하기 위해 높이를 설정한다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Ladder : MonoBehaviour
{
    public float exitHeight = 2;
    
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    private void OnTriggerEnter(Collider other)
    {
        // 부딪힌 대상이 플레이어인지 확인한다.
        PlayerMove player = other.GetComponent<PlayerMove>();

        // 만일 플레이어가 맞다면
        if(player)
        {
            // 플레이어의 상태를 클라이밍 상태로 전환한다.
            player.moveState = PlayerMove.MoveState.Climb;

            // 플레이어가 사다리의 종점에 도달했는지를 확인하기 위한 종점의 높이 값을 전달한다.
            player.exHeight = exitHeight;

        }

    }

}

 

 

 

 

 

 

 

PlayerMove에서 Climb와 Normal상태를 구분하기 위해 Enum생성

public enum MoveState
    {
        Normal,
        Climb,
        ClimbEnd
    }
    public MoveState moveState;

 

 

 

 

기존의 움직이는 방식은 Normal로 처리하고, Climb상태일 때 상하이동으로 전환

else if(moveState == MoveState.Climb)
        {
            // 만일 플레이어의 높이가 사다리의 종점에 닿지 않았다면
            if (transform.position.y < exHeight)
            {

                // 사용자의 상하 입력 키를 받아서 
                float v = Input.GetAxis("Vertical");

                // 상하 입력이 상하 이동 방향으로 될 수 있도록 벡터를 만든다.
                dir = new Vector3(0, v, 0);
            }
            
            // 그렇지 않다면 사다리의 앞쪽으로 이동하는 기능을 실행한다.
            else
            {
                // 플레이어의 이동 상태를 클라이밍 종료 상태로 전환한다.
                moveState = MoveState.ClimbEnd;

                // 플레이어를 앞으로 이동시키는 코루틴 함수를 실행한다.
                StartCoroutine("ClimbEndWalk");
            }
        }

 

 

 

 

 

 

끝부분에 도달했을 때 자동으로 사다리에서 벗어나며 Normal상태로 전환하는 코루틴 생성

// 플레이어를 자동으로 앞으로 이동시키는 함수
    IEnumerator ClimbEndWalk()
    {
        // 앞으로 이동하기 위한 시작 지점과 종료 지점을 설정한다.
        Vector3 startPos = transform.position;
        Vector3 endPos = transform.position + transform.forward * 1;
        float currentTime = 0;

        // 1초 동안에 startPos에서 endPos까지 이동시킨다.
        while(true)
        {
            if(currentTime < 1)
            {
                currentTime += Time.deltaTime;

                transform.position = Vector3.Lerp(startPos, endPos, currentTime);

                // 이동을 했으면 다음 프레임으로 넘긴다.
                yield return null;
            }

            else
            {
                // 플레이어의 이동 상태를 Normal 상태로 전환한다.
                moveState = MoveState.Normal;

                // 코루틴을 종료한다.
                yield break;
            }
        }
    }

 

 

 

 

 

PlayerMove 전문

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


// 사용자의 입력에 따라 앞뒤좌우로 이동하고싶다.
// 점프를 뛰고싶다.  중력, 뛰는힘, y속도
public class PlayerMove : MonoBehaviour
{
    public enum MoveState
    {
        Normal,
        Climb,
        ClimbEnd
    }
    public MoveState moveState;
    
    // 크기
    public float speed = 5;
    public float gravity = -9.81f;
    public float jumpPower = 10;
    public float exHeight = 0;
    
    float yVelocity;

    CharacterController cc;

    // Start is called before the first frame update
    void Start()
    {
        cc = GetComponent<CharacterController>();
        moveState = MoveState.Normal;
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 dir = Vector3.zero;

        if (moveState == MoveState.Normal)
        {
            // y속도에 중력을 계속 더하고싶다.
            yVelocity += gravity * Time.deltaTime;

            // 만약 사용자가 점프버튼을 누르면 y속도에 뛰는힘을 대입하고싶다.
            if (Input.GetButtonDown("Jump"))
            {
                yVelocity = jumpPower;
            }

            // 사용자의 입력에 따라
            float h = Input.GetAxis("Horizontal");
            float v = Input.GetAxis("Vertical");

            // 앞뒤좌우로 방향을 만들고
            dir = Vector3.right * h + Vector3.forward * v;

            // 카메라가 바라보는 방향을 앞방향으로 하고싶다.
            dir = Camera.main.transform.TransformDirection(dir);

            // dir의 크기를 1로 만들고싶다.
            dir.Normalize();

            // y 속도를 최종 dir의 y에 대입하고싶다.
            dir.y = yVelocity;
        }

        else if(moveState == MoveState.Climb)
        {
            // 만일 플레이어의 높이가 사다리의 종점에 닿지 않았다면
            if (transform.position.y < exHeight)
            {

                // 사용자의 상하 입력 키를 받아서 
                float v = Input.GetAxis("Vertical");

                // 상하 입력이 상하 이동 방향으로 될 수 있도록 벡터를 만든다.
                dir = new Vector3(0, v, 0);
            }
            
            // 그렇지 않다면 사다리의 앞쪽으로 이동하는 기능을 실행한다.
            else
            {
                // 플레이어의 이동 상태를 클라이밍 종료 상태로 전환한다.
                moveState = MoveState.ClimbEnd;

                // 플레이어를 앞으로 이동시키는 코루틴 함수를 실행한다.
                StartCoroutine("ClimbEndWalk");
            }
        }


        // 그 방향으로 이동하고싶다.
        // P = P0 + vt
        cc.Move(dir * speed * Time.deltaTime);

    }

    // 플레이어를 자동으로 앞으로 이동시키는 함수
    IEnumerator ClimbEndWalk()
    {
        // 앞으로 이동하기 위한 시작 지점과 종료 지점을 설정한다.
        Vector3 startPos = transform.position;
        Vector3 endPos = transform.position + transform.forward * 1;
        float currentTime = 0;

        // 1초 동안에 startPos에서 endPos까지 이동시킨다.
        while(true)
        {
            if(currentTime < 1)
            {
                currentTime += Time.deltaTime;

                transform.position = Vector3.Lerp(startPos, endPos, currentTime);

                // 이동을 했으면 다음 프레임으로 넘긴다.
                yield return null;
            }

            else
            {
                // 플레이어의 이동 상태를 Normal 상태로 전환한다.
                moveState = MoveState.Normal;

                // 코루틴을 종료한다.
                yield break;
            }
        }
    }
}

 

'공부 > Unity 기초' 카테고리의 다른 글

3D FPS - 15 / 애니메이션 순환  (0) 2022.05.26
3D FPS - 14 / 애니메이션 상태 설계  (0) 2022.05.25
3D FPS - 12 / 모델링 적용  (0) 2022.05.23
3D FPS - 11 / 적 시야각  (0) 2022.05.23
3D FPS - 10 / 적 생성 유지  (0) 2022.05.21