이글은 인프런 [따라하면서 배우는 고박사의 유니티 기초] 강의를 수강하고 정리한 글이다.
[지금 무료] 따라하면서 배우는 고박사의 유니티 기초 | 고박사 - 인프런
고박사 | 유니티로 게임을 개발하고 싶은 초보자를 대상으로 하며, 유니티 설치부터 2D/3D 게임 개발에 필요한 기초 지식까지 자세하게 설명합니다. (강의에 사용되는 모든 리소스는 영상 상단의
www.inflearn.com
강의를 시작하기에 앞서서 플레이어의 이동, 점프등 구현을 위해 2D 오브젝트를 생성하여 원하는 위치에 배치한다.
- 유니티 패키지 파일: 원하는 파일들을 하나로 묶어 다른 프로젝트로 전달할 때 사용
- 패키지 파일 생성하기 : Project View에서 원하는 파일들을 선택한 후 마우스 오른쪽을 클릭 → Export Package로 저장
- 패키지 파일 사용하기 : 파일을 적용하고 싶은 프로젝트의 Project View로 패키지 파일을 드래그앤 드롭으로 가져온다.


player 오브젝트는 중력을 받을 수 있도록 rigidbody2d들을 적용시키고 freeze rotation z를 선택하게 되면 이동할 때 z축으로 회전하지 않게 된다. 그리고 충돌 처리를 위해 Capsule Collider 2D를 추가한다.
Rigidbody2D 컴포넌트의 Constraints
- Freeze Position: 물리에 의한 이동 중지
- Freeze Rotation: 물리에 의한 회전 중지
플레이어 오브젝트 이동(Rigidbody2D)
플레이어 이동을 구현해보도록 movement2D 스크립트를 작성한다.
using UnityEngine;
public class Movement2D : MonoBehaviour
{
[SerializeField]
private float speed = 5.0f; //이동 속도
private Rigidbody2D rigid2D;
private void Awake()
{
rigid2D = GetComponent<Rigidbody2D>();
}
public void Move(float x)
{
//x축 이동은 x*speed로, y축 이동은 기존의 속력 값(현재는 중력)
rigid2D.velocity = new Vector2(x * speed, rigid2D.velocity.y);
}
}
velocity 변수를 설정한다.
그리고 PlayerController 스크립트를 작성하여 플레이어 좌우 방향키값을 입력하게 되면 movement2D에 함수의 키값을 적용에 오브젝트가 이동한다.
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private Movement2D movement2D;
private void Awake()
{
movement2D = GetComponent<Movement2D>();
}
private void Update()
{
//left or a = -1 / right or d = 1
float x = Input.GetAxisRaw("Horizontal");
//좌우 이동 방향 제어
movement2D.Move(x);
}
}
플레이어 오브젝트 점프
플레이어 이동을 위한 Move 함수와 마찬가지로 Jump 함수를 추가한다.
Jump함수가 호출되면 y축 +방향으로 속력이 설정된다. 이때 점프의 정도는 jumpforce 변가 결정한다.
Jump함수는 PlayerController안에서 스페이스 바를 눌렀을 때 실행되도록 한다.
using UnityEngine;
public class Movement2D : MonoBehaviour
{
[SerializeField]
private float speed = 5.0f; //이동 속도
[SerializeField]
private float jumpForce = 8.0f; //점프 힘(클수록 높게 점프)
private Rigidbody2D rigid2D;
private void Awake()
{
rigid2D = GetComponent<Rigidbody2D>();
}
public void Move(float x)
{
//x축 이동은 x*speed로, y축 이동은 기존의 속력 값(현재는 중력)
rigid2D.velocity = new Vector2(x * speed, rigid2D.velocity.y);
}
public void Jump()
{
//jumpForce의 크기만큼 윗쪽 방향으로 속력 설정
rigid2D.velocity = Vector2.up * jumpForce;
}
}
위에 코드에서는 아무런 제약없이 무한히 점프할 수 있다.
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private Movement2D movement2D;
private void Awake()
{
movement2D = GetComponent<Movement2D>();
}
private void Update()
{
//left or a = -1 / right or d = 1
float x = Input.GetAxisRaw("Horizontal");
//좌우 이동 방향 제어
movement2D.Move(x);
//플레이어 점프(스페이스 키를 누르면 점프)
if (Input.GetKeyDown(KeyCode.Space))
{
movement2D.Jump();
}
}
}
낮은 점프, 높은 점프
using UnityEngine;
public class Movement2D : MonoBehaviour
{
[SerializeField]
private float speed = 5.0f; //이동 속도
[SerializeField]
private float jumpForce = 8.0f; //점프 힘(클수록 높게 점프)
private Rigidbody2D rigid2D;
[SerializeField]
public bool isLongJump = false; // 낮은/높은 점프 체크
private void Awake()
{
rigid2D = GetComponent<Rigidbody2D>();
}
private void FixedUpdate()
{
//낮은 점프, 높은 점프 구현 위한 중력 계수 조절 Jump Up일 때만 적용)
//중력 계수가 낮은 if문은 높은 점프가 되고, 중력 계수가 높은 else문은 낮은 점프가 됨.
if (isLongJump && rigid2D.velocity.y > 0)
{
rigid2D.gravityScale = 1.0f;
}
else
{
rigid2D.gravityScale = 2.5f;
}
}
public void Move(float x)
{
//x축 이동은 x*speed로, y축 이동은 기존의 속력 값(현재는 중력)
rigid2D.velocity = new Vector2(x * speed, rigid2D.velocity.y);
}
public void Jump()
{
//jumpForce의 크기만큼 윗쪽 방향으로 속력 설정
rigid2D.velocity = Vector2.up * jumpForce;
}
}
jump키를 눌렀는지 판단하는 isLongJump변수가 PlayerController에서 GetKey로 설정된다.
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private Movement2D movement2D;
private void Awake()
{
movement2D = GetComponent<Movement2D>();
}
private void Update()
{
//left or a = -1 / right or d = 1
float x = Input.GetAxisRaw("Horizontal");
//좌우 이동 방향 제어
movement2D.Move(x);
//플레이어 점프(스페이스 키를 누르면 점프)
if (Input.GetKeyDown(KeyCode.Space))
{
movement2D.Jump();
}
//스페이스 키를 누르고 있으면 isLongJump=true
if(Input.GetKeyUp(KeyCode.Space))
{
movement2D.isLongJump = true;
}
//스페이스 키를 떼면 isLongJump=false
else if (Input.GetKeyUp(KeyCode.Space))
{
movement2D.isLongJump = false;
}
}
}
스페이스바를 길게 누르냐 짧게 누르냐에 따라 점프의 높이가 달라진다. 길게 눌렀을 때랑 크게 다른 점은 없지만 이중점프가 가능했다..
바닥 판정 및 점프 제어
바닥에 닿아 있을 때만 플레이어가 뛸 수 있도록 설정하는 코드를 작성해보겠다.
플레이어의 발 위치를 알아야 하며, 코드에서 내가 설정한 collider과 맞게 설정해주어야한다.
충돌이 일어나면 isGrounded 변수가 참이 된다.
using System;
using UnityEngine;
public class Movement2D : MonoBehaviour
{
[SerializeField]
private float speed = 5.0f; //이동 속도
[SerializeField]
private float jumpForce = 8.0f; //점프 힘(클수록 높게 점프)
private Rigidbody2D rigid2D;
[SerializeField]
public bool isLongJump = false; // 낮은/높은 점프 체크
[SerializeField]
private LayerMask groundLayer; //바닥 체크를 위한 충돌 레이어
private CapsuleCollider2D capsuleCollider2D; //오브젝트의 충돌 범위 컴포넌트
private bool isGrounded; //바닥 체크 (바닥에 닿아있을 때 true)
private Vector3 footPosition; //발의 위치
private void Awake()
{
rigid2D = GetComponent<Rigidbody2D>();
capsuleCollider2D = GetComponent<CapsuleCollider2D>();
}
private void FixedUpdate()
{
//플레이어 오브젝트의 Collider2D min, center, max 위치 정보
Bounds bounds = capsuleCollider2D.bounds;
//플레이어의 발 위치 설정
footPosition = new Vector2(bounds.center.x, bounds.min.y);
//플레이어의 발 위치에 원을 생성하고, 원이 바닥과 닿아있으면 isGrounded = true
isGrounded = Physics2D.OverlapCircle(footPosition, 0.1f, groundLayer);
//낮은 점프, 높은 점프 구현 위한 중력 계수 조절 Jump Up일 때만 적용)
//중력 계수가 낮은 if문은 높은 점프가 되고, 중력 계수가 높은 else문은 낮은 점프가 됨.
if (isLongJump && rigid2D.velocity.y > 0)
{
rigid2D.gravityScale = 1.0f;
}
else
{
rigid2D.gravityScale = 2.5f;
}
}
private void OnDrawGizmos()
{
Gizmos.color = Color.blue;
Gizmos.DrawSphere(footPosition, 0.1f);
}
public void Move(float x)
{
//x축 이동은 x*speed로, y축 이동은 기존의 속력 값(현재는 중력)
rigid2D.velocity = new Vector2(x * speed, rigid2D.velocity.y);
}
public void Jump()
{
if(isGrounded == true)
{
//jumpForce의 크기만큼 윗쪽 방향으로 속력 설정
rigid2D.velocity = Vector2.up * jumpForce;
}
}
}
땅으로 사용되는 모든 오브젝트의 layer 값을 Ground로 바꿔주고, 플레이어 오브젝트에도 Ground Layer 변수를 Ground로 설정한다. Movement2D에 게임을 실행하면, 땅에 닿아야지 점프가 되는 것을 확인할 수 있다.
최대 점프 횟수 설정
점프하는 횟수 조절을 할 수 있도록 하여 2단,3단 점프가 가능하게끔 코드를 짠다.
using UnityEngine;
public class Movement2D : MonoBehaviour
{
[SerializeField]
private float speed = 5.0f; //이동 속도
[SerializeField]
private float jumpForce = 8.0f; //점프 힘(클수록 높게 점프)
private Rigidbody2D rigid2D;
[SerializeField]
public bool isLongJump = false; // 낮은/높은 점프 체크
[SerializeField]
private LayerMask groundLayer; //바닥 체크를 위한 충돌 레이어
private CapsuleCollider2D capsuleCollider2D; //오브젝트의 충돌 범위 컴포넌트
private bool isGrounded; //바닥 체크 (바닥에 닿아있을 때 true)
private Vector3 footPosition; //발의 위치
[SerializeField]
private int maxJumpCount = 2; //땅을 밟기 전까지 할 수 있는 최대 점프 횟수
private int currentJumpCount = 0; //현재 가능한 점프 횟수
private void Awake()
{
rigid2D = GetComponent<Rigidbody2D>();
capsuleCollider2D = GetComponent<CapsuleCollider2D>();
}
private void FixedUpdate()
{
//플레이어 오브젝트의 Collider2D min, center, max 위치 정보
Bounds bounds = capsuleCollider2D.bounds;
//플레이어의 발 위치 설정
footPosition = new Vector2(bounds.center.x, bounds.min.y);
//플레이어의 발 위치에 원을 생성하고, 원이 바닥과 닿아있으면 isGrounded = true
isGrounded = Physics2D.OverlapCircle(footPosition, 0.1f, groundLayer);
//플레이어의 발이 땅에 닿아 있고, y축 속도가 0이하이면 점프 횟수 초기화
//velocity.y <= 0을 추가하지 않으면 점프키를 누르는 순간에도 초기화가 되어
//최대 점프 횟수를 2로 설정하면 3번까지 점프가 가능하게 된다.
if(isGrounded == true && rigid2D.velocity.y <=0)
{
currentJumpCount = maxJumpCount;
}
//낮은 점프, 높은 점프 구현 위한 중력 계수 조절 Jump Up일 때만 적용)
//중력 계수가 낮은 if문은 높은 점프가 되고, 중력 계수가 높은 else문은 낮은 점프가 됨.
if (isLongJump && rigid2D.velocity.y > 0)
{
rigid2D.gravityScale = 1.0f;
}
else
{
rigid2D.gravityScale = 2.5f;
}
}
private void OnDrawGizmos()
{
Gizmos.color = Color.blue;
Gizmos.DrawSphere(footPosition, 0.1f);
}
public void Move(float x)
{
//x축 이동은 x*speed로, y축 이동은 기존의 속력 값(현재는 중력)
rigid2D.velocity = new Vector2(x * speed, rigid2D.velocity.y);
}
public void Jump()
{
//if(isGrounded == true)
if (currentJumpCount > 0)
{
//jumpForce의 크기만큼 윗쪽 방향으로 속력 설정
rigid2D.velocity = Vector2.up * jumpForce;
//점프 횟수 1 감소
currentJumpCount--;
}
}
}
위에 코드에서 maxJumpCount 변수의 값으로 2번이라 했기 때문에 최대 점프 값이 2번임을 알 수 있다.
오브젝트 마찰력 설정
위에 게임들을 실행하였을 때 마찰력에 의해 벽면에 플레이어가 붙어 버린다. 이것을 조작하려면 프로젝트 뷰에서 physics Meterial 2D를 설정하면 된다.
'자기개발 > Unity' 카테고리의 다른 글
[유니티기초] 2D Animation 실습 (0) | 2024.04.29 |
---|---|
[유니티기초] 2D sprite/ animation (0) | 2024.04.29 |
[유니티 기초] 게임오브젝트 삭제 함수 (0) | 2024.04.16 |
[유니티 기초] 인스턴스 활용 예제 (0) | 2024.04.16 |
[유니티 기초] 게임오브젝트 생성 함수 (0) | 2024.04.16 |