본문 바로가기

Unity/▶ Game Development: Dodge

[Dodge] #3. 스크립트 개선하기

728x90
반응형

PlayController 스크립트를 저번 차시에 완성했으나, 아직 몇 가지 문제가 존재한다.

 

1. 조작의 즉시 반영 불가

- Addforce 메서드로 인해 누적된 힘을 통해 속도가 점진적으로 증가함. 이로 인해 속도가 원하는 속도에 도달할 때까지 시간이 걸리는 문제가 발생한다. 또한 관성으로 인해 방향을 바꾸고자 할 때에도 시간이 걸리는 문제점이 발생한다.

 

2. 입력 감지 코드가 복잡함

- 방향키를 감지하는데 if 조건문은 4개나 사용한다.

 

3. playRigidbody에 컴포넌트를 드래그&드롭으로 할당하는 것의 불편함

- PlayController 컴포넌트의 Player Rigidbody 필드로 리지드 바디를 직접 드래그&드롭하여 할당했는데, 이 과정은 불편하며 잘못 할당하는 문제가 발생할 수 있다. 이러한 문제점을 해결하기 위해 변수에 컴포넌트의 참조를 할당하는 과정을 코드로 실현해보자.

 

리지드바디 컴포넌트를 코드에서 할당하기

playRigidbodyStart() 메서드 코드 수정

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

public class PlayerController : MonoBehaviour
{
    // Start is called before the first frame update
    private Rigidbody PlayerRigidbody; 
    public float speed = 8f;
    void Start()
    {
        PlayerRigidbody = GetComponent<Rigidbody>();
    }

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

        
    }

    public void Die(){
        gameObject.SetActive(false);
    }
}

 

playRigidbody의 접근한정자를 public에서 private로 변경함에 따라 인스펙터 창에서 PlayController 컴포넌트를 봤을 때 Player Rigidbody 필드가 더 이상 표시 되지 않는다.

public이 아닌 변수는 유니티 인스펙터 창에서 관측되지 않기 때문에 표시되지 않는다.

따라서 이제는  드래그&드롭으로 리지드 바디 컴포넌트를 playerRigidbody에 할당할 수 없다.

 

GetComponent() 메서드

  • GetComponent()메서드는 원하는 타입의 컴포넌트를 자신의 게임 오브젝트에서 찾아오는 메서드이다.
void Start()
{
    PlayerRigidbody = GetComponent<Rigidbody>();
}
GetComponent<Rigidbody>();는 자신의 게임 오브젝트에서 Rigidbody 컴포넌트를 찾아서 가져온다.
즉, 게임 오브젝트에서 리지드 바디 컴포넌트를 찾아 PlayerRigidbody 변수에 할당한다.

 

GetComponent<Type>() 메서드 할당 성공 원하는 타입의 컴포넌트를 좌변에 할당
GetComponent<Type>() 메서드 할당 실패 null을 할당

 

제네릭

GetComponent<>();에서 사용한 꺽쇠 <>은 제네릭 기법이다. 제네릭은 메서드나 클래스가 여러 타입에 호환되게 하는 역할을 한다. 꺽쇠안에 원하는 타입을 명시하면 클래스나 메서드가 해당 타입에 맞춰 동작한다.

제네릭을 사용하지 않으면 같은 처리를 위한 여러 타입의 메서드나 클래스를 일일이 만들어야하는 단점이 있다.

 

조작감 개선하기

PlayerController 스크립트의 Update()메서드를 다음과 같이 수정한다.

void Update()
    {
        //수평축과 수직축의 입력값을 감지하여 저장
        float xInput = Input.GetAxis("Horizontal"); //평행의
        float zInput = Input.GetAxis("Vertical"); //수직의

        //실제 이동 속도를 입력값과 이동 속력을 사용해 결정
        float xSpeed = xInput* speed;
        float zSpeed = zInput* speed;
        
        //Vector3 속도를 (xSpeed,0f,zSpeed)로 생성
        Vector3 newVelocity = new Vector3(xSpeed,0f,zSpeed);
        //리지드 바디의 속도에 newVelocity 할당
        PlayerRigidbody.velocity = newVelocity;
    }
  • 수평축과 수직축의 입력값을 감지
  • 속도를 나타낼 새로운 Vector3를 생성
  • 리지드바디 컴포넌트의 속도를 변경

GetAxis() 메서드

  • GetAxis() 메서드는 어떤 축에 대한 입력값을 숫자로 변환하는 메서드이다.
float Input.GetAxis()(string axisName);

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

축의 음의 방향으로 대응되는 버튼 입력 -1.0
아무것도 누르지 않음 0
축의 양의 방향으로 대응되는 버튼 입력 +1.0

 

Horizontal 축과Vertical 축의 대응입력키와 출력되는 입력값

Horizontal Horizontal(수평) 축에 대응되는 키 - 음의 방향: ⬅️, A
- 양의 방향: ➡️,D
Input.GetAxis("Horizontal")의 출력값 - 음의 방향: -1.0
- 아무것도 누르지 않음: 0
- 양의 방향: +1.0
Vertical Vertical(수직) 축에 대응되는 키 - 음의 방향: ⬇️,W
- 양의 방향: ⬆️,S
Input.GetAxis("Vertical")의 출력값 - 음의 방향: -1.0
- 아무것도 누르지 않음: 0
- 양의 방향: +1.0

새로 개선한 xInput은 수평 방향 입력, 변수 zInput은 수직 방향 입력을 저장한다.

//수평축과 수직축의 입력값을 감지하여 저장
float xInput = Input.GetAxis("Horizontal"); //평행의
float zInput = Input.GetAxis("Vertical"); //수직의

//실제 이동 속도를 입력값과 이동 속력을 사용해 결정
float xSpeed = xInput* speed;
float zSpeed = zInput* speed;

 

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

코드를 통해 음/양의 속도와 정지 상태를 모두 표현할 수 있다.

 

X,Y,Z 방향의 속도 할당

//Vector3 속도를 (xSpeed,0f,zSpeed)로 생성
Vector3 newVelocity = new Vector3(xSpeed,0f,zSpeed);
//리지드 바디의 속도에 newVelocity 할당
PlayerRigidbody.velocity = newVelocity;

newVelocity는X,Y,Z 방향으로의 속도를 나타내기 위한 변수로서, Vector3 데이터를 생성하여 할당했다.

newVelocityPlayerRigidbody.velocity에 대입하여 속도를 저장한다.

 

Vector3() 메서드

  • 원소 x,y,z를 가지는 타입. 위치, 속도, 크기 등을 나타낼 때 주로 사용한다.
Vector3 newvector = new Vector3(x,y,z);
/*
newvector: 벡터를 저장할 변수
x, y, z: 각 방향값에 대응하는 값
*/

 

최종 코드

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

public class PlayerController : MonoBehaviour
{
    // Start is called before the first frame update
    private Rigidbody PlayerRigidbody; 
    public float speed = 10f;
    void Start()
    {
        PlayerRigidbody = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    
    void Update()
    {
        //수평축과 수직축의 입력값을 감지하여 저장
        float xInput = Input.GetAxis("Horizontal"); //평행의
        float zInput = Input.GetAxis("Vertical"); //수직의

        //실제 이동 속도를 입력값과 이동 속력을 사용해 결정
        float xSpeed = xInput* speed;
        float zSpeed = zInput* speed;
        
        //Vector3 속도를 (xSpeed,0f,zSpeed)로 생성
        Vector3 newVelocity = new Vector3(xSpeed,0f,zSpeed);
        //리지드 바디의 속도에 newVelocity 할당
        PlayerRigidbody.velocity = newVelocity;
    }

    public void Die(){
        gameObject.SetActive(false);
    }
}

 

유니티를 실행하면 관성이 사라지고 입력값에 따른 조작이 즉시 작용하는 것을 볼 수 있다.

728x90
반응형

'Unity > ▶ Game Development: Dodge' 카테고리의 다른 글

[Dodge] #6. 바닥 회전  (0) 2022.03.02
[Dodge] #5. 탄알 생성기  (0) 2022.02.26
[Dodge] #4. 탄알 생성  (0) 2022.02.25
[Dodge] #2. 플레이어  (0) 2022.02.04
[Dodge] #1. 게임 베이스 생성  (0) 2022.02.04
댓글