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

[Unity] #8. 게임 플레이 컨텐츠 만들기 : 미션과 플레이어 세팅

by 로토마 2022. 3. 4.

지금까지 6종류의 미션을 배치하고 구현하는 것까지 성공했다. 

하지만.. 그대로 게임을 플레이 해보면,,,

전에 구현한 미션이 플레이 안되는 오류가 발생한다.

그 이유는 미션이 플레이 되어야하는 조건을 코딩으로 연결해주지 않아 충돌이 일어나기 때문이다.

그럼 오늘은 MissionCtrl 과 PlayerCtrl script를 통해 미션 섹션을 마무리 해보자!!

 

구현해야 할 기능 - MissionCtrl

- 모든 미션 초기화

- 미션 성공시 게이지up

- 성공한 미션 enabled화

- 7개의 미션 모두 성공시 "미션 성공" text 띄우기

- text 띄운 후 mainView로 전환, gameObject 비활성화, 캐릭터 삭제

 

MissionCtrl script)

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class MissionCtrl : MonoBehaviour
{
    public Slider guage;
    public CircleCollider2D[] colls;
    public GameObject text_anim, mainView;
 
    int missionCount;
 
    // 미션 초기화
    public void MissionReset()
    {
        guage.value = 0;
        missionCount = 0;
 
        for(int i = 0; i < colls.Length; i++)
        {
            colls[i].enabled = true;
        }
        text_anim.SetActive(false);
 
    }
 
    //미션 성공하면 호출
    public void MissionSuccess(CircleCollider2D coll)
    {
        missionCount++;
 
        guage.value = missionCount / 7f;
 
        //성공한 미션은 다시 플레이 X
        coll.enabled = false;
 
        // 성공여부 체크 + text_success 실행
        if(guage.value == 1)
        {
            text_anim.SetActive(true);
 
            Invoke("Change", 1f);
        }
    }
 
 
 
    // 화면 전환
    public void Change()
    {
        mainView.SetActive(true);
        gameObject.SetActive(false);
 
        //캐릭터 삭제
        FindObjectOfType<PlayerCtrl>().DestroyPlayer();
    }
 
}
 
cs

추가적으로 구현해야 할 기능 - PlayerCtrl

- collider 감지 시 MissionStart 호출

- Mission 수행하는 동안 캐릭터 못움직이게 isCantMove를 false로

 

PlayerCtrl script)

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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
 
public class PlayerCtrl : MonoBehaviour
{
    public GameObject joyStick, mainView, playView;
    public Settings settings_script;
    public Button Btn;
    public Sprite use, kill;
    public Text text_cool;
 
    Animator anim;
    GameObject coll;
    KillCtrl killctrl_script;
    
 
    //speed 변수 생성
    public float speed;
 
    public bool isCantMove,isMission;
 
    float timer;
    bool isCool,isAnim;
 
 
    //시작할 때의 실행
    private void Start()
    {
        anim = GetComponent<Animator>();
 
        // main camera를 Character의 자식으로 지정
        Camera.main.transform.parent = transform;
        // 처음 위치 지정 => 유니티에서의 main camera의 원래 위치를 상쇄해주기 위해
        Camera.main.transform.localPosition = new Vector3(00-10);
 
        // 미션이라면
        if (isMission)
        {
            Btn.GetComponent<Image>().sprite = use;
 
            text_cool.text = "";
 
        }
        // 킬 퀘스트라면,
        else
        {
            killctrl_script = FindObjectOfType<KillCtrl>();
 
            Btn.GetComponent<Image>().sprite = kill;
 
            timer = 5;
            isCool = true;
        }
    }
    private void Update()
    {
        // 쿨타임
        if (isCool)
        {
            timer -= Time.deltaTime;
            text_cool.text = Mathf.Ceil(timer).ToString();
 
            if(text_cool.text == "0")
            {
                text_cool.text = "";
                isCool = false;
            }
        }
 
        if (isCantMove)
        {
            joyStick.SetActive(false);
        }
        else
        {
            //move함수 호출
            Move();
        }
        
        //애니메이션이 끝났다면
        if(isAnim && killctrl_script.kill_anim.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).normalizedTime >= 1)
        {
            killctrl_script.kill_anim.SetActive(false);
            killctrl_script.Kill();
            isCantMove = false;
            isAnim = false;
        }
    }
 
    // 캐릭터 움직임 관리 함수
   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);
    }
 
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.tag == "Mission" && isMission)
        {
            coll = collision.gameObject;
            Btn.interactable = true;
        }
 
        if (collision.tag == "NPC" && !isMission)
        {
            coll = collision.gameObject;
            Btn.interactable = true;
        }
    }
 
    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.tag == "Mission")
        {
            coll = null;
 
            Btn.interactable = false;
        }
 
        if (collision.tag == "NPC" && !isMission && !isCool)
        {
            coll = null;
            Btn.interactable = false;
        }
 
    }
 
    // 버튼 누르면 호출
    public void ClickButton()
    {
        // 미션일 때
        if (isMission)
        {
            //MissionStart 호출
            coll.SendMessage("MissionStart");
        }
 
        //킬 퀘스트일 때
        else
        {
            Kill();
        }
 
        isCantMove = true;
        Btn.interactable = false;
 
    }
 
    void Kill()
    {
        //죽이는 애니메이션
        killctrl_script.kill_anim.SetActive(true);
        isAnim = true;
 
        //죽은 이미지 변경
        coll.SendMessage("Dead");
 
        // 죽은 NPC는 다시 죽일 수 없게
        coll.GetComponent<CircleCollider2D>().enabled = false;
    }
 
    // 미션 종료하면 호출
    public void MissionEnd()
    {
        isCantMove = false;
    }
}
 
 
 
 
cs

 

자, 이렇게 추가적으로 script로 게임의 흐름에 맞게 조건을 추가해주고, 장면 전환 기능 등을 추가해주면,

미션 섹션은 완성이다!!

이제 마지막으로 Kill 섹션만 구현해주면 어몽어스 프로젝트 완료!!

 

구현 완료 섹션!