사람의 방향키 입력을 받아 공을 굴리는 C# 프로그램 분석
1. Rigidbody
오브젝트를 물리에 의해 움직이게 만들어주는 컴포넌트
힘을 받아 오브젝트가 움직이게 만들어줌
해당 오브젝트 - Add component - Ridigbody
https://docs.unity3d.com/kr/2023.2/Manual/class-Rigidbody.html
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한 다음 움직여보면 공이 훨씬 빨라짐
'프로그래밍 > Unity&C#' 카테고리의 다른 글
Unity 물체가 벽과 충돌할 수 있는 이유는 collider의 is trigger (0) | 2024.05.18 |
---|---|
Unity 게임 카메라 움직이는 코드 분석 (0) | 2024.05.04 |
Unity 기본13 - 오버로드(overload), 오버라이드(override), 추상(abstract), 인터페이스(interface) (0) | 2024.04.27 |
unity 기본12 - scope, 캡슐화, getter, setter, public, private, protected (0) | 2024.04.26 |
Unity 기본11 - class 상속, is, as 연산자 (0) | 2024.04.25 |