기획한 게임을 실제로 만들기 시작하였다.

내가 담당한 부분은 게임내의 개발자를 모아서 팀을 만들고, 그 팀에서 프로젝트를 진행 → 앱을 만드는 과정을 구현하는 것이었다. 이번 주차에는 App과 Team클래스의 기초 코드를 작성했다.

Team Class 코드:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Unity.Android.Gradle.Manifest;
using UnityEngine;

public class Team : MonoBehaviour
{
    [SerializeField] private GameManager gameManager;
    private List<App> managedApps; // 이 팀에서 관리하고 있는 앱들
    private List<Employee> teamMembers; // 팀에 소속되어있는 사람들
    private string teamName; // 팀명
    private int maxManagedAppsCount; // 팀에서 최대로 관리 가능한 앱 수
    private int teamStat; // 팀의 총 능력치
    private int developerStat; // 팀 개발자 스탯
    private int developerCount; // 개발자 인원
    private int designerStat; // 팀 디자이너 스탯
    private int designerCount; // 디자이너 인원
    private int plannerStat; // 팀 기획자 스탯
    private int plannerCount; // 팀 기획자 인원
    private int teamMemberCount; // 팀 인원수
    private long teamEarnMoney; // 팀에서 나오는 수익
    private long teamUseMoney; // 팀이 사용하는 비용
    private bool isProjectWorking;

    public Team(List<Employee> employees, string teamName, GameManager gameManager)
    {
        this.gameManager = gameManager;
        isProjectWorking = false;
        teamMembers = new List<Employee>();
        managedApps = new List<App>();
        for (int i = 0; i < employees.Count; i++)
        {
            teamMembers.Add(employees[i]);
            employees[i].SetIsWorking(true); // 일하는중으로 바꿈
        }

        SetTeamName(teamName);
        Debug.Log("팀 생성완료 팀명: " + teamName);
        TeamInit();
    }

    public void TeamInit()
    {
        teamMemberCount = teamMembers.Count;
        developerStat = 0;
        designerStat = 0;
        plannerStat = 0;
        developerCount = 0;
        designerCount = 0;
        plannerCount = 0;
        for (int i = 0; i < teamMemberCount; i++) // 팀 스탯 세팅
        {
            int memberJob = teamMembers[i].GetJob();
            int memberStat = teamMembers[i].GetStat();
            if (memberJob == 0)
            {
                developerStat += memberStat;
                developerCount++;
            }
            if (memberJob == 1)
            {
                designerStat += memberStat;
                designerCount++;
            }
            if (memberJob == 2)
            {
                plannerStat += memberStat;
                plannerCount++;
            }
        }

        teamStat = developerStat + designerStat + plannerStat;

        int minDevCount = DataBase.teamBalance[teamMemberCount, 0];
        int minDesCount = DataBase.teamBalance[teamMemberCount, 1];
        int minPlaCount = DataBase.teamBalance[teamMemberCount, 2];

        if (developerCount < minDevCount || designerCount < minDesCount || plannerCount < minPlaCount) // 각 종류별 인원수 모자르면 컷
        {
            teamStat = Math.Max(3, teamStat / 100);
        }

        for (int i = 0; i < managedApps.Count; i++) // 앱에서 버는 돈 갱신
        {
            managedApps[i].UpdateState();
        }

        long EarnMoney = 0; // 팀 버는 돈 / 쓰는 돈 세팅
        long UseMoney = 0;
        for (int i = 0; i < managedApps.Count; i++)
        {
            EarnMoney += managedApps[i].GetMoneyPerMonth();
            UseMoney += managedApps[i].GetMaintenanceCost();
        }
        teamEarnMoney = EarnMoney;
        teamUseMoney = UseMoney;

        int baseCount = gameManager.GetAppValue().GetMax();
        int additionalCount = (int)Math.Log10(teamStat / 100);
        maxManagedAppsCount = baseCount + additionalCount; // 팀에서 관리 가능한 앱 수 세팅
    }

    //TeamData -> Team
    public void InitializeFromData(TeamData data, List<Employee> loadedMembers, List<App> loadedApps)
    {
        this.teamName = data.teamName;
        this.isProjectWorking = data.isProjectWorking;

        // 불러온 실제 객체들로 리스트를 채웁니다.
        this.teamMembers = loadedMembers;
        this.managedApps = loadedApps;

        // 모든 멤버들에게 다시 일하는 상태(isWorking)를 설정해줍니다.
        foreach (Employee member in this.teamMembers)
        {
            member.SetIsWorking(true);
        }

        // 모든 값이 세팅되었으니, 스탯과 수익 등을 다시 계산합니다.
        TeamInit();
    }

    public void AddApp(App app) // 앱 추가
    {
        if (managedApps.Count == maxManagedAppsCount) return;
        managedApps.Add(app);
        TeamInit();
    }
    public void Project(long cost)
    {
        if (isProjectWorking) return; // 프로젝트가 이미 실행중, 화면에 문구 출력 구현해주면 될듯 
        gameManager.SubWon(cost);
        int appGrade = GetAppGrade();
        float time = 10f * (float)Math.Pow(3, appGrade);
        var appInfo = DataBase.AllApps[UnityEngine.Random.Range(0, DataBase.AllApps.Count)];
        string appName = appInfo.Item1;
        double[] stateRate = new double[] { appInfo.Item3, appInfo.Item5, appInfo.Item7, appInfo.Item9, appInfo.Item11, appInfo.Item13, appInfo.Item15, appInfo.Item17 };
        App app = new App(appName, appGrade, gameManager.GetDate(), stateRate);
        StartCoroutine(DelayedEvent(time)); // time만큼 기다림 / 몇초남았는지 알 수 없어서 나중에 변경 해야함
        AddApp(app); // 새로운 앱 (생성 / 추가) 화면에 문구 출력 구현해줘야될듯
    }
    public int GetAppGrade()
    {
        int baseGrade = (int)Math.Log10(teamStat / 100);
        int additionalGrade = UnityEngine.Random.Range(-1, 2);
        int appGrade = Math.Max(0, baseGrade + additionalGrade);
        return appGrade;
    }
    IEnumerator DelayedEvent(float time)
    {
        yield return new WaitForSeconds(time);
    }

    public List<Employee> GetTeamMembers() { return teamMembers; }
    public int GetTeamStat() { return teamStat; }
    public int GetTeamMemberCount() { return teamMemberCount; }
    public string GetTeamName() { return teamName; }
    public long GetTeamEarnMoney() { return teamEarnMoney; }
    public long GetTeamUseMoney() { return teamUseMoney; }
    public void SetTeamName(string teamName) { this.teamName = teamName; }
    public bool GetIsProjectWorking() { return isProjectWorking; }
}

App 클래스 코드:

using System;
using System.Threading;
using UnityEngine;
using UnityEngine.InputSystem.iOS;

public class App : MonoBehaviour
{
    [SerializeField] private GameManager gameManager;
    private string appName;
    private int grade;
    private long moneyPerMonth;
    private long maintenanceCost;
    private long baseMoney;
    private Date releaseDate;
    double[] stateRate; // 8가지 state에 대한 가중치 저장

    public App(string appName, int grade, Date date, double[] stateRate)
    {
        this.appName = appName;
        this.grade = grade;
        releaseDate = date;
        this.stateRate = new double[stateRate.Length];
        baseMoney = 100 * (long)Math.Pow(10, grade);
        maintenanceCost = (long)(baseMoney * 0.1 * UnityEngine.Random.Range(0.7f, 1.3f));
        Array.Copy(stateRate, this.stateRate, stateRate.Length);
    }
    public void UpdateState()
    {
        double money = 0;
        money += gameManager.GetStateValue("food") * stateRate[0];
        money += gameManager.GetStateValue("construction") * stateRate[1];
        money += gameManager.GetStateValue("medicine") * stateRate[2];
        money += gameManager.GetStateValue("energy") * stateRate[3];
        money += gameManager.GetStateValue("transit") * stateRate[4];
        money += gameManager.GetStateValue("it_ai") * stateRate[5];
        money += gameManager.GetStateValue("semiconductor") * stateRate[6];
        money += gameManager.GetStateValue("education") * stateRate[7];
        money *= baseMoney;
        money /= 100;
        moneyPerMonth = (long)money;
    }

    public long GetMoneyPerMonth() { return moneyPerMonth; }
    public long GetMaintenanceCost() { return maintenanceCost; }
    public string GetAppName() { return appName; }
    public int GetAppGrade() { return grade; }
}