유니티/플랫포머 기초

[Unity] 플랫포머 기초 - 2. 지면 감지

이름?없음 2024. 11. 26. 10:57
반응형

 

반응형

2024.11.26 - [유니티/플랫포머 기초] - [Unity] 플랫포머 기초 - 1. 플레이어 이동

 

[Unity] 플랫포머 기초 - 1. 플레이어 이동

이번에는 유니티를 사용하여 간단한 2D플랫포머 게임을 만들어 보겠습니다.우선 기본적인 플레이어 이동부터 구현해 보겠습니다 우선 플레이어 이동을 구현하는데 필요한 오브젝트들을 배치

no-name-stroy.tistory.com

이전 글에서는 플레이어 이동을 구현해 보았습니다

하지만 지면에 있을 때만 점프가 되어야 하는데 그렇지 않다는 문제가 있었습니다

이번 글에서는 지면 감지를 추가하여 이를 해결해 보겠습니다

 

우선 코드 작성 이전에 사전 설정이 필요합니다

 

Ground라는 이름의 Tag를 만들어 주세요

 

그 후 Ground오브젝트의 태그를 Ground로 바꾸어주세요

 

플레이어 오브젝트에 자식으로 GroundSencer라는 빈 오브젝트를 하나 만들어 주세요

 

그 후 GroundSencer오브젝트에 콜라이더를 하나 추가하고 IsTrigger를 체크해 주세요

 

그 후 GroundSencer의 위치와 크기를 잘 조정하여 다음과 같이 플레이어 아래에 오도록 만들어주세요

 

이것으로 사전 설정은 완료되었습니다

이제 코드를 작성해 보도록 하겠습니다

 

콜라이더 감지를 담당하는 Sencer컴포넌트를 만들 것입니다

Sencer라는 이름을 가진 스크립트를 하나 추가해 주세요

using UnityEngine;

/// <summary>
/// 콜라이더 감지를 담당하는 클래스
/// </summary>
public class Sencer : MonoBehaviour
{

    /// <summary>
    /// 대상으로 할 테그
    /// </summary>
    [SerializeField] private string _targetTag;

    /// <summary>
    /// 샌서의 감지 여부
    /// </summary>
    public bool Sensed { get; private set; }

    /// <summary>
    /// 트리거 접촉이 일어났을 때 실행되는 함수
    /// </summary>
    /// <param name="collision">대상 오브젝트의 콜라이더</param>
    private void OnTriggerEnter2D(Collider2D collision)
    {
        //만약 오브젝트가 해당 테그라면?
        if (collision.CompareTag(_targetTag))
        {
            //감지 여부를 true로 바꾸어주기
            Sensed = true;
        }
    }

    /// <summary>
    /// 트리거와 접촉중일 때 실행되는 함수
    /// </summary>
    /// <param name="collision">대상 오브젝트의 콜라이더</param>
    private void OnTriggerStay2D(Collider2D collision)
    {
        //만약 오브젝트가 해당 테그라면?
        if (collision.CompareTag(_targetTag))
        {
            //감지 여부를 true로 바꾸어주기
            Sensed = true;
        }
    }

    /// <summary>
    /// 트리거와 접촉이 끝났을 때 실행되는 함수
    /// </summary>
    /// <param name="collision">대상 오브젝트의 콜라이더</param>
    private void OnTriggerExit2D(Collider2D collision)
    {
        //만약 오브젝트가 해당 테그라면?
        if (collision.CompareTag(_targetTag))
        {
            //감지 여부를 false로 바꾸어주기
            Sensed = false;
        }
    }

}

Sencer의 경우 유니티의 트리거 이벤트 함수를 사용하여 특정 태그를 가진 오브젝트를 감지할 수 있도록 구현하였습니다

 

이후 PlayerJump를 수정해야 합니다

using UnityEngine;

public class PlayerJump : MonoBehaviour
{
    /// <summary>
    /// 점프파워
    /// </summary>
    [SerializeField] private float _jumpPower;

    /// <summary>
    /// 물리 사용을 위하여 Rigidbody를 받기
    /// </summary>
    private Rigidbody2D _rigid;

    /// <summary>
    /// Input사용을 위하여 InputController를 받기
    /// </summary>
    private InputController _input;

    /// <summary>
    /// 지면 여부를 감지하기 위한 센서
    /// </summary>
    private Sencer _ground;

    private void Awake()
    {
        //GetComponent로 찾아오기
        _input = GetComponent<InputController>();
        _rigid = GetComponent<Rigidbody2D>();

        //자식에서 Sencer를 찾아오기
        _ground = GetComponentInChildren<Sencer>();

        //Input에 점프 이벤트 구독
        _input.OnJumpEvent += HandleJump;
    }

    /// <summary>
    /// 점프 이벤트 처리를 위한 함수
    /// </summary>
    private void HandleJump()
    {
        //지면이 감지되었다면?
        if (_ground.Sensed)
        {
            //점프를 한다
            _rigid.AddForce(Vector2.up * _jumpPower, ForceMode2D.Impulse);
        }
    }

    private void OnDestroy()
    {
        //Input이 아직 존재한다면?
        if (_input != null)
        {
            //이벤트 구독을 해제
            _input.OnJumpEvent -= HandleJump;
        }
    }
}

PlayerJump에 지면 감지 로직을 추가하였습니다 이제 플레이어는 발이 지면과 닿아 있는 경우에만 점프를 할 수 있습니다

 

이제 만든 Sencer 컴포넌트를 GroundSencer오브젝트에 넣어주세요

 

그 후 Sencer의 TargetTag를 Ground로 설정하여 주세요

 

실행시켜 본다면 땅에 있을 때만 점프가 되는 것을 확인할 수 있습니다

 

다음 글에서는 에셋을 다운로드하고 플레이어의 애니메이션을 적용해 보도록 하겠습니다

반응형