사람의 방향키 입력을 받아 공을 굴리는 C# 프로그램 분석

1. Rigidbody

 

오브젝트를 물리에 의해 움직이게 만들어주는 컴포넌트

 

힘을 받아 오브젝트가 움직이게 만들어줌

 

해당 오브젝트 - Add component - Ridigbody

 

 

 

 

https://docs.unity3d.com/kr/2023.2/Manual/class-Rigidbody.html

 

Rigidbody 컴포넌트 레퍼런스 - Unity 매뉴얼

Rigidbody 컴포넌트를 사용하여 게임 오브젝트에 리지드바디를 적용합니다.리지드바디는 게임 오브젝트의 움직임과 포지션을 제어하는 물리 기반 방법을 제공합니다.Transform 프로퍼티 대신 시뮬

docs.unity3d.com

 

 

 

2. Input system

 

사용자의 키보드 입력을 받기 위해 필요한 패키지

 

Window - package manager

 

 

 

 

All을 누르고, Input System을 찾은 다음 우측에 Install을 누르면 설치됨

 

 

 

 

윈도우 게임 제작을 위해 File - build setting

 

 

 

 

platform에서 windows, mac, linux 선택하고 architecture에서 intel 64-bit

 

 

 

 

player 오브젝트에서 add component - player input 추가

 

 

 

 

그리고 create action 버튼이 있는데, 이걸 누르고 Inputs 폴더를 생성 - inputactions 라고 이름 짓고 에셋 생성

 

player input에서는 어떤 액션이 발생하면 스크립트를 통해 사용할 수 있는 알림을 트리거하여

 

게임 내 여러 요소를 트리거한다고 함

 

 

 

 

3. 스크립트 작성

 

player 오브젝트에 스크립트를 생성하고..

 

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

public class PlayerController : MonoBehaviour
{
    public float speed = 0;
    private Rigidbody rb;
    private float movementX;
    private float movementY;

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void OnMove(InputValue movementValue)
    {
        // Function body
        Vector2 movementVector = movementValue.Get<Vector2>();

        movementX = movementVector.x;
        movementY = movementVector.y;

    }

    void FixedUpdate()
    {
        Vector3 movement = new Vector3(movementX,0.0f, movementY);
        rb.AddForce(movement * speed);
    }
}

 

 

 

Start()는 게임 시작시 한번 호출

 

Update()는 게임 프레임마다 호출

 

게임 프레임마다 플레이어의 입력을 확인하고, 플레이어 게임 오브젝트에 적용해야 모든 프레임마다 움직임으로 적용

 

Update()는 프레임 렌더링 전에 호출되어 대부분 코드가 적용되는 곳

 

Fixedupdate()는 물리 계산을 수행하기 직전에 호출되며 물리 코드가 적용

 

Rigidbody에 힘을 적용해 공을 움직여야한다면 FixedUpdate()에 적용

 

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

public class PlayerController : MonoBehaviour
{

    // Start is called before the first frame update
    void Start()
    {
    }

    void FixedUpdate()
    {
    }
}

 

 

Input System을 사용하기 위해 네임스페이스에 추가해야함

 

네임스페이스는 클래스, 기타 데이터의 컬렉션으로, 스크립트 시작시에 import

 

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

 

기본으로 3개 사용

 

InputSystem을 사용하고 싶으면

 

using UnityEngine.InputSystem;

 

 

PlayerInput 컴포넌트는 이 스크립트에 액션 발생을 알리기 위해 스크립트 내에 사전 정의된 함수를 호출한다

 

사전 정의된 이름이 다음과 같이 적혀있다

 

 

 

움직임으로 WASD를 누르거나, 조이스틱을 누르는 등 이런 함수는 OnMove

 

상,하,좌,우 입력값을 읽고 FixedUpdate 코드를 통해 공을 움직인다

 

 

PlayerInput이 입력값을 스크립트에 전송할 때 InputValue 데이터 타입으로 전송한다

 

InputValue는 위-아래(y direction), 좌-우(x direction) 두 방향으로 움직임을 캡쳐

 

이런 x,y 두 방향 데이터는 Vector2 타입의 자료구조로 저장

 

    void OnMove(InputValue movementValue)
    {
        // Function body
        Vector2 movementVector = movementValue.Get<Vector2>();

    }

 

 

입력받은 움직임에서 Vector2 데이터를 가져온 다음 Vector2 타입의 movementVector라는 변수에 저장

 

 

이제 Rigidbody 컴포넌트에 엑세스해서 물리적 힘을 적용해야함

 

Rigidbody라는 변수를 선언하고, Start()함수에 GetComponent<Rigidbody>();로 연결하여 rb에 저장

 

 

이러면 연결한 Rigidbody 컴포넌트 정보를 rb에 저장할 수 있다

 

    private Rigidbody rb;

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

 

 

게임 시작에 한번 호출하여, 플레이어가 게임 시작하자마자 공을 움직일 수 있도록 함

 

 

이제 FixedUpdate() 함수로 변수 rb에 힘을 추가하는 함수를 호출

 

    void FixedUpdate()
    {
        rb.AddForce(movementVector);
    }

 

 

AddForce()에는 Vector3가 들어가야하는데 Vector2가 들어가서 에러남

 

 

 

 

Vector2가 X,Y 데이터를 저장하듯이 Vector3는 X,Y,Z 3개 축 데이터를 저장

 

3D 게임이라 공에는 X,Y,Z 3개 축이 있다

 

 

 

 

 

먼저 float형으로 X,Y축 움직임 변수 movementX, movementY를 선언하고,

 

OnMove의 Vector2에서 movementVector.x, movementVector.y로 할당해준다.

 

public class PlayerController : MonoBehaviour
{
    private Rigidbody rb;
    private float movementX;
    private float movementY;

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void OnMove(InputValue movementValue)
    {
        // Function body
        Vector2 movementVector = movementValue.Get<Vector2>();

        movementX = movementVector.x;
        movementY = movementVector.y;

    }

 

 

 

movementVector는 OnMove 함수내에 있고, FixedUpdate()에는 없어서, 에러가 난다

 

 

 

 

FixedUpdate()내에서 Vector3 변수를 새로 만든다.

 

공은 3D공간 내에서는, X,Z축을 따라 움직여야하므로, Y축에는 0.0f를 할당하고, X,Z축에는 멤버변수 movementX, movementY를 준다

 

왜 x,z축으로 움직이나??? 그럴것 같기는 한데... 궁금해서 

 

Vector3 movement = new Vector3(movementX, movementY ,0.0f);

 

이렇게 하면 공이 위아래로는 안움직이더라

 

 

이렇게 만든 Vector3 변수를 AddForce에 줘서 Rigidbody에 힘을 가한다

 

    void FixedUpdate()
    {

        Vector3 movement = new Vector3(movementX,0.0f,movementY);
        rb.AddForce(movement);
    }

 

 

프로젝트에서 play모드로 들어간 다음 방향키로 움직여보면 공이 움직인다

 

 

 

 

4. 속도 조절

 

public float speed = 0;으로 선언

 

    public float speed = 0;
    private Rigidbody rb;
    private float movementX;
    private float movementY;

 

 

다음 Rigidbody에서 AddForce에 movement * speed로 속도를 곱해준다

 

 

    void FixedUpdate()
    {
        Vector3 movement = new Vector3(movementX,0.0f, movementY);
        rb.AddForce(movement * speed);
    }

 

 

speed 변수를 public으로 설정하면, 프로젝트 inspector에서 스크립트 쪽에 speed를 조절할 수 있다

 

 

 

 

 

속도를 10으로 올리고 play한 다음 움직여보면 공이 훨씬 빨라짐 

TAGS.

Comments