본문 바로가기
Project/[Unity] 지진 시뮬레이션

[Unity] 지진 시뮬레이션 11 - 생존 리스트 생성

by ruki 2024. 4. 3.

생존 리스트를 생성하여 유전이 일어날 수 있도록 할 것이다.


1. 턴 종료

플레이어가 50명 이하로 줄면 턴을 종료할 것이다.

public int LiveObjectNumber;

void Start()
{
    LiveObjectNumber = Count;
}

먼저 현재 생존한 플레이어를 모니터링할 변수를 gameManager 코드에 추가한다.

 

void OnTriggerEnter(Collider other)
{
    if(other.tag == "box" || other.tag == "book") 
    {
        float damage = other.GetComponent<Rigidbody>().velocity.magnitude;
        if(damage > 1) gameObject.SetActive(false);
    }
    else if(other.transform.parent.gameObject.tag == "wall") 
    {
        gameObject.SetActive(false);
    }
}

이 코드에서 비활성화 부분을 따로 함수로 꺼내고 플레이어가 줆을 나타내는 코드를 추가한다.

void OnTriggerEnter(Collider other)
{
    if(other.tag == "box" || other.tag == "book") 
    {
        float damage = other.GetComponent<Rigidbody>().velocity.magnitude;
        
        if(damage > 1) GameOver();
    }
    else if(other.transform.parent.gameObject.tag == "wall") GameOver();
}   

void GameOver()
{
    gameManager.instance.LiveObjectNumber -= 1;
    gameObject.SetActive(false);
}

 

다시 gameManager로 돌아가서 플레이어가 절반만 살아남게 되면 종료 함수를 실행하도록 한다.

void Update()
{
    if(LiveObjectNumber <= Count/2) Reset();
}

2. 하위 플레이어 탈락

Reset 함수에서 플레이어의 점수를 평균을 내어 평균 이하의 점수를 가진 플레이어를 탈락시킨 리스트를 추출할 것이다.

 

생존 리스트를 생성하고, 활성화된 오브젝트로 구성한다.

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

for (int N = 0; N < Count; N++)
{
    if(ObjectList[N].gameObject.activeSelf) 
    {
        Survivor.Add(N);
    }
}

 

플레이어의 모든 점수의 합을 나타내는 변수와 플레이어 각각의 점수를 나타내는 변수를 추가하고 할당한다.

float AllScore = 0;
int[] PlayerScores  = new int[Count];

for (int N = 0; N < Count; N++)
{
    if(ObjectList[N].gameObject.activeSelf) 
    {
        PlayerScores[N] = ObjectList[N].GetComponent<playerScore>().score;
        AllScore += PlayerScores[N];
    }
}

 

평균 이하의 점수를 가진 플레이어를 생존 리스트에서 제외시킨다.

for (int i = 0; i < Survivor.Count; i++)
{
    if(PlayerScores[Survivor[i]] < AllScore / Survivor_Count) 
    {
        Survivor.RemoveAt(i);
        i -= 1;
    }
}

 

이로써 벽이나 장애물에 충돌하기 않았으며, 평균 이상의 점수를 가진 플레이어 리스트를 생성하였다.

 

시각적으로 확인하기 위해 선별된 플레이어를 제외한 모든 플레이어를 비활성화하는 코드를 추가하였다.

for (int i = 0; i < Count; i++)         ObjectList[i].SetActive(false);
for (int i = 0; i < Survivor.Count; i++)ObjectList[Survivor[i]].SetActive(true);

 

 

전체 코드는 다음과 같다.

 

gameManager

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

public class gameManager : MonoBehaviour
{
    public static gameManager instance;
    
    private void Awake() 
    {
        instance = this;
    } 
    public int Count; 
    public GameObject BaseObject; 
    public GameObject ParentObject; 
    public List<GameObject> ObjectList = new List<GameObject>(); 

    public int LiveObjectNumber;

    void Start()
    {
        LiveObjectNumber = Count;

        SetObject();
    }

    void Update()
    {
        if(LiveObjectNumber <= Count/2) {Reset(); EditorApplication.isPaused = true;}
    }

    void Reset()
    {
        float AllScore = 0;

        List<int> Survivor  = new List<int>();
        int[] PlayerScores  = new int[Count];

        for (int N = 0; N < Count; N++)
        {
            if(ObjectList[N].gameObject.activeSelf) 
            {
                PlayerScores[N] = ObjectList[N].GetComponent<playerScore>().score;
                AllScore += PlayerScores[N];

                Survivor.Add(N);
            }
        }

        float Survivor_Count = Survivor.Count;

        for (int i = 0; i < Survivor.Count; i++)
        {
            if(PlayerScores[Survivor[i]] < AllScore / Survivor_Count) 
            {
                Survivor.RemoveAt(i);
                i -= 1;
            }
        }

        for (int i = 0; i < Count; i++)         ObjectList[i].SetActive(false);
        for (int i = 0; i < Survivor.Count; i++)ObjectList[Survivor[i]].SetActive(true);
    }

    void SetObject()
    {
        for (int i = 0; i < Count; i++) 
        {
            ObjectList.Add(Instantiate(BaseObject, ParentObject.transform));
            ObjectList[i].name = i.ToString();
            ObjectList[i].SetActive(true);
        } 
    }
}

잘 작동한다.