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. 블럭에 빠지는 함정 만들기(함정 특징: 땅바닥인척 하지만 갑자기 내려감)
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)로 사용하면 좌표 값을 건드리지 않고 이동거리로 제어가 가능해져서 유용하다.
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() 메서드가 자꾸 호출하여서 점프가 안되는 버그가 있었다.
대처방법으로 콜리더가 호출 되더라도 점프 상태인 경우에만 점프상태를 초기화 할 수 있게 로직을 변경하였음
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();
}
}
'내일배움캠프_Unity_6기 > TIL(Today I Learend)' 카테고리의 다른 글
TIL : 2024-09-02(월) :: 옵저버패턴 , C#(Unity) Delegate,Event 예제 (0) | 2024.09.02 |
---|---|
TIL : 2024-08-29(목) (0) | 2024.08.29 |
TIL : 2024-08-27(화) (0) | 2024.08.27 |
TIL : 2024-08-26(월) (0) | 2024.08.26 |
TIL : 2024-08-22(금) (0) | 2024.08.23 |