Initial. Added files
This commit is contained in:
8
Assets/Scripts/Bots.meta
generated
Executable file
8
Assets/Scripts/Bots.meta
generated
Executable file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3dc587379a04ee44a393d478183cdbb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Bots/Behaviours.meta
generated
Executable file
8
Assets/Scripts/Bots/Behaviours.meta
generated
Executable file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9fbac871417fccb40831b0f935247a29
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
17
Assets/Scripts/Bots/Behaviours/BaseBehaviour.cs
Executable file
17
Assets/Scripts/Bots/Behaviours/BaseBehaviour.cs
Executable file
@ -0,0 +1,17 @@
|
||||
using Unity;
|
||||
using UnityEngine;
|
||||
public abstract class BaseBehaviour
|
||||
{
|
||||
protected NPC thisNPC;
|
||||
protected IDoActivity DoActivity;
|
||||
|
||||
protected BaseBehaviour(NPC npc)
|
||||
{
|
||||
thisNPC = npc;
|
||||
}
|
||||
|
||||
public void DoAction()
|
||||
{
|
||||
DoActivity?.DoActivity();
|
||||
}
|
||||
}
|
11
Assets/Scripts/Bots/Behaviours/BaseBehaviour.cs.meta
generated
Executable file
11
Assets/Scripts/Bots/Behaviours/BaseBehaviour.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60bdb2d866ca9324cbe3639e7c47ae23
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Bots/Behaviours/BehaviourClasses.meta
generated
Executable file
8
Assets/Scripts/Bots/Behaviours/BehaviourClasses.meta
generated
Executable file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 362d340e6754883459f3dc89c9ddc476
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Bots/Behaviours/BehaviourClasses/DumbAttacker.cs
Executable file
8
Assets/Scripts/Bots/Behaviours/BehaviourClasses/DumbAttacker.cs
Executable file
@ -0,0 +1,8 @@
|
||||
public class DumbAttacker : BaseBehaviour
|
||||
{
|
||||
public DumbAttacker(NPC npc) : base(npc)
|
||||
{
|
||||
DoActivity = new DumbAttackerBehaviour();
|
||||
}
|
||||
}
|
||||
|
11
Assets/Scripts/Bots/Behaviours/BehaviourClasses/DumbAttacker.cs.meta
generated
Executable file
11
Assets/Scripts/Bots/Behaviours/BehaviourClasses/DumbAttacker.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 138d13d4fe8a06444acb1da6bfc55aa7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
7
Assets/Scripts/Bots/Behaviours/BehaviourClasses/DumbDefender.cs
Executable file
7
Assets/Scripts/Bots/Behaviours/BehaviourClasses/DumbDefender.cs
Executable file
@ -0,0 +1,7 @@
|
||||
public class DumbDefender : BaseBehaviour
|
||||
{
|
||||
public DumbDefender(NPC npc) : base(npc)
|
||||
{
|
||||
DoActivity = new DumbDefenderBehaviour();
|
||||
}
|
||||
}
|
11
Assets/Scripts/Bots/Behaviours/BehaviourClasses/DumbDefender.cs.meta
generated
Executable file
11
Assets/Scripts/Bots/Behaviours/BehaviourClasses/DumbDefender.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64552bae354dc614d8012f07511a51e8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
7
Assets/Scripts/Bots/Behaviours/BehaviourClasses/Human.cs
Executable file
7
Assets/Scripts/Bots/Behaviours/BehaviourClasses/Human.cs
Executable file
@ -0,0 +1,7 @@
|
||||
public class Human : BaseBehaviour
|
||||
{
|
||||
public Human(NPC npc) : base(npc)
|
||||
{
|
||||
DoActivity = new HumanBehaviour();
|
||||
}
|
||||
}
|
11
Assets/Scripts/Bots/Behaviours/BehaviourClasses/Human.cs.meta
generated
Executable file
11
Assets/Scripts/Bots/Behaviours/BehaviourClasses/Human.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59d3d253756147e469e418971625a04c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Bots/Behaviours/BehaviourRealization.meta
generated
Executable file
8
Assets/Scripts/Bots/Behaviours/BehaviourRealization.meta
generated
Executable file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93364cc95c8c9764e83d70fcce9da482
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
||||
using UnityEngine;
|
||||
class DumbAttackerBehaviour : IDoActivity
|
||||
{
|
||||
public void DoActivity()
|
||||
{
|
||||
Debug.Log("I do attackers things!");
|
||||
}
|
||||
}
|
||||
|
11
Assets/Scripts/Bots/Behaviours/BehaviourRealization/DumbAttackerBehaviour.cs.meta
generated
Executable file
11
Assets/Scripts/Bots/Behaviours/BehaviourRealization/DumbAttackerBehaviour.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2cc7b0640887454e96d42f6bd066750
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
||||
using UnityEngine;
|
||||
|
||||
class DumbDefenderBehaviour : IDoActivity
|
||||
{
|
||||
public void DoActivity()
|
||||
{
|
||||
Debug.Log("I do defenders things!");
|
||||
}
|
||||
}
|
11
Assets/Scripts/Bots/Behaviours/BehaviourRealization/DumbDefenderBehaviour.cs.meta
generated
Executable file
11
Assets/Scripts/Bots/Behaviours/BehaviourRealization/DumbDefenderBehaviour.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27106553be3f26b4da5220e39a3098c3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Bots/Behaviours/BehaviourRealization/HumanBehaviour.cs
Executable file
8
Assets/Scripts/Bots/Behaviours/BehaviourRealization/HumanBehaviour.cs
Executable file
@ -0,0 +1,8 @@
|
||||
class HumanBehaviour : IDoActivity
|
||||
{
|
||||
public void DoActivity()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
11
Assets/Scripts/Bots/Behaviours/BehaviourRealization/HumanBehaviour.cs.meta
generated
Executable file
11
Assets/Scripts/Bots/Behaviours/BehaviourRealization/HumanBehaviour.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d207d14aaf634504e84f3e3bd8b52428
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
4
Assets/Scripts/Bots/Behaviours/IDoActivity.cs
Executable file
4
Assets/Scripts/Bots/Behaviours/IDoActivity.cs
Executable file
@ -0,0 +1,4 @@
|
||||
public interface IDoActivity
|
||||
{
|
||||
void DoActivity();
|
||||
}
|
11
Assets/Scripts/Bots/Behaviours/IDoActivity.cs.meta
generated
Executable file
11
Assets/Scripts/Bots/Behaviours/IDoActivity.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e7275817852aa941963daa476581224
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Bots/CharacterFactory.meta
generated
Executable file
8
Assets/Scripts/Bots/CharacterFactory.meta
generated
Executable file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93133f9c3db1b944d9120ea789988f9b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
45
Assets/Scripts/Bots/CharacterFactory/CharacterFactory.cs
Executable file
45
Assets/Scripts/Bots/CharacterFactory/CharacterFactory.cs
Executable file
@ -0,0 +1,45 @@
|
||||
public abstract class AbstractCharacterFactory
|
||||
{
|
||||
protected IDoActivity behaviour;
|
||||
protected AbstractCharacterFactory() { }
|
||||
public abstract BaseBehaviour CreateCharacterBehaviour(NPC npc);
|
||||
}
|
||||
|
||||
public class DumbDefenderFactory : AbstractCharacterFactory
|
||||
{
|
||||
public DumbDefenderFactory()
|
||||
{
|
||||
behaviour = new DumbDefenderBehaviour();
|
||||
}
|
||||
|
||||
public override BaseBehaviour CreateCharacterBehaviour(NPC npc)
|
||||
{
|
||||
return new DumbDefender(npc);
|
||||
}
|
||||
}
|
||||
|
||||
public class DumbAttackerFactory : AbstractCharacterFactory
|
||||
{
|
||||
public DumbAttackerFactory()
|
||||
{
|
||||
behaviour = new DumbAttackerBehaviour();
|
||||
}
|
||||
|
||||
public override BaseBehaviour CreateCharacterBehaviour(NPC npc)
|
||||
{
|
||||
return new DumbAttacker(npc);
|
||||
}
|
||||
}
|
||||
|
||||
public class HumanFactory : AbstractCharacterFactory
|
||||
{
|
||||
public HumanFactory()
|
||||
{
|
||||
behaviour = new HumanBehaviour();
|
||||
}
|
||||
|
||||
public override BaseBehaviour CreateCharacterBehaviour(NPC npc)
|
||||
{
|
||||
return new Human(npc);
|
||||
}
|
||||
}
|
11
Assets/Scripts/Bots/CharacterFactory/CharacterFactory.cs.meta
generated
Executable file
11
Assets/Scripts/Bots/CharacterFactory/CharacterFactory.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f973f98c4f699745a605d09e2c1e46e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
55
Assets/Scripts/Bots/CharacterFactory/CharacterSpawner.cs
Executable file
55
Assets/Scripts/Bots/CharacterFactory/CharacterSpawner.cs
Executable file
@ -0,0 +1,55 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public class CharacterSpawner : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private GameObject botPrefab;
|
||||
[SerializeField] private List<NavPoint> defendersSpawnPoints;
|
||||
[SerializeField] private List<NavPoint> attackersSpawnPoints;
|
||||
private static Dictionary<(TypeAI, Team), Func<NPC, BaseBehaviour>> behaviourDictionary;
|
||||
private static System.Random random;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
behaviourDictionary = new Dictionary<(TypeAI, Team), Func<NPC, BaseBehaviour>>()
|
||||
{
|
||||
{ (TypeAI.DumbAlgorithm, Team.Attackers), new Func<NPC,BaseBehaviour>( npc => new DumbAttacker(npc))},
|
||||
{ (TypeAI.DumbAlgorithm, Team.Defenders), new Func<NPC,BaseBehaviour>( npc => new DumbDefender(npc)) },
|
||||
{ (TypeAI.HumanAI, Team.Defenders), new Func<NPC,BaseBehaviour>( npc => new Human(npc))},
|
||||
{ (TypeAI.HumanAI, Team.Attackers), new Func<NPC,BaseBehaviour>( npc => new Human(npc))},
|
||||
//And Other behaviours
|
||||
};
|
||||
|
||||
if (SettingsReader.Instance.GetSettings.hasHumanAttacker && SettingsReader.Instance.GetSettings.hasHumanDefender)
|
||||
throw new System.Exception("Not allowed to have two players");
|
||||
else if (SettingsReader.Instance.GetSettings.hasHumanAttacker == true)
|
||||
{
|
||||
spawnCharacter(behaviourDictionary[(TypeAI.HumanAI, Team.Attackers)], Team.Attackers);
|
||||
}
|
||||
else if (SettingsReader.Instance.GetSettings.hasHumanDefender == true)
|
||||
{
|
||||
spawnCharacter(behaviourDictionary[(TypeAI.HumanAI, Team.Defenders)], Team.Defenders);
|
||||
}
|
||||
|
||||
for (int i = 0; i < SettingsReader.Instance.GetSettings.numOfAttackers - (SettingsReader.Instance.GetSettings.hasHumanAttacker ? 1 : 0); i++)
|
||||
{
|
||||
spawnCharacter(behaviourDictionary[(SettingsReader.Instance.GetSettings.atcTeamAI, Team.Attackers)], Team.Attackers);
|
||||
}
|
||||
for (int i = 0; i < SettingsReader.Instance.GetSettings.numOfAttackers - (SettingsReader.Instance.GetSettings.hasHumanDefender ? 1 : 0); i++)
|
||||
{
|
||||
spawnCharacter(behaviourDictionary[(SettingsReader.Instance.GetSettings.defTeamAI, Team.Defenders)], Team.Defenders);
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnCharacter(Func<NPC, BaseBehaviour> behaviourFunc, Team team)
|
||||
{
|
||||
var spawnPoint = team == Team.Defenders ?
|
||||
defendersSpawnPoints[random.Next(0, defendersSpawnPoints.Count)].position :
|
||||
attackersSpawnPoints[random.Next(0, attackersSpawnPoints.Count)].position;
|
||||
var entity = Instantiate(botPrefab, spawnPoint, Quaternion.identity);
|
||||
var npc = entity.GetComponent<NPC>();
|
||||
npc.SetBehaviour(behaviourFunc(npc));
|
||||
}
|
||||
}
|
||||
|
11
Assets/Scripts/Bots/CharacterFactory/CharacterSpawner.cs.meta
generated
Executable file
11
Assets/Scripts/Bots/CharacterFactory/CharacterSpawner.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 672f5411fc3ccb74d8a17a6efdee9df4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
4
Assets/Scripts/Bots/CharacterPooler.cs
Executable file
4
Assets/Scripts/Bots/CharacterPooler.cs
Executable file
@ -0,0 +1,4 @@
|
||||
public class CharacterPooler
|
||||
{
|
||||
|
||||
}
|
11
Assets/Scripts/Bots/CharacterPooler.cs.meta
generated
Executable file
11
Assets/Scripts/Bots/CharacterPooler.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0835d77f48130e4f81c678f710bf87c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
5
Assets/Scripts/Bots/TeamEnum.cs
Executable file
5
Assets/Scripts/Bots/TeamEnum.cs
Executable file
@ -0,0 +1,5 @@
|
||||
public enum Team
|
||||
{
|
||||
Defenders,
|
||||
Attackers,
|
||||
}
|
11
Assets/Scripts/Bots/TeamEnum.cs.meta
generated
Executable file
11
Assets/Scripts/Bots/TeamEnum.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d3022a2bd8119d4eb3a822c05320c69
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Bots/TypeAIEnum.cs
Executable file
8
Assets/Scripts/Bots/TypeAIEnum.cs
Executable file
@ -0,0 +1,8 @@
|
||||
public enum TypeAI
|
||||
{
|
||||
DumbAlgorithm,
|
||||
SmartAlgorithm,
|
||||
NeuralNetworkAI,
|
||||
D0DiskAI,
|
||||
HumanAI
|
||||
}
|
11
Assets/Scripts/Bots/TypeAIEnum.cs.meta
generated
Executable file
11
Assets/Scripts/Bots/TypeAIEnum.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2eecfca4413a96468c26c7b764b6f16
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Character.meta
generated
Executable file
8
Assets/Scripts/Character.meta
generated
Executable file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69350f8bd44c3344694acbbe304a5177
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
39
Assets/Scripts/Character/CharacterCondition.cs
Executable file
39
Assets/Scripts/Character/CharacterCondition.cs
Executable file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public class CharacterCondition : MonoBehaviour
|
||||
{
|
||||
public event Action<object> OnKilledEvent;
|
||||
public event Action<int> OnDamageHealthTakenEvent;
|
||||
public event Action<int> OnDamageArmourTakenEvent;
|
||||
public event Action<int> OnAmmunitionTakenEvent;
|
||||
|
||||
[SerializeField] private int HealthPoints;
|
||||
[SerializeField] private int ArmourPoints;
|
||||
[SerializeField] private int Ammunition;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void GetDamage(float damage)
|
||||
{
|
||||
HealthPoints -= Mathf.RoundToInt(damage * (1 - ArmourPoints * 0.5f));
|
||||
ArmourPoints -= Mathf.RoundToInt(Mathf.Sqrt(damage) * 5);
|
||||
|
||||
OnDamageHealthTakenEvent?.Invoke(HealthPoints);
|
||||
OnDamageArmourTakenEvent?.Invoke(ArmourPoints);
|
||||
if (HealthPoints < 0)
|
||||
OnKilledEvent?.Invoke(gameObject);
|
||||
}
|
||||
public void GiveHealth(int health) => HealthPoints = Mathf.Clamp(health + HealthPoints, 0, 100);
|
||||
public void SetHealth(int health) => HealthPoints = Mathf.Clamp(health, 0, 100);
|
||||
public void GiveArmour(int armour) => ArmourPoints = Mathf.Clamp(armour + ArmourPoints, 0, 100);
|
||||
public void SetArmour(int armour) => ArmourPoints = Mathf.Clamp(armour, 0, 100);
|
||||
public void TakeAmmo(int ammo)
|
||||
{
|
||||
Ammunition += ammo;
|
||||
OnAmmunitionTakenEvent?.Invoke(Ammunition);
|
||||
}
|
||||
}
|
11
Assets/Scripts/Character/CharacterCondition.cs.meta
generated
Executable file
11
Assets/Scripts/Character/CharacterCondition.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a9e40cbb5d1b6249ab74556c14e2787
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
38
Assets/Scripts/Character/MovementController.cs
Executable file
38
Assets/Scripts/Character/MovementController.cs
Executable file
@ -0,0 +1,38 @@
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
|
||||
[RequireComponent(typeof(NavMeshAgent))]
|
||||
public class MovementController : MonoBehaviour
|
||||
{
|
||||
public NavPoint currentPosition { get; private set; }
|
||||
[SerializeField] private MapManager mapManager;
|
||||
[SerializeField] private NavMeshAgent navMeshAgent;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
navMeshAgent.speed = SettingsReader.Instance.GetSettings.movementSpeed;
|
||||
}
|
||||
|
||||
public void Move()
|
||||
{
|
||||
var pointCandidate = getPointCandidate();
|
||||
goToNextNavPoint(pointCandidate);
|
||||
}
|
||||
|
||||
|
||||
// todo внутри сенсора передавать в mlagents как variable length observations: https://github.com/Unity-Technologies/ml-agents/blob/main/docs/Learning-Environment-Design-Agents.md#variable-length-observations
|
||||
private NavPoint getPointCandidate()
|
||||
{
|
||||
var NavPointsPositions = mapManager.navPoints
|
||||
.Select(point => point.transform.position)
|
||||
.Where(point => (currentPosition.transform.position - point).magnitude <= SettingsReader.Instance.GetSettings.movementSpeed)
|
||||
.ToList();
|
||||
//TODO AI
|
||||
return null;
|
||||
}
|
||||
|
||||
private void goToNextNavPoint(NavPoint destination) =>
|
||||
navMeshAgent.SetDestination(destination.transform.position);
|
||||
}
|
11
Assets/Scripts/Character/MovementController.cs.meta
generated
Executable file
11
Assets/Scripts/Character/MovementController.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3ebcf807a37f344998fd648dfc9376d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
37
Assets/Scripts/Character/NPC.cs
Executable file
37
Assets/Scripts/Character/NPC.cs
Executable file
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Unity.MLAgents;
|
||||
using Unity.MLAgents.Sensors;
|
||||
|
||||
public class NPC : Agent
|
||||
{
|
||||
public float LastTimeHit;
|
||||
private BaseBehaviour NPCBehaviour;
|
||||
public List<Action> ActionList;
|
||||
|
||||
[SerializeField]
|
||||
private List<ISensor> SensorList; // todo тут интерфейс должен быть наш
|
||||
|
||||
public void SetBehaviour(BaseBehaviour behaviour) => NPCBehaviour = behaviour;
|
||||
public Team Team { get; set; }
|
||||
private void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void CollectObservations(VectorSensor sensor)
|
||||
{
|
||||
// Target and Agent positions
|
||||
foreach (var _sensor in SensorList)
|
||||
{
|
||||
sensor.AddObservation(1); // todo
|
||||
// sensor.AddObservation(_sensor.GetValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
//NPCBehaviour.DoAction();
|
||||
}
|
||||
}
|
11
Assets/Scripts/Character/NPC.cs.meta
generated
Executable file
11
Assets/Scripts/Character/NPC.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6f2a081cfc8c4b4bb6864331109d147
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
259
Assets/Scripts/Character/scr_CharacterController.cs
Executable file
259
Assets/Scripts/Character/scr_CharacterController.cs
Executable file
@ -0,0 +1,259 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Barracuda;
|
||||
using UnityEngine;
|
||||
|
||||
using static scr_Models;
|
||||
|
||||
public class scr_CharacterController : MonoBehaviour
|
||||
{
|
||||
|
||||
private CharacterController characterController;
|
||||
private DefaultInput defaultInput;
|
||||
private Vector2 input_Movement;
|
||||
[HideInInspector]
|
||||
public Vector2 input_View;
|
||||
|
||||
private Vector3 newCameraRotation;
|
||||
private Vector3 newCharacterRotation;
|
||||
|
||||
[Header("References")]
|
||||
public Transform cameraHolder;
|
||||
public Transform feetTransform;
|
||||
|
||||
[Header("Settings")]
|
||||
public PlayerSettingsModel playerSettings;
|
||||
|
||||
public float ViewClampYMin = -70;
|
||||
public float ViewClampYMax = 80;
|
||||
public LayerMask playerMask;
|
||||
|
||||
[Header("Gravity")]
|
||||
public float gravityAmount;
|
||||
public float gravityMin;
|
||||
private float playerGravity;
|
||||
|
||||
public Vector3 jumpingForce;
|
||||
private Vector3 jumpingForceVelocity;
|
||||
|
||||
[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;
|
||||
|
||||
private bool isSprinting;
|
||||
|
||||
private Vector3 newMovementSpeed;
|
||||
private Vector3 newMovementSpeedVelocity;
|
||||
|
||||
[Header("Weapon")] public scr_WeaponController currentWeapon;
|
||||
private void Awake()
|
||||
{
|
||||
defaultInput = new DefaultInput();
|
||||
|
||||
defaultInput.Character.Movement.performed += e => input_Movement = e.ReadValue<Vector2>();
|
||||
defaultInput.Character.View.performed += e => input_View = e.ReadValue<Vector2>();
|
||||
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;
|
||||
newCharacterRotation = transform.localRotation.eulerAngles;
|
||||
characterController = GetComponent<CharacterController>();
|
||||
|
||||
cameraHeight = cameraHolder.localPosition.y;
|
||||
|
||||
if (currentWeapon)
|
||||
{
|
||||
currentWeapon.Initialise(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
CalculateView();
|
||||
CalculateMovement();
|
||||
CalculateJump();
|
||||
CalculateCameraHeight();
|
||||
}
|
||||
|
||||
private void CalculateView()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
private void CalculateMovement()
|
||||
{
|
||||
if (input_Movement.y <= 0.2f)
|
||||
{
|
||||
isSprinting = false;
|
||||
}
|
||||
|
||||
var verticalSpeed = playerSettings.WalkingForwardSpeed;
|
||||
var horizontalSpeed = playerSettings.WalkingStrafeSpeed;
|
||||
|
||||
if (isSprinting)
|
||||
{
|
||||
verticalSpeed = playerSettings.RunningForwardSpeed;
|
||||
horizontalSpeed = playerSettings.RunningStrafeSpeed;
|
||||
}
|
||||
|
||||
// Effectors
|
||||
if (!characterController.isGrounded)
|
||||
{
|
||||
playerSettings.SpeedEffector = playerSettings.FallingSpeedEffector;
|
||||
}
|
||||
else if(playerStance == PlayerStance.Crouch)
|
||||
{
|
||||
playerSettings.SpeedEffector = playerSettings.CrouchSpeedEffector;
|
||||
}
|
||||
else if(playerStance == PlayerStance.Prone)
|
||||
{
|
||||
playerSettings.SpeedEffector = playerSettings.ProneSpeedEffector;
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
playerGravity -= gravityAmount * Time.deltaTime;
|
||||
}
|
||||
|
||||
if (playerGravity < -0.1f && characterController.isGrounded)
|
||||
{
|
||||
playerGravity = -0.1f;
|
||||
}
|
||||
|
||||
MovementSpeed.y += playerGravity;
|
||||
MovementSpeed += jumpingForce * Time.deltaTime;
|
||||
|
||||
characterController.Move(MovementSpeed);
|
||||
}
|
||||
|
||||
private void CalculateJump()
|
||||
{
|
||||
jumpingForce = Vector3.SmoothDamp(jumpingForce, Vector3.zero, ref jumpingForceVelocity, playerSettings.JumpingFalloff);
|
||||
}
|
||||
|
||||
private void CalculateCameraHeight()
|
||||
{
|
||||
var stanceHeight = playerStandStance.CameraHeight;
|
||||
|
||||
if (playerStance == PlayerStance.Crouch)
|
||||
{
|
||||
stanceHeight = playerCrouchStance.CameraHeight;
|
||||
}
|
||||
else if (playerStance == PlayerStance.Prone)
|
||||
{
|
||||
stanceHeight = playerProneStance.CameraHeight;
|
||||
}
|
||||
|
||||
cameraHeight = Mathf.SmoothDamp(cameraHolder.localPosition.y, stanceHeight, ref cameraHeightVelocity, playerStanceSmoothing);
|
||||
|
||||
cameraHolder.localPosition = new Vector3(cameraHolder.localPosition.x, cameraHeight, cameraHolder.localPosition.z);
|
||||
}
|
||||
private void Jump()
|
||||
{
|
||||
if (!characterController.isGrounded || playerStance == PlayerStance.Prone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (playerStance == PlayerStance.Crouch)
|
||||
{
|
||||
if (StanceCheck(playerStandStance.StanceCollider.height))
|
||||
{
|
||||
return;
|
||||
}
|
||||
playerStance = PlayerStance.Stand;
|
||||
return;
|
||||
}
|
||||
|
||||
// Jump
|
||||
jumpingForce = Vector3.up * playerSettings.JumpingHeight;
|
||||
playerGravity = 0;
|
||||
}
|
||||
|
||||
private void Crouch()
|
||||
{
|
||||
if (playerStance == PlayerStance.Crouch)
|
||||
{
|
||||
if (StanceCheck(playerStandStance.StanceCollider.height))
|
||||
{
|
||||
return;
|
||||
}
|
||||
playerStance = PlayerStance.Stand;
|
||||
return;
|
||||
}
|
||||
if (StanceCheck(playerCrouchStance.StanceCollider.height))
|
||||
{
|
||||
return;
|
||||
}
|
||||
playerStance = PlayerStance.Crouch;
|
||||
}
|
||||
|
||||
private void Prone()
|
||||
{
|
||||
playerStance = PlayerStance.Prone;
|
||||
}
|
||||
|
||||
private bool StanceCheck(float stanceCheckheight)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
private void ToggleSprint()
|
||||
{
|
||||
if (input_Movement.y <= 0.2f)
|
||||
{
|
||||
isSprinting = false;
|
||||
return;
|
||||
}
|
||||
isSprinting = !isSprinting;
|
||||
}
|
||||
|
||||
private void StopSprint()
|
||||
{
|
||||
if (playerSettings.SprintingHold)
|
||||
{
|
||||
isSprinting = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
11
Assets/Scripts/Character/scr_CharacterController.cs.meta
generated
Executable file
11
Assets/Scripts/Character/scr_CharacterController.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9826297ef4d853741b2af768441ec7f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
75
Assets/Scripts/Character/scr_Models.cs
Executable file
75
Assets/Scripts/Character/scr_Models.cs
Executable file
@ -0,0 +1,75 @@
|
||||
using System;
|
||||
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;
|
||||
|
||||
public bool ViewXInverted;
|
||||
public bool ViewYInverted;
|
||||
|
||||
[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;
|
||||
|
||||
[Header("Jumping")]
|
||||
public float JumpingHeight;
|
||||
public float JumpingFalloff;
|
||||
public float FallingSmoothing;
|
||||
|
||||
[Header("Speed Effectors")]
|
||||
public float SpeedEffector = 1;
|
||||
public float CrouchSpeedEffector;
|
||||
public float ProneSpeedEffector;
|
||||
public float FallingSpeedEffector;
|
||||
}
|
||||
|
||||
[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
|
||||
}
|
11
Assets/Scripts/Character/scr_Models.cs.meta
generated
Executable file
11
Assets/Scripts/Character/scr_Models.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 907ff02de47a55a4e971d73d25e7d006
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Managers.meta
generated
Executable file
8
Assets/Scripts/Managers.meta
generated
Executable file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e8296213ea8c344f97335579f7b1b54
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
57
Assets/Scripts/Managers/GameManager.cs
Executable file
57
Assets/Scripts/Managers/GameManager.cs
Executable file
@ -0,0 +1,57 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
|
||||
public class GameManager : MonoBehaviour
|
||||
{
|
||||
|
||||
private static GameManager instance;
|
||||
public static GameManager Instance { get { return instance; } }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance == null)
|
||||
instance = this;
|
||||
else if (Instance == this)
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
GlobalEventManager.onCaptureFlag += flagCaptured;
|
||||
GlobalEventManager.onTimeLeft += timeOut;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void flagCaptured(Team team)
|
||||
{
|
||||
switch(team)
|
||||
{
|
||||
case Team.Attackers:
|
||||
Debug.Log("Attackers Win");
|
||||
break;
|
||||
case Team.Defenders:
|
||||
Debug.Log("Defenders Win");
|
||||
break;
|
||||
default:
|
||||
Debug.LogError("Unexpected Team");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void timeOut()
|
||||
{
|
||||
Debug.Log("Time is out");
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
GlobalEventManager.onCaptureFlag -= flagCaptured;
|
||||
GlobalEventManager.onTimeLeft -= timeOut;
|
||||
}
|
||||
}
|
11
Assets/Scripts/Managers/GameManager.cs.meta
generated
Executable file
11
Assets/Scripts/Managers/GameManager.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5bc70199fbcaaa44e8683edeec4ab3bc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
19
Assets/Scripts/Managers/GlobalEventManager.cs
Executable file
19
Assets/Scripts/Managers/GlobalEventManager.cs
Executable file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
public class GlobalEventManager
|
||||
{
|
||||
public static event Action<Team> onCaptureFlag;
|
||||
|
||||
public static void SendCaptureFlag(Team team)
|
||||
{
|
||||
onCaptureFlag?.Invoke(team);
|
||||
onCaptureFlag = null;
|
||||
}
|
||||
|
||||
public static event Action onTimeLeft;
|
||||
public static void SendTimeout()
|
||||
{
|
||||
onTimeLeft?.Invoke();
|
||||
onTimeLeft = null;
|
||||
}
|
||||
}
|
11
Assets/Scripts/Managers/GlobalEventManager.cs.meta
generated
Executable file
11
Assets/Scripts/Managers/GlobalEventManager.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ab1008b51a03e3429285a87c6893647
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
13
Assets/Scripts/Managers/MapManager.cs
Executable file
13
Assets/Scripts/Managers/MapManager.cs
Executable file
@ -0,0 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class MapManager : MonoBehaviour
|
||||
{
|
||||
public List<NavPoint> navPoints { get; private set; }
|
||||
private void Start()
|
||||
{
|
||||
var navPointsGameObj = GameObject.FindGameObjectsWithTag("Point");
|
||||
foreach (var gameobj in navPointsGameObj)
|
||||
navPoints.Add(gameobj.GetComponent<NavPoint>());
|
||||
}
|
||||
}
|
11
Assets/Scripts/Managers/MapManager.cs.meta
generated
Executable file
11
Assets/Scripts/Managers/MapManager.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 593162665e908cf4ea4429f8385dc627
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 100
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
26
Assets/Scripts/Managers/TimeManager.cs
Executable file
26
Assets/Scripts/Managers/TimeManager.cs
Executable file
@ -0,0 +1,26 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class TimeManager : MonoBehaviour
|
||||
{
|
||||
public static TimeManager instance = null;
|
||||
public float CurrentTime;
|
||||
void Start()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = this;
|
||||
instance.CurrentTime = 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Only one Instance");
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
CurrentTime += Time.deltaTime;
|
||||
}
|
||||
}
|
11
Assets/Scripts/Managers/TimeManager.cs.meta
generated
Executable file
11
Assets/Scripts/Managers/TimeManager.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81d1d84442a0ba441976abd6fdd22788
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Misc.meta
generated
Executable file
8
Assets/Scripts/Misc.meta
generated
Executable file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83ca2321026d29e4c91a8594f30e9852
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
77
Assets/Scripts/Misc/FlagZone.cs
Executable file
77
Assets/Scripts/Misc/FlagZone.cs
Executable file
@ -0,0 +1,77 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class FlagZone : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
public float TimeStayAttackers { get; private set; }
|
||||
public float TimeStayDefenders { get; private set; }
|
||||
private int occupDefenders;
|
||||
private int occupAttackers;
|
||||
private bool isOccupBoth => (occupDefenders>0) && (occupAttackers>0);
|
||||
private bool isNotOccup => (occupDefenders == 0) && (occupAttackers == 0);
|
||||
private float timeForWin;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
|
||||
timeForWin = SettingsReader.Instance.GetSettings.timeToWin;
|
||||
Debug.Log("32");
|
||||
TimeStayAttackers = 0;
|
||||
TimeStayDefenders = 0;
|
||||
occupAttackers = 0;
|
||||
occupDefenders = 0;
|
||||
}
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
switch(other.tag)
|
||||
{
|
||||
case "Defender":
|
||||
occupDefenders++;
|
||||
break;
|
||||
case "Attacker":
|
||||
occupAttackers++;
|
||||
break;
|
||||
default:
|
||||
Debug.LogWarning("Entered non-team entity");
|
||||
break;
|
||||
}
|
||||
}
|
||||
private void OnTriggerExit(Collider other)
|
||||
{
|
||||
switch (other.tag)
|
||||
{
|
||||
case "Defender":
|
||||
occupDefenders--;
|
||||
break;
|
||||
case "Attacker":
|
||||
occupAttackers--;
|
||||
break;
|
||||
default:
|
||||
Debug.LogWarning("Exited non-team entity");
|
||||
break;
|
||||
}
|
||||
}
|
||||
private void Update()
|
||||
{
|
||||
if (isOccupBoth || isNotOccup)
|
||||
{
|
||||
TimeStayAttackers = 0;
|
||||
TimeStayDefenders = 0;
|
||||
return;
|
||||
}
|
||||
else if (occupAttackers > 0)
|
||||
{
|
||||
TimeStayAttackers += Time.deltaTime;
|
||||
if (TimeStayAttackers > timeForWin)
|
||||
GlobalEventManager.SendCaptureFlag(Team.Attackers);
|
||||
}
|
||||
else
|
||||
{
|
||||
TimeStayDefenders += Time.deltaTime;
|
||||
if (TimeStayDefenders > timeForWin)
|
||||
GlobalEventManager.SendCaptureFlag(Team.Defenders);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/Misc/FlagZone.cs.meta
generated
Executable file
11
Assets/Scripts/Misc/FlagZone.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6063c9db39fbafe4eb31a4a1bf09b641
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
27
Assets/Scripts/Misc/NavPoint.cs
Executable file
27
Assets/Scripts/Misc/NavPoint.cs
Executable file
@ -0,0 +1,27 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class NavPoint : MonoBehaviour
|
||||
{
|
||||
public Vector3 position => gameObject.transform.position;
|
||||
public float FlagDistance { get; private set; }
|
||||
[System.NonSerialized] public float DeathAttr;
|
||||
[System.NonSerialized] public List<Vector3> EnemiesSeen;
|
||||
//Here other attributes;
|
||||
|
||||
[SerializeField]
|
||||
public int PointId;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
//DO NOT DELETE
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
FlagDistance = (GameObject.FindGameObjectWithTag("Flag").transform.position - position).magnitude;
|
||||
EnemiesSeen = new List<Vector3>();
|
||||
DeathAttr = 0;
|
||||
}
|
||||
}
|
11
Assets/Scripts/Misc/NavPoint.cs.meta
generated
Executable file
11
Assets/Scripts/Misc/NavPoint.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a2d29bfc31a8cf4e831e3bb80720414
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 10
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
24
Assets/Scripts/Misc/Settings.cs
Executable file
24
Assets/Scripts/Misc/Settings.cs
Executable file
@ -0,0 +1,24 @@
|
||||
using UnityEngine;
|
||||
|
||||
[CreateAssetMenu(fileName ="Game Settings", menuName = "Game/Settings", order = 51)]
|
||||
public class Settings : ScriptableObject
|
||||
{
|
||||
public float timeToWin;
|
||||
public float timeOut;
|
||||
|
||||
[Header("movement")]
|
||||
public float movementDistance;
|
||||
public float movementSpeed;
|
||||
|
||||
public TypeAI defTeamAI;
|
||||
public TypeAI atcTeamAI;
|
||||
public int numOfDefenders;
|
||||
public int numOfAttackers;
|
||||
public bool hasHumanDefender;
|
||||
public bool hasHumanAttacker;
|
||||
|
||||
public int healthPickupAmount;
|
||||
public int armourPickupAmount;
|
||||
public int ammunitionPickupAmount;
|
||||
public int pickupsAmount;
|
||||
}
|
11
Assets/Scripts/Misc/Settings.cs.meta
generated
Executable file
11
Assets/Scripts/Misc/Settings.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e2c47233b9062c84482336b145c6891b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
18
Assets/Scripts/Misc/SettingsReader.cs
Executable file
18
Assets/Scripts/Misc/SettingsReader.cs
Executable file
@ -0,0 +1,18 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class SettingsReader : MonoBehaviour
|
||||
{
|
||||
private static SettingsReader instance;
|
||||
public static SettingsReader Instance { get { return instance; } }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Debug.Log("init");
|
||||
instance = this;
|
||||
}
|
||||
|
||||
[SerializeField] private Settings gameSettings;
|
||||
public Settings GetSettings { get { return gameSettings; } }
|
||||
}
|
11
Assets/Scripts/Misc/SettingsReader.cs.meta
generated
Executable file
11
Assets/Scripts/Misc/SettingsReader.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ec3ce69f2a888e4cadd8eb47406ea42
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 1
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
9
Assets/Scripts/Misc/Statistics.cs
Executable file
9
Assets/Scripts/Misc/Statistics.cs
Executable file
@ -0,0 +1,9 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class Statistics : MonoBehaviour
|
||||
{
|
||||
private void Start()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
11
Assets/Scripts/Misc/Statistics.cs.meta
generated
Executable file
11
Assets/Scripts/Misc/Statistics.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf3fe86787bfb0c4b8751fe495148ede
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Pickups.meta
generated
Executable file
8
Assets/Scripts/Pickups.meta
generated
Executable file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86da7e04acd709f409582108dc5d2351
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
19
Assets/Scripts/Pickups/AmmoPickUp.cs
Executable file
19
Assets/Scripts/Pickups/AmmoPickUp.cs
Executable file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(BoxCollider))]
|
||||
public class AmmoPickUp : MonoBehaviour, IPickable
|
||||
{
|
||||
public PickUpType type => PickUpType.Ammunition;
|
||||
|
||||
public void OnTriggerEnter(Collider other)
|
||||
{
|
||||
PickObject(other.gameObject);
|
||||
}
|
||||
|
||||
public void PickObject(GameObject obj)
|
||||
{
|
||||
obj.GetComponent<CharacterCondition>()?.TakeAmmo(SettingsReader.Instance.GetSettings.ammunitionPickupAmount);
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
11
Assets/Scripts/Pickups/AmmoPickUp.cs.meta
generated
Executable file
11
Assets/Scripts/Pickups/AmmoPickUp.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09e043466612b024bbb02951e04cc660
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
19
Assets/Scripts/Pickups/ArmourPickUp.cs
Executable file
19
Assets/Scripts/Pickups/ArmourPickUp.cs
Executable file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(BoxCollider))]
|
||||
public class ArmourPickUp : MonoBehaviour, IPickable
|
||||
{
|
||||
public PickUpType type => PickUpType.Armour;
|
||||
|
||||
public void OnTriggerEnter(Collider other)
|
||||
{
|
||||
PickObject(other.gameObject);
|
||||
}
|
||||
|
||||
public void PickObject(GameObject obj)
|
||||
{
|
||||
obj.GetComponent<CharacterCondition>()?.GiveArmour(SettingsReader.Instance.GetSettings.armourPickupAmount);
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
11
Assets/Scripts/Pickups/ArmourPickUp.cs.meta
generated
Executable file
11
Assets/Scripts/Pickups/ArmourPickUp.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f289a8ab0c20a314e95dd32f0c0d249b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
19
Assets/Scripts/Pickups/HealthPickUp.cs
Executable file
19
Assets/Scripts/Pickups/HealthPickUp.cs
Executable file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(BoxCollider))]
|
||||
public class HealthPickUp : MonoBehaviour, IPickable
|
||||
{
|
||||
public PickUpType type => PickUpType.Health;
|
||||
|
||||
public void OnTriggerEnter(Collider other)
|
||||
{
|
||||
PickObject(other.gameObject);
|
||||
}
|
||||
|
||||
public void PickObject(GameObject obj)
|
||||
{
|
||||
obj.GetComponent<CharacterCondition>()?.GiveHealth(SettingsReader.Instance.GetSettings.healthPickupAmount);
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
11
Assets/Scripts/Pickups/HealthPickUp.cs.meta
generated
Executable file
11
Assets/Scripts/Pickups/HealthPickUp.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7ed17f03cadcf446b4fb1bb6c3c4dd6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
7
Assets/Scripts/Pickups/IPickable.cs
Executable file
7
Assets/Scripts/Pickups/IPickable.cs
Executable file
@ -0,0 +1,7 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
public interface IPickable
|
||||
{
|
||||
PickUpType type { get; }
|
||||
void PickObject(GameObject obj);
|
||||
}
|
11
Assets/Scripts/Pickups/IPickable.cs.meta
generated
Executable file
11
Assets/Scripts/Pickups/IPickable.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c45940f40fa881248b8b21eb76d1bcc7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
68
Assets/Scripts/Pickups/PickUpSpawner.cs
Executable file
68
Assets/Scripts/Pickups/PickUpSpawner.cs
Executable file
@ -0,0 +1,68 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
public class PickUpSpawner : MonoBehaviour
|
||||
{
|
||||
private PickUpSpawner instance;
|
||||
public PickUpSpawner Instance { get { return instance; } }
|
||||
|
||||
private List<GameObject> pickups;
|
||||
[SerializeField] private GameObject healthPrefab;
|
||||
[SerializeField] private GameObject armourPrefab;
|
||||
[SerializeField] private GameObject ammoPrefab;
|
||||
|
||||
[SerializeField] private List<NavPoint> spawnPoints;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
pickups = new List<GameObject>();
|
||||
var amount = SettingsReader.Instance.GetSettings.pickupsAmount;
|
||||
for (int i = 0; i < amount; i++)
|
||||
pickups.Add(GameObject.Instantiate(healthPrefab, spawnPoints[Random.Range(0, spawnPoints.Count)].transform.position, Quaternion.identity));
|
||||
for (int i = 0; i < amount; i++)
|
||||
pickups.Add(GameObject.Instantiate(armourPrefab, spawnPoints[Random.Range(0, spawnPoints.Count)].transform.position, Quaternion.identity));
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
pickups.Add(GameObject.Instantiate(ammoPrefab, spawnPoints[Random.Range(0, spawnPoints.Count)].transform.position, Quaternion.identity));
|
||||
}
|
||||
foreach (var gameobj in pickups)
|
||||
gameobj.SetActive(true);
|
||||
|
||||
StartCoroutine(SpawnNewPickUps());
|
||||
}
|
||||
|
||||
private IEnumerator SpawnNewPickUps()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
GameObject item;
|
||||
if(IsDisableCheck(out item))
|
||||
{
|
||||
yield return new WaitForSeconds(3);
|
||||
if (item != null)
|
||||
{
|
||||
item.transform.position = spawnPoints[Random.Range(0, spawnPoints.Count)].position;
|
||||
item.SetActive(true);
|
||||
}
|
||||
}
|
||||
yield return new WaitForSeconds(2);
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsDisableCheck(out GameObject gameobj)
|
||||
{
|
||||
foreach(var pick in pickups)
|
||||
{
|
||||
if (!pick.activeInHierarchy)
|
||||
{
|
||||
gameobj = pick;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
gameobj = null;
|
||||
return false;
|
||||
}
|
||||
}
|
11
Assets/Scripts/Pickups/PickUpSpawner.cs.meta
generated
Executable file
11
Assets/Scripts/Pickups/PickUpSpawner.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b12853c3d6c08a47be61979ae90c4aa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
6
Assets/Scripts/Pickups/PickUpType.cs
Executable file
6
Assets/Scripts/Pickups/PickUpType.cs
Executable file
@ -0,0 +1,6 @@
|
||||
public enum PickUpType
|
||||
{
|
||||
Health,
|
||||
Armour,
|
||||
Ammunition,
|
||||
}
|
11
Assets/Scripts/Pickups/PickUpType.cs.meta
generated
Executable file
11
Assets/Scripts/Pickups/PickUpType.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4464b030c02e1f74fa0d97b55fe7a0f9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Sensors.meta
generated
Executable file
8
Assets/Scripts/Sensors.meta
generated
Executable file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e73ba257bc6b684c86edf9ecfd475ef
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
5
Assets/Scripts/Sensors/ISensor.cs
Executable file
5
Assets/Scripts/Sensors/ISensor.cs
Executable file
@ -0,0 +1,5 @@
|
||||
public interface ISensor<T>
|
||||
{
|
||||
T GetValue();
|
||||
SensorType GetSensorType();
|
||||
}
|
11
Assets/Scripts/Sensors/ISensor.cs.meta
generated
Executable file
11
Assets/Scripts/Sensors/ISensor.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4599c57bc5b1c3945847dead0f9f0ba4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
6
Assets/Scripts/Sensors/SensorType.cs
Executable file
6
Assets/Scripts/Sensors/SensorType.cs
Executable file
@ -0,0 +1,6 @@
|
||||
public enum SensorType
|
||||
{
|
||||
Visual,
|
||||
Sound,
|
||||
Other
|
||||
}
|
11
Assets/Scripts/Sensors/SensorType.cs.meta
generated
Executable file
11
Assets/Scripts/Sensors/SensorType.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f76201fe6436164789d10350a0fd6e2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Utils.meta
generated
Executable file
8
Assets/Scripts/Utils.meta
generated
Executable file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f5929931d06f4834f97aed766d86bee2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
746
Assets/Scripts/Utils/SerializableDictionary.cs
Executable file
746
Assets/Scripts/Utils/SerializableDictionary.cs
Executable file
@ -0,0 +1,746 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
[Serializable, DebuggerDisplay("Count = {Count}")]
|
||||
public class SerializableDictionary<TKey, TValue> : IDictionary<TKey, TValue>
|
||||
{
|
||||
[SerializeField, HideInInspector] int[] _Buckets;
|
||||
[SerializeField, HideInInspector] int[] _HashCodes;
|
||||
[SerializeField, HideInInspector] int[] _Next;
|
||||
[SerializeField, HideInInspector] int _Count;
|
||||
[SerializeField, HideInInspector] int _Version;
|
||||
[SerializeField, HideInInspector] int _FreeList;
|
||||
[SerializeField, HideInInspector] int _FreeCount;
|
||||
[SerializeField, HideInInspector] TKey[] _Keys;
|
||||
[SerializeField, HideInInspector] TValue[] _Values;
|
||||
|
||||
readonly IEqualityComparer<TKey> _Comparer;
|
||||
|
||||
// Mainly for debugging purposes - to get the key-value pairs display
|
||||
public Dictionary<TKey, TValue> AsDictionary
|
||||
{
|
||||
get { return new Dictionary<TKey, TValue>(this); }
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _Count - _FreeCount; }
|
||||
}
|
||||
|
||||
public TValue this[TKey key, TValue defaultValue]
|
||||
{
|
||||
get
|
||||
{
|
||||
int index = FindIndex(key);
|
||||
if (index >= 0)
|
||||
return _Values[index];
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public TValue this[TKey key]
|
||||
{
|
||||
get
|
||||
{
|
||||
int index = FindIndex(key);
|
||||
if (index >= 0)
|
||||
return _Values[index];
|
||||
throw new KeyNotFoundException(key.ToString());
|
||||
}
|
||||
|
||||
set { Insert(key, value, false); }
|
||||
}
|
||||
|
||||
public SerializableDictionary()
|
||||
: this(0, null)
|
||||
{
|
||||
}
|
||||
|
||||
public SerializableDictionary(int capacity)
|
||||
: this(capacity, null)
|
||||
{
|
||||
}
|
||||
|
||||
public SerializableDictionary(IEqualityComparer<TKey> comparer)
|
||||
: this(0, comparer)
|
||||
{
|
||||
}
|
||||
|
||||
public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer)
|
||||
{
|
||||
if (capacity < 0)
|
||||
throw new ArgumentOutOfRangeException("capacity");
|
||||
|
||||
Initialize(capacity);
|
||||
|
||||
_Comparer = (comparer ?? EqualityComparer<TKey>.Default);
|
||||
}
|
||||
|
||||
public SerializableDictionary(IDictionary<TKey, TValue> dictionary)
|
||||
: this(dictionary, null)
|
||||
{
|
||||
}
|
||||
|
||||
public SerializableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
|
||||
: this((dictionary != null) ? dictionary.Count : 0, comparer)
|
||||
{
|
||||
if (dictionary == null)
|
||||
throw new ArgumentNullException("dictionary");
|
||||
|
||||
foreach (KeyValuePair<TKey, TValue> current in dictionary)
|
||||
Add(current.Key, current.Value);
|
||||
}
|
||||
|
||||
public bool ContainsValue(TValue value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
for (int i = 0; i < _Count; i++)
|
||||
{
|
||||
if (_HashCodes[i] >= 0 && _Values[i] == null)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var defaultComparer = EqualityComparer<TValue>.Default;
|
||||
for (int i = 0; i < _Count; i++)
|
||||
{
|
||||
if (_HashCodes[i] >= 0 && defaultComparer.Equals(_Values[i], value))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool ContainsKey(TKey key)
|
||||
{
|
||||
return FindIndex(key) >= 0;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if (_Count <= 0)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < _Buckets.Length; i++)
|
||||
_Buckets[i] = -1;
|
||||
|
||||
Array.Clear(_Keys, 0, _Count);
|
||||
Array.Clear(_Values, 0, _Count);
|
||||
Array.Clear(_HashCodes, 0, _Count);
|
||||
Array.Clear(_Next, 0, _Count);
|
||||
|
||||
_FreeList = -1;
|
||||
_Count = 0;
|
||||
_FreeCount = 0;
|
||||
_Version++;
|
||||
}
|
||||
|
||||
public void Add(TKey key, TValue value)
|
||||
{
|
||||
Insert(key, value, true);
|
||||
}
|
||||
|
||||
private void Resize(int newSize, bool forceNewHashCodes)
|
||||
{
|
||||
int[] bucketsCopy = new int[newSize];
|
||||
for (int i = 0; i < bucketsCopy.Length; i++)
|
||||
bucketsCopy[i] = -1;
|
||||
|
||||
var keysCopy = new TKey[newSize];
|
||||
var valuesCopy = new TValue[newSize];
|
||||
var hashCodesCopy = new int[newSize];
|
||||
var nextCopy = new int[newSize];
|
||||
|
||||
Array.Copy(_Values, 0, valuesCopy, 0, _Count);
|
||||
Array.Copy(_Keys, 0, keysCopy, 0, _Count);
|
||||
Array.Copy(_HashCodes, 0, hashCodesCopy, 0, _Count);
|
||||
Array.Copy(_Next, 0, nextCopy, 0, _Count);
|
||||
|
||||
if (forceNewHashCodes)
|
||||
{
|
||||
for (int i = 0; i < _Count; i++)
|
||||
{
|
||||
if (hashCodesCopy[i] != -1)
|
||||
hashCodesCopy[i] = (_Comparer.GetHashCode(keysCopy[i]) & 2147483647);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < _Count; i++)
|
||||
{
|
||||
int index = hashCodesCopy[i] % newSize;
|
||||
nextCopy[i] = bucketsCopy[index];
|
||||
bucketsCopy[index] = i;
|
||||
}
|
||||
|
||||
_Buckets = bucketsCopy;
|
||||
_Keys = keysCopy;
|
||||
_Values = valuesCopy;
|
||||
_HashCodes = hashCodesCopy;
|
||||
_Next = nextCopy;
|
||||
}
|
||||
|
||||
private void Resize()
|
||||
{
|
||||
Resize(PrimeHelper.ExpandPrime(_Count), false);
|
||||
}
|
||||
|
||||
public bool Remove(TKey key)
|
||||
{
|
||||
if (key == null)
|
||||
throw new ArgumentNullException("key");
|
||||
|
||||
int hash = _Comparer.GetHashCode(key) & 2147483647;
|
||||
int index = hash % _Buckets.Length;
|
||||
int num = -1;
|
||||
for (int i = _Buckets[index]; i >= 0; i = _Next[i])
|
||||
{
|
||||
if (_HashCodes[i] == hash && _Comparer.Equals(_Keys[i], key))
|
||||
{
|
||||
if (num < 0)
|
||||
_Buckets[index] = _Next[i];
|
||||
else
|
||||
_Next[num] = _Next[i];
|
||||
|
||||
_HashCodes[i] = -1;
|
||||
_Next[i] = _FreeList;
|
||||
_Keys[i] = default(TKey);
|
||||
_Values[i] = default(TValue);
|
||||
_FreeList = i;
|
||||
_FreeCount++;
|
||||
_Version++;
|
||||
return true;
|
||||
}
|
||||
num = i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void Insert(TKey key, TValue value, bool add)
|
||||
{
|
||||
if (key == null)
|
||||
throw new ArgumentNullException("key");
|
||||
|
||||
if (_Buckets == null)
|
||||
Initialize(0);
|
||||
|
||||
int hash = _Comparer.GetHashCode(key) & 2147483647;
|
||||
int index = hash % _Buckets.Length;
|
||||
int num1 = 0;
|
||||
for (int i = _Buckets[index]; i >= 0; i = _Next[i])
|
||||
{
|
||||
if (_HashCodes[i] == hash && _Comparer.Equals(_Keys[i], key))
|
||||
{
|
||||
if (add)
|
||||
throw new ArgumentException("Key already exists: " + key);
|
||||
|
||||
_Values[i] = value;
|
||||
_Version++;
|
||||
return;
|
||||
}
|
||||
num1++;
|
||||
}
|
||||
int num2;
|
||||
if (_FreeCount > 0)
|
||||
{
|
||||
num2 = _FreeList;
|
||||
_FreeList = _Next[num2];
|
||||
_FreeCount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_Count == _Keys.Length)
|
||||
{
|
||||
Resize();
|
||||
index = hash % _Buckets.Length;
|
||||
}
|
||||
num2 = _Count;
|
||||
_Count++;
|
||||
}
|
||||
_HashCodes[num2] = hash;
|
||||
_Next[num2] = _Buckets[index];
|
||||
_Keys[num2] = key;
|
||||
_Values[num2] = value;
|
||||
_Buckets[index] = num2;
|
||||
_Version++;
|
||||
|
||||
//if (num3 > 100 && HashHelpers.IsWellKnownEqualityComparer(comparer))
|
||||
//{
|
||||
// comparer = (IEqualityComparer<TKey>)HashHelpers.GetRandomizedEqualityComparer(comparer);
|
||||
// Resize(entries.Length, true);
|
||||
//}
|
||||
}
|
||||
|
||||
private void Initialize(int capacity)
|
||||
{
|
||||
int prime = PrimeHelper.GetPrime(capacity);
|
||||
|
||||
_Buckets = new int[prime];
|
||||
for (int i = 0; i < _Buckets.Length; i++)
|
||||
_Buckets[i] = -1;
|
||||
|
||||
_Keys = new TKey[prime];
|
||||
_Values = new TValue[prime];
|
||||
_HashCodes = new int[prime];
|
||||
_Next = new int[prime];
|
||||
|
||||
_FreeList = -1;
|
||||
}
|
||||
|
||||
private int FindIndex(TKey key)
|
||||
{
|
||||
if (key == null)
|
||||
throw new ArgumentNullException("key");
|
||||
|
||||
if (_Buckets != null)
|
||||
{
|
||||
int hash = _Comparer.GetHashCode(key) & 2147483647;
|
||||
for (int i = _Buckets[hash % _Buckets.Length]; i >= 0; i = _Next[i])
|
||||
{
|
||||
if (_HashCodes[i] == hash && _Comparer.Equals(_Keys[i], key))
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public bool TryGetValue(TKey key, out TValue value)
|
||||
{
|
||||
int index = FindIndex(key);
|
||||
if (index >= 0)
|
||||
{
|
||||
value = _Values[index];
|
||||
return true;
|
||||
}
|
||||
value = default(TValue);
|
||||
return false;
|
||||
}
|
||||
private static class PrimeHelper
|
||||
{
|
||||
public static readonly int[] Primes = new int[]
|
||||
{
|
||||
3,
|
||||
7,
|
||||
11,
|
||||
17,
|
||||
23,
|
||||
29,
|
||||
37,
|
||||
47,
|
||||
59,
|
||||
71,
|
||||
89,
|
||||
107,
|
||||
131,
|
||||
163,
|
||||
197,
|
||||
239,
|
||||
293,
|
||||
353,
|
||||
431,
|
||||
521,
|
||||
631,
|
||||
761,
|
||||
919,
|
||||
1103,
|
||||
1327,
|
||||
1597,
|
||||
1931,
|
||||
2333,
|
||||
2801,
|
||||
3371,
|
||||
4049,
|
||||
4861,
|
||||
5839,
|
||||
7013,
|
||||
8419,
|
||||
10103,
|
||||
12143,
|
||||
14591,
|
||||
17519,
|
||||
21023,
|
||||
25229,
|
||||
30293,
|
||||
36353,
|
||||
43627,
|
||||
52361,
|
||||
62851,
|
||||
75431,
|
||||
90523,
|
||||
108631,
|
||||
130363,
|
||||
156437,
|
||||
187751,
|
||||
225307,
|
||||
270371,
|
||||
324449,
|
||||
389357,
|
||||
467237,
|
||||
560689,
|
||||
672827,
|
||||
807403,
|
||||
968897,
|
||||
1162687,
|
||||
1395263,
|
||||
1674319,
|
||||
2009191,
|
||||
2411033,
|
||||
2893249,
|
||||
3471899,
|
||||
4166287,
|
||||
4999559,
|
||||
5999471,
|
||||
7199369
|
||||
};
|
||||
|
||||
public static bool IsPrime(int candidate)
|
||||
{
|
||||
if ((candidate & 1) != 0)
|
||||
{
|
||||
int num = (int)Math.Sqrt((double)candidate);
|
||||
for (int i = 3; i <= num; i += 2)
|
||||
{
|
||||
if (candidate % i == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return candidate == 2;
|
||||
}
|
||||
|
||||
public static int GetPrime(int min)
|
||||
{
|
||||
if (min < 0)
|
||||
throw new ArgumentException("min < 0");
|
||||
|
||||
for (int i = 0; i < PrimeHelper.Primes.Length; i++)
|
||||
{
|
||||
int prime = PrimeHelper.Primes[i];
|
||||
if (prime >= min)
|
||||
return prime;
|
||||
}
|
||||
for (int i = min | 1; i < 2147483647; i += 2)
|
||||
{
|
||||
if (PrimeHelper.IsPrime(i) && (i - 1) % 101 != 0)
|
||||
return i;
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
public static int ExpandPrime(int oldSize)
|
||||
{
|
||||
int num = 2 * oldSize;
|
||||
if (num > 2146435069 && 2146435069 > oldSize)
|
||||
{
|
||||
return 2146435069;
|
||||
}
|
||||
return PrimeHelper.GetPrime(num);
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection<TKey> Keys
|
||||
{
|
||||
get { return _Keys.Take(Count).ToArray(); }
|
||||
}
|
||||
|
||||
public ICollection<TValue> Values
|
||||
{
|
||||
get { return _Values.Take(Count).ToArray(); }
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
public bool Contains(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
int index = FindIndex(item.Key);
|
||||
return index >= 0 &&
|
||||
EqualityComparer<TValue>.Default.Equals(_Values[index], item.Value);
|
||||
}
|
||||
|
||||
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
|
||||
{
|
||||
if (array == null)
|
||||
throw new ArgumentNullException("array");
|
||||
|
||||
if (index < 0 || index > array.Length)
|
||||
throw new ArgumentOutOfRangeException(string.Format("index = {0} array.Length = {1}", index, array.Length));
|
||||
|
||||
if (array.Length - index < Count)
|
||||
throw new ArgumentException(string.Format("The number of elements in the dictionary ({0}) is greater than the available space from index to the end of the destination array {1}.", Count, array.Length));
|
||||
|
||||
for (int i = 0; i < _Count; i++)
|
||||
{
|
||||
if (_HashCodes[i] >= 0)
|
||||
array[index++] = new KeyValuePair<TKey, TValue>(_Keys[i], _Values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public bool Remove(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
return Remove(item.Key);
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>
|
||||
{
|
||||
private readonly SerializableDictionary<TKey, TValue> _Dictionary;
|
||||
private int _Version;
|
||||
private int _Index;
|
||||
private KeyValuePair<TKey, TValue> _Current;
|
||||
|
||||
public KeyValuePair<TKey, TValue> Current
|
||||
{
|
||||
get { return _Current; }
|
||||
}
|
||||
|
||||
internal Enumerator(SerializableDictionary<TKey, TValue> dictionary)
|
||||
{
|
||||
_Dictionary = dictionary;
|
||||
_Version = dictionary._Version;
|
||||
_Current = default(KeyValuePair<TKey, TValue>);
|
||||
_Index = 0;
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (_Version != _Dictionary._Version)
|
||||
throw new InvalidOperationException(string.Format("Enumerator version {0} != Dictionary version {1}", _Version, _Dictionary._Version));
|
||||
|
||||
while (_Index < _Dictionary._Count)
|
||||
{
|
||||
if (_Dictionary._HashCodes[_Index] >= 0)
|
||||
{
|
||||
_Current = new KeyValuePair<TKey, TValue>(_Dictionary._Keys[_Index], _Dictionary._Values[_Index]);
|
||||
_Index++;
|
||||
return true;
|
||||
}
|
||||
_Index++;
|
||||
}
|
||||
|
||||
_Index = _Dictionary._Count + 1;
|
||||
_Current = default(KeyValuePair<TKey, TValue>);
|
||||
return false;
|
||||
}
|
||||
|
||||
void IEnumerator.Reset()
|
||||
{
|
||||
if (_Version != _Dictionary._Version)
|
||||
throw new InvalidOperationException(string.Format("Enumerator version {0} != Dictionary version {1}", _Version, _Dictionary._Version));
|
||||
|
||||
_Index = 0;
|
||||
_Current = default(KeyValuePair<TKey, TValue>);
|
||||
}
|
||||
|
||||
object IEnumerator.Current
|
||||
{
|
||||
get { return Current; }
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class DictionaryDrawer<TK, TV> : PropertyDrawer
|
||||
{
|
||||
private SerializableDictionary<TK, TV> _Dictionary;
|
||||
private bool _Foldout;
|
||||
private const float kButtonWidth = 18f;
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
CheckInitialize(property, label);
|
||||
if (_Foldout)
|
||||
return (_Dictionary.Count + 1) * 17f;
|
||||
return 17f;
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
CheckInitialize(property, label);
|
||||
|
||||
position.height = 17f;
|
||||
|
||||
var foldoutRect = position;
|
||||
foldoutRect.width -= 2 * kButtonWidth;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
_Foldout = EditorGUI.Foldout(foldoutRect, _Foldout, label, true);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
EditorPrefs.SetBool(label.text, _Foldout);
|
||||
|
||||
var buttonRect = position;
|
||||
buttonRect.x = position.width - kButtonWidth + position.x;
|
||||
buttonRect.width = kButtonWidth + 2;
|
||||
|
||||
if (GUI.Button(buttonRect, new GUIContent("+", "Add item"), EditorStyles.miniButton))
|
||||
{
|
||||
AddNewItem();
|
||||
}
|
||||
|
||||
buttonRect.x -= kButtonWidth;
|
||||
|
||||
if (GUI.Button(buttonRect, new GUIContent("X", "Clear dictionary"), EditorStyles.miniButtonRight))
|
||||
{
|
||||
ClearDictionary();
|
||||
}
|
||||
|
||||
if (!_Foldout)
|
||||
return;
|
||||
|
||||
foreach (var item in _Dictionary)
|
||||
{
|
||||
var key = item.Key;
|
||||
var value = item.Value;
|
||||
|
||||
position.y += 17f;
|
||||
|
||||
var keyRect = position;
|
||||
keyRect.width /= 2;
|
||||
keyRect.width -= 4;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var newKey = DoField(keyRect, typeof(TK), key);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
try
|
||||
{
|
||||
_Dictionary.Remove(key);
|
||||
_Dictionary.Add(newKey, value);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.Log(e.Message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var valueRect = position;
|
||||
valueRect.x = position.width / 2 + 15;
|
||||
valueRect.width = keyRect.width - kButtonWidth;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
value = DoField(valueRect, typeof(TV), value);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
_Dictionary[key] = value;
|
||||
break;
|
||||
}
|
||||
|
||||
var removeRect = valueRect;
|
||||
removeRect.x = valueRect.xMax + 2;
|
||||
removeRect.width = kButtonWidth;
|
||||
if (GUI.Button(removeRect, new GUIContent("x", "Remove item"), EditorStyles.miniButtonRight))
|
||||
{
|
||||
RemoveItem(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveItem(TK key)
|
||||
{
|
||||
_Dictionary.Remove(key);
|
||||
}
|
||||
|
||||
private void CheckInitialize(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
if (_Dictionary == null)
|
||||
{
|
||||
var target = property.serializedObject.targetObject;
|
||||
_Dictionary = fieldInfo.GetValue(target) as SerializableDictionary<TK, TV>;
|
||||
if (_Dictionary == null)
|
||||
{
|
||||
_Dictionary = new SerializableDictionary<TK, TV>();
|
||||
fieldInfo.SetValue(target, _Dictionary);
|
||||
}
|
||||
|
||||
_Foldout = EditorPrefs.GetBool(label.text);
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Dictionary<Type, Func<Rect, object, object>> _Fields =
|
||||
new Dictionary<Type, Func<Rect, object, object>>()
|
||||
{
|
||||
{ typeof(int), (rect, value) => EditorGUI.IntField(rect, (int)value) },
|
||||
{ typeof(float), (rect, value) => EditorGUI.FloatField(rect, (float)value) },
|
||||
{ typeof(string), (rect, value) => EditorGUI.TextField(rect, (string)value) },
|
||||
{ typeof(bool), (rect, value) => EditorGUI.Toggle(rect, (bool)value) },
|
||||
{ typeof(Vector2), (rect, value) => EditorGUI.Vector2Field(rect, GUIContent.none, (Vector2)value) },
|
||||
{ typeof(Vector3), (rect, value) => EditorGUI.Vector3Field(rect, GUIContent.none, (Vector3)value) },
|
||||
{ typeof(Bounds), (rect, value) => EditorGUI.BoundsField(rect, (Bounds)value) },
|
||||
{ typeof(Rect), (rect, value) => EditorGUI.RectField(rect, (Rect)value) },
|
||||
};
|
||||
|
||||
private static T DoField<T>(Rect rect, Type type, T value)
|
||||
{
|
||||
Func<Rect, object, object> field;
|
||||
if (_Fields.TryGetValue(type, out field))
|
||||
return (T)field(rect, value);
|
||||
|
||||
if (type.IsEnum)
|
||||
return (T)(object)EditorGUI.EnumPopup(rect, (Enum)(object)value);
|
||||
|
||||
if (typeof(UnityObject).IsAssignableFrom(type))
|
||||
return (T)(object)EditorGUI.ObjectField(rect, (UnityObject)(object)value, type, true);
|
||||
|
||||
UnityEngine.Debug.Log("Type is not supported: " + type);
|
||||
return value;
|
||||
}
|
||||
|
||||
private void ClearDictionary()
|
||||
{
|
||||
_Dictionary.Clear();
|
||||
}
|
||||
|
||||
private void AddNewItem()
|
||||
{
|
||||
TK key;
|
||||
if (typeof(TK) == typeof(string))
|
||||
key = (TK)(object)"";
|
||||
else key = default(TK);
|
||||
|
||||
var value = default(TV);
|
||||
try
|
||||
{
|
||||
_Dictionary.Add(key, value);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.Log(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable] public class DictionaryOfTeamsAndNavPoints : SerializableDictionary<Team, NavPoint> { }
|
||||
[CustomPropertyDrawer(typeof(DictionaryOfTeamsAndNavPoints))]
|
||||
public class DictionaryOfTeamsAndNavPointsDrawer : DictionaryDrawer<Team, NavPoint> { }
|
11
Assets/Scripts/Utils/SerializableDictionary.cs.meta
generated
Executable file
11
Assets/Scripts/Utils/SerializableDictionary.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: baaabca40bed4b845a14c4d2801350f0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Weapons.meta
generated
Executable file
8
Assets/Scripts/Weapons.meta
generated
Executable file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a568b47f8681ad4ba1cb863add36d94
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
48
Assets/Scripts/Weapons/scr_WeaponController.cs
Executable file
48
Assets/Scripts/Weapons/scr_WeaponController.cs
Executable file
@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using static scr_Models;
|
||||
public class scr_WeaponController : MonoBehaviour
|
||||
{
|
||||
private scr_CharacterController characterController;
|
||||
[Header("Settings")]
|
||||
public WeaponSettingsModel settings;
|
||||
|
||||
private bool isInitialised;
|
||||
|
||||
Vector3 newWeaponRotation;
|
||||
Vector3 newWeaponRotationVelocity;
|
||||
|
||||
Vector3 targetWeaponRotation;
|
||||
Vector3 targetWeaponRotationVelocity;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
newWeaponRotation = transform.localRotation.eulerAngles;
|
||||
}
|
||||
|
||||
public void Initialise(scr_CharacterController CharacterController)
|
||||
{
|
||||
characterController = CharacterController;
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (!isInitialised)
|
||||
{
|
||||
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;
|
||||
//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);
|
||||
}
|
||||
}
|
11
Assets/Scripts/Weapons/scr_WeaponController.cs.meta
generated
Executable file
11
Assets/Scripts/Weapons/scr_WeaponController.cs.meta
generated
Executable file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 088bf904d7c90a44dbb35c1d47c2692e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user