본문 바로가기
유니티강좌

플래피 치킨(Flappy Chicken) 게임만들기. 병아리 구출게임. 마우스연타(연속탭) 게임 | 플래피 버드(Flappy Bird) 카피게임. 유니티 2D 게임제작강좌

by Ncube 2021. 1. 17.

마우스 왼쪽 버튼을 연타하거나 안드로이드 폰 화면을 연속 탭하면서 떨어지는 치킨을 점점 위로 올려 다가오는 장애물을 피해 병아리를 구출하는게임입니다. 상단에는 구출한 숫자가 표시되며 좌측하단에는 재시작(Restart), 일시정지(Pause) 버튼이 있어 조작가능하며 플레이 시작시 딜레이 타임을 두어 스타트를 원활히 할 수 있는 게임입니다.
유명한 게임인 플래피 버드(Flappy Bird)게임 비슷하게 만든 플래피 치킨(Flappy Chicken) 게임 만들기를 하나씩 따라해 볼 수 있게 총 3부로 나눠서 영상을 만들었습니다. 

 

 

 

 

1부에서는 배경(Background), 무한반복배경(Scrolling Repeat BG), 플레이어(Chicken), 프리팹(Prefabs)등을 다루었습니다.  | 유니티 게임 개발 튜토리얼(Unity & C# Script)

 

00:30 씬 등록
00:40 배경이미지
00:50 무한반복배경(Repeat Forest)
02:35 플레이어(Chicken) 설정
04:35 프리팹(FriedChicken - 충돌시 나타나는 오브젝트)
06:15 프리팹(Chick - 구출해야할 오브젝트)
07:10 ~ 10:42 프리팹(Lava1,2,3 - 좌측으로 다가오는 충돌체(장애물))

 

 

 

 

 

2부에서는 용암 장애물(LavaSpawner)생성기 만들기, 아이템(ChickSpawner) 생성기 만들기, 화면 위아래 불꽃 애니메이션(Fire Field) 만들기, 효과음 넣기(아이템(병아리) 획득시, 장애물(용암기둥, 불꽃)에 부딪혔을 때 효과음 발생)등을 다루었습니다.  | 유니티 게임 개발 튜토리얼(Unity & C# Script)

 

00:29 Anim_FriedChicken의 Loop Time 체크 해제
00:45 용암 장애물(LavaSpawner) 생성기 만들기
02:17 아이템(ChickSpawner) 생성기 만들기
03:47 화면 위아래 불꽃 애니메이션(Fire Field) 만들기 
09:35 효과음 넣기 - 아이템(병아리) 획득시, 장애물(용암기둥, 불꽃)에 부딪혔을 때 효과음 발생 

 

 

 

 

 

3부에서는 시작시 딜레이타임 적용(3, 2, 1, GO!) / 스코어보드(병아리 구출시 카운터) / 버튼(재시작, 일시정지) 등을 다루었습니다.  | 유니티 게임 개발 튜토리얼(Unity & C# Script)

 

00:28 시작시 딜레이타임 적용(3, 2, 1, GO!)
02:26 스코어보드(병아리 구출시 카운터)
06:06 버튼(재시작, 일시정지)
09:32 게임플레이
10:22 안드로이드폰 테스트

 

 

 

[RepeatBG.cs]

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

public class RepeatBG : MonoBehaviour
{
    [SerializeField] [Range(1f, 20f)] float speed = 2f;

    [SerializeField] float posValue;

    Vector2 startPos;
    float newPos;

    void Start()
    {
        startPos = transform.position;
    }

    void Update()
    {
        newPos = Mathf.Repeat(Time.time * -speed, posValue);
        transform.position = startPos + Vector2.right * newPos;
    }
}

 

 

 

[FriedChicken.cs]

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

public class FriedChicken : MonoBehaviour
{
    void Start()
    {
        Destroy(gameObject, 1f);
    }
}

 

 

[Player.cs]

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

public class Player : MonoBehaviour
{
    [SerializeField] float FlappyPower = 550f;

    Rigidbody2D rb;
    float startTime;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        rb.isKinematic = true;
        startTime = Time.time + 3f;
    }

    void Update()
    {
        if (Time.time >= startTime)
            rb.isKinematic = false;

        if (Input.GetMouseButtonDown(0))
        {
            rb.AddForce(new Vector2(0f, FlappyPower), ForceMode2D.Force);
        }

        /*
        if(Input.touchCount > 0)
        {
            Touch touch = Input.GetTouch(0);

            switch (touch.phase)
            {
                case TouchPhase.Began:
                    rb.AddForce(new Vector2(0f, FlappyPower), ForceMode2D.Force);
                    break;
            }
        }
        */
    }
}

 

 

[Lava.cs]

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

public class Lava : MonoBehaviour
{
    [SerializeField] GameObject friedChicken;

    void OnTriggerEnter2D(Collider2D col)
    {
        if (col.gameObject.tag.Equals("Player"))
        {
            SfxControl.SfxFried();
            Instantiate(friedChicken, col.gameObject.transform.position, Quaternion.identity);
            Destroy(col.gameObject);
        }
    }
}

 

 

[Obstacle.cs]

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

public class Obstacle : MonoBehaviour
{
    [SerializeField] float speed = -5f;

    void Start()
    {
        Destroy(gameObject, 10f);
    }

    void Update()
    {
        transform.position = new Vector2(transform.position.x + speed * Time.deltaTime, transform.position.y);
    }
}

 

 

[ObstacleSpawner.cs]

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

public class ObstacleSpawner : MonoBehaviour
{
    public GameObject[] obstacles;

    void Start()
    {
        InvokeRepeating("SpawnObstacle", 3f, 2f);
    }

    void SpawnObstacle()
    {
        int obstacleNum = Random.Range(0, obstacles.Length);

        Instantiate(obstacles[obstacleNum], transform.position, Quaternion.identity);
    }
}

 

 

[Fire.cs]

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

public class Fire : MonoBehaviour
{
    [SerializeField] GameObject friedChicken;

    void OnTriggerEnter2D(Collider2D col)
    {
        SfxControl.SfxFried();
        Instantiate(friedChicken, col.gameObject.transform.position, Quaternion.identity);
        Destroy(col.gameObject);
    }
}

 

 

[Item.cs]

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

public class Item : MonoBehaviour
{
    [SerializeField] float speed = -5f;

    void Start()
    {
        Destroy(gameObject, 10f);
    }

    void Update()
    {
        transform.position = new Vector2(transform.position.x + speed * Time.deltaTime, transform.position.y);
    }

    void OnTriggerEnter2D(Collider2D col)
    {
        if (col.gameObject.tag.Equals("Player"))
        {
            SfxControl.SfxGetItem();
            ItemCounter.numItems += 1;
            Destroy(gameObject);
        }
    }
}

 

 

[ItemSpawner.cs]

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

public class ItemSpawner : MonoBehaviour
{
    [SerializeField] GameObject item;
    Vector2 itemSpawnPos;

    void Start()
    {
        InvokeRepeating("SpawnItem", 2f, 2f);
    }

    void SpawnItem()
    {
        int randomValue = (int)Random.Range(0f, 2f);

        switch (randomValue)
        {
            case 0:
                itemSpawnPos = new Vector2(transform.position.x, 2.7f);
                break;
            case 1:
                itemSpawnPos = new Vector2(transform.position.x, -2.7f);
                break;
            case 2:
                itemSpawnPos = new Vector2(transform.position.x, 0f);
                break;
        }

        Instantiate(item, itemSpawnPos, Quaternion.identity);
    }
}

 

 

[SfxControl.cs]

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

public class SfxControl : MonoBehaviour
{
    static AudioSource audioSource;
    public static AudioClip audioClip1, audioClip2;

    void Start()
    {
        audioSource = GetComponent<AudioSource>();
        audioClip1 = Resources.Load<AudioClip>("FriedChicken");
        audioClip2 = Resources.Load<AudioClip>("GetItem2");
    }

    public static void SfxFried()
    {
        audioSource.PlayOneShot(audioClip1);
    }

    public static void SfxGetItem()
    {
        audioSource.PlayOneShot(audioClip2);
    }
}

 

 

[StartDelayTime.cs]

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

public class StartDelayTime : MonoBehaviour
{
    Text startDelayText;

    void Start()
    {
        startDelayText = GetComponent<Text>();
        startDelayText.text = "3";

        StartCoroutine("StartDelay");
    }

    IEnumerator StartDelay()
    {
        for (int i = 3; i >= 0; i -= 1)
        {
            switch (i)
            {
                case 3:
                    startDelayText.text = i.ToString();
                    break;
                case 2:
                    startDelayText.text = i.ToString();
                    break;
                case 1:
                    startDelayText.text = i.ToString();
                    break;
                case 0:
                    startDelayText.text = "GO!";
                    break;
            }

            yield return new WaitForSeconds(1f);
        }

        this.gameObject.SetActive(false);
    }
}

 

 

[ItemCounter.cs]

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

public class ItemCounter : MonoBehaviour
{
    public static int numItems;

    Text itemCounterText;

    void Start()
    {
        numItems = 0;
        itemCounterText = GetComponent<Text>();
    }

    void Update()
    {
        itemCounterText.text = "Rescue Chick : " + numItems.ToString();
    }
}

 

 

[Buttons.cs]

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

public class Buttons : MonoBehaviour
{
    bool pauseActive = false;

    public void RestartBtn()
    {
        SceneManager.LoadScene("FlappyChicken");
    }

    public void PauseBtn()
    {
        if (pauseActive)
        {
            Time.timeScale = 1;
            pauseActive = false;
        }
        else
        {
            Time.timeScale = 0;
            pauseActive = true;
        }
    }
}

 

댓글