From c8af0e528415cb8b3b198edc7eb513fdf9133710 Mon Sep 17 00:00:00 2001 From: Krazerleo Date: Wed, 4 May 2022 23:50:07 +0700 Subject: [PATCH] to new git --- Assets/Scripts/Bots/CharacterFactory.cs | 44 +++-- Assets/Scripts/Bots/TeamEnum.cs | 11 ++ Assets/Scripts/Character/Character.cs | 6 - .../Scripts/Character/CharacterCondition.cs | 32 +++- .../Interfaces.meta} | 2 +- .../Character/Interfaces/ICharacter.cs | 5 + .../Interfaces/ICharacter.cs.meta} | 2 +- .../Character/Interfaces/INpcBaseState.cs | 17 ++ .../Interfaces/INpcBaseState.cs.meta} | 2 +- .../Scripts/Character/MovementController.cs | 70 +++++-- Assets/Scripts/Character/NPC.cs | 178 ++++++++++++------ Assets/Scripts/Character/NPC_State.cs | 46 ----- Assets/Scripts/Character/NpcState.cs | 68 +++++++ .../{NPC_State.cs.meta => NpcState.cs.meta} | 0 Assets/Scripts/Character/Player.cs | 12 +- .../Character/scr_CharacterController.cs | 64 +++---- Assets/Scripts/Character/scr_Models.cs | 120 ++++++------ Assets/Scripts/Managers/GameManager.cs | 107 ++++++++--- Assets/Scripts/Managers/MapManager.cs | 63 ++++++- Assets/Scripts/Managers/TimeManager.cs | 8 +- Assets/Scripts/Misc/FlagZone.cs | 14 +- Assets/Scripts/Misc/NavPoint.cs | 20 +- Assets/Scripts/Misc/Settings.cs | 4 +- Assets/Scripts/Misc/SettingsReader.cs | 16 +- Assets/Scripts/Misc/Statistics.cs | 9 - Assets/Scripts/Pickups/AmmoPickUp.cs | 8 +- Assets/Scripts/Pickups/ArmourPickUp.cs | 8 +- Assets/Scripts/Pickups/HealthPickUp.cs | 8 +- Assets/Scripts/Pickups/IPickable.cs | 5 +- Assets/Scripts/Pickups/PickUpSpawner.cs | 10 +- Assets/Scripts/Sensors/SensorType.cs | 6 - Assets/Scripts/Sensors/Sensors.cs | 4 - Assets/Scripts/Statistics.meta | 8 + Assets/Scripts/Statistics/Logger.cs | 19 ++ Assets/Scripts/Statistics/Logger.cs.meta | 11 ++ Assets/Scripts/Statistics/StatisticManager.cs | 51 +++++ .../StatisticManager.cs.meta} | 2 +- .../Scripts/Utils/SerializableDictionary.cs | 4 +- .../Scripts/Weapons/scr_WeaponController.cs | 15 +- 39 files changed, 720 insertions(+), 359 deletions(-) rename Assets/Scripts/{Sensors.meta => Character/Interfaces.meta} (77%) mode change 100755 => 100644 create mode 100644 Assets/Scripts/Character/Interfaces/ICharacter.cs rename Assets/Scripts/{Sensors/SensorType.cs.meta => Character/Interfaces/ICharacter.cs.meta} (83%) mode change 100755 => 100644 create mode 100644 Assets/Scripts/Character/Interfaces/INpcBaseState.cs rename Assets/Scripts/{Sensors/Sensors.cs.meta => Character/Interfaces/INpcBaseState.cs.meta} (83%) delete mode 100644 Assets/Scripts/Character/NPC_State.cs create mode 100644 Assets/Scripts/Character/NpcState.cs rename Assets/Scripts/Character/{NPC_State.cs.meta => NpcState.cs.meta} (100%) delete mode 100755 Assets/Scripts/Misc/Statistics.cs delete mode 100755 Assets/Scripts/Sensors/SensorType.cs delete mode 100644 Assets/Scripts/Sensors/Sensors.cs create mode 100644 Assets/Scripts/Statistics.meta create mode 100644 Assets/Scripts/Statistics/Logger.cs create mode 100644 Assets/Scripts/Statistics/Logger.cs.meta create mode 100644 Assets/Scripts/Statistics/StatisticManager.cs rename Assets/Scripts/{Misc/Statistics.cs.meta => Statistics/StatisticManager.cs.meta} (91%) mode change 100755 => 100644 diff --git a/Assets/Scripts/Bots/CharacterFactory.cs b/Assets/Scripts/Bots/CharacterFactory.cs index ab18289..0ca7c1d 100644 --- a/Assets/Scripts/Bots/CharacterFactory.cs +++ b/Assets/Scripts/Bots/CharacterFactory.cs @@ -1,26 +1,28 @@ using System.Collections.Generic; using UnityEngine; -using Unity; public class CharacterFactory : MonoBehaviour { - private CharacterFactory instance; - public CharacterFactory Instance { get { return instance; } } + private static CharacterFactory instance; + public static CharacterFactory Instance => instance; [SerializeField] private List spawnPointsForDefendersTeam; [SerializeField] private List spawnPointsForAttackersTeam; [SerializeField] private GameObject AIPrefab; [SerializeField] private GameObject PlayerPrefab; - private List Bots = new List(); - private GameObject Player; + private List bots = new List(); + 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() @@ -53,7 +55,7 @@ public class CharacterFactory : MonoBehaviour { var gameobject = GameObject.Instantiate( typeAi == TypeAI.HumanAI ? PlayerPrefab : AIPrefab, - spawnPoint.position, + spawnPoint.Position, Quaternion.identity); gameobject.SetActive(true); if (team == Team.Attackers) @@ -64,35 +66,49 @@ public class CharacterFactory : MonoBehaviour if (typeAi == TypeAI.HumanAI) { gameobject.GetComponent().GetCharacter.Team = team; - Player = gameobject; + player = gameobject; } else { gameobject.GetComponent().GetCharacter.Team = team; - gameobject.GetComponent().CurrentNavPoint = spawnPoint; - Bots.Add(gameobject); + gameobject.GetComponent().PointStartID = spawnPoint.PointId; + bots.Add(gameobject); } } + 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) + foreach (var bot in bots) { var npc = bot.GetComponent(); npc.ResetCharacter(); if (npc.GetCharacter.Team == Team.Attackers) - bot.transform.position = spawnPointsForAttackersTeam[Random.Range(0, spawnPointsForAttackersTeam.Count)].position; + bot.transform.position = spawnPointsForAttackersTeam[Random.Range(0, spawnPointsForAttackersTeam.Count)].Position; else - bot.transform.position = spawnPointsForDefendersTeam[Random.Range(0, spawnPointsForDefendersTeam.Count)].position; + bot.transform.position = spawnPointsForDefendersTeam[Random.Range(0, spawnPointsForDefendersTeam.Count)].Position; } Player player; if (TryGetComponent(out player)) { player.ResetCharacter(); if (player.GetCharacter.Team == Team.Attackers) - Player.transform.position = spawnPointsForAttackersTeam[Random.Range(0, spawnPointsForAttackersTeam.Count)].position; + this.player.transform.position = spawnPointsForAttackersTeam[Random.Range(0, spawnPointsForAttackersTeam.Count)].Position; else - Player.transform.position = spawnPointsForDefendersTeam[Random.Range(0, spawnPointsForDefendersTeam.Count)].position; + this.player.transform.position = spawnPointsForDefendersTeam[Random.Range(0, spawnPointsForDefendersTeam.Count)].Position; } } } \ No newline at end of file diff --git a/Assets/Scripts/Bots/TeamEnum.cs b/Assets/Scripts/Bots/TeamEnum.cs index 68279f5..a2c8a95 100755 --- a/Assets/Scripts/Bots/TeamEnum.cs +++ b/Assets/Scripts/Bots/TeamEnum.cs @@ -2,4 +2,15 @@ { Defenders, Attackers, +} + +public static class TeamExtension +{ + public static Team GetOppositeTeam(this Team team) + { + if (team == Team.Attackers) + return Team.Defenders; + else + return Team.Attackers; + } } \ No newline at end of file diff --git a/Assets/Scripts/Character/Character.cs b/Assets/Scripts/Character/Character.cs index 50e7313..3713998 100644 --- a/Assets/Scripts/Character/Character.cs +++ b/Assets/Scripts/Character/Character.cs @@ -7,12 +7,6 @@ public class Character public Character() { - Debug.Log("init"); Condition = new CharacterCondition(); } -} - -public interface ICharacter -{ - Character GetCharacter { get; } } \ No newline at end of file diff --git a/Assets/Scripts/Character/CharacterCondition.cs b/Assets/Scripts/Character/CharacterCondition.cs index b674222..de60740 100755 --- a/Assets/Scripts/Character/CharacterCondition.cs +++ b/Assets/Scripts/Character/CharacterCondition.cs @@ -9,17 +9,17 @@ public class CharacterCondition public event Action OnChangeAmmunitionEvent; private int health; - public int HealthPoints - { - get - { - return health; - } + public int HealthPoints + { + get + { + return health; + } private set { health = value; OnChangeHealthEvent?.Invoke(value); - } + } } public int GetHealthPointsInQuantile() @@ -30,7 +30,7 @@ public class CharacterCondition return 1; else if (health < 75) return 2; - else return 3; + else return 3; } private int armour; public int ArmourPoints @@ -45,6 +45,17 @@ public class CharacterCondition OnChangeArmourEvent?.Invoke(value); } } + public int GetArmourPointsInQuantile() + { + if (armour < 25) + return 0; + else if (armour < 50) + return 1; + else if (armour < 75) + return 2; + else return 3; + } + private int ammo; public int Ammunition { @@ -60,6 +71,11 @@ public class CharacterCondition } public CharacterCondition() + { + this.Reset(); + } + + public void Reset() { var settings = SettingsReader.Instance.GetSettings; ammo = settings.MaxAmmo; diff --git a/Assets/Scripts/Sensors.meta b/Assets/Scripts/Character/Interfaces.meta old mode 100755 new mode 100644 similarity index 77% rename from Assets/Scripts/Sensors.meta rename to Assets/Scripts/Character/Interfaces.meta index a808c2b..cb4a3aa --- a/Assets/Scripts/Sensors.meta +++ b/Assets/Scripts/Character/Interfaces.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5e73ba257bc6b684c86edf9ecfd475ef +guid: f23b6db3be1e4cd469fd18dfe3e39764 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Scripts/Character/Interfaces/ICharacter.cs b/Assets/Scripts/Character/Interfaces/ICharacter.cs new file mode 100644 index 0000000..aef14a7 --- /dev/null +++ b/Assets/Scripts/Character/Interfaces/ICharacter.cs @@ -0,0 +1,5 @@ +public interface ICharacter +{ + Character GetCharacter { get; } + void ResetCharacter(); +} \ No newline at end of file diff --git a/Assets/Scripts/Sensors/SensorType.cs.meta b/Assets/Scripts/Character/Interfaces/ICharacter.cs.meta old mode 100755 new mode 100644 similarity index 83% rename from Assets/Scripts/Sensors/SensorType.cs.meta rename to Assets/Scripts/Character/Interfaces/ICharacter.cs.meta index 26f4b58..b53c34e --- a/Assets/Scripts/Sensors/SensorType.cs.meta +++ b/Assets/Scripts/Character/Interfaces/ICharacter.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 8f76201fe6436164789d10350a0fd6e2 +guid: b6dfb78244ae35c4db1326d5f5b73375 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/Character/Interfaces/INpcBaseState.cs b/Assets/Scripts/Character/Interfaces/INpcBaseState.cs new file mode 100644 index 0000000..bf17ad2 --- /dev/null +++ b/Assets/Scripts/Character/Interfaces/INpcBaseState.cs @@ -0,0 +1,17 @@ +using UnityEngine; + +public interface INpcBaseState +{ + NpcEnumState State { get; } + bool InCover { get; } + bool IsRunning { get; } + bool InDirectPoint { get; } + float HitChance { get; } + float DoDamageChance { get; } +} + +public interface INpcBaseBodyState +{ + NpcBodyState State { get; } + Vector3 GetPointToHit(GameObject go); +} \ No newline at end of file diff --git a/Assets/Scripts/Sensors/Sensors.cs.meta b/Assets/Scripts/Character/Interfaces/INpcBaseState.cs.meta similarity index 83% rename from Assets/Scripts/Sensors/Sensors.cs.meta rename to Assets/Scripts/Character/Interfaces/INpcBaseState.cs.meta index 1109bef..f0585e4 100644 --- a/Assets/Scripts/Sensors/Sensors.cs.meta +++ b/Assets/Scripts/Character/Interfaces/INpcBaseState.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 4599c57bc5b1c3945847dead0f9f0ba4 +guid: 58b7e1962495ada4c8e6ee6219c99a20 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/Character/MovementController.cs b/Assets/Scripts/Character/MovementController.cs index 334b7d2..2319c08 100644 --- a/Assets/Scripts/Character/MovementController.cs +++ b/Assets/Scripts/Character/MovementController.cs @@ -1,24 +1,32 @@ -using System.Linq; -using System.Collections.Generic; +using System.Collections.Generic; +using System.Linq; using UnityEngine; using UnityEngine.AI; -using System.Threading.Tasks; [RequireComponent(typeof(NavMeshAgent))] public class MovementController : MonoBehaviour { - public NavPoint CurrentNavPoint { get; set; } + public int PointStartID { get; set; } + public int PointEndID { get; private set; } public float FlagDistance { get; private set; } - private GameObject flag; - private const float updateFlagPositionDelay = 5; - [SerializeField] private NavMeshAgent navMeshAgent; + private const float updateFlagPositionDelay = 5; + private const float updateReachedDestinationDelay = 5; - private void Start() + [SerializeField] private NavMeshAgent navMeshAgent; + [SerializeField] private GameObject flag; + public float DistanceToGo { get; private set; } + public float RemainingDistance => navMeshAgent.remainingDistance; + private Dictionary idNavPointDict; + + + private void Awake() { navMeshAgent.speed = SettingsReader.Instance.GetSettings.MovementSpeed; + idNavPointDict = MapManager.IDToNavPoint; InvokeRepeating(nameof(UpdateFlagPosition), 0, updateFlagPositionDelay); + InvokeRepeating(nameof(ReachedDestination), 0, updateReachedDestinationDelay); } - + private void OnDestroy() { CancelInvoke(nameof(UpdateFlagPosition)); @@ -30,18 +38,46 @@ public class MovementController : MonoBehaviour } public void MoveToRandomPoint() - { - Debug.Log(MapManager.navPoints == null); - goToNextNavPoint(MapManager.navPoints[Random.Range(0, MapManager.navPoints.Count)]); + { + Debug.Log(MapManager.NavPoints == null); + GoToNextNavPoint(MapManager.NavPoints[Random.Range(0, MapManager.NavPoints.Count)]); } - public List getPointsCandidate() + public List GetPointsCandidate() { - return MapManager.navPoints - .Where(point => (CurrentNavPoint.position - point.position).magnitude < SettingsReader.Instance.GetSettings.MovementSpeed) + return MapManager.NavPoints + .Where(point => + (idNavPointDict[PointStartID].Position - point.Position).magnitude < SettingsReader.Instance.GetSettings.MovementDistance) .ToList(); } - public void goToNextNavPoint(NavPoint destination) => - navMeshAgent.SetDestination(destination.position); + public void GoToNextNavPoint(NavPoint destination) + { + if (navMeshAgent.isStopped == true) navMeshAgent.isStopped = false; + PointStartID = PointEndID; + PointEndID = destination.PointId; + navMeshAgent.SetDestination(destination.Position); + DistanceToGo = navMeshAgent.remainingDistance; + } + + public void ReturnToStartPoint() + { + if (navMeshAgent.isStopped == true) navMeshAgent.isStopped = false; + navMeshAgent.SetDestination(idNavPointDict[PointStartID].Position); + PointEndID = PointStartID; + PointStartID = -1; + } + + public void StopOnPath() + { + navMeshAgent.isStopped = true; + PointStartID = -1; + PointEndID = -1; + } + + public void ReachedDestination() + { + if ((navMeshAgent.isStopped == false) && (navMeshAgent.velocity.magnitude < 0.1)) + PointStartID = PointEndID; + } } diff --git a/Assets/Scripts/Character/NPC.cs b/Assets/Scripts/Character/NPC.cs index c738d0b..d47e377 100644 --- a/Assets/Scripts/Character/NPC.cs +++ b/Assets/Scripts/Character/NPC.cs @@ -1,108 +1,170 @@ using System; -using UnityEngine; +using System.Collections.Generic; using Unity.MLAgents; -using Unity.MLAgents.Sensors; using Unity.MLAgents.Actuators; +using Unity.MLAgents.Sensors; +using UnityEngine; -[RequireComponent(typeof(MovementController))] +[RequireComponent(typeof(MovementController),typeof(BufferSensor))] public class NPC : Agent, ICharacter { [HideInInspector] - public Character AgentCharacter; + private Character AgentCharacter; public CharacterCondition Condition; - private FlagZone flagZone; + private FlagZone flagZone = null; - public NPC_BaseState NPC_State { get; private set; } + public INpcBaseState NpcState { get; private set; } + public INpcBaseBodyState NpcBodyState { get; private set; } public Character GetCharacter => AgentCharacter; - private NPC_DirectPointState DirectState; - private NPC_InCoverState CoverState; - private NPC_RunningState RunningState; + private NpcDirectPointState DirectState; + private NpcInCoverState CoverState; + private NpcRunningState RunningState; + + private NpcStandingState StandingState; + private NpcCrouchingState CrouchingState; private MovementController moveController; private BufferSensorComponent bufferSensor; + private Dictionary navPointIdDict; + + #region UnityEvents and ML private void Awake() { - DirectState = new NPC_DirectPointState(); - CoverState = new NPC_InCoverState(); - RunningState = new NPC_RunningState(); - NPC_State = DirectState; + DirectState = new NpcDirectPointState(); + CoverState = new NpcInCoverState(); + RunningState = new NpcRunningState(); + NpcState = DirectState; + + CrouchingState = new NpcCrouchingState(); + StandingState = new NpcStandingState(); + NpcBodyState = StandingState; AgentCharacter = new Character(); Condition = AgentCharacter.Condition; moveController = gameObject.GetComponent(); bufferSensor = gameObject.GetComponent(); - } - - public void ResetCharacter() + flagZone = GameObject.FindObjectOfType(); + if (flagZone == null) + Debug.LogError("Flag Is Not Setted"); + + navPointIdDict = MapManager.IDToNavPoint; + if (navPointIdDict is null) + Debug.LogError("Cant Find Nav Point Dictionary"); + } + + private void OnDestroy() { - Condition = new CharacterCondition(); - EndEpisode(); + Debug.LogWarning("Pooled object was destroyed"); } public override void OnEpisodeBegin() - { - NPC_State = DirectState; + { + NpcState = DirectState; flagZone = GameObject.FindObjectOfType(); } public override void CollectObservations(VectorSensor sensor) { - var candidates = moveController.getPointsCandidate(); + var candidates = moveController.GetPointsCandidate(); - sensor.AddObservation(Condition.HealthPoints); - sensor.AddObservation(Condition.ArmourPoints); - sensor.AddObservation(Condition.Ammunition); - sensor.AddObservation((int)NPC_State.State); - sensor.AddObservation((!flagZone.isNotOccup).ToInt()); + //common sensors + sensor.AddObservation(GameManager.IsHaveSeenByEnemy(AgentCharacter.Team.GetOppositeTeam(), + NpcBodyState.GetPointToHit(gameObject)).ToInt()); sensor.AddObservation(AgentCharacter.LastTimeHit); + sensor.AddObservation((!flagZone.IsNotOccup).ToInt()); sensor.AddObservation(Condition.GetHealthPointsInQuantile()); + sensor.AddObservation(Condition.GetArmourPointsInQuantile()); sensor.AddObservation(candidates.Count); - sensor.AddObservation(GameManager.IsEnemyNearby(gameObject.transform.position, AgentCharacter.Team)); - + sensor.AddObservation(moveController.PointStartID); + sensor.AddObservation(moveController.PointEndID); + //state sensors + sensor.AddObservation((int)NpcState.State); + sensor.AddObservation((int)NpcBodyState.State); + sensor.AddObservation(GameManager.IsEnemyNearby(gameObject.transform.position, AgentCharacter.Team)); + sensor.AddObservation(navPointIdDict[moveController.PointStartID].DeathAttr); + sensor.AddObservation(navPointIdDict[moveController.PointEndID].DeathAttr); + sensor.AddObservation(moveController.FlagDistance); + + //point sensors foreach (var point in candidates) { - Debug.Log((float)moveController.CurrentNavPoint.PointId); - bufferSensor.AppendObservation(new float[] { - //1 position in navpointId - (float)moveController.CurrentNavPoint.PointId, - //2 distance to flag - moveController.FlagDistance, - //3 death count in point - moveController.CurrentNavPoint.DeathAttr, + point.DeathAttr, + (int)point.navType, //4 flagEnemyDistance GameManager.IsCloserToFlagFromNextNavPoint(point, transform.position).ToInt(), //5 EnemyVsNavPointDistance - GameManager.IsCloserToEnemyThanToNextNavPoint(point,transform.position, AgentCharacter.Team).ToInt() - }); - - } - } - - public override void Heuristic(in ActionBuffers actionsOut) - { - var discreteActionsOut = actionsOut.DiscreteActions; - if (Input.GetKeyDown(KeyCode.W)) - { - discreteActionsOut[0] = 1; + GameManager.IsCloserToEnemyThanToNextNavPoint(point,transform.position, AgentCharacter.Team.GetOppositeTeam()).ToInt(), + //6 Have been seen by enemy in this point + GameManager.IsHaveSeenByEnemy(AgentCharacter.Team.GetOppositeTeam(), + point.Position).ToInt() + }); } } public override void OnActionReceived(ActionBuffers actions) { - if (actions.DiscreteActions[0] == 1) + var result = actions.DiscreteActions; + if (result[0] == 0) { - moveController.MoveToRandomPoint(); - NPC_State = RunningState; + if (navPointIdDict[moveController.PointStartID].navType != NavPointType.Cover) + return; + NpcState = CoverState; + + switch (result[1]) + { + case 0: Peek(); break; + case 1: Cover(); break; + case 3: Peek(); moveController.GoToNextNavPoint(navPointIdDict[result[2]]); break; + case 4: NpcState = DirectState; break; + default: throw new ArgumentException("Undefined Action recieved"); + } + } + if (result[0] == 1) + { + if (navPointIdDict[moveController.PointStartID].navType != NavPointType.Direction) + return; + switch (result[1]) + { + case 0: moveController.GoToNextNavPoint(navPointIdDict[result[2]]); + NpcState = RunningState; break; + case 1: NpcState = DirectState; break; + default: throw new ArgumentException("Undefined Action recieved"); + } + } + if (result[0] == 2) + { + if (moveController.PointStartID == moveController.PointEndID && moveController.PointEndID != -1) + return; + switch (result[1]) + { + case 0: moveController.StopOnPath(); NpcState = DirectState; break; + case 1: moveController.ReturnToStartPoint(); NpcState = RunningState; break; + default: throw new ArgumentException("Undefined Action recieved"); + } } } + #endregion - public event Action OnKilledEvent; + public event Action OnChangePosition; + private void Peek() + { + OnChangePosition?.Invoke(global::NpcBodyState.Standing); + NpcBodyState = StandingState; + } + + private void Cover() + { + OnChangePosition?.Invoke(global::NpcBodyState.Crouching); + NpcBodyState = CrouchingState; + } + + public event Action OnDamageRecieved; public void GetDamage(float damage) { AgentCharacter.LastTimeHit = TimeManager.Instance.CurrentTime; @@ -111,13 +173,17 @@ public class NPC : Agent, ICharacter if (Condition.HealthPoints < 0) { - OnKilledEvent?.Invoke(this); - moveController.CurrentNavPoint.DeathAttr += 1; + MapManager.AddDeathAttributeToPoints(moveController.PointStartID, moveController.PointEndID, + moveController.DistanceToGo, moveController.RemainingDistance); + var pos = gameObject.transform.position; + var id = moveController.PointStartID; + CharacterFactory.Instance.ReSpawn(this, ref pos, ref id); } } - private void OnDestroy() + public void ResetCharacter() { - Debug.LogWarning("Pooled object was destroyed"); + Condition.Reset(); + EndEpisode(); } } diff --git a/Assets/Scripts/Character/NPC_State.cs b/Assets/Scripts/Character/NPC_State.cs deleted file mode 100644 index cc2802c..0000000 --- a/Assets/Scripts/Character/NPC_State.cs +++ /dev/null @@ -1,46 +0,0 @@ -public enum NPC_EnumState -{ - InCover, - InDirectPoint, - InRunning, -} - -public interface NPC_BaseState -{ - NPC_EnumState State { get; } - bool InCover { get; } - bool IsRunning { get; } - bool InDirectPoint { get; } - float HitChance { get; } - float DoDamageChance { get; } -} - -public class NPC_DirectPointState : NPC_BaseState -{ - public bool InCover => false; - public bool IsRunning => false; - public bool InDirectPoint => false; - public float HitChance => SettingsReader.Instance.GetSettings.GetHitChanceInDirectPoint; - public float DoDamageChance => SettingsReader.Instance.GetSettings.DoDamageChanceInDirectPoint; - public NPC_EnumState State => NPC_EnumState.InDirectPoint; -} - -public class NPC_RunningState : NPC_BaseState -{ - public bool InCover => false; - public bool IsRunning => true; - public bool InDirectPoint => false; - public float HitChance => SettingsReader.Instance.GetSettings.GetHitChanceInRunning; - public float DoDamageChance => SettingsReader.Instance.GetSettings.DoDamageChanceInRunning; - public NPC_EnumState State => NPC_EnumState.InRunning; -} - -public class NPC_InCoverState : NPC_BaseState -{ - public bool InCover => true; - public bool IsRunning => false; - public bool InDirectPoint => false; - public float HitChance => SettingsReader.Instance.GetSettings.GetHitChanceInCover; - public float DoDamageChance => SettingsReader.Instance.GetSettings.DoDamageChanceInCover; - public NPC_EnumState State => NPC_EnumState.InCover; -} diff --git a/Assets/Scripts/Character/NpcState.cs b/Assets/Scripts/Character/NpcState.cs new file mode 100644 index 0000000..51feda6 --- /dev/null +++ b/Assets/Scripts/Character/NpcState.cs @@ -0,0 +1,68 @@ +using UnityEngine; + +public enum NpcEnumState +{ + InCover, + InDirectPoint, + InRunning, +} + +public enum NpcBodyState +{ + Crouching, + Standing, +} + +public class NpcCrouchingState : INpcBaseBodyState +{ + public NpcBodyState State => NpcBodyState.Crouching; + + public Vector3 GetPointToHit(GameObject go) + { + MeshRenderer meshRenderer; + go.TryGetComponent(out meshRenderer); + return meshRenderer.bounds.center; + } +} + +public class NpcStandingState : INpcBaseBodyState +{ + public NpcBodyState State => NpcBodyState.Standing; + + public Vector3 GetPointToHit(GameObject go) + { + MeshRenderer meshRenderer; + go.TryGetComponent(out meshRenderer); + return meshRenderer.bounds.center; + } +} + +public class NpcDirectPointState : INpcBaseState +{ + public bool InCover => false; + public bool IsRunning => false; + public bool InDirectPoint => false; + public float HitChance => SettingsReader.Instance.GetSettings.GetHitChanceInDirectPoint; + public float DoDamageChance => SettingsReader.Instance.GetSettings.DoDamageChanceInDirectPoint; + public NpcEnumState State => NpcEnumState.InDirectPoint; +} + +public class NpcRunningState : INpcBaseState +{ + public bool InCover => false; + public bool IsRunning => true; + public bool InDirectPoint => false; + public float HitChance => SettingsReader.Instance.GetSettings.GetHitChanceInRunning; + public float DoDamageChance => SettingsReader.Instance.GetSettings.DoDamageChanceInRunning; + public NpcEnumState State => NpcEnumState.InRunning; +} + +public class NpcInCoverState : INpcBaseState +{ + public bool InCover => true; + public bool IsRunning => false; + public bool InDirectPoint => false; + public float HitChance => SettingsReader.Instance.GetSettings.GetHitChanceInCover; + public float DoDamageChance => SettingsReader.Instance.GetSettings.DoDamageChanceInCover; + public NpcEnumState State => NpcEnumState.InCover; +} diff --git a/Assets/Scripts/Character/NPC_State.cs.meta b/Assets/Scripts/Character/NpcState.cs.meta similarity index 100% rename from Assets/Scripts/Character/NPC_State.cs.meta rename to Assets/Scripts/Character/NpcState.cs.meta diff --git a/Assets/Scripts/Character/Player.cs b/Assets/Scripts/Character/Player.cs index e593f51..593a326 100644 --- a/Assets/Scripts/Character/Player.cs +++ b/Assets/Scripts/Character/Player.cs @@ -15,9 +15,9 @@ public class Player : MonoBehaviour, ICharacter Condition = PlayerCharacter.Condition; } - public void ResetCharacter() + private void OnDestroy() { - Condition = new CharacterCondition(); + Debug.LogWarning("Pooled object was destroyed"); } public event Action OnKilledEvent; @@ -27,12 +27,12 @@ public class Player : MonoBehaviour, ICharacter Condition.GiveHealth(-Mathf.RoundToInt(damage * (1 - Condition.ArmourPoints * 0.5f))); Condition.GiveArmour(-Mathf.RoundToInt(Mathf.Sqrt(damage) * 5)); - if (Condition.HealthPoints < 0) - OnKilledEvent?.Invoke(this); + if (Condition.HealthPoints < 0) + OnKilledEvent?.Invoke(this); } - private void OnDestroy() + public void ResetCharacter() { - Debug.LogWarning("Pooled object was destroyed"); + Condition = new CharacterCondition(); } } diff --git a/Assets/Scripts/Character/scr_CharacterController.cs b/Assets/Scripts/Character/scr_CharacterController.cs index 2e54f22..e4f847d 100755 --- a/Assets/Scripts/Character/scr_CharacterController.cs +++ b/Assets/Scripts/Character/scr_CharacterController.cs @@ -1,10 +1,6 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using Unity.Barracuda; -using UnityEngine; +using UnityEngine; -using static scr_Models; +using static scr_Models; public class scr_CharacterController : MonoBehaviour { @@ -14,7 +10,7 @@ public class scr_CharacterController : MonoBehaviour private Vector2 input_Movement; [HideInInspector] public Vector2 input_View; - + private Vector3 newCameraRotation; private Vector3 newCharacterRotation; @@ -22,14 +18,14 @@ public class scr_CharacterController : MonoBehaviour public Transform cameraHolder; public Transform feetTransform; - [Header("Settings")] + [Header("Settings")] public PlayerSettingsModel playerSettings; public float ViewClampYMin = -70; public float ViewClampYMax = 80; public LayerMask playerMask; - - [Header("Gravity")] + + [Header("Gravity")] public float gravityAmount; public float gravityMin; private float playerGravity; @@ -37,14 +33,14 @@ public class scr_CharacterController : MonoBehaviour public Vector3 jumpingForce; private Vector3 jumpingForceVelocity; - [Header("Stance")] + [Header("Stance")] public PlayerStance playerStance; public float playerStanceSmoothing; public CharacterStance playerStandStance; public CharacterStance playerCrouchStance; public CharacterStance playerProneStance; private float stanceCheckErrorMargin = 0.05f; - + private float cameraHeight; private float cameraHeightVelocity; @@ -61,13 +57,13 @@ public class scr_CharacterController : MonoBehaviour defaultInput.Character.Movement.performed += e => input_Movement = e.ReadValue(); defaultInput.Character.View.performed += e => input_View = e.ReadValue(); defaultInput.Character.Jump.performed += e => Jump(); - + defaultInput.Character.Crouch.performed += e => Crouch(); defaultInput.Character.Prone.performed += e => Prone(); - + defaultInput.Character.Sprint.performed += e => ToggleSprint(); defaultInput.Character.SprintReleased.performed += e => StopSprint(); - + defaultInput.Enable(); newCameraRotation = cameraHolder.localRotation.eulerAngles; @@ -80,7 +76,7 @@ public class scr_CharacterController : MonoBehaviour { currentWeapon.Initialise(this); } - + } private void Update() @@ -95,10 +91,10 @@ public class scr_CharacterController : MonoBehaviour { newCharacterRotation.y += playerSettings.ViewXSensetivity * (playerSettings.ViewXInverted ? -input_View.x : input_View.x) * Time.deltaTime; transform.localRotation = Quaternion.Euler(newCharacterRotation); - + newCameraRotation.x += playerSettings.ViewYSensetivity * (playerSettings.ViewYInverted ? input_View.y : -input_View.y) * Time.deltaTime; newCameraRotation.x = Mathf.Clamp(newCameraRotation.x, ViewClampYMin, ViewClampYMax); - + cameraHolder.localRotation = Quaternion.Euler(newCameraRotation); } @@ -108,7 +104,7 @@ public class scr_CharacterController : MonoBehaviour { isSprinting = false; } - + var verticalSpeed = playerSettings.WalkingForwardSpeed; var horizontalSpeed = playerSettings.WalkingStrafeSpeed; @@ -117,17 +113,17 @@ public class scr_CharacterController : MonoBehaviour verticalSpeed = playerSettings.RunningForwardSpeed; horizontalSpeed = playerSettings.RunningStrafeSpeed; } - + // Effectors if (!characterController.isGrounded) { playerSettings.SpeedEffector = playerSettings.FallingSpeedEffector; } - else if(playerStance == PlayerStance.Crouch) + else if (playerStance == PlayerStance.Crouch) { playerSettings.SpeedEffector = playerSettings.CrouchSpeedEffector; - } - else if(playerStance == PlayerStance.Prone) + } + else if (playerStance == PlayerStance.Prone) { playerSettings.SpeedEffector = playerSettings.ProneSpeedEffector; } @@ -135,15 +131,15 @@ public class scr_CharacterController : MonoBehaviour { playerSettings.SpeedEffector = 1; } - + verticalSpeed *= playerSettings.SpeedEffector; horizontalSpeed *= playerSettings.SpeedEffector; - + newMovementSpeed = Vector3.SmoothDamp(newMovementSpeed, new Vector3(horizontalSpeed * input_Movement.x * Time.deltaTime, 0, verticalSpeed * input_Movement.y * Time.deltaTime), ref newMovementSpeedVelocity, characterController.isGrounded ? playerSettings.MovementSmoothing : playerSettings.FallingSmoothing); - + var MovementSpeed = transform.TransformDirection(newMovementSpeed); if (playerGravity > gravityMin) @@ -158,7 +154,7 @@ public class scr_CharacterController : MonoBehaviour MovementSpeed.y += playerGravity; MovementSpeed += jumpingForce * Time.deltaTime; - + characterController.Move(MovementSpeed); } @@ -179,7 +175,7 @@ public class scr_CharacterController : MonoBehaviour { stanceHeight = playerProneStance.CameraHeight; } - + cameraHeight = Mathf.SmoothDamp(cameraHolder.localPosition.y, stanceHeight, ref cameraHeightVelocity, playerStanceSmoothing); cameraHolder.localPosition = new Vector3(cameraHolder.localPosition.x, cameraHeight, cameraHolder.localPosition.z); @@ -190,7 +186,7 @@ public class scr_CharacterController : MonoBehaviour { return; } - + if (playerStance == PlayerStance.Crouch) { if (StanceCheck(playerStandStance.StanceCollider.height)) @@ -200,7 +196,7 @@ public class scr_CharacterController : MonoBehaviour playerStance = PlayerStance.Stand; return; } - + // Jump jumpingForce = Vector3.up * playerSettings.JumpingHeight; playerGravity = 0; @@ -233,8 +229,8 @@ public class scr_CharacterController : MonoBehaviour { var start = new Vector3(feetTransform.position.x, feetTransform.position.y + characterController.radius + stanceCheckErrorMargin, feetTransform.position.z); var end = new Vector3(feetTransform.position.x, feetTransform.position.y - characterController.radius - stanceCheckErrorMargin + stanceCheckheight, feetTransform.position.z); - - + + return Physics.CheckCapsule(start, end, characterController.radius, playerMask); } @@ -247,7 +243,7 @@ public class scr_CharacterController : MonoBehaviour } isSprinting = !isSprinting; } - + private void StopSprint() { if (playerSettings.SprintingHold) @@ -255,5 +251,5 @@ public class scr_CharacterController : MonoBehaviour isSprinting = false; } } - + } diff --git a/Assets/Scripts/Character/scr_Models.cs b/Assets/Scripts/Character/scr_Models.cs index 3aca984..c735db5 100755 --- a/Assets/Scripts/Character/scr_Models.cs +++ b/Assets/Scripts/Character/scr_Models.cs @@ -3,73 +3,73 @@ using UnityEngine; public static class scr_Models { - #region Player - - public enum PlayerStance - { - Stand, - Crouch, - Prone - } - - [Serializable] - public class PlayerSettingsModel - { - [Header("View Settings")] - public float ViewXSensetivity; - public float ViewYSensetivity; + #region Player - public bool ViewXInverted; - public bool ViewYInverted; + public enum PlayerStance + { + Stand, + Crouch, + Prone + } - [Header("Movement Settings")] - public bool SprintingHold; - public float MovementSmoothing; - - [Header("Movement - Running")] - public float RunningForwardSpeed; - public float RunningStrafeSpeed; - - [Header("Movement - Walking")] - public float WalkingForwardSpeed; - public float WalkingBackwardSpeed; - public float WalkingStrafeSpeed; + [Serializable] + public class PlayerSettingsModel + { + [Header("View Settings")] + public float ViewXSensetivity; + public float ViewYSensetivity; - [Header("Jumping")] - public float JumpingHeight; - public float JumpingFalloff; - public float FallingSmoothing; + public bool ViewXInverted; + public bool ViewYInverted; - [Header("Speed Effectors")] - public float SpeedEffector = 1; - public float CrouchSpeedEffector; - public float ProneSpeedEffector; - public float FallingSpeedEffector; - } + [Header("Movement Settings")] + public bool SprintingHold; + public float MovementSmoothing; - [Serializable] - public class CharacterStance - { - public float CameraHeight; - public CapsuleCollider StanceCollider; - } + [Header("Movement - Running")] + public float RunningForwardSpeed; + public float RunningStrafeSpeed; - #endregion + [Header("Movement - Walking")] + public float WalkingForwardSpeed; + public float WalkingBackwardSpeed; + public float WalkingStrafeSpeed; - #region - Weapons - + [Header("Jumping")] + public float JumpingHeight; + public float JumpingFalloff; + public float FallingSmoothing; - [Serializable] - public class WeaponSettingsModel - { - [Header("Sway")] - public float SwayAmount; - public bool SwayYInverted; - public bool SwayXInverted; - public float SwaySmoothing; - public float SwayResetSmoothing; - public float SwayClampX; - public float SwayClampY; - } + [Header("Speed Effectors")] + public float SpeedEffector = 1; + public float CrouchSpeedEffector; + public float ProneSpeedEffector; + public float FallingSpeedEffector; + } - #endregion + [Serializable] + public class CharacterStance + { + public float CameraHeight; + public CapsuleCollider StanceCollider; + } + + #endregion + + #region - Weapons - + + [Serializable] + public class WeaponSettingsModel + { + [Header("Sway")] + public float SwayAmount; + public bool SwayYInverted; + public bool SwayXInverted; + public float SwaySmoothing; + public float SwayResetSmoothing; + public float SwayClampX; + public float SwayClampY; + } + + #endregion } diff --git a/Assets/Scripts/Managers/GameManager.cs b/Assets/Scripts/Managers/GameManager.cs index b91908d..7720a90 100755 --- a/Assets/Scripts/Managers/GameManager.cs +++ b/Assets/Scripts/Managers/GameManager.cs @@ -1,76 +1,123 @@ -using Unity.MLAgents; +using System; +using Unity.MLAgents; using UnityEngine; -using System; public class GameManager : MonoBehaviour { private static GameManager instance; - public static GameManager Instance { get { return instance; } } + public static GameManager Instance => instance; - private static SimpleMultiAgentGroup DefendersTeam = new SimpleMultiAgentGroup(); - private static SimpleMultiAgentGroup AttackersTeam = new SimpleMultiAgentGroup(); + private static SimpleMultiAgentGroup defendersTeam = new SimpleMultiAgentGroup(); + private static SimpleMultiAgentGroup attackersTeam = new SimpleMultiAgentGroup(); private void Awake() { - if (Instance == null) + if (instance is null) instance = this; - else if (Instance == this) + else + { Destroy(gameObject); + Debug.LogError("Only 1 Instance"); + } } private void Start() { Academy.Instance.OnEnvironmentReset += ResetScene; - GlobalEventManager.onCaptureFlag += flagCaptured; - GlobalEventManager.onTimeLeft += timeOut; + GlobalEventManager.onCaptureFlag += FlagCaptured; + GlobalEventManager.onTimeLeft += TimeOut; var agents = GameObject.FindObjectsOfType(); foreach (var item in agents) { var agent = item as NPC; if (agent.GetCharacter.Team == Team.Attackers) - AttackersTeam.RegisterAgent(agent); + attackersTeam.RegisterAgent(item); else - DefendersTeam.RegisterAgent(agent); + defendersTeam.RegisterAgent(item); } } - public static bool IsCloserToEnemyThanToNextNavPoint(NavPoint navPoint, Vector3 currentTransform, Team team) + private static SimpleMultiAgentGroup getAgentList(Team team) { - SimpleMultiAgentGroup agentGroup; if (team == Team.Attackers) - agentGroup = AttackersTeam; + return attackersTeam; else - agentGroup = DefendersTeam; + return defendersTeam; + } - var distToNavPoint = (currentTransform - navPoint.position).magnitude; + public static bool IsCloserToEnemyThanToNextNavPoint(NavPoint navPoint, Vector3 currentTransform, Team oppositeTeam) + { + var agentGroup = getAgentList(oppositeTeam); + + var distToNavPoint = (currentTransform - navPoint.Position).magnitude; foreach (var agent in agentGroup.GetRegisteredAgents()) if (distToNavPoint > (currentTransform - agent.transform.position).magnitude) return true; + if ((SettingsReader.Instance.GetSettings.HasHumanAttacker == true && oppositeTeam == Team.Attackers) || + (SettingsReader.Instance.GetSettings.HasHumanDefender == true && oppositeTeam == Team.Defenders)) + { + if (distToNavPoint > (currentTransform - CharacterFactory.Instance.player.transform.position).magnitude) + return true; + } return false; } - public static bool IsEnemyNearby(Vector3 currentTransform, Team team) + public static bool IsEnemyNearby(Vector3 currentTransform, Team oppositeTeam) { - SimpleMultiAgentGroup agentGroup; - if (team == Team.Attackers) - agentGroup = AttackersTeam; - else - agentGroup = DefendersTeam; + var agentGroup = getAgentList(oppositeTeam); foreach (var agent in agentGroup.GetRegisteredAgents()) if ((currentTransform - agent.transform.position).magnitude < SettingsReader.Instance.GetSettings.ViewDistance) return true; + if ((SettingsReader.Instance.GetSettings.HasHumanAttacker == true && oppositeTeam == Team.Attackers) || + (SettingsReader.Instance.GetSettings.HasHumanDefender == true && oppositeTeam == Team.Defenders)) + { + if ((currentTransform - CharacterFactory.Instance.player.transform.position).magnitude < SettingsReader.Instance.GetSettings.ViewDistance) + return true; + } return false; } public static bool IsCloserToFlagFromNextNavPoint(NavPoint navPoint, Vector3 currentTransform) => navPoint.FlagDistance < (currentTransform - GameObject.FindGameObjectWithTag("Flag").transform.position).magnitude; - private void flagCaptured(Team team) + public static bool IsHaveSeenByEnemy(Team oppositeTeam, Vector3 position) { - switch(team) + var agentGroup = getAgentList(oppositeTeam); + RaycastHit rayHit = new RaycastHit(); + foreach (var agent in agentGroup.GetRegisteredAgents() ) + { + var npc = agent as NPC; + if (Physics.Raycast(position, + (npc.NpcBodyState.GetPointToHit(npc.gameObject) - position).normalized, + out rayHit, + SettingsReader.Instance.GetSettings.ViewDistance)) + { + if (rayHit.collider.gameObject.GetComponent() != null) + return true; + } + } + if ((SettingsReader.Instance.GetSettings.HasHumanAttacker == true && oppositeTeam == Team.Attackers) || + (SettingsReader.Instance.GetSettings.HasHumanDefender == true && oppositeTeam == Team.Defenders)) + { + var player = CharacterFactory.Instance.player; + if (Physics.Raycast(position, + (player.GetComponent().bounds.center - position).normalized, + out rayHit, + SettingsReader.Instance.GetSettings.ViewDistance)) + { + if (rayHit.collider.gameObject.GetComponent() != null) + return true; + } + } + return false; + } + + private void FlagCaptured(Team team) + { + switch (team) { case Team.Attackers: Debug.Log("Attackers Win"); @@ -78,21 +125,19 @@ public class GameManager : MonoBehaviour case Team.Defenders: Debug.Log("Defenders Win"); break; - default: - Debug.LogError("Unexpected Team"); - break; } + ResetScene(); } - private void timeOut() + private void TimeOut() { - Debug.Log("Time is out"); + ResetScene(); } private void OnDestroy() { - GlobalEventManager.onCaptureFlag -= flagCaptured; - GlobalEventManager.onTimeLeft -= timeOut; + GlobalEventManager.onCaptureFlag -= FlagCaptured; + GlobalEventManager.onTimeLeft -= TimeOut; } public static event Action OnResetScene; diff --git a/Assets/Scripts/Managers/MapManager.cs b/Assets/Scripts/Managers/MapManager.cs index 8c64208..b28dcba 100755 --- a/Assets/Scripts/Managers/MapManager.cs +++ b/Assets/Scripts/Managers/MapManager.cs @@ -3,17 +3,62 @@ using UnityEngine; public class MapManager : MonoBehaviour { - public static List navPoints { get; private set; } - private void Start() + private static MapManager instance; + public static MapManager Instance => instance; + private static List navPoints = new List(); + private static Dictionary iDToNavPoint = new Dictionary(); + public static List NavPoints { get => navPoints; private set => navPoints = value; } + public static Dictionary IDToNavPoint { get => iDToNavPoint; private set => iDToNavPoint = value; } + + private void Awake() { - var i = 0; - navPoints = new List(); - var navPointsGameObj = GameObject.FindGameObjectsWithTag("Point"); - foreach (var gameobj in navPointsGameObj) + if (instance is null) + instance = this; + else { - var navpoint = gameobj.GetComponent(); - navpoint.PointId = i; i++; - navPoints.Add(navpoint); + Destroy(gameObject); + Debug.LogError("Only 1 Instance"); } } + + private void Start() + { + var navPointSet = GameObject.Find("NavPoint Set"); + var count = navPointSet.transform.childCount; + for (int i=0; i < count; i++) + NavPoints.Add(navPointSet.transform.GetChild(i) + .gameObject.GetComponent()); + + NavPointSetToID(); + } + + private void NavPointSetToID() + { + int i = 0; + foreach (var navPoint in NavPoints) + { + IDToNavPoint.Add(i, navPoint); + navPoint.PointId = i; + i++; + } + } + + public static void AddDeathAttributeToPoints(int startPoint, int endPoint, + float allDistance, float remainingDistance) + { + var startNavPoint = IDToNavPoint[startPoint]; + var endNavPoint = IDToNavPoint[endPoint]; + float coef; + try + { + coef = remainingDistance / allDistance; + } + catch (System.ArithmeticException) + { + Debug.LogError("Path Length is zero"); + return; + } + startNavPoint.DeathAttr += 1 - coef; + endNavPoint.DeathAttr += coef; + } } diff --git a/Assets/Scripts/Managers/TimeManager.cs b/Assets/Scripts/Managers/TimeManager.cs index ea7fec4..4aa32a1 100755 --- a/Assets/Scripts/Managers/TimeManager.cs +++ b/Assets/Scripts/Managers/TimeManager.cs @@ -1,6 +1,4 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; +using UnityEngine; public class TimeManager : MonoBehaviour { @@ -17,12 +15,14 @@ public class TimeManager : MonoBehaviour } else { - Debug.LogError("Only one Instance"); + Debug.LogError("Only 1 Instance"); Destroy(gameObject); } } void Update() { CurrentTime += Time.deltaTime; + if (CurrentTime > SettingsReader.Instance.GetSettings.TimeOut) + GlobalEventManager.SendTimeout(); } } diff --git a/Assets/Scripts/Misc/FlagZone.cs b/Assets/Scripts/Misc/FlagZone.cs index c6328dd..c66d5bb 100755 --- a/Assets/Scripts/Misc/FlagZone.cs +++ b/Assets/Scripts/Misc/FlagZone.cs @@ -1,6 +1,4 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; +using UnityEngine; public class FlagZone : MonoBehaviour { @@ -9,8 +7,8 @@ public class FlagZone : MonoBehaviour public float TimeStayDefenders { get; private set; } private int occupDefenders; private int occupAttackers; - public bool isOccupBoth => (occupDefenders>0) && (occupAttackers>0); - public bool isNotOccup => (occupDefenders == 0) && (occupAttackers == 0); + public bool IsOccupBoth => (occupDefenders > 0) && (occupAttackers > 0); + public bool IsNotOccup => (occupDefenders == 0) && (occupAttackers == 0); private float timeForWin; private void Start() @@ -24,7 +22,7 @@ public class FlagZone : MonoBehaviour } private void OnTriggerEnter(Collider other) { - switch(other.tag) + switch (other.tag) { case "Defender": occupDefenders++; @@ -54,7 +52,7 @@ public class FlagZone : MonoBehaviour } private void Update() { - if (isOccupBoth || isNotOccup) + if (IsOccupBoth || IsNotOccup) { TimeStayAttackers = 0; TimeStayDefenders = 0; @@ -64,7 +62,7 @@ public class FlagZone : MonoBehaviour { TimeStayAttackers += Time.deltaTime; if (TimeStayAttackers > timeForWin) - GlobalEventManager.SendCaptureFlag(Team.Attackers); + GlobalEventManager.SendCaptureFlag(Team.Attackers); } else { diff --git a/Assets/Scripts/Misc/NavPoint.cs b/Assets/Scripts/Misc/NavPoint.cs index 2b43e84..a70fd61 100755 --- a/Assets/Scripts/Misc/NavPoint.cs +++ b/Assets/Scripts/Misc/NavPoint.cs @@ -1,20 +1,28 @@ -using System.Collections; -using System.Collections.Generic; +using System.Collections.Generic; +using System; using UnityEngine; +public enum NavPointType +{ + Cover, + Direction, +} + + public class NavPoint : MonoBehaviour { - public Vector3 position => gameObject.transform.position; + public Vector3 Position => gameObject.transform.position; public float FlagDistance { get; private set; } + public NavPointType navType = NavPointType.Direction; + [HideInInspector] - public int? PointId; + public int PointId = 0; public float DeathAttr = 0; public List EnemiesSeen = new List(); - //Here other attributes; private void Start() { - FlagDistance = (GameObject.FindGameObjectWithTag("Flag").transform.position - position).magnitude; + FlagDistance = (GameObject.FindGameObjectWithTag("Flag").transform.position - Position).magnitude; } } diff --git a/Assets/Scripts/Misc/Settings.cs b/Assets/Scripts/Misc/Settings.cs index b1b7ea8..4e333fc 100755 --- a/Assets/Scripts/Misc/Settings.cs +++ b/Assets/Scripts/Misc/Settings.cs @@ -1,6 +1,6 @@ using UnityEngine; -[CreateAssetMenu(fileName ="Game Settings", menuName = "Game/Settings", order = 51)] +[CreateAssetMenu(fileName = "Game Settings", menuName = "Game/Settings", order = 51)] public class Settings : ScriptableObject { public bool IsTesting; @@ -36,4 +36,6 @@ public class Settings : ScriptableObject public float DoDamageChanceInDirectPoint; public float DoDamageChanceInRunning; public float DoDamageChanceInCover; + + public float CrouchingCoefficient; } diff --git a/Assets/Scripts/Misc/SettingsReader.cs b/Assets/Scripts/Misc/SettingsReader.cs index ab60b87..9e709ad 100755 --- a/Assets/Scripts/Misc/SettingsReader.cs +++ b/Assets/Scripts/Misc/SettingsReader.cs @@ -1,17 +1,21 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; +using UnityEngine; public class SettingsReader : MonoBehaviour { private static SettingsReader instance; - public static SettingsReader Instance { get { return instance; } } + public static SettingsReader Instance => instance; private void Awake() { - instance = this; + if (instance is null) + instance = this; + else + { + Destroy(gameObject); + Debug.LogError("Only 1 Instance"); + } } [SerializeField] private Settings gameSettings; - public Settings GetSettings { get { return gameSettings; } } + public Settings GetSettings => gameSettings; } diff --git a/Assets/Scripts/Misc/Statistics.cs b/Assets/Scripts/Misc/Statistics.cs deleted file mode 100755 index 98be783..0000000 --- a/Assets/Scripts/Misc/Statistics.cs +++ /dev/null @@ -1,9 +0,0 @@ -using UnityEngine; - -public class Statistics : MonoBehaviour -{ - private void Start() - { - - } -} diff --git a/Assets/Scripts/Pickups/AmmoPickUp.cs b/Assets/Scripts/Pickups/AmmoPickUp.cs index 8439c21..e7af1ce 100755 --- a/Assets/Scripts/Pickups/AmmoPickUp.cs +++ b/Assets/Scripts/Pickups/AmmoPickUp.cs @@ -1,5 +1,4 @@ -using System; -using UnityEngine; +using UnityEngine; [RequireComponent(typeof(BoxCollider))] public class AmmoPickUp : MonoBehaviour, IPickable @@ -11,6 +10,11 @@ public class AmmoPickUp : MonoBehaviour, IPickable PickObject(other.gameObject); } + private void OnDestroy() + { + Debug.LogWarning("Pooled object was destroyed"); + } + public void PickObject(GameObject obj) { obj.GetComponent()?.GetCharacter.Condition.TakeAmmo(SettingsReader.Instance.GetSettings.AmmunitionPickupAmount); diff --git a/Assets/Scripts/Pickups/ArmourPickUp.cs b/Assets/Scripts/Pickups/ArmourPickUp.cs index c68e491..b5303f6 100755 --- a/Assets/Scripts/Pickups/ArmourPickUp.cs +++ b/Assets/Scripts/Pickups/ArmourPickUp.cs @@ -1,5 +1,4 @@ -using System; -using UnityEngine; +using UnityEngine; [RequireComponent(typeof(BoxCollider))] public class ArmourPickUp : MonoBehaviour, IPickable @@ -11,6 +10,11 @@ public class ArmourPickUp : MonoBehaviour, IPickable PickObject(other.gameObject); } + private void OnDestroy() + { + Debug.LogWarning("Pooled object was destroyed"); + } + public void PickObject(GameObject obj) { obj.GetComponent()?.GetCharacter.Condition.GiveArmour(SettingsReader.Instance.GetSettings.ArmourPickupAmount); diff --git a/Assets/Scripts/Pickups/HealthPickUp.cs b/Assets/Scripts/Pickups/HealthPickUp.cs index 36f81ba..ba8d136 100755 --- a/Assets/Scripts/Pickups/HealthPickUp.cs +++ b/Assets/Scripts/Pickups/HealthPickUp.cs @@ -1,5 +1,4 @@ -using System; -using UnityEngine; +using UnityEngine; [RequireComponent(typeof(BoxCollider))] public class HealthPickUp : MonoBehaviour, IPickable @@ -11,6 +10,11 @@ public class HealthPickUp : MonoBehaviour, IPickable PickObject(other.gameObject); } + private void OnDestroy() + { + Debug.LogWarning("Pooled object was destroyed"); + } + public void PickObject(GameObject obj) { obj.GetComponent()?.GetCharacter.Condition.GiveHealth(SettingsReader.Instance.GetSettings.HealthPickupAmount); diff --git a/Assets/Scripts/Pickups/IPickable.cs b/Assets/Scripts/Pickups/IPickable.cs index fb218d0..37cced3 100755 --- a/Assets/Scripts/Pickups/IPickable.cs +++ b/Assets/Scripts/Pickups/IPickable.cs @@ -1,7 +1,6 @@ -using System; -using UnityEngine; +using UnityEngine; public interface IPickable { - PickUpType type { get; } + PickUpType type { get; } void PickObject(GameObject obj); } \ No newline at end of file diff --git a/Assets/Scripts/Pickups/PickUpSpawner.cs b/Assets/Scripts/Pickups/PickUpSpawner.cs index 7a29705..f9c320b 100755 --- a/Assets/Scripts/Pickups/PickUpSpawner.cs +++ b/Assets/Scripts/Pickups/PickUpSpawner.cs @@ -44,25 +44,25 @@ public class PickUpSpawner : MonoBehaviour private IEnumerator SpawnNewPickUps() { - while(true) + while (true) { GameObject item; - if(IsDisableCheck(out item)) + if (IsDisableCheck(out item)) { yield return new WaitForSeconds(3); if (item != null) { - item.transform.position = spawnPoints[Random.Range(0, spawnPoints.Count)].position; + item.transform.position = spawnPoints[Random.Range(0, spawnPoints.Count)].Position; item.SetActive(true); } } - yield return new WaitForSeconds(2); + yield return new WaitForSeconds(2); } } private bool IsDisableCheck(out GameObject gameobj) { - foreach(var pick in pickups) + foreach (var pick in pickups) { if (!pick.activeInHierarchy) { diff --git a/Assets/Scripts/Sensors/SensorType.cs b/Assets/Scripts/Sensors/SensorType.cs deleted file mode 100755 index 8d85790..0000000 --- a/Assets/Scripts/Sensors/SensorType.cs +++ /dev/null @@ -1,6 +0,0 @@ -public enum SensorType -{ - Visual, - Sound, - Other -} diff --git a/Assets/Scripts/Sensors/Sensors.cs b/Assets/Scripts/Sensors/Sensors.cs deleted file mode 100644 index b38d85f..0000000 --- a/Assets/Scripts/Sensors/Sensors.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Collections.Generic; -using Unity.MLAgents.Sensors; - - diff --git a/Assets/Scripts/Statistics.meta b/Assets/Scripts/Statistics.meta new file mode 100644 index 0000000..4e72120 --- /dev/null +++ b/Assets/Scripts/Statistics.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3a9f7f0a9faf11f49a433480722bffc5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Statistics/Logger.cs b/Assets/Scripts/Statistics/Logger.cs new file mode 100644 index 0000000..e293d25 --- /dev/null +++ b/Assets/Scripts/Statistics/Logger.cs @@ -0,0 +1,19 @@ +using System.IO; +using UnityEngine; + +public class Logger +{ + private const string directory = "/Logs/"; + private const string baseName = "Log#"; + + public static void SaveLog(T objToSerialize) + { + string dir = Application.persistentDataPath + directory; + if (!Directory.Exists(dir)) + Directory.CreateDirectory(dir); + + var logName = baseName + (Directory.GetFiles(dir).Length + 1).ToString(); + string json = JsonUtility.ToJson(objToSerialize); + File.WriteAllText(dir + logName, json); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Statistics/Logger.cs.meta b/Assets/Scripts/Statistics/Logger.cs.meta new file mode 100644 index 0000000..e455173 --- /dev/null +++ b/Assets/Scripts/Statistics/Logger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b3a1cec894fa98b4bbe20470f1e316c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Statistics/StatisticManager.cs b/Assets/Scripts/Statistics/StatisticManager.cs new file mode 100644 index 0000000..399e7fb --- /dev/null +++ b/Assets/Scripts/Statistics/StatisticManager.cs @@ -0,0 +1,51 @@ +using UnityEngine; + +internal class Log +{ + public int damageTakenByDefs = 0; + public int damageTakenByAtc = 0; + + public int AtcWin = 0; + public int DefWin = 0; + + public int TimeOuts = 0; +} + +public class StatisticManager : MonoBehaviour +{ + private Log log = new Log(); + private void Awake() + { + foreach (var npc in GameObject.FindObjectsOfType()) + npc.OnDamageRecieved += RegisterDamage; + + GlobalEventManager.onCaptureFlag += RegisterWin; + GlobalEventManager.onTimeLeft += RegisterTimeOut; + } + + private void RegisterDamage(int damage, Team team) + { + if (team == Team.Attackers) + log.damageTakenByAtc += damage; + else + log.damageTakenByDefs += damage; + } + + private void RegisterWin(Team team) + { + if (team == Team.Attackers) + log.AtcWin += 1; + else + log.DefWin += 1; + } + + private void RegisterTimeOut() + { + log.TimeOuts += 1; + } + + private void OnApplicationQuit() + { + Logger.SaveLog(log); + } +} diff --git a/Assets/Scripts/Misc/Statistics.cs.meta b/Assets/Scripts/Statistics/StatisticManager.cs.meta old mode 100755 new mode 100644 similarity index 91% rename from Assets/Scripts/Misc/Statistics.cs.meta rename to Assets/Scripts/Statistics/StatisticManager.cs.meta index b8be93a..3a27c34 --- a/Assets/Scripts/Misc/Statistics.cs.meta +++ b/Assets/Scripts/Statistics/StatisticManager.cs.meta @@ -4,7 +4,7 @@ MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] - executionOrder: 0 + executionOrder: 300 icon: {instanceID: 0} userData: assetBundleName: diff --git a/Assets/Scripts/Utils/SerializableDictionary.cs b/Assets/Scripts/Utils/SerializableDictionary.cs index c0877b9..8cb258e 100755 --- a/Assets/Scripts/Utils/SerializableDictionary.cs +++ b/Assets/Scripts/Utils/SerializableDictionary.cs @@ -1,10 +1,10 @@ using System; -using System.Linq; using System.Collections; using System.Collections.Generic; using System.Diagnostics; -using UnityEngine; +using System.Linq; using UnityEditor; +using UnityEngine; using UnityObject = UnityEngine.Object; [Serializable, DebuggerDisplay("Count = {Count}")] diff --git a/Assets/Scripts/Weapons/scr_WeaponController.cs b/Assets/Scripts/Weapons/scr_WeaponController.cs index 2fc59e5..613fc61 100755 --- a/Assets/Scripts/Weapons/scr_WeaponController.cs +++ b/Assets/Scripts/Weapons/scr_WeaponController.cs @@ -1,17 +1,16 @@ -using System; -using UnityEngine; +using UnityEngine; using static scr_Models; public class scr_WeaponController : MonoBehaviour { private scr_CharacterController characterController; - [Header("Settings")] + [Header("Settings")] public WeaponSettingsModel settings; private bool isInitialised; Vector3 newWeaponRotation; Vector3 newWeaponRotationVelocity; - + Vector3 targetWeaponRotation; Vector3 targetWeaponRotationVelocity; @@ -32,17 +31,17 @@ public class scr_WeaponController : MonoBehaviour { return; } - + targetWeaponRotation.y += settings.SwayAmount * (settings.SwayXInverted ? -characterController.input_View.x : characterController.input_View.x) * Time.deltaTime; - targetWeaponRotation.x += settings.SwayAmount * (settings.SwayYInverted ? characterController.input_View.y : -characterController.input_View.y) * Time.deltaTime; + targetWeaponRotation.x += settings.SwayAmount * (settings.SwayYInverted ? characterController.input_View.y : -characterController.input_View.y) * Time.deltaTime; //newWeaponRotation.x = Mathf.Clamp(newWeaponRotation.x, ViewClampYMin, ViewClampYMax); - + targetWeaponRotation.x = Mathf.Clamp(targetWeaponRotation.x, -settings.SwayClampX, settings.SwayClampX); targetWeaponRotation.y = Mathf.Clamp(targetWeaponRotation.y, -settings.SwayClampY, settings.SwayClampY); targetWeaponRotation = Vector3.SmoothDamp(targetWeaponRotation, Vector3.zero, ref targetWeaponRotationVelocity, settings.SwayResetSmoothing); newWeaponRotation = Vector3.SmoothDamp(newWeaponRotation, targetWeaponRotation, ref newWeaponRotationVelocity, settings.SwaySmoothing); - + transform.localRotation = Quaternion.Euler(newWeaponRotation); } }