반응형
지금까지 구현한 것
-화면 백그라운드, 바닥 움직이기
-쿠키 작동하기 (런, 점프, 슬라이드 등등)
애니메이션
런 점프 슬라이드 정상적으로 작동
버튼 클릭시
점프 슬라이드
-장애물 생성하기 (랜덤하게 생성하게 되어있음(차후 변경))
아래 솟공, 위에 꼬치
-게임 UI 및 기능
체력 게이지 및 UI
체력게이지는 시간이 지날수록 깍임
게이지 0일때 게임 오버
게임오버 및 화면클릭시 리스타트
젤리 먹으면 점수 올라감
+ 추가해야하는 것
부딪치면 체력이 깍이게 해야함
아이템 구현하기
젤리 및 캐릭터 이펙트 추가하기 (디테일)
사운드 추가하기
# 개선점
스크립터를 너무 많이 쓴것 같음. 메서드나 게임매니저, 델리게이트를 조금 더 많이 쓰는 연습을 해야할듯
--------
동영상
스크린샷
코드
PlayerController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PlayerController : MonoBehaviour
{
//유아이가져오기
public GameUI gameUI;
//점프 힘
public float jumpForce = 250f;
//누적 점프 횟수
private int jumpCount = 0;
//바닥에 닿았는지 나타냄
private bool isGrounded = false;
//사망 상태
public bool isDie = false;
//사용할 리지드바디 컴포넌트
public Rigidbody2D playerRigidbody;
//사용할 애니메이터 컴포넌트
public Animator animator;
//슬라이드 상태인지 나타냄
public bool isSlide = false;
//콜리더 배열
public CapsuleCollider2D[] components;
//죽는 애니모션 유무
public bool deadAni = false;
void Start()
{
this.playerRigidbody = this.GetComponent<Rigidbody2D>();
this.animator = this.GetComponent<Animator>();
this.gameUI.jumpBtn.onClick.AddListener(() =>
{
Jump();
});
}
void Update()
{
this.animator.SetBool("Grounded", this.isGrounded);
}
public void OnPointerDown() {
this.isSlide = true;
this.animator.SetBool("Slide", this.isSlide);
this.components[0].enabled = false;
this.components[1].enabled = true;
}
public void OnPointerUp() {
this.isSlide = false;
this.animator.SetBool("Slide", this.isSlide);
this.components[0].enabled = true;
this.components[1].enabled = false;
}
private void Jump()
{
if (this.isDie) return;
if (this.jumpCount < 2)
{
//점프 횟수 증가
this.jumpCount++;
//점프 직전에 속도를 순간적으로 0,0으로 변경
playerRigidbody.velocity = Vector2.zero;
//리지드바디에 위쪽 힘주기
this.playerRigidbody.AddForce(new Vector2(0, this.jumpForce));
if (this.jumpCount == 2)
{
this.animator.SetTrigger("Jump2");
}
}
else if (this.playerRigidbody.velocity.y > 0)
{
//현재속도를 절반으로
this.playerRigidbody.velocity = this.playerRigidbody.velocity * 0.5f;
}
}
private void Slide() {
}
public void Die()
{
//사망처리
//애니메이터의 Die 트리거 파라메터 설정
this.animator.SetTrigger("Die");
//속도를 0으로 변경
this.playerRigidbody.velocity = Vector2.zero;
//사망 상태 변경
this.isDie = true;
this.deadAni = true;
//게임매니저의 게임오버 메서도 소환
GameManager.instance.OnPlayerDead();
}
private void OnTriggerEnter2D(Collider2D collision)
{
//트리거 콜라이더를 가진 장애물과의 충돌감지
if (collision.tag == "Dead" && !this.isDie)
{
//충돌한 상대방의 태그가 Dead고 아직 죽지 않았다면
this.Die();
}
//트리거 콜라이더를 가진 장애물과의 충돌감지
if (collision.tag == "jelly01" && !this.isDie)
{
//충돌한 상대방의 태그가 Dead고 아직 죽지 않았다면
Debug.Log("젤리를 먹었습니다");
//충돌 후 사라짐
collision.gameObject.SetActive(false);
//충돌하면 GameManage에 있는 score 점수를 올림
GameManager.instance.AddScore(19840);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
//바닥에 닿았음을 감지 하는 처리
//어떤 콜라이더와 닿았으며 충돌 표면이 위쪽을 보고있으면
if (collision.contacts[0].normal.y > 0.7f)
{
//isGrounded를 true로 변경 누적점프 횟수를 0으로 리셋
this.isGrounded = true;
this.jumpCount = 0;
}
}
private void OnCollisionExit2D(Collision2D collision)
{
//바닥에서 벗어났음을 감지하는 처리
isGrounded = false;
}
}
ScrollingObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScrollingObject : MonoBehaviour
{
public float speed = 10f;
public PlayerController player;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (player.isDie == false)
{
transform.Translate(Vector3.left * speed * Time.deltaTime);
}
if (player.isDie == true) {
transform.Translate(Vector3.zero);
}
}
}
BackgroundLoop
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BackgroundLoop : MonoBehaviour
{
private float width; //배경의 가로 길이
public float createValue = 5;
public PlayerController player;
private void Awake()
{
//가로 길이를 측정하는 처리
BoxCollider2D backgroundCollider = this.GetComponent<BoxCollider2D>();
this.width = backgroundCollider.size.x;
}
void Update()
{
if (player.isDie == false) {
if (this.transform.position.x <= -width * 2)
{
this.Reposition();
}
}
}
private void Reposition()
{
//위치를 재 정렬하는 메서드
Vector2 offset = new Vector2(width * createValue, 0);
transform.position = (Vector2)transform.position + offset;
}
}
Circulation
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Circulation : MonoBehaviour
{
public float speed = 15;
public float startPositon;
public float endPositon;
public PlayerController player;
void Update()
{
if (player.isDie == false) {
transform.Translate(-1 * speed * Time.deltaTime, 0, 0);
//목죠지점에 도달하면
if (transform.position.x <= endPositon)
{
ScrollEnd();
}
}
}
void ScrollEnd()
{
//원래 위치로 초기화 시킨다.
transform.Translate(-1 * (endPositon - startPositon), 0, 0);
}
}
GameManager
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public static GameManager instance; //싱글턴을 할당할 변수
public bool isGameover = false;
//public Text scoreText;
//public GameObject gameoverUI;
private int score = 0;
public GameUI gameUI;
public float hpMax = 1;
public float hp;
private float delta;
public PlayerController player;
void Awake() {
if (instance == null)
{
instance = this;
}
else
{
Destroy(gameObject);
}
}
private void Start()
{
this.hp = this.hpMax;
}
void Update()
{
if (isGameover == false) {
this.delta += Time.deltaTime;
this.gameUI.hpBarUI.fillAmount = (hp - (delta * 0.07f));
}
if (this.gameUI.hpBarUI.fillAmount == 0 && player.deadAni == false) {
player.Die();
}
if (isGameover && Input.GetMouseButtonDown(0)) {
//게임오버 상태에서 클릭시 다시 시작
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
public void AddScore(int newScore) { //점수 추가하는 메서드
if (!isGameover) {
//점수를 증가
score += newScore;
string scoreStr = string.Format("{0:n0}", score);
gameUI.scoreText.text = scoreStr;
}
}
public void OnPlayerDead()
{
//현재상태를 게임오버로 상태로
isGameover = true;
//게임오버 UI 활성화 //추가 필요
gameUI.gameOverUI.SetActive(true);
}
}
GameUI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameUI : MonoBehaviour
{
public Button jumpBtn;
public Button slideBtn;
public GameObject gameOverUI;
public Image hpBarUI;
public Text scoreText;
}
HpGaugeEff
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HpGaugeEff : MonoBehaviour
{
public Image img;
public GameObject eff;
public float value = 2;
private float width;
void Start()
{
this.width = this.img.GetComponent<RectTransform>().rect.width;
}
void Update()
{
var pos = this.eff.transform.localPosition;
pos.x = this.img.fillAmount * this.width -12 -2; // 12: eff의 넓이의 반, 2: offset
this.eff.transform.localPosition = pos;
}
}
JellyMoving
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class JellyMoving : MonoBehaviour
{
public float speed = 14f;
public PlayerController player;
void Start()
{
}
// Update is called once per frame
void Update()
{
if (player.isDie == false)
{
transform.Translate(Vector3.left * speed * Time.deltaTime);
}
if (player.isDie == true)
{
transform.Translate(Vector3.zero);
}
}
}
ScrewMoivng
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScrewMoivng : MonoBehaviour
{
public float speed = 10f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (GameManager.instance.isGameover == false)
{
transform.Translate(Vector3.left * speed * Time.deltaTime);
}
if (GameManager.instance.isGameover == true)
{
transform.Translate(Vector3.zero);
}
}
}
ScrewSpawner
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScrewSpawner : MonoBehaviour
{
public GameObject screwPrefab;
public float timeBetSpawnMin = 4.25f;
public float timeBetSpawnMax = 8.25f;
private float timeBetSpawn; //다음배치까지의 시간 간격
private float xPos = 20f; // x 소환 위치
private float lastSpawnTime;
// Start is called before the first frame update
void Start()
{
this.timeBetSpawn = 0;
this.lastSpawnTime = 0;
}
// Update is called once per frame
void Update()
{
if (Time.time >= lastSpawnTime + timeBetSpawn && GameManager.instance.isGameover == false) {
//기록된 마지막 배치 시점을 현재 시점으로 갱신
this.lastSpawnTime = Time.time;
//다음 배치까지의 시간 간격을 사이에서 랜덤 설정
this.timeBetSpawn = Random.Range(timeBetSpawnMin, timeBetSpawnMax);
//
newObject();
}
}
public void newObject()
{
Instantiate(screwPrefab, new Vector3(14.23f, -1.415f, 0), Quaternion.identity);
}
}
StickMoving
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StickMoving : MonoBehaviour
{
public float speed = 12f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (GameManager.instance.isGameover == false)
{
transform.Translate(Vector3.left * speed * Time.deltaTime);
}
if (GameManager.instance.isGameover == true)
{
transform.Translate(Vector3.zero);
}
}
}
StickSpawner
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StickSpawner : MonoBehaviour
{
public GameObject stickPrefab;
public float timeBetSpawnMin = 6.25f;
public float timeBetSpawnMax = 12.25f;
private float timeBetSpawn; //다음배치까지의 시간 간격
private float xPos = 20f; // x 소환 위치
private float lastSpawnTime;
// Start is called before the first frame update
void Start()
{
this.timeBetSpawn = 0;
this.lastSpawnTime = 0;
}
// Update is called once per frame
void Update()
{
if (Time.time >= lastSpawnTime + timeBetSpawn && GameManager.instance.isGameover == false)
{
//기록된 마지막 배치 시점을 현재 시점으로 갱신
this.lastSpawnTime = Time.time;
//다음 배치까지의 시간 간격을 사이에서 랜덤 설정
this.timeBetSpawn = Random.Range(timeBetSpawnMin, timeBetSpawnMax);
//
newObject();
}
}
public void newObject()
{
Instantiate(stickPrefab, new Vector3(20.48f, 2.8f, 0), Quaternion.identity);
}
}
반응형
'유니티 챌린지 > 쿠키런' 카테고리의 다른 글
쿠키런_ 젤리 생성 및 먹기 (0) | 2021.04.13 |
---|---|
쿠키런_ 죽음 시 게임오버 -> 클릭 시 다시 시작 (0) | 2021.04.13 |
쿠키런_체력 게이지 만들기 (2) | 2021.04.13 |