2D Platform

플랫포머 게임을 제작하다 보니 다양한 플랫폼을 제작해야 하는 상황이 왔다..!

제작하면서 쉽게 만들었던 방법도 있고 다양한 방법이 많아서 여러가지 적어보고 포스팅할려고 한다.

플랫폼 게임이란 게임의 형식 또는 장르. 플랫포머나 점프 앤 런이라고도 한다. 플랫폼이란 발판을 의미한다. 따라서 플랫포머 게임이란 발판이 등장하는 게임을 뜻한다. 어떤 장르와 결합되었든 기본적으로 액션 게임의 하위 부류다.(나무위키)

이동 플랫폼

플랫포머 게임에서 가장 많이 등장하는 플랫폼으로 시작지점과 마지막지점을 왕복운동을 하는 플랫폼을 말한다.

이동 플랫폼도 세분화를 하게 된다면 정말 많은 방식으로 나뉘지만 베이스를 잘 만들어 두고 이후에 세분화할 수 있도록 하는 편이 좋다.

이미지

이동 플랫폼의 필수 데이터는 시작점, 종료지점, 속도, 멈춰있는 시간정도가 필요하다.

빈 오브젝트에 움직이게할 플랫폼 그리고 시작위치, 종료위치를 가져가는 빈오브젝트(Transform만 있으면 된다.)

이미지

위 처럼 설정해야 하는 이유는 부모인 MovingTile만 옮겨도 시작 위치와 종료위치 또한 부모의 Tramform만큼 이동하기 때문에 사용에 용이하다.

using System.Collections;
using UnityEngine;

public class MovingPlatform : MonoBehaviour
{
    public Transform startpos;  // 컴포넌트 할당
    public Transform endPos;
    private Transform desPos;
    public float speed;
    public float stopTime;

    private void OnEnable()
    {
        transform.position = startpos.position;
        desPos = endPos;
        StartCoroutine(nameof(Moving));
    }

    private void OnCollisionEnter2D(Collision2D col)
    {
        if (col.transform.CompareTag("Player"))
        {
            if(transform.position.y < col.transform.position.y)
                col.transform.SetParent(transform);
        }
    }

    private void OnCollisionExit2D(Collision2D other)
    {
        if (other.transform.CompareTag("Player"))
        {
            other.transform.SetParent(null);
        }
    }

    private IEnumerator Moving()
    {
        while (true)
        {
            transform.position = Vector2.MoveTowards(transform.position, desPos.position, Time.deltaTime * speed);
            
            if (Vector2.Distance(transform.position, desPos.position) <= 0.05f)
            {
                if (stopTime > 0f)
                    yield return new WaitForSeconds(stopTime);

                if (desPos == endPos) desPos = startpos;
                else desPos = endPos;
            }

            yield return null;
        }
    }
}

움직이는 부분은 코루틴으로 MoveTowards함수로 처리했다.

Distance함수를 통해서 종료위치를 체크하고 정지 시간이 있다면 해당 시간만큼 정지 후 위치를 전환시켜서 실행한다.

위의 OnCollision함수는 플랫폼의 움직임 만큼 플레이어도 움직여야 하기 때문에 자식으로 설정하여 따라가게 한다.

대각선 움직임도 가능하고 덜컹거리는? 움직임을 추가하고 싶다면 다양하게 연출 또한 가능하다.

뒤에서 소개하게될 다양한 플랫폼과도 합쳐서 다양하게 연출도 기대된다..!

슬라이드 플랫폼

이번에는 코드보다 유니티에서 제공해주는 기능인 effector 2D를 사용해보았다..!

이미지

코드로 제어하는게 아니라 컴포넌트를 할당하면 되기 때문에 해당 컴포넌트 위주로 공부하면 될 것 같다.

이미지

사용하기 위해선 BoxCollider2D에서 Used By Effector를 체크하고 컴포넌트를 사용하면 된다.

Unity Documentation

간단하게 사용방법이 나와 있으며 speed로 방향을 제어할 수 있다.(-20, 20)

소멸 플랫폼

똑같이 많이 사용되는 유령형식의 플랫폼이다.

일정 시간이 지나면 플랫폼이 사라지고 다시 생성되거나 이스터에그같은 요소로 넣을 수 있다면 영구 삭제로도 사용이 된다.

이미지

현재는 애니메이션이 없기 때문에 알파값을 조절하여 투명도로 가시성을 사용했다.

똑같이 필요한 데이터는 사라지는데 걸리는 시간, respawn여부, 재생성 시간이 있다.

using System.Collections;
using UnityEngine;

public class GhostPlatform : MonoBehaviour
{
    public float fadeTime;
    public bool respawn;
    public float respawnTime;
    
    private SpriteRenderer _spriteRenderer;
    private BoxCollider2D _boxCollider2D;
    private Coroutine CoroutineFade = null;
    private void Awake()
    {
        _spriteRenderer = GetComponent<SpriteRenderer>();
        _boxCollider2D = GetComponent<BoxCollider2D>();
    }

    private void OnCollisionEnter2D(Collision2D col)
    {
        if (col.transform.CompareTag("Player"))
        {
            if (CoroutineFade == null)
                CoroutineFade = StartCoroutine(Fade(1, 0));
        }
    }
    
    private IEnumerator Fade(float start, float end)
    {
        float current = 0;
        float percent = 0;

        while (percent < 1)
        {
            current += Time.deltaTime;
            percent = current / fadeTime;

            Color color = _spriteRenderer.color;
            color.a = Mathf.Lerp(start, end, percent);
            _spriteRenderer.color = color;

            yield return null;
        }

        _boxCollider2D.enabled = false;

        if (respawn)
        {
            yield return new WaitForSeconds(respawnTime);
            CoroutineFade = null;
            _boxCollider2D.enabled = true;
            _spriteRenderer.color = new Color(1, 1, 1);
        }
    }
}

투명도를 조절해야하기 때문에 SpriteRenderer, 충돌영역을 지웠다 켰다 해야하기 때문에 BoxCollider2D를 할당 받는다.

OnCollisionEnter2D의 중복입력을 방지하기 위해 코루틴Fade를 변수로 만들어 관리한다.

위치 플랫폼

얇은 플랫폼의 경우 플레이어는 점프로 뛰어 넘을 수 있고 아래키로 내려갈 수 있어야한다.

GIF

다양하게 동작가능하며 다른플랫폼에 조합하여 사용하기 적합하다.

이번 플랫폼은 구현된 컴포넌트와 스크립트를 같이 사용한다.

Unity Documentation

Platform Effector 2D는 앞서 본 슬라이드 플랫폼과 같이 사용하고 해당 레이어를 지정할 수 있다.

코드로 필요한 부분은 아래 점프 즉, Jump off기능때문에 넣어야 한다.

using UnityEngine;

public class PositionPlatform : MonoBehaviour
{
    public float retentionTime;
    private PlatformEffector2D _effector2D;
    private float _waitTime;

    private void Awake()
    {
        _effector2D = GetComponent<PlatformEffector2D>();
    }

    private void Update()
    {
        if (Input.GetKey(KeyCode.DownArrow))
        {
            if (_waitTime <= 0)
            {
                _effector2D.rotationalOffset = 179f;
                _waitTime = retentionTime;
            }
            else
            {
                _waitTime -= Time.deltaTime;
            }
        }

        if (Input.GetKey(KeyCode.Space))
        {
            _effector2D.rotationalOffset = 0f;
        }
    }
}

Platform Effector 2D는 충돌영역을 각도로 지정할 수 있는데 해당 각도를 뒤집어 가며 제어하는 방식이다.

스프링 플랫폼

스프링 플랫폼의 경우 매우 단순하다. 플레이어가 충돌하면 위쪽으로 힘을 주면 끝..!

Physics Material 2D의 Bounciness기능을 사용하여 제작도 가능하지만 높이에 따라 달라지기 때문에 일정한 힘 그리고 순간적인 힘ForceMode2D.Impulse을 줘야한다.

gif

using UnityEngine;

public class JumpingPlatform : MonoBehaviour
{
    public float bounce = 30f;
    private void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.CompareTag("Player"))
        {
            col.gameObject.GetComponent<Rigidbody2D>().AddForce(Vector2.up * bounce, ForceMode2D.Impulse);
        }
    }
}

태그: ,

카테고리:

업데이트:

댓글남기기