유니티

2D 이동 (position, velocity, Input System)

잼잼재미 2023. 11. 27. 12:30

position


오브젝트의 position 값을 변경해서 이동

 

 

GetAxis


-1 ~ 1 까지의 숫자를 입력으로 불러옴

void Update()
{
    float x = Input.GetAxis("Horizontal");
    float y = Input.GetAxis("Vertical");

    transform.position += new Vector3(x, y, 0) * Time.deltaTime;
    // Time.deltaTime : 이전 프레임과 현재 프레임 사이의 시간
    
    // 동시 입력 시, 일정한 속도를 가지려면
    //transform.position += new Vector3(x, y, 0).normalized * Time.deltaTime;
}

 

 

GetAxisRaw


-1, 0, 1 의 숫자를 입력으로 불러옴

void Update()
{
    float x = Input.GetAxisRaw("Horizontal");
    float y = Input.GetAxisRaw("Vertical");

    transform.position += new Vector3(x, y, 0) * Time.deltaTime;
	
    // 동시 입력 시, 일정한 속도를 가지려면
    //transform.position += new Vector3(x, y, 0).normalized * Time.deltaTime;
}

 

 

GetKey


void Update()
{
    // 오른쪽 이동
    if(Input.GetKey(KeyCode.RightArrow))
    {
        transform.position += new Vector3 (1f, 0, 0) * Time.deltaTime;
    }

    // 왼쪽 이동
    if(Input.GetKey(KeyCode.LeftArrow))
    {
        transform.position += new Vector3 (-1f, 0, 0) * Time.deltaTime;
    }

    // 위쪽 이동
    if(Input.GetKey(KeyCode.UpArrow))
    {
        transform.position += new Vector3 (0, 1f, 0) * Time.deltaTime;
    }

    // 아래쪽 이동
    if(Input.GetKey(KeyCode.DownArrow))
    {
        transform.position += new Vector3 (0, -1f, 0) * Time.deltaTime;
    }
}

 

 

velocity


Rigidbody를 추가해서 실제 물리적인 힘으로 이동

 

 

public Rigidbody2D rb;

void Update()
{
    float x = Input.GetAxisRaw("Horizontal");
    rb.velocity = new Vector2(x, rb.velocity.y);	// y값에 0을 넣으면 천천히 아래로 떨어짐.
}

 

 

 

Input System


Input System 준비


 

 

 

 

 

 

 

 

 

 

 

 

+ 버튼으로 Keyboard, Mouse 추가 후, Save

 

+ 버튼으로 Action Maps 추가

 

Player가 받을 키입력에 대해서 추가

 

 

 

No Binding 삭제

 

입력 받을 Key를 각각 설정

 

+ 버튼으로 Actions 추가

 

 

 

저장

 

Player Input 컴포넌트 추가, Controller 드래그

 

Send Messages 클릭

 

  • Send Messages : OnMove와 OnLook 함수를 현재 오브젝트에 있는 스크립트에서 찾음
  • Broadcast Messages : OnMove와 OnLook 함수를 현재, 자식 오브젝트에 있는 스크립트에서 찾음
  • Invoke Unity Events : Button과 같이 함수가 있는 스크립트를 가진 오브젝트를 추가해서 사용

 

 

코드 작성


 

 

1.  TopDownCharacterController

게임 컨트롤러 기능

using System;   // 추가해야 함

public event Action<Vector2> OnMoveEvent;   // Vector2 매개변수를 받음
public event Action<Vector2> OnLookEvent;   // 다른 함수를 연결할 수 있음

public void CallMoveEvent(Vector2 direction)
{
    OnMoveEvent?.Invoke(direction); // ? : null이 아니면 실행
                                    // Invoke : OnMoveEvent와 연결된 함수 모두 실행
}

public void CallLookEvent(Vector2 direction)
{
    OnLookEvent?.Invoke(direction);
}

 

 

2. PlayerInputController

InputSystem으로 받은 값을 관리

using UnityEngine.InputSystem;  // 추가해야 함

public class PlayerInputController : TopDownCharacterController // 상속
{
    public void OnMove(InputValue value)
    {
        Vector2 moveInput = value.Get<Vector2>().normalized;
        CallMoveEvent(moveInput);    // TopDownCharacterController 부모클래스 함수
    }

    public void OnLook(InputValue value)
    {
        Vector2 newAim = value.Get<Vector2>();
        Vector2 worldPos = Camera.main.ScreenToWorldPoint(newAim);
        newAim = (worldPos - (Vector2)transform.position).normalized;

        if(newAim.magnitude > 0f)
        {
            CallLookEvent(newAim);
        }
    }
}

 

 

3. TopDownMovement

실제 이동 구현

private TopDownCharacterController _controller;
private Rigidbody2D _rigidbody;

private Vector2 _movementDirction = Vector2.zero;

private void Awake()
{
    _controller = GetComponent<TopDownCharacterController>();
    _rigidbody = GetComponent<Rigidbody2D>();
}

void Start()
{
    _controller.OnMoveEvent += Move;
}

void Move(Vector2 direction)
{
    _movementDirction = direction;
}

private void FixedUpdate()
{
    ApplyMovement(_movementDirction);
}

void ApplyMovement(Vector2 direction)
{
    direction *= 5;
    _rigidbody.velocity = direction;
}

 

 

4. TopDownAimRotation

실제 회전 구현

TopDownCharacterController _controller;
[SerializeField] private SpriteRenderer characterRenderer;

private void Awake()
{
    _controller = GetComponent<TopDownCharacterController>();
}

void Start()
{
    _controller.OnLookEvent += OnAim;
}

void OnAim(Vector2 aimDirection)
{
    Rotate(aimDirection);
}

void Rotate(Vector2 direction)
{
    float rotZ = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;

    characterRenderer.flipX = Mathf.Abs(rotZ) > 90f;
}

 

 

스크립트 추가


 

 

'유니티' 카테고리의 다른 글

카메라 이동  (0) 2023.11.27
타일맵  (1) 2023.11.27
월드 좌표와 로컬 좌표  (0) 2023.11.27
Pixel Per Unit  (0) 2023.11.24
스크립트 라이프 사이클  (0) 2023.11.24