5주차 숙제 게임개발

 

Run & Jump - 프로토타입 설명

1.마우스를 누르면 캐릭터 머리 위에 파워 게이지가 표시됨

2.마우스를 놓으면 놓은 방향으로 캐릭터가 빙글빙글 돌아가며 발판들을 넘어감

3.이미 한번 착지한 발판은 점수 x , 발판을 처음 밟을때만 점수 증가

 

오늘 구현 한것

1. 블럭 사이에 있을때 점프로 가시 통과할 수 있게 구현

2. 블럭 끼리 겹치지 않게 구현 - BlockSpanwer에서 생성 로직 변경 필요

3. LV에 따른 스테이지 난이도 변경

4. 블럭에 빠지는 함정 만들기(함정 특징: 땅바닥인척 하지만 갑자기 내려감)

4-1. Player 점프 로직 변경(떨어지는 블럭 위에 있을때 점프 가능하게)

 

구현 목표

1.옆으로 흐르는 백그라운드 만들기

2.Title Scene 만들기(마스크 트랜지션 사용해서 화면 옮겨보기)

3.파티클 및 연출 효과 넣어 시각적으로 좋게 만들기

4.사운드 추가하기


1. 블럭 사이에 있을때 점프로 가시 통과할 수 있게 구현

 

각 블럭의 높이를 줄여 공간을 확보 하였고 , 가시의 갯수가 많아 게임이 너무 어려워 1개로 듬성듬성 배치하기로 함

 

2. 블럭 끼리 겹치지 않게 구현 - BlockSpanwer에서 생성 로직 변경 필요

코드를 따로 변경하진 않았고, 블럭의 속도를 전부 똑같이 통일 하였다.

전부 똑같이 변경한 이유는 게임이 [점프킹] 같은 점프 시스템을 가져왔다보니

블럭들의 속도가 종류에 상관없이 일정해야  게임의 난이도가 좀 나아질것 같다.

 

3. LV에 따른 스테이지 난이도 변경

BlockSpanwer.cs

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

public enum defineNum
{
    Blokc_End_posX = -17, //해당 x좌표에 닿으면 pivot이 닿으면 사라지는 좌표 
}

public class BlockSpawner : MonoBehaviour
{
    [SerializeField] List<Block> block_list;
    [SerializeField] float blockSummonCoolTime = 2.0f;

    [SerializeField] float startPosX = 17.0f; //생성 시작되는 위치 x좌표
    [SerializeField] float startPosY_Min = -5.0f;
    [SerializeField] float startPosY_Max = 2.0f;

    Coroutine coroutineBlockSpanw;
    [SerializeField] List<float> blockSpawnPosY;

    [SerializeField] bool isstop = false;

    int isSpawnBlockIndex = -1;

    public void BlockSpawnerON()
    {
        if (!isstop)
        {
            if (coroutineBlockSpanw == null)
            {
                coroutineBlockSpanw = StartCoroutine(BlockSpanw());
            }
            else
            {
                StopCoroutine(coroutineBlockSpanw);
                coroutineBlockSpanw = StartCoroutine(BlockSpanw());
            }
        }
    }

    public void BlockSpawnerOFF()
    {
        if (coroutineBlockSpanw != null)
        {
            StopCoroutine(coroutineBlockSpanw);
        }
    }

    IEnumerator BlockSpanw()
    {
        float LevelSuummonCoolTime;

        while (true)
        {
            MakeBlock();

            //현재 레벨의 10% 만큼 블럭 생성주기 증가 -> 블럭이 늦게 등장함
            LevelSuummonCoolTime = blockSummonCoolTime + ( (GameManager.Instance.CurLevel - 1) *  0.1f);
            
            yield return  new WaitForSeconds(LevelSuummonCoolTime);
        }
    }

   private void MakeBlock()
    {
        //블록 생성확률이 100% 에서 75%까지 떨어짐
        //생성확률은 6레벨 이하까지만 적용 그 이후로는 50% 동일
        int curStageLv = GameManager.Instance.CurLevel;
        int SuumonPercent = curStageLv >= 5 ? 5 : (curStageLv - 1);

        if (SuumonPercent <= Random.Range(0, 20))
        {

            int type = Random.Range(0, block_list.Count);

            Block block = Instantiate(block_list[type]);
            block.gameObject.SetActive(false);

            float x = startPosX;
            //y 범위 : -4.5 ,-1.5,1.5, 4.5
        
            //한번 생겼던 위치에 다시 생기지 않는 함수
            int y;
            do
            {
                y = Random.Range(0, blockSpawnPosY.Count);
            }
            while (isSpawnBlockIndex == y);
            isSpawnBlockIndex = y;


            block.Block_pos = new Vector3(x, blockSpawnPosY[y], 0);
            //레벨 수치의 10% 만큼 모든 블럭의 speed 증가
            if (curStageLv > 1) block.Speed += (curStageLv * 0.1f);
            block.gameObject.SetActive(true);
        }
    }
}

블럭 생성시 게임매니저에서 현재 스테이지 레벨을 호출 하여 블록 생성 확률,블록 생성 주기,블록 이동 속도 수치를 조절하게 함.

4. 블럭에 빠지는 함정 만들기(함정 특징: 땅바닥인척 하지만 갑자기 내려감)

 

1.좌우로 이동하는 블록 추가

 

BlockGroup.cs

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

public class BlockGroup : Block
{
    [SerializeField] protected List<GameObject> blocks;

    private void Update()
    {
        MoveBlock();
    }
}

MovePattern.cs

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

public class MovePattern : MonoBehaviour
{
    [SerializeField] float avoidSpeed = 2.0f;

    int dir = 1;
    private Vector3 originPos;
    private float moveRange = 1.0f;

    private void Start()
    {
    	//처음 위치 좌표 저장
        originPos = transform.localPosition;
    }

    private void Update()
    {
    	//이동거리(MoveRange) 이상 이동한경우 방향값(dir) 변경
        if(Mathf.Abs(transform.localPosition.x - originPos.x) >= moveRange) dir *= -1;
         
        transform.localPosition += dir * ((Vector3.right  * avoidSpeed)) * Time.deltaTime;
    }
}

좌,우로 왔다 갔다 하는 패턴을 만들때 왼쪽/오른쪽 좌표로 설정해도 되지만

조건문을 이동거리(MoveRange)로 사용하면 좌표 값을 건드리지 않고 이동거리로 제어가 가능해져서 유용하다.

2.밟으면 떨어지는 블록 추가

DropPattern.cs

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

public class DropPattern : MonoBehaviour
{
    [SerializeField] float DropSpeed = 0.5f;

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if(collision.gameObject.CompareTag("Player"))
        {
            StartCoroutine(Drop());
        }
    }

    IEnumerator Drop()
    {
        while(transform.position.y >= -12f)
        {
            transform.position += Vector3.down * DropSpeed * Time.deltaTime;
            yield return null;
        }
    }

}

 

위에 블럭들의 콜리더 분리가 필요해서 부모 오브젝트를 만들고 자식으로 3개의 블럭을 추가하였다.

각 블럭마다 콜리더를 추가하였고 기믹이 필요한곳에만 스크립트(MovePattern.cs , DropPattern.cs)를 넣어서 사용 하였고 3개의 블럭은 동시에 같은속도로 같이 이동해야 되기때문에

새 스크립트인 BlockGroup 스크립트를 만들고 Block을 부모로 상속하여 이동하는 함수를 사용하였다.

 

4-1. Player 점프 로직 변경(떨어지는 블럭 위에 있을때 점프 가능하게)

떨어지는 블럭에 캐릭터가 서있으면 OnColliderEnter() 메서드가 자꾸 호출하여서 점프가 안되는 버그가 있었다.

Collider 함수 안에 점프상태를 초기화하는 내용이 있음

대처방법으로 콜리더가 호출 되더라도 점프 상태인 경우에만 점프상태를 초기화 할 수 있게 로직을 변경하였음 

 

떨어지지만 게이지는 초기화 되지 않기 때문에 점프가 가능해짐

 

Player.cs

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Block"))
        {
            // 캐릭터가 점프 + 점프중 이라는 상태를 만족해야만 멈춤
            if (isJump && isJumping)
            {
                PlayerStop();
                anim.SetBool("isJump", false);
            }
        }

        if (collision.gameObject.CompareTag("Spike"))
        {
            Debug.Log("Player 가시 닿음");
            isdead = true;
            anim.SetBool("isDead", true);
            PlayerStop();
            GameManager.Instance.PlayerDie();
        }
    }

 

+ Recent posts