본문 바로가기
Unity 공부

[Unity] 어몽어스 미니게임 - 방패 임무 (Among Us Shield Task)

by 개발하는 디토 2022. 11. 4.

Among Us 미니 게임 중 Shield 게임을 만들어보았다.

 

 

준비

Canvas - Panel 하나 만들고 배경 이미지 (TurtleBackGround), 12각형 이미지, 육각형 이미지, Exit 버튼, GameEnd Text 등을 만들어둔다.

Hierarchy

배경 이미지 TurtleBackGround와 효과음은 아래의 사이트에서 구할 수 있다.

12각형과 육각형은 직접 PPT에서 제작했다. 아래의 이미지를 써도 좋고 직접 만들고 싶다면 PPT에서 만드시길 바란다. 흰 윤곽선을 제법 두껍게 주었고 도형 내부는 흰색으로 채운 뒤 일부러 투명도를 50% 정도 주었다.

 

 

Prime Shields

Prime Shields is a short task in Among Us, featured on The Skeld and MIRA HQ. Prime Shields consists of a single stage. A Crewmate must go to Shields or Admin, on The Skeld or MIRA HQ respectively, and click or tap the red hexagons until all of the hexagon

among-us.fandom.com

12gon.png
0.02MB
hexagon.png
0.00MB

 

다음과 같이 배치를 완료하면 된다. Dodgecagon(12각형)은 Image, Red Button은 Image, Button 2개의 component를 달고 있는 UI 오브젝트이다.

  1. 12각형과 육각형 모두 색을 빨갛게 설정한다.
  2. 12각형은 Alpha값을 0.4~0.5 사이로 적당히 준다.
  3. 육각형은 Alpha 값을 1로 하되 Button - Disabled Color의 Alpha 값도 1로 준다. 이미 흰색이 된 버튼은 Interactable을 꺼줄 건데 그때 Disabled Color의 Alpha가 0.5 정도로 되어있으면 희끄무레하게 보이기 때문이다.

세팅이 끝난 모습

 

12각형, Color는 빨갛게, 투명도는 적당히 ( 0.4 정도? )
육각형 Color ( 1, 0, 0, 1 ), Disabled color Alpha 1로

GameEndText는 모든 육각형이 흰색으로 바뀌었을 때 알려주기 위한 text로 적당히 Task Completed! 같이 게임이 끝났음을 알리는 내용을 적어두자.

Exit 버튼은 게임 패널을 끌 수 있는 버튼이다. 필요에 따라 Canvas나 GamePanel을 연결하고 OnClick에서 GameObject SetActive(false);를 설정한다.

 

Script 작성

Shield 게임은 빨간색으로 되어있는 버튼을 모두 눌러 흰색으로 바꿔주면 끝나는 간단한 게임이다. 빨간색으로 되어 있는 육각형 중 몇 개만 랜덤으로 뽑아 흰색으로 바꿔준다면 매번 눌러야 하는 버튼이 달라질 것이다. 빨간 버튼을 클릭하면 버튼 이미지가 흰색으로 바뀌게 하고 모든 버튼이 흰색으로 바뀌면 게임을 종료하게끔 만들면 된다.

 

InitBtn() : 버튼 초기화를 담당한다. 버튼을 담아둔 배열을 돌면서 모든 버튼의 interactable을 켜주고 ClickHexagon 이벤트를 추가한다.

ColorButtons() : 초기 버튼 색칠을 담당한다. 처음 시작할 때 흰색 버튼이 몇개가 될 것인지 랜덤으로 뽑아 일부 버튼을 흰색으로 칠한다. 흰 버튼은 클릭할 필요가 없으므로 버튼의 interactable 옵션을 끄고 이미 click되었다고 bool 배열에 표시한다. 전부 흰 버튼으로 칠해지면 안 되므로 최소한 2개의 버튼은 무조건 빨간색으로 남을 수 있게 Random.Range(0, 버튼 배열 개수 -2) 로 칠할 버튼 개수를 뽑았다.

ClickHexagon(Button) : 버튼 눌렸을 때 실행할 함수이다. 빨간 버튼이 눌릴 것이므로 버튼을 흰색으로 바꿔준다. 또한 그 버튼이 담긴 배열에서의 index 값을 찾아 bool 배열 btnClicked에서 버튼이 눌렸다고 표시해준다.

FindGameObj(GameObject) : 육각형 버튼이 담긴 배열 안에서 버튼의 index를 찾기 위한 함수이다. btnClicked에 접근해 버튼이 흰색으로 바뀌었는지 아닌지 표시할 대 사용한다.

CheckComplete() : 게임 종료 조건을 체크한다. btnClicked 안의 모든 값이 true이면 모든 버튼이 흰색으로 바뀐 것이므로 12각형의 색도 흰색으로 바꾸고 게임 종료 text를 띄운다.

 

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

public class Hexagons : MonoBehaviour
{
    [Header("Game")]
    [SerializeField] private GameObject[] hexagons;
    [SerializeField] private bool[] btnClicked;
    Color white = new Color(1f, 1f, 1f, 1f);

    [Header("Game Complete")]
    [SerializeField] private Image dodgecagon;
    [SerializeField] private GameObject endText;
    private bool gameEnd;

    // Start is called before the first frame update
    void Start()
    {
        InitBtn();
        btnClicked = new bool[hexagons.Length];
        endText.SetActive(false);
        gameEnd = false;

        ColorButtons();
    }

    private void InitBtn()
    {
        foreach(var h in hexagons)
        {
            var hBtn = h.GetComponent<Button>();
            hBtn.interactable = true;
            hBtn.onClick.AddListener(() => { ClickHexagon(hBtn); });
        }
    }

    private void ColorButtons()
    {
        int pickCount = Random.Range(0, hexagons.Length-2); // at least two buttons are red

        for(int i = 0; i < pickCount; i++)
        {
            int randNum = Random.Range(0, hexagons.Length);
            Button btn = hexagons[randNum].GetComponent<Button>();
            Image btnImg = hexagons[randNum].GetComponent<Image>();
            btnImg.color = Color.white;
            btn.interactable = false;
            btnClicked[randNum] = true; // white colored -> true
        }

    }

    public void ClickHexagon(Button hexBtn)
    {
        hexBtn.GetComponent<Image>().color = Color.white;        
        int index = FindGameObj(hexBtn.gameObject);
        Debug.Log(index);   
        if (index < 0)
        {
            Debug.Log($"{hexBtn.gameObject.name} not found or already turned off.");
            return;
        }
        btnClicked[index] = true; // if clicked, btn becomes white, so update boolean array
        CheckComplete();
    }

    private int FindGameObj(GameObject go)
    {
        for(int i = 0; i<hexagons.Length; i++)
        {
            if (hexagons[i] == go) return i;
        }
        return -1; // not found
    }
    public void CheckComplete()
    {
        if( System.Array.TrueForAll(btnClicked, value => { return value; }))
        {
            dodgecagon.color = white;
            endText.SetActive(true);
            gameEnd = true;
        }
    }

}

 

gameEnd는 지금 당장 사용하지는 않지만 나중에 본 게임과 합칠 때 이 미니게임 Task를 완료했는지 판단할 때 사용할 수 있을 것이다.

 

 

결과

영상에서는 처음 시작할 때 흰 버튼이 하나도 안 켜졌는데 랜덤으로 몇개씩 켜진다. 

 

댓글