flrto

Unity에서의 키입력으로 오브젝트를 이동시키는 방법 본문

Unity/TIL

Unity에서의 키입력으로 오브젝트를 이동시키는 방법

갈릭새우칩 2019. 5. 17. 18:55
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class PlayerController : MonoBehaviour
{
    public Rigidbody playerRigidbody;   // 이동에 사용할 리지드바디 컴포넌트
    public float speed = 8f;             //이동 속력
    
    void Start()
    {
        
    }
 
    void Update()
    {
        if (Input.GetKey(KeyCode.UpArrow) == true)
        {
            playerRigidbody.AddForce(0f, 0f, speed);
        }
        if (Input.GetKey(KeyCode.DownArrow) == true)
        {
            playerRigidbody.AddForce(0f, 0f, -speed);
        }
        if (Input.GetKey(KeyCode.RightArrow) == true)
        {
            playerRigidbody.AddForce(speed, 0f, 0f);
        }
        if (Input.GetKey(KeyCode.LeftArrow) == true)
        {
            playerRigidbody.AddForce(-speed, 0f, 0f);
        }
    }
 
 
    
    public void Die()
    {
        //자신의 게임 오브젝트를 비활성화
        gameObject.SetActive(false);
    }
}
 

다음 코드는 Unity에서 Player Object에 추가할 스크립트 코드이다.

 

딱 보면 알겠지만 오브젝트에 화살표 키를 눌렀을때 움직임을 하게 하는 기능을 제공하는 스크립트 코드이다.

 

Update 함수에서 if문으로 GetKey를 통해 화살표 키입력을 받았을때 AddForce(x, y, z) 를 이용해 speed만큼의 힘을 줘

 

Player 오브젝트를 움직이게 하는 방식이다.

 

실제로 이 코드를 player 오브젝트에 적용 시키면 움직이게 된다.

 

 

C, 와 C++ 때 간단하게 게임을 만들었을때와 비슷한 느낌의 코드로 그러려니 하고 넘어간 코드였는데

 

Unity에서는 더 쌈박하고 효율적인 기능을 제공한다고 한다.

 

일단 위의 코드를 좀더 효율적으로 바꾼 코드를 보겠다.

 

다음 코드를 보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class PlayerController : MonoBehaviour
{
    private Rigidbody playerRigidbody;   // 이동에 사용할 리지드바디 컴포넌트
    public float speed = 16f;            //이동 속력
    
    void Start()
    {
        playerRigidbody = GetComponent<Rigidbody>(); //리지드바디 컴포넌트를 유니티 에디터에서 직접 드래그&드랍
                                                      //하지 않고 코드가 할당하게 함
    }
 
    void Update()
    {
        // 수평축과 수직축의 입력값을 지정하여 저장
        float xInput = Input.GetAxis("Horizontal");
        float zInput = Input.GetAxis("Vertical");
 
        // 실제 이동 속도를 입력값과 이동 속력을 사용해 결정
        float xSpeed = xInput * speed;
        float zSpeed = zInput * speed;
 
        // Vector3 속도를 (xSpeed, 0, zSpeed)로 생성
        Vector3 newVelocity = new Vector3(xSpeed, 0f, zSpeed);
        // 리지드바디의 속도에 newVelocity 할당
        playerRigidbody.velocity = newVelocity;
    }
 
 
    
    public void Die()
    {
        //자신의 게임 오브젝트를 비활성화
        gameObject.SetActive(false);
    }
}
 

1)

자, 일단 바뀐건

 

public Rigidbody playerRigidbody; 에서

 

private Rigidbody playerRigidbody; 로 public -> private 로 접근제한자를 변경하였다.

 

 

PlayerComponent 스크립트 코드에서 public 으로 선언되어 있을경우 Unity 에디터에 나타난다.

 

playerRigidbody 변수의 접근제한자가 private로 변경된후 Unity 에디터에서 보이지 않게 변경되고 접근이 불가능하다.

2)

자, 그다음 바뀐 코드는 Start()함수에 추가된 코드다.

 

playerRigidbody = GetComponent<Rigidbody>();

 

여기에 사용된 건 제네릭 이라고 하는 제네릭 기법이다 이에 대한 설명은 이글을 참조..

 

2019/05/17 - [Unity/TIL] - GetComponent<>(); 의 제네릭(Generic) 기법

 

GetComponent<>(); 의 제네릭(Generic) 기법

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { priva..

gcoding.tistory.com

 

간단히 설명하자면...

 

보통의 경우 스크립트를 오브젝트에 컴포넌트로 추가후 변수가 가리키는 것이 어떤 것 인지

다음 그림과 같이 드래그 앤 드랍으로 지정해 주어야 한다.

스크립트를 오브젝트에 컴포넌트로 추가할때 대략의 흐름

이와 같은 과정은 드래그 & 드랍으로 일일히 해줘야 하는것이 번거롭기도 하고 실수가 생길 위험이 있다.

 

하지만 제네릭 기법이 활용된 다음 코드를 활용하면

 

playerRigidbody = GetComponent<Rigidbody>();

 

※ 위 코드는 자신의 게임 오브젝트에서 <>안의 타입으로 컴포넌트를 찾아서 가져온다.

즉, 위 코드에선 Rigidbody타입의 컴포넌트를 찾아서 가져와서 playerRigidbody 변수에 할당한다.

 

 

3)

마지막으로 제일 중요한 바뀐점인 이동에 관한 코드를 보면,

 

        float xInput = Input.GetAxis("Horizontal");

        float zInput = Input.GetAxis("Vertical");

 

        // 실제 이동 속도를 입력값과 이동 속력을 사용해 결정

        float xSpeed = xInput * speed;

        float zSpeed = zInput * speed;

 

        // Vector3 속도를 (xSpeed, 0, zSpeed)로 생성

        Vector3 newVelocity = new Vector3(xSpeed, 0f, zSpeed);

        // 리지드바디의 속도에 newVelocity 할당

        playerRigidbody.velocity = newVelocity;

 

 

자! 일단 if문이 사라졌다. 딱 봐도 훨씬 간결해 보인다.

 

처음 코드 방식은 if문으로 각각 화살표에 대응하는 키가 눌렸을시 Addforce로 오브젝트에 힘을 가하는 방식이였다.

 

대신 xInput, yInput이라는 변수를 선언후

 

Input.GetAxis(); 라는 메서드를 통해 변수에 무언가 할당하고 있다.

 

 

Input.GetAxis(); 메서드는 축(Axis)의 이름을 받는다. 그리고 다음 경우에 따라 감지된 입력 값을 반환한다.

 

  • 축의 음의 방향에 대응되는 버튼을 누름 : -1.0
  • 아무것도 누르지 않음 : 0
  • 축의 양의 방향에 대응되는 버튼을 누름 : +1.0

 

"Horizontal" 축의 경우

  ● Horizontal(수평) 축에 대응되는 키

  • 음의 방향 : ←(왼쪽 방향키), A키
  • 양의 방향 : →(오른쪽 방향키), D키

  ● Input.GetAxis("Horizontal")의 출력값

  • ← 또는 A 키를 누름 : -1.0
  • 아무것도 누르지 않음 : 0
  • → 또는 D 키를 누름 : +1.0

"Vertical" 축의 경우

  Vertical(수직) 축에 대응되는 키

  • ↓(아래쪽 방향키), S키
  • ↑(위쪽 방향키), W키

 

  ● Input.GetAxis("Vertical")의 출력값

  • ↓또는 S키를 누름 : -1.0
  • 아무것도 누르지 않음 : 0
  • ↑또는 W키를 누름 : +1.0

 

즉, 다음 코드는

float xInput = Input.GetAxis("Horizontal");

float zInput = Input.GetAxis("Vertical");

 

xInput에는 왼쪽, 오른쪽 화살표키나 A, D키를 눌렀을때 각각 대응 하는 값을 저장하고

yInput에는 아래쪽, 위쪽 화살표키나 S, W키를 눌렀을때 각각 대응 하는 값을 저장한다.

 

그 뒤,

float xSpeed = xInput * speed;

float zSpeed = zInput * speed;

 

이 코드에서 각각 방향키를 누른 만큼의 값에다 speed를 곱하여 누른만큼의 이동량을 저장한다.

 

마지막으로

// Vector3 속도를 (xSpeed, 0, zSpeed)로 생성

Vector3 newVelocity = new Vector3(xSpeed, 0f, zSpeed);

// 리지드바디의 속도에 newVelocity 할당

playerRigidbody.velocity = newVelocity;

 

 

Vector3 타입의 변수 newVelocity를 선언한 후 (xSpeed, 0f, zSpeed)를 가지는 Vector3 데이터를 생성하여 할당하였다.

 

그다음 playerRigidbody.velocity  에  newVelocity를 할당한다.

 

 

 

※ 또 하나 바뀐게 있다면 Rigidbody에서 AddForce() 를 이용한 이동에서 velocity로 바꾸었는데

 

AddForce는 관성의 영향을 받는다. 즉, 이동하는 방향만큼 힘이 누적되고 속력이 점진적으로 증가되고 이동중 반대방향

으로 이동하면 관성의 영향을 받아 반응이 늦다.

 

반면 Rigidbody의 velocity를 수정하는 것은 이전 속도를 지우고 새로운 속도를 사용한다. 따라서 관성을 무시하고

속도가 즉각적으로 변경된다.

 

※ 중요 내용 요약

  • 변수 = GetComponent<타입>();   자신의 게임 오브젝트에서 <>안의 타입으로 컴포넌트를 찾아서 가져와 변수에 할당하는 코드, 제네릭(generic) 기법이다.
  • Input.GetAxis();    메서드는 유니티 에디터의 입력매니저에 미리 설정되어 있는 축(Axis)의 이름을 받는다. 그리고 그 축의 입력에 따라 입력매니저에 설정되어있는 해당 값을 반환 받는다.

 

 

이로써 이동관련 스크립트가 훨씬 간결해 보이게 변경되었다.

 

간결한 것 뿐 아니라 다른 또 중요한 이유로 인해 GetAxis()메서드를 이용하는게 좋은데 그건 다음글

 

입력 매니저(Input Manager) 라는 글 에서 포스팅 하려 한다.

2019/05/17 - [Unity/TIL] - Get.Axis()메서드와 입력매니저(Input Manager)

 

GetAxis()메서드와 입력매니저(Input Manager)

2019/05/17 - [Unity/TIL] - Unity에서의 키입력으로 오브젝트를 이동시키는 방법 ←이전글 GetAxis()메서드 이전 글에서 Unity에서 오브젝트를 키입력을 받아 이동시키는 코드를 만들어 보았다. 내가 일반적..

gcoding.tistory.com

 

 

 

Comments