[Unity] 1인칭 FPS 게임 - 6. Game System

홍예주·2021년 7월 17일
0

1. GameManager

게임 진행에 대해 관리하는 부분이다.

  • 플레이어 사망 시 : 플레이어가 게임 매니저의 EndGame()을 호출
  • 레벨 클리어 시 : 게임 매니저의 NextLevel()을 호출

Game Info는 2번에서 설명하겠지만, 게임을 종료하기 전까지 가지고 있어야할 정보를 저장해두었다. 중간에 코드가 좀 꼬여서 불필요하게 레벨이나 킬카운트를 매니저와 인포 둘 다에서 올릴 수 있게 되었다. (추후 수정 필요)

using UnityEngine.SceneManagement;
using UnityEngine;


public class GameManager : MonoBehaviour
{
    //public bool gameHasEnded = false;

    public GameInfo gameInfo;

    public GameObject failedUI;
    Spawner spawner;

    public bool isClear;

    public GameObject ClearUI;


    public void Start()
    {
        isClear = false;
        //gameHasEnded = false;
    }


    public void EndGame()
    {

        Debug.Log("EndGame");
        //Debug.Log(gameHasEnded);
        //if (gameHasEnded == false)
        //{

            Debug.Log("failedUI set");

           // gameHasEnded = true;

            GameObject newfailedUI = Instantiate(failedUI);

            newfailedUI.SetActive(true);
            //failedUI.SetActive(true);

        //}
    }

    public void NextLevel()
    {
        isClear = true;
        GameObject newclearUI = Instantiate(ClearUI);

        //IncreaseLevel();
        //gameInfo.SetIndex();
        newclearUI.SetActive(true);
        //Invoke("SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex)",3f);
    }

    public void IncreaseLevel()
    {
        gameInfo.IncreaseLevel();
    }

    public void IncreaseKillCount()
    {
        gameInfo.IncreaseKillCount();
    }

    public void ResetGameInfo()
    {
        gameInfo.Reset();
    }

    public int GetLevel()
    {
        return gameInfo.GetLevel();
    }

    public int GetKillcount()
    {
        return gameInfo.GetKillcount();
    }
}

2. GameInfo

총 레벨 수와 총 킬카운트를 가지고 있는 클래스다.
해당 게임에서 무한 레벨을 게임 씬을 계속 새로 불러오는 형식으로 구현했기 때문에, 씬이 바뀔 때도 파괴되지 않도록 DontDestroyOnLoad로 구현했다.

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

public class GameInfo : MonoBehaviour
{

    public int maxLevel = 0;
    public int killCount = 0;
    int index = 0;
    //public MapGenerator mapGenerator;

    public void Start()
    {


        var obj = FindObjectsOfType<GameInfo>();

        if(obj.Length ==1)
        {
            DontDestroyOnLoad(this);
        }

        else
        {
            Destroy(gameObject);
        }

    }

    public void IncreaseLevel()
    {
        
        maxLevel++;
        //mapGenerator.mapindex = (mapGenerator.mapindex + 1) % 5;
    }

    public void IncreaseKillCount()
    {
        killCount++;
    }

    public int GetLevel()
    {
        return maxLevel;
    }

    public int GetKillcount()
    {
        return killCount;
    }

    public int GetIndex()
    {
        return index;
    }

    public void Reset()
    {
        killCount = 0;
        maxLevel = 0;
    }

    //public void SetIndex()
    //{
    //    index = (index + 1) % 5;
    //}

}

3. Spawner

씬이 시작될 때 좀비들과 플레이어를 스폰해준다. 플레이어는 고정된 시작 위치에, 좀비는 랜덤 위치에서 스폰한다.

using System.Collections;
using UnityEngine;

public class Spawner : MonoBehaviour
{

    public EnemyAI enemy;
    public Player player;
    public int enemyNum = 0;
    MapGenerator map;
    public Camera startCamera;

    private void Start()
    {
        map = FindObjectOfType<MapGenerator>();


        Invoke("SpawnPlayer",0f);
        Invoke("SpawnEnemy",1f);

    }

    void OnEnemyDeath()
    {
        Debug.Log("Enemy die");
    }


    void SpawnEnemy()
    {

        Debug.Log("spawn");
        for (int i = 0; i < enemyNum; i++)
        {
            Transform randomTile = map.GetRandomOpenTile();
            //Debug.Log("pos");
            //Debug.Log(randomTile.position.x);
            //Debug.Log(randomTile.position.y);
           // Debug.Log(randomTile.position.z);

            Vector3 pos = new Vector3(randomTile.position.x, 0f, randomTile.position.z);
            EnemyAI spawnedEnemy = Instantiate(enemy, pos, Quaternion.identity) as EnemyAI;
            spawnedEnemy.OnDeath += OnEnemyDeath;
        }
    }

    void SpawnPlayer()
    {
        Vector3 playerPos = new Vector3(-13.18f, 0.2f, -13.47f);
        Player spawnPlayer = Instantiate(player, playerPos , Quaternion.identity) as Player;
        spawnPlayer.setHealth(spawnPlayer.startingHealth);
        startCamera.enabled = false;;
    }
}

4. 발생했던 문제점

1. Game Info의 처리 문제

원래는 gameinfo를 프리팹이 아니라 그냥 씬에 올려놓은 오브젝트로 생성했는데, DontDestroyOnLoad 때문에 Find로 찾아지지 않아서 프리팹으로 변경했다.

그래서 gameinfo를 gameManager가 가지고, game info 정보를 매니저 쪽에서 수정하도록 gameinfo 자체는 숨겨둘려 했는데 아직 코드 수정을 덜했다.

2. Spawn했을 때 서로 인식하지 못하는 문제

좀비들을 스폰했을 때 맵, 장애물, 플레이어 등등을 인식하지 못하는 것을 확인했다.
로그를 찍어보니 스폰이 너무 빨리 되어서 다른 객체들이 생성되기 전에 좀비들이 스폰되어서 인식하지 못한 것이었다.(생성 안된 것을 가져올려고 함)
그래서 Invoke로 좀비 생성을 지연시켰다.

profile
기록용.

0개의 댓글