기록 보관소

[Unity/유니티] 기초-뱀서라이크: 플레이어 이동 구현하기[02] 본문

유니티 프로젝트/뱀서라이크

[Unity/유니티] 기초-뱀서라이크: 플레이어 이동 구현하기[02]

JongHoon 2023. 3. 24. 02:47

개요

유니티 독학을 위해 아래 링크의 골드메탈님의 영상들을 보고 직접 따라 해보면서 진행 상황을 쓰고 배웠던 점을 요약한다.

https://youtube.com/playlist?list=PLO-mt5Iu5TeYI4dbYwWP8JqZMC9iuUIW2 

 

📚유니티 기초 강좌

유니티 게임 개발을 배우고 싶은 분들을 위한 기초 강좌

www.youtube.com


뱀서라이크: 플레이어 이동 구현하기[02]

1. C# 스크립트 만들기

우클릭 - Create - Folder로 폴더 생성
우클릭 - Create - C# Script로 스크립트 생성
Assets 안에 Codes 폴더를 만들고 Player 스크립트를 생성했다.

  • Inspector 창에 보이듯 스크립트 생성시 해당 클래스는 MonoBehaviour 클래스를 상속받는다.
  • MonoBehaviour 클래스는 기본적인 게임 로직을 위한 함수, 속성 등이 포함된 클래스다.

Unity 메뉴 탭 Edit - Preferences...
Preferences - Analysis - External Tools에서 Externel Script Editor 항목을 변경

  • 번외로, 유니티에서 스크립트를 실행할 때 Visual Studio 버전 변경이나 다른 에디터를 사용하려면 위와 같이 유니티 Preferences 변경 과정을 따르면 된다. 
  • 이 외에 다른 자세한 사항은 마이크로소프트의 설명을 찾아보면 될 것 같다.

2. 키보드 입력 받기

//Plyaer Script

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

public class Player : MonoBehaviour {
    public Vector2 inputVector;    //입력 값 저장 변수

    void Start() {
        
    }

    void Update() { //하나의 프레임마다 한 번씩 호출되는 생명주기 함수. 대문자 유의할 것.
		//Input : 유니티에서 받는 모든 입력을 관리하는 클래스. Axis 값은 -1 ~ 1.
		inputVector.x = Input.GetAxis("Horizontal");    //좌,우 방향키 또는 A,D 키
		inputVector.y = Input.GetAxis("Vertical");      //상,하 방향키 또는 W,S 키
	}
}
  • 일단 키보드 입력을 잘 받고 있는지 확인하기 위해서 inputVector를 public으로 했다.

Player 오브젝트에 스크립트를 넣어주자
실행 후 좌측 방향키(A), 위쪽 방향키(W)를 누르니 Player Script의 Input Vector 값이 변경되는 것을 보아 잘 입력받고 있다.

  • Axis 값의 범위는 -1 ~ 1로 Horizontal의 경우 좌측이 -1, 우측이 1이 되고 Vertical의 경우 위쪽이 1, 아래쪽이 -1이 된다.

3. 물리 이동 방법

//Plyaer Script

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

public class Player : MonoBehaviour {
    Vector2 inputVec;    //입력 값 저장 변수
    Rigidbody2D rigid;

    void Awake() {  //시작할 때 한번만 실행되는 생명주기 함수
        rigid = GetComponent<Rigidbody2D>();    //GetComponent<T> : 오브젝트에서 컴포넌트 T를 가져오는 함수
    }

    void Update() { //하나의 프레임마다 한 번씩 호출되는 생명주기 함수. 대문자 유의할 것.
		//Input : 유니티에서 받는 모든 입력을 관리하는 클래스. Axis 값은 -1 ~ 1.
		inputVec.x = Input.GetAxis("Horizontal");    //좌,우 방향키 또는 A,D 키
		inputVec.y = Input.GetAxis("Vertical");      //상,하 방향키 또는 W,S 키
	}

    void FixedUpdate() {    //물리 연산 프레임마다 호출되는 생명주기 함수
        //1. 힘을 준다 = AddForce
        rigid.AddForce(inputVec);    //입력 방향으로 밀기

        //2. 속도 제어 = Velocity
        rigid.velocity = inputVec;   //속도 직접 제어

        //3. 위치 이동 = MovePosition
        rigid.MovePosition(rigid.position + inputVec);  //현재 위치 + 나아갈 방향 : (x, y) 좌표 활용
    }
}
  • Rigidbody 2D를 사용한 물리 이동 방법으로는 3가지가 방법이 있다. 여태 배운 것을 정리한다고 보면 될듯하다.
    1. 힘 주기 : Add Force
    2. 속도 제어 : velocity
    3. 위치 이동 : MovePosition
  • 추가적으로 앞서 입력 확인을 위해 public으로 설정했던 inputVector 변수를 다시 private로 변경하고, 변수 이름도 영상에 맞추기 위해서 inputVec으로 바꿔주었다.

4. 물리 이동 구현

//Plyaer Script

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

public class Player : MonoBehaviour {
    Vector2 inputVec;    //입력 값 저장 변수
    Rigidbody2D rigid;

    void Awake() {  //시작할 때 한번만 실행되는 생명주기 함수
        rigid = GetComponent<Rigidbody2D>();    //GetComponent<T> : 오브젝트에서 컴포넌트 T를 가져오는 함수
    }

    void Update() { //하나의 프레임마다 한 번씩 호출되는 생명주기 함수. 대문자 유의할 것.
		//Input : 유니티에서 받는 모든 입력을 관리하는 클래스. Axis 값은 -1 ~ 1.
		inputVec.x = Input.GetAxis("Horizontal");    //좌,우 방향키 또는 A,D 키
		inputVec.y = Input.GetAxis("Vertical");      //상,하 방향키 또는 W,S 키
	}

    void FixedUpdate() {    //물리 연산 프레임마다 호출되는 생명주기 함수
        //위치 이동
        rigid.MovePosition(rigid.position + inputVec);  //현재 위치 + 나아갈 방향 : (x, y) 좌표 활용
    }
}

위치 이동 방식의 플레이어 이동 테스트

  • 이번 강좌 프로젝트에서는 앞선 3가지 방식 중 3번 위치 이동 방식을 사용해서 플레이어 이동을 구현한다고 한다. 그래서 앞선 코드에서 1, 2번을 제거하고 테스트해보았다.
  • 테스트 결과는 위 이미지에 보이듯이 잘 이동하지만 매우 빠르다. 살짝만 눌러도 꽤 많은 거리를 이동하고, 금방 화면 밖으로 빠져나간다. 그리고 프레임 환경에 따라 이동 속도 차이가 발생할 수 있기 때문에, 수정이 더 필요하다.
//Plyaer Script

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

public class Player : MonoBehaviour {
    Vector2 inputVec;   //입력 값 저장 변수
	public float speed; //속도 관리용 변수

    Rigidbody2D rigid;

    void Awake() {  //시작할 때 한번만 실행되는 생명주기 함수
        rigid = GetComponent<Rigidbody2D>();    //GetComponent<T> : 오브젝트에서 컴포넌트 T를 가져오는 함수
    }

    void Update() { //하나의 프레임마다 한 번씩 호출되는 생명주기 함수. 대문자 유의할 것.
		//Input : 유니티에서 받는 모든 입력을 관리하는 클래스. Axis 값은 -1 ~ 1.
		inputVec.x = Input.GetAxis("Horizontal");    //좌,우 방향키 또는 A,D 키
		inputVec.y = Input.GetAxis("Vertical");      //상,하 방향키 또는 W,S 키
	}

    void FixedUpdate() {    //물리 연산 프레임마다 호출되는 생명주기 함수
		//위치 이동
		//normalized : 벡터 값의 크기가 1이 되도록 좌표가 수정된 값. 대각선 이동시 값 고정을 위함.
		Vector2 nextVec = inputVec.normalized * speed * Time.fixedDeltaTime;    //fixedDeltaTime : 물리 프레임 하나가 소비한 시간. Update에서는 DeltaTime 사용.
        rigid.MovePosition(rigid.position + nextVec);  //현재 위치 + 나아갈 방향 : (x, y) 좌표 활용
    }
}

Speed 값 설정
수정 후 이동 테스트(GetAxis)

  • 대각선 이동시 값을 1로 고정하기 위해 normalized하고, 또한 속도 조절을 위해서 float 변수 speed를 추가하고, 프레임 환경에 따른 차이가 없도록 Time 클래스의 fixedDeltaTime을 다 곱한 새로운 변수 nextVec값을 만들어 수정했다.
  • 위 테스트 이미지에서 살짝 미끄러지듯 움직이는 것은 입력이 GetAxis 함수로 처리되어서 그렇다. 이를 바꾸려면 GetAxisRaw 함수를 사용하면 된다. 이는 취향의 영역이라 자유롭게 선택하면 될 것 같다. 나는 그 약간의 차이가 좀 거슬린다고 생각해서 GetAxisRaw로 변경했다.
//Plyaer Script

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

public class Player : MonoBehaviour {
    Vector2 inputVec;   //입력 값 저장 변수
	public float speed; //속도 관리용 변수

    Rigidbody2D rigid;

    void Awake() {  //시작할 때 한번만 실행되는 생명주기 함수
        rigid = GetComponent<Rigidbody2D>();    //GetComponent<T> : 오브젝트에서 컴포넌트 T를 가져오는 함수
    }

    void Update() { //하나의 프레임마다 한 번씩 호출되는 생명주기 함수. 대문자 유의할 것.
		//Input : 유니티에서 받는 모든 입력을 관리하는 클래스. Axis 값은 -1 ~ 1.
		inputVec.x = Input.GetAxisRaw("Horizontal");    //좌,우 방향키 또는 A,D 키
		inputVec.y = Input.GetAxisRaw("Vertical");      //상,하 방향키 또는 W,S 키
	}

    void FixedUpdate() {    //물리 연산 프레임마다 호출되는 생명주기 함수
		//위치 이동
		//normalized : 벡터 값의 크기가 1이 되도록 좌표가 수정된 값. 대각선 이동시 값 고정을 위함.
		Vector2 nextVec = inputVec.normalized * speed * Time.fixedDeltaTime;    //fixedDeltaTime : 물리 프레임 하나가 소비한 시간. Update에서는 DeltaTime 사용.
        rigid.MovePosition(rigid.position + nextVec);  //현재 위치 + 나아갈 방향 : (x, y) 좌표 활용
    }
}

최종 수정 후 이동 테스트(GetAxisRaw)