본문 바로가기
유니티/AmongUs 클론코딩 (30일 프로젝트)

[Unity] #2 게임 플레이 환경 만들기 : 메뉴, 캐릭터, 맵, 설정

by 로토마 2022. 1. 16.

총 8일차까지의 강의를 듣고, 드디어!! 게임 플레이 환경을 구축하는 것에 성공했다. 

즉, 대략적인 메인 UI 부분의 작업을 마무리하고, 이제 기능들을 C# script로 구현하고 연결하는 작업을 하고 있다.

빌드는 안드로이드 기준으로 하기 때문에 안드로이드 모듈을 먼저 유니티 엔진에 추가해 준 뒤, 

세팅에서 안드로이드로 빌드 할 것임을 먼저 설정해주어야 한다. 그 후 전체적인 프로그래밍에 들어갔다.

 

1) MainMenu UI 

게임의 컨셉을 바닷속에서의 어몽어스 느낌으로 잡았기 때문에 배경을 인디 바다 느낌이 나도록 조정해 줄 것이다.

이 작업은 Main Camera에서 조작해주면 된다.

이렇게 배경색 먼저 설정해주면, 버튼이나 다른 이미지 배치에 있어서 전체적인 느낌을 파악할 수 있기 때문에 좋다!

그 후, MainMenu에서 버블 모양의 Particle System을 추가했고,

속도와 크기가 랜덤인 버블을 생성해 바닷 속같은 느낌을 주었다.

 

아래는 Inspector 창에서 구체적으로 랜덤값을 어떻게 부여했는지 조작한 결과를 담고 있다.

Particle System Inspector

또 캔버스에 안에 Title 이미지를 추가해 among_us sprite를 넣고,

버튼으로 Quit, Mission, Kill sprite를 넣어 MainMenu UI를 구성했다. 

보기 좋게 위치를 조작해주는 것은 필수!!! 

Hierachy 창

이렇게 전체적인 MainMenu 틀을 짜주었다.

완성된 첫 시작화면은 아래와 같다. 생각보다 갬성 게임 같은 분위기를 풍기는 걸 볼 수 있다 ㅎ

MainMenu UI 화면

그 후 본격적으로 MainMenu script를 작성해 Quit, Mission Click 함수를 만들고 각 버튼에 연결해 주었다.

- ClickQuit() 함수는 유니티 에디터 그리고 안드로이드 에서 종료가 되도록 만들었다. 

- ClickMission() 함수는 미션을 수행할 수 있는 맵과 그리고 캐릭터가 있는 화면이 전환되도록 만들어주었다.

 

MainMenu.cs )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class MainMenu : MonoBehaviour
{
    public GameObject missionView;
    
    //게임 종료 버튼 누르면 호출
    public void ClickQuit()
    {
        // 유니티 에디터
#if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
 
        //안드로이드
#else
Application.Quit();
#endif
    }
    //미션 버튼 누르면 호출
    public void ClickMission()
    {
        gameObject.SetActive(false);
        missionView.SetActive(true);
 
        GameObject player = Instantiate(Resources.Load("Character"),new Vector3(9,-1,0), Quaternion.identity) as GameObject;
        player.GetComponent<PlayerCtrl>().mainView = gameObject;
        player.GetComponent<PlayerCtrl>().missionView = missionView;
    }
}
 
cs

이렇게 코드를 작성한 뒤, Hierachy의 MainMenu에 스크립트를 추가해주고 캔버스안의 버튼에 각 함수를 연결했다.

연결은 이런식으로!! 

버튼의 Inspector 창의 On Click() 부분

2) Mission Map UI 

무엇보다 맵은 게임에서 가장 큰 비중을 차지하는 부분이기 때문에 꼼꼼하게 이미지를 배치해주었다.

이미지는 베어유에서 공급해준 파일로 구성했다.

맴 전체가 하나로 된 이미지가 아니라, 방끼리 조각조각 나있는 여러개의 이미지로 구성되어 있어서,

배치하는데 은근 시간이 꽤 걸렸다.

이렇게 시간이 좀 걸려도 여러 개의 파일로 구성되어 있는 이유는 화질을 최대한 보존하기 위해서라고 하니..! 

최대한 하나같이 보이도록 연결 부위를 깔끔하게 연결해주었다. 

이 부분이 꼼꼼해야!! 나중에 벽 colider을 씌워줄 때 매끄럽게 연결할 수 있으므로 최선을 다해 이쁘게 연결했다.

 

Hierarchy 창을 보면 이렇게 Back 안에 각 방들이 배치되어 있는 걸 볼 수 있다. 

이제 담주 차시에 각 방에 미션을 배치해 줄것이다!! (두근두근)

Mission Hierarchy

이제 Main Carmera로 맵을 전체적으로 보면 아래와 같다!!

전체 맵 구성

3) Character UI

캐릭터 같은 경우는 MainMenu에서 미션 버튼을 눌렀을 때 생성되고 그 전까지는 보이면 안되기 때문에 따로 project창에 Resources 파일을 만들고 그 안에 캐릭터로 저장해 두어, Mission 버튼이 눌리면 Load 해주는 방식으로 코딩했다.

 

캐릭터 이미지를 생성해 주고,

- 캐릭터의 움직임을 두 가지 방식 (마우스와 조이스틱)으로 조정하는 코드

- 앞으로 만들 설정 창이 떴을 때와 같이 움직이지 않게끔 하기 위해 isCantMove와 같은 bool형 변수로 움직임을 조정하는 코드

- 또 움직일 때 실제 움직이는 것처럼 보일 수 있도록, 애니메이터 기능을 사용해 애니메이션

등등을 만들어주었고 위 코드와 캐릭터가 움직일때는 walk를 가만히 있을 때는 idle 애니메이션을 입혀주었다. 

 

아래는 project resources 폴더에 넣은 캐릭터 Hierarchy 창이다. 캐릭터 이미지 말고도 조이스틱과 세팅에 들어가는 버튼 들로 구성되어 있다.

Character Hierachy
캐릭터의 animator 창

지금까지 위 기능들을 구현한 PlayerCtrl.cs)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
 
public class PlayerCtrl : MonoBehaviour
{
    public GameObject joyStick, mainView, missionView;
    public Settings settings_script;
    public Button Btn;
 
    Animator anim;
    GameObject coll;
    
 
    //speed 변수 생성
    public float speed;
 
    public bool isCantMove;
 
 
    //시작할 때의 실행
    private void Start()
    {
        anim = GetComponent<Animator>();
 
        // main camera를 Character의 자식으로 지정
        Camera.main.transform.parent = transform;
        // 처음 위치 지정 => 유니티에서의 main camera의 원래 위치를 상쇄해주기 위해
        Camera.main.transform.localPosition = new Vector3(00-10);
    }
    private void Update()
    {
        if (isCantMove)
        {
            joyStick.SetActive(false);
        }
        else
        {
            //move함수 호출
            Move();
        }
        
    }
 
    // 캐릭터 움직임 관리 함수
   void Move()
   {
        if (settings_script.isJoyStick)
        {
            joyStick.SetActive(true);
        }
        else
        {
            joyStick.SetActive(false);
            //JoyStick 말고 화면을 클릭했는지 판단
            if (Input.GetMouseButton(0)) //좌측을 클릭 혹은 터치 했을 때
            {
                if (!EventSystem.current.IsPointerOverGameObject())
                {
                    //dir 변수에 클릭한 위치 - 중간 위치를 빼주고 normalized 해준다
                    Vector3 dir = (Input.mousePosition - new Vector3(Screen.width * 0.5f, Screen.height * 0.5f)).normalized;
                    //위치를 speed 값과 시간을 고려해 업데이트 해준다
                    transform.position += dir * speed * Time.deltaTime;
 
                    //animation 의 isWalk를 true로
                    anim.SetBool("isWalk"true);
 
                    //왼쪽으로 이동
                    if (dir.x < 0)
                    {
                        transform.localScale = new Vector3(-111);
                    }
                    //오른쪽으로 이동 (좌우반전)
                    else
                    {
                        transform.localScale = new Vector3(111);
                    }
                }
               
            }
            //클릭하지 않는다면
            else
            {
                anim.SetBool("isWalk"false);
            }
        }
 
       
   }
 
    //캐릭터 삭제
    public void DestroyPlayer()
    {
        Camera.main.transform.parent = null;
        Destroy(gameObject);
    }
 
 
}
 
 
 
 
cs

 

캐릭터 - 마우스 컨트롤
캐릭터 - 조이스틱 컨트롤

 

4) Setting UI 

설정 창은 미션 플레이 중 캐릭터 이동 방식을 터치 이동 및 조이스틱으로 바꿀 수 있도록 하고, 게임 나가기 버튼 및 다시 돌아가기 버튼이 있어서 다시 메인 메뉴 혹은 게임으로 돌아갈 수 있도록 한 창이다. 미션을 클릭했을 때, 오른쪽 위쪽 톱니바퀴 모양의 버튼을 누르면 설정 창이 아래와 같이 뜨게끔 만들어주었다. 또, 현재 이동 방식이 터치이동 방식인지, 또 조이스틱 방식인지 플레이어가 알 수 있게끔 파란색으로 버튼색이 변하게끔 하는 기능도 넣어주었다. 

설정의 이미지 파일 및 버튼은 모두 캐릭터와 함께 넣어주었다. 

setting UI (현재 터치이동 방식 사용중임을 알 수 있다)

Setting.cs)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class Settings : MonoBehaviour
{
    public bool isJoyStick;
    public Image touchBtn, joyStickBtn;
    public Color blue;
    public PlayerCtrl playerCtrl_script;
 
    GameObject mainView, missionView;
 
    private void Start()
    {
        mainView = playerCtrl_script.mainView;
        missionView = playerCtrl_script.missionView;   
    }
 
    // 설정 버튼을 누르면 호출
    public void ClickSetting()
    {
        gameObject.SetActive(true);
        playerCtrl_script.isCantMove=true;
    }
 
    //게임으로 돌아가기 버튼 누르면 호출
    public void ClickBack()
    {
        gameObject.SetActive(false);
        playerCtrl_script.isCantMove = false;
 
    }
 
    // 터치이동을 누르면 호출
    public void ClickTouch()
    {
        //print("click touch");
        isJoyStick = false;
        touchBtn.color = blue;
        joyStickBtn.color = Color.white;
    }
 
    // 조이스틱을 누르면 호출
    public void ClickJoyStick()
    {
        //print("click joystick");
        isJoyStick = true;
        touchBtn.color = Color.white;
        joyStickBtn.color = blue;
    }
 
    // 게임 나가기 버튼 누르면 호출
    public void ClickQuit()
    {
        mainView.SetActive(true);
        missionView.SetActive(false);
 
        //캐릭터 삭제
        playerCtrl_script.DestroyPlayer();
    }
}
 
cs
Setting 플레이 영상

이렇게 해서 기본적인 게임 플레이 환경을 조성해 주었다. 

 

 

코드를 하나하나 치면서 작업했음에도 아직 유니티 안의 여러 기능에 혼란이 와서, 감을 좀 더 잡아가야 할 것 같은 느낌이 들었다..ㅎ 벌써부터 겉으로 보기엔 게임 분위기가 폴폴 나기 시작해서 얼른 미션도 구현하고 싶은 생각이 마구마구 들었다. 확실히 익숙해지려면 좀 더 많이 코드를 작성해보고 여러 게임 기능을 구현해 봐야겠다. 

 

다음 내용은 #3. 게임 플레이 콘텐츠 만들기 : 미니게임 미션으로 찾아오겠습니당~ ㅎ