Unity2D_Basic #6

haechi·2021년 7월 25일
0

unity

목록 보기
27/39

210725
Unity2D_Basic #6


  • 플랫포머 플레이어 이동, 점프 구현

-이동
player오브젝트 생성 및 코드 작성

1.PlayerController.cs
플레이어 이동을 위해 키 입력시 이동하도록 한다.

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

public class PlayerController : MonoBehaviour
{
    private Movement2D movement2D;

    private void Awake()
    {
        movement2D = GetComponent<Movement2D>();
    }

    private void Update()
    {
        float x = Input.GetAxisRaw("Horizontal");   // 좌우 입력
        movement2D.Move(x); // 이동 방향 제어
    }
}

2.Movement2D.cs
PlayerController에서 키 입력시 Move 함수 호출 -> Move함수에서 이동방향을 제어
해당 기능을 가지고 있는 코드

using System.Collections;
using System.Collections.Generic;
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);
    }
}

rigidbody와 collider 적용으로 중력의 영향을 받아 아래로 떨어지고 다른 오브젝트와 부딪혀 이동할 수 있다.

+점프
PlayerController, Movement2D의 코드 수정

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

public class PlayerController : MonoBehaviour
{
    private Movement2D movement2D;

    private void Awake()
    {
        movement2D = GetComponent<Movement2D>();
    }

    private void Update()
    {
        float x = Input.GetAxisRaw("Horizontal");   // 좌우 입력
        movement2D.Move(x); // 이동 방향 제어

        // 스페이스 키를 누르면 점프
        if (Input.GetKeyDown(KeyCode.Space))
        {
            movement2D.Jump();
        }
        // 스페이스 키를 누르고 있으면 isLongJump = true
        if (Input.GetKey(KeyCode.Space))
        {
            movement2D.isLongJump = true;
        }
        // 스페이스 키를 떼면 false
        if (Input.GetKeyUp(KeyCode.Space))
        {
            movement2D.isLongJump = false;
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Movement2D : MonoBehaviour
{
    [SerializeField]
    private float speed = 5.0f; // 이동 속도
    [SerializeField]
    private float jumpForce = 8.0f; // 점프 힘 (클수록 높이 점프한다)
    private Rigidbody2D rigid2D;
    [HideInInspector]   // public 타입 변수를 Inspector view에서 보이지 않게 한다.
    public bool isLongJump = false; // 낮은 점프, 높은 점프를 체크
    
    private void Awake()
    {
        rigid2D = GetComponent<Rigidbody2D>();
    }

    private void FixedUpdate()
    {
        // 낮은 점프, 높은 점프 구현을 위한 중력 계수 (gravityScale) 조절

        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()
    {
        // fumpForce의 크기만큼 위 방향으로 속력 설정
        rigid2D.velocity = Vector2.up * jumpForce;
    }
}

-rigid2D.gravityScale : 중력 계수
플레이어에게 가해지는 중력 -> (0,-9.81, 0) * gravityScale
gravityScale
-> 1 : transform.position += (0, -9.81, 0)의 연산 추가
-> 2.5 : transform.position += (0, -24.525, 0)의 연산 추가

스페이스바 입력 -> 점프
길게 누른다 -> 긴 점프 짧게 누르고 뗀다 -> 낮은 점프
GetKey / GetKeyUP의 차이로

-현재 무한대로 점프할 수 있으나 바닥에 닿아있을때만 점프하도록 수정해보자
Movement2D.cs

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

public class Movement2D : MonoBehaviour
{
    [SerializeField]
    private float speed = 5.0f; // 이동 속도
    [SerializeField]
    private float jumpForce = 8.0f; // 점프 힘 (클수록 높이 점프한다)
    private Rigidbody2D rigid2D;
    [HideInInspector]   // public 타입 변수를 Inspector view에서 보이지 않게 한다.
    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);
        // 발 위치에 원 생성, 원이 바닥과 닿아있으면 true
        isGrounded = Physics2D.OverlapCircle(footPosition, 0.1f, groundLayer);

        // 낮은 점프, 높은 점프 구현을 위한 중력 계수 (gravityScale) 조절
        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);  // 발의 위치에 0.1 반지름의 구 생성
    }
    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역할(변수 타입 LayerMask)
오브젝트가 그려지는 순서 설정
오브젝트 충돌에서 지정한 레이어와의 충돌을 제외 가능
Layer 추가


플레이어가 밟을 수 있는 모든 오브젝트에 Ground레이어 설정

플레이어 오브젝트의 GroundLayer에 레이어를 Ground로 설정

-Gizmos
화면에 보이지 않는 충돌 범위와 같은 것들을 원하는 위치에 잘 배치했는지 확이하고 싶을 때 선, 사각형, 원 등을 그려서 확인하는 용도로 사용
-> 게임 뷰에서 보이지 않는다.

  • 점프 가능 횟수 추가
    Movement2D.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Movement2D : MonoBehaviour
{
    [SerializeField]
    private float speed = 5.0f; // 이동 속도
    [SerializeField]
    private float jumpForce = 8.0f; // 점프 힘 (클수록 높이 점프한다)
    private Rigidbody2D rigid2D;
    [HideInInspector]   // public 타입 변수를 Inspector view에서 보이지 않게 한다.
    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);
        // 발 위치에 원 생성, 원이 바닥과 닿아있으면 true
        isGrounded = Physics2D.OverlapCircle(footPosition, 0.1f, groundLayer);

        // 플레이어가 바닥에 닿아있고 y축 속도가 0 이하
        // y축 속도가 0 이하라는 조건을 추가하지 않을 시 점프키를 누르는 순간에도 초기화가 된다
        if (isGrounded == true && rigid2D.velocity.y <= 0)
        {
            currentJumpCount = maxJumpCount;
        }

        // 낮은 점프, 높은 점프 구현을 위한 중력 계수 (gravityScale) 조절
        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);  // 발의 위치에 0.1 반지름의 구 생성
    }
    public void Move(float x)
    {
        // x 축 이동은  x * speed, y 축은 기존의 속력 값
        rigid2D.velocity = new Vector2(x * speed, rigid2D.velocity.y);
    }

    public void Jump()
    {
        if (currentJumpCount > 0) // 남은 점프 횟수가 0 보다 클 때
        {
            // jumpForce의 크기만큼 위 방향으로 속력 설정
            rigid2D.velocity = Vector2.up * jumpForce;
            // 점프횟수 1회 감소
            currentJumpCount--;
        }
    }
}

private int maxJumpCount = 2; // 땅을 밟기 전까지의 최대 점프 횟수
private int currentJumpCount = 0; // 현재 가능한 점프 횟수
최대 점프 횟수를 추가하고 점프시 1회 감소하도록 한다.
땅에 닿아있을 때 그리고 y축 속도가 0이하를 조건으로 둔다. 속력제한을 두지 않으면 점프중에 초기화가 되어 최대 3회가 된다.

참고
https://www.inflearn.com/course/%EA%B3%A0%EB%B0%95%EC%82%AC-%EC%9C%A0%EB%8B%88%ED%8B%B0-%EA%B8%B0%EC%B4%88/lecture/48460?tab=note&mm=null

profile
공부중인 것들 기록

0개의 댓글