Files
real-shooter/Assets/Scripts/Bots/CharacterFactory.cs
2022-05-16 17:59:47 +07:00

139 lines
5.2 KiB
C#

using System.Collections.Generic;
using Unity.Barracuda;
using Unity.MLAgents.Policies;
using UnityEngine;
public class CharacterFactory : MonoBehaviour
{
private static CharacterFactory instance;
public static CharacterFactory Instance => instance;
[SerializeField] private List<NavPoint> spawnPointsForDefendersTeam;
[SerializeField] private List<NavPoint> spawnPointsForAttackersTeam;
[SerializeField] private GameObject AIPrefab;
[SerializeField] private GameObject PlayerPrefab;
private List<GameObject> bots = new List<GameObject>();
public GameObject player { get; private set; }
private void Awake()
{
if (instance == null)
instance = this;
else
{
Destroy(gameObject);
Debug.LogError("Only 1 Instance");
}
}
private void Start()
{
var attcNum = SettingsReader.Instance.GetSettings.NumOfAttackers;
var defNum = SettingsReader.Instance.GetSettings.NumOfDefenders;
var humanDef = SettingsReader.Instance.GetSettings.HasHumanDefender == true ? 1 : 0;
var humanAtc = SettingsReader.Instance.GetSettings.HasHumanAttacker == true ? 1 : 0;
if (humanAtc == 1 && humanDef == 1)
throw new System.ArgumentException("Can be only one human player");
for (int i = 0; i < attcNum - humanAtc; i++)
InstantiateEntity(Team.Attackers, TypeAI.D0DiskAI,
spawnPointsForAttackersTeam[Random.Range(0, spawnPointsForAttackersTeam.Count)]);
for (int i = 0; i < defNum - humanDef; i++)
InstantiateEntity(Team.Defenders, TypeAI.D0DiskAI,
spawnPointsForDefendersTeam[Random.Range(0, spawnPointsForDefendersTeam.Count)]);
if (humanAtc == 1)
InstantiateEntity(Team.Attackers, TypeAI.HumanAI,
spawnPointsForAttackersTeam[Random.Range(0, spawnPointsForAttackersTeam.Count)]);
if (humanDef == 1)
InstantiateEntity(Team.Defenders, TypeAI.HumanAI,
spawnPointsForDefendersTeam[Random.Range(0, spawnPointsForDefendersTeam.Count)]);
GameManager.OnResetScene += ResetCharacters;
}
private void InstantiateEntity(Team team, TypeAI typeAi, NavPoint spawnPoint)
{
var gameobject = GameObject.Instantiate(
typeAi == TypeAI.HumanAI ? PlayerPrefab : AIPrefab,
spawnPoint.Position,
Quaternion.identity);
ApplyMaterial(team, gameobject);
gameobject.SetActive(true);
gameObject.tag = team == Team.Attackers ? "Attacker" : "Defender";
if (typeAi == TypeAI.HumanAI)
{
gameobject.GetComponent<Player>().GetCharacter.Team = team;
player = gameobject;
}
else
{
var npc = gameobject.GetComponent<NPC>();
if (team == Team.Attackers)
GameManager._attackersTeam.RegisterAgent(npc);
else
{
GameManager._defendersTeam.RegisterAgent(npc);
}
npc.GetCharacter.Team = team;
npc.SetModel(team.ToString(), null, InferenceDevice.Default );
gameobject.GetComponent<MovementController>().PointStartID = spawnPoint.PointId;
bots.Add(gameobject);
}
}
private void ApplyMaterial(Team team, GameObject go)
{
var mat = team == Team.Attackers
? SettingsReader.Instance.GetSettings.atcMaterial
: SettingsReader.Instance.GetSettings.defMaterial;
for (var i = 0; i < go.transform.childCount; i++)
{
if (go.transform.GetChild(i)
.TryGetComponent<SkinnedMeshRenderer>(out var skin))
{
skin.material = mat;
}
}
}
public void ReSpawn(ICharacter character, ref Vector3 pos, ref int startPointId)
{
character.ResetCharacter();
var team = character.GetCharacter.Team;
NavPoint navPoint;
if (team == Team.Attackers)
navPoint = spawnPointsForAttackersTeam[Random.Range(0, spawnPointsForAttackersTeam.Count)];
else
navPoint = spawnPointsForDefendersTeam[Random.Range(0, spawnPointsForDefendersTeam.Count)];
pos = navPoint.Position;
startPointId = navPoint.PointId;
}
private void ResetCharacters()
{
foreach (var bot in bots)
{
var npc = bot.GetComponent<NPC>();
npc.ResetCharacter();
if (npc.GetCharacter.Team == Team.Attackers)
bot.transform.position = spawnPointsForAttackersTeam[Random.Range(0, spawnPointsForAttackersTeam.Count)].Position;
else
bot.transform.position = spawnPointsForDefendersTeam[Random.Range(0, spawnPointsForDefendersTeam.Count)].Position;
}
Player player;
if (TryGetComponent<Player>(out player))
{
player.ResetCharacter();
if (player.GetCharacter.Team == Team.Attackers)
this.player.transform.position = spawnPointsForAttackersTeam[Random.Range(0, spawnPointsForAttackersTeam.Count)].Position;
else
this.player.transform.position = spawnPointsForDefendersTeam[Random.Range(0, spawnPointsForDefendersTeam.Count)].Position;
}
}
}