Initial. Added files

This commit is contained in:
Andrey Gumirov
2022-04-12 11:54:05 +07:00
parent 19900f6446
commit 8aa8e3d79b
254 changed files with 44750 additions and 0 deletions

8
Assets/Scripts/Bots.meta generated Executable file
View 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
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9fbac871417fccb40831b0f935247a29
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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();
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 60bdb2d866ca9324cbe3639e7c47ae23
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 362d340e6754883459f3dc89c9ddc476
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
public class DumbAttacker : BaseBehaviour
{
public DumbAttacker(NPC npc) : base(npc)
{
DoActivity = new DumbAttackerBehaviour();
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 138d13d4fe8a06444acb1da6bfc55aa7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
public class DumbDefender : BaseBehaviour
{
public DumbDefender(NPC npc) : base(npc)
{
DoActivity = new DumbDefenderBehaviour();
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 64552bae354dc614d8012f07511a51e8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
public class Human : BaseBehaviour
{
public Human(NPC npc) : base(npc)
{
DoActivity = new HumanBehaviour();
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 59d3d253756147e469e418971625a04c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 93364cc95c8c9764e83d70fcce9da482
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
using UnityEngine;
class DumbAttackerBehaviour : IDoActivity
{
public void DoActivity()
{
Debug.Log("I do attackers things!");
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d2cc7b0640887454e96d42f6bd066750
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
using UnityEngine;
class DumbDefenderBehaviour : IDoActivity
{
public void DoActivity()
{
Debug.Log("I do defenders things!");
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 27106553be3f26b4da5220e39a3098c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
class HumanBehaviour : IDoActivity
{
public void DoActivity()
{
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d207d14aaf634504e84f3e3bd8b52428
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,4 @@
public interface IDoActivity
{
void DoActivity();
}

View 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
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 93133f9c3db1b944d9120ea789988f9b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4f973f98c4f699745a605d09e2c1e46e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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));
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 672f5411fc3ccb74d8a17a6efdee9df4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,4 @@
public class CharacterPooler
{
}

11
Assets/Scripts/Bots/CharacterPooler.cs.meta generated Executable file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b0835d77f48130e4f81c678f710bf87c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,5 @@
public enum Team
{
Defenders,
Attackers,
}

11
Assets/Scripts/Bots/TeamEnum.cs.meta generated Executable file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4d3022a2bd8119d4eb3a822c05320c69
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
public enum TypeAI
{
DumbAlgorithm,
SmartAlgorithm,
NeuralNetworkAI,
D0DiskAI,
HumanAI
}

11
Assets/Scripts/Bots/TypeAIEnum.cs.meta generated Executable file
View 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
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 69350f8bd44c3344694acbbe304a5177
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2a9e40cbb5d1b6249ab74556c14e2787
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}

View 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
View 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
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a6f2a081cfc8c4b4bb6864331109d147
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9826297ef4d853741b2af768441ec7f7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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
View 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
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0e8296213ea8c344f97335579f7b1b54
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5bc70199fbcaaa44e8683edeec4ab3bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2ab1008b51a03e3429285a87c6893647
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 593162665e908cf4ea4429f8385dc627
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 100
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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
View 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
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 83ca2321026d29e4c91a8594f30e9852
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

77
Assets/Scripts/Misc/FlagZone.cs Executable file
View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e2c47233b9062c84482336b145c6891b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8ec3ce69f2a888e4cadd8eb47406ea42
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 1
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
using UnityEngine;
public class Statistics : MonoBehaviour
{
private void Start()
{
}
}

11
Assets/Scripts/Misc/Statistics.cs.meta generated Executable file
View 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
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 86da7e04acd709f409582108dc5d2351
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 09e043466612b024bbb02951e04cc660
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f289a8ab0c20a314e95dd32f0c0d249b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d7ed17f03cadcf446b4fb1bb6c3c4dd6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c45940f40fa881248b8b21eb76d1bcc7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3b12853c3d6c08a47be61979ae90c4aa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,6 @@
public enum PickUpType
{
Health,
Armour,
Ammunition,
}

11
Assets/Scripts/Pickups/PickUpType.cs.meta generated Executable file
View 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
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5e73ba257bc6b684c86edf9ecfd475ef
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,5 @@
public interface ISensor<T>
{
T GetValue();
SensorType GetSensorType();
}

11
Assets/Scripts/Sensors/ISensor.cs.meta generated Executable file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4599c57bc5b1c3945847dead0f9f0ba4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,6 @@
public enum SensorType
{
Visual,
Sound,
Other
}

11
Assets/Scripts/Sensors/SensorType.cs.meta generated Executable file
View 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
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f5929931d06f4834f97aed766d86bee2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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> { }

View 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
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4a568b47f8681ad4ba1cb863add36d94
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 088bf904d7c90a44dbb35c1d47c2692e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: