개발/게임 교육

[Unity Class] 게임 교육 23 - 쿨타임

이게될까 2024. 1. 7. 00:18
728x90
728x90

이번엔 킬 후 쿨타임이다! 그리고 중복없는 랜덤!

이렇게 설정해준다.
이렇게 표시된다

이제 쿨타임 움직이게 구현해보자

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems; //UI를 선택한 것인지 그냥 움직인 것인지 확인


public class PlayerCtrl : MonoBehaviour
{
    public GameObject joyStick, mainView, playView;
    public Button btn;
    Animator anim;
    GameObject coll;
    public Sprite use, kill;

    public Text text_Cool;


    public float speed;
    public Settings settings_script;

    public bool isCantMove,isMission; // 이건 settings에서 바꾼다.

    float timer;
    bool isCool;


    private void Start()
    {
        anim = GetComponent<Animator>();
        Camera.main.transform.parent = transform; //캐릭터 이탈 방지
        Camera.main.transform.localPosition = new Vector3(0, 0, -10);

        if (isMission)
        {// 미션
            btn.GetComponent<Image>().sprite = use;
            text_Cool.text = "";
        }
        else
        {// 킬퀘스트
            btn.GetComponent<Image>().sprite = kill;

            timer = 5;
            isCool = true;
        }
    }
    private void Update()
    {
        // 쿨타임
        if (isCool)
        {
            timer -= Time.deltaTime; // 1초에 1씩 감소한다.
            text_Cool.text = Mathf.Ceil(timer).ToString();
            if(text_Cool.text == "0")
            {
                text_Cool.text = "";
                isCool = false;

            }
        }
        if (isCantMove)
        {
            joyStick.SetActive(false);// 못움직이는 상황에서는 조이스틱도 보이지 않는다.
        }
        else
        {
            Move();
        }
    }
    
    // 캐릭터 움직임 관리
    void Move()
    {
        if (settings_script.isJoyStick)
        {
            joyStick.SetActive(true);
        }
        else
        {
            joyStick.SetActive(false);

            // 상하좌우를 터치하여 움직이기

            //클릭했는지 판단.
            if (Input.GetMouseButton(0))
            {            // 좌클릭 누르고 있는 중 컴퓨터 모바일 다 해준다.
                if (!EventSystem.current.IsPointerOverGameObject())
                {//클릭한 것이 UI가 아니라면
                    Vector3 dir = (Input.mousePosition - new Vector3(Screen.width * 0.5f, Screen.height * 0.5f)).normalized; // 화면 정중앙을 빼서 얼마나 이동하는지를 노말 백터화 한다.

                    transform.position += dir * speed * Time.deltaTime;

                    anim.SetBool("isWalk", true);// 어떤 불값을 어떻게


                    //왼쪽으로 이동
                    if (dir.x < 0)
                    {
                        transform.localScale = new Vector3(-1, 1, 1);
                    }
                    else
                    {
                        //오른쪽으로 이동
                        transform.localScale = new Vector3(1, 1, 1);

                    }
                }
                

            }
            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 && !isCool)
        {// 킬게임이다
            coll = collision.gameObject;
            btn.interactable = true;
        }
    }

    //트리거와 떨어진경우
    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.tag == "Mission" && isMission)
        {
            coll = null;

            btn.interactable = false;
        }

        if (collision.tag == "NPC" && !isMission)
        {// 킬게임이다
            coll = null;
            btn.interactable = false;
        }
    }

    //버튼 누르면 호출
    public void ClickButton()
    {
        //미션 스타트를 호출
        // 미션 스타트 스크립트를 받아와야 하는데 간단하게 호출 가능
        coll.SendMessage("MissionStart");
        isCantMove = true;
        btn.interactable = false;


    }

    //미션 종료하면 호출
    // mission1파일에서 호출
    public void MissionEnd()
    {
        isCantMove = false;
    }
}

시간 받아온 것 말고 없다.

Text_Cool 넣는거 잊지 말기!
쿨타임 감소가 보인다

잘 된다!

NPC 랜덤 생성 ㄱ

Create Empty로 spawn point를 만들고 NPC를 넣어준다.

이제 스폰포인트 채로 애들을 배치해준다 ctrl D 난사!

이렇게!

다 배치해준다.

이중 하나만 resource 파일에 넣어두고 NPC만 다 지워준다.

텅 비었다.

이제 코드 작성!

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

public class KillCtrl : MonoBehaviour
{
    public Transform[] spawnPoints;

    List<int> number = new List<int>();

    // 초기화
    public void KillReset()
    {
        number.Clear();
        for(int i = 0; i < spawnPoints.Length; i++)
        {
            Destroy(spawnPoints[i].GetChild(0).gameObject);
        }

        NPCSpawn();

    }

    //NPC 스폰
    public void NPCSpawn()
    {
        int rand = Random.Range(0,10);
        for(int i = 0; i < 5;)
        {
            // 중복 되었는지 확인
            if (number.Contains(rand))
            {
                rand = Random.Range(0, 10);

            }
            else
            {// 중복 X
                number.Add(rand);
                i++;
            }
        }

        // NPC 스폰
        for(int i = 0; i < number.Count; i++)
        {
            Instantiate(Resources.Load("NPC"),spawnPoints[number[i]]);
        }
    }
}

스폰 코드!

중복에 대한 검증은 알고리즘 적으론 별로지만 구현이 대단히 쉽다.

넣어주는거 잊지 말기1

오류가 났을 것이다... 자식이 있는지 없는지 확인을 안했다.

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

public class KillCtrl : MonoBehaviour
{
    public Transform[] spawnPoints;

    List<int> number = new List<int>();

    // 초기화
    public void KillReset()
    {
        number.Clear();
        for(int i = 0; i < spawnPoints.Length; i++)
        {
            if(spawnPoints[i].childCount != 0)
            Destroy(spawnPoints[i].GetChild(0).gameObject);
        }

        NPCSpawn();

    }

    //NPC 스폰
    public void NPCSpawn()
    {
        int rand = Random.Range(0,10);
        for(int i = 0; i < 5;)
        {
            // 중복 되었는지 확인
            if (number.Contains(rand))
            {
                rand = Random.Range(0, 10);

            }
            else
            {// 중복 X
                number.Add(rand);
                i++;
            }
        }

        // NPC 스폰
        for(int i = 0; i < number.Count; i++)
        {
            Instantiate(Resources.Load("NPC"),spawnPoints[number[i]]);
        }
    }
}

확인 하는 과정을 하나 넣었다.

랜덤 생성 성공!

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

public class MainMenu : MonoBehaviour
{
    public GameObject missionView,killView;
    // 게임 종료 버튼 누르면 호출
    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(0,-2,0),Quaternion.identity)as GameObject;
        // PlayerCtrl 스크립트를 가져와서 메인 뷰에 게임 오브젝트를 넣는다.
        player.GetComponent<PlayerCtrl>().mainView = gameObject;
        player.GetComponent<PlayerCtrl>().playView = missionView;
        player.GetComponent<PlayerCtrl>().isMission = true;

        missionView.SendMessage("MissionReset");
    }    
    // 킬 버튼 누르면 호출
    public void ClickKill()
    {
        gameObject.SetActive(false);
        killView.SetActive(true);
        //캐릭터가 메인 화면에서 보이는 것 때문에 캐릭터를 지운 뒤 여기서 읽어 온다.
        GameObject player = Instantiate(Resources.Load("Character"), new Vector3(0,-2,0),Quaternion.identity)as GameObject;
        // PlayerCtrl 스크립트를 가져와서 메인 뷰에 게임 오브젝트를 넣는다.
        player.GetComponent<PlayerCtrl>().mainView = gameObject;
        player.GetComponent<PlayerCtrl>().playView = killView;
        player.GetComponent<PlayerCtrl>().isMission = false;

        killView.SendMessage("KillReset");
    }
}

저번 코드에서 missionView로 그대로 내비둔 것이 있었다....

잘 됩니당

728x90