유니티 챌린지/쿠키런

쿠키런모작_ 지금까지 구현 한 것 정리하기

minquu 2021. 4. 13. 22:50
반응형

지금까지 구현한 것

 

-화면 백그라운드, 바닥 움직이기

 

-쿠키 작동하기 (런, 점프, 슬라이드 등등)

   애니메이션 
      런 점프 슬라이드 정상적으로 작동
   버튼 클릭시 
      점프   슬라이드

 

-장애물 생성하기 (랜덤하게 생성하게 되어있음(차후 변경))

   아래 솟공, 위에 꼬치


-게임 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);
    }
}
반응형