[유니티] 플레이어 이동시키기 (INPUT/ GET.AXIS / PROPERTY)

NOAH·2021년 6월 1일
0

Unity

목록 보기
4/33
post-thumbnail

키보드에서 누른 값을 받아오자! Input

Update()
{
Input.method
}

유니티의 Input 클래스는 사용자 입력을 감지하는 메서드를 모아둔 집합이다.
Input.method()가 실행 시점에서 누른 키 값을 반환한다.

그런데 Update() 메서드는 1초에 수십번씩 실행 되기 때문에
Update()메서드 안에서 입력을 받으면

짧은 간격으로 반복 실행하기에 플레이어는 입력이 즉각 반영 된다고 느낀다.

수평축 수직축의 입력값을 감지한다. 어떻게 ? GetAxis()

float Input.GetAxis(string axisName) 

축에 대한 입력값을 숫자로 반환! 한다.
음의 방향 축에 대응 되는 버튼을 누르면 : -1.0
아무것도 누르지 않으면 : 0
양의 방향에 대응되는 버튼을 누르면 : +1.0

기본 설정으로 Horizontal축과 Vertical 축의 대응 입력키는
다음과 같다.

Horizontal : <- or A, 0 , -> or D
Vertical : W or ↑, 0 , S or ↓


void Update()
float xinput = Input.GetAxis("Horizontal");
float zinput = Input.GetAxis("Vertinal");

float xSpeed = xInput * speed;
float zSpeed = zInput * speed;

Vector3 newVelocity = new Vector(xSpeed, 0f, zSpeed);
playerRigidbody.velocity = newVelocity;
  • 속도를 나타내는 새로운 Vector3의 생성

x(좌우)축,z(전후)축을 조절할 것이므로
(GetAxis로 받는 값) * (속도) 를 새로운 새로운 벡터(newVelocity)에 할당

  • 리지드바디 컴포넌트의 속도변경

newVelocity를 플레이어 리지드바디의 속력에 할당한다.

컴포넌트 가져오기? GetCompnent()

원하는 타입의 컴포넌트를 자신의 게임 오브젝트에 찾아온다.
꺽쇠<> 안에는 가져올 타입의 컴포넌트를 할당한다.

void Start() {
	playerRigidbody = GetComponent<Rigidobody>();
}

의 뜻은 Player 게임 오브젝트에 리지드 바디 컴포넌트를 찾아서 player Rigidbody 변수에 할당한다는 의미이다.

변수처럼 생겼는데 메서드인 특수한 형태의 메서드, 프로퍼티(Property)

get     
* 이미 들어있는 값을 호출하면 자동적으로 get 호출  

set 

* 값을 변경할 때, 자동적으로 호출된다. 
* set 호출시 변경될 값에 대해서 내장된 조건에 따라서 방어적으로 값을 할당할 수 있다. 

실제적으로 해보자.

보통 입력을 감지하는 인풋 스크립트와 이동 스크립트를 2개로 나누어 짠다.

플레이어 인풋 스크립트에서 입력을 감지하고 다른 컴포넌트에 알려준다.

using UnityEngine;

// 플레이어 캐릭터를 조작하기 위한 사용자 입력을 감지
// 감지된 입력값을 다른 컴포넌트들이 사용할 수 있도록 제공
public class PlayerInput : MonoBehaviour {
    public string moveAxisName = "Vertical"; // 앞뒤 움직임을 위한 입력축 이름
    public string rotateAxisName = "Horizontal"; // 좌우 회전을 위한 입력축 이름
    public string fireButtonName = "Fire1"; // 발사를 위한 입력 버튼 이름
    public string reloadButtonName = "Reload"; // 재장전을 위한 입력 버튼 이름

    // 값 할당은 내부에서만 가능
    public float move { get; private set; } // 감지된 움직임 입력값
    public float rotate { get; private set; } // 감지된 회전 입력값
    public bool fire { get; private set; } // 감지된 발사 입력값
    public bool reload { get; private set; } // 감지된 재장전 입력값

    // 매프레임 사용자 입력을 감지
    private void Update() {
        // 게임오버 상태에서는 사용자 입력을 감지하지 않는다
        if (GameManager.instance != null && GameManager.instance.isGameover)
        {
            move = 0;
            rotate = 0;
            fire = false;
            reload = false;
            return;
        }

        // move에 관한 입력 감지
        move = Input.GetAxis(moveAxisName);
        // rotate에 관한 입력 감지
        rotate = Input.GetAxis(rotateAxisName);
        // fire에 관한 입력 감지
        fire = Input.GetButton(fireButtonName);
        // reload에 관한 입력 감지
        reload = Input.GetButtonDown(reloadButtonName);
    }
}

이제 이동 스크립트에서 변수를 가져와서 무브먼트 스크립트에 전달해서 만들어보자.


using UnityEngine;

// 플레이어 캐릭터를 사용자 입력에 따라 움직이는 스크립트
public class PlayerMovement : MonoBehaviour {
    public float moveSpeed = 5f; // 앞뒤 움직임의 속도
    public float rotateSpeed = 180f; // 좌우 회전 속도


    private PlayerInput playerInput; // 플레이어 입력을 알려주는 컴포넌트
    private Rigidbody playerRigidbody; // 플레이어 캐릭터의 리지드바디
    private Animator playerAnimator; // 플레이어 캐릭터의 애니메이터

    private void Start() {
        // 사용할 컴포넌트들의 참조를 가져오기
        playerInput = GetComponent<PlayerInput>();
        playerRigidbody = GetComponent<Rigidbody>();
        playerAnimator = GetComponent<Animator>();

    }

    // FixedUpdate는 물리 갱신 주기에 맞춰 실행됨
    private void FixedUpdate() {
        // 물리 갱신 주기마다 움직임, 회전, 애니메이션 처리 실행
        Rotate();
        Move();
        playerAnimator.SetFloat("Move", playerInput.move);
    }

    // 입력값에 따라 캐릭터를 앞뒤로 움직임
    private void Move() {

        Vector3 moveDistance = playerInput.move * transform.forward * moveSpeed * Time.deltaTime;

        playerRigidbody.MovePosition(playerRigidbody.position + moveDistance);


    }

    // 입력값에 따라 캐릭터를 좌우로 회전
    private void Rotate() {

        float turn = playerInput.rotate * rotateSpeed * Time.deltaTime;

        playerRigidbody.rotation = playerRigidbody.rotation * Quaternion.Euler(0, turn, 0f);


    }
}

0개의 댓글