Initial Commit

This commit is contained in:
Simeon Radivoev 2022-02-12 12:53:50 +02:00
commit ee5c2f922d
Signed by: simeonradivoev
GPG key ID: 7611A451D2A5D37A
2255 changed files with 547750 additions and 0 deletions

View file

@ -0,0 +1,82 @@
using Cinemachine;
using DefaultNamespace;
using Events;
using System;
using UnityEngine;
using Zenject;
using Entity = Unity.Entities.Entity;
using Hash128 = Unity.Entities.Hash128;
using Random = UnityEngine.Random;
public class EnemyDeathSystem : InjectableComponentSystem
{
[Serializable]
public class Settings
{
public CinemachineImpulseSource EnemyImpulseSource;
public float ImpulseSourceSize;
public float ItemDropShootForce;
}
[Inject] private readonly ParticleSystemFactory particleFactory;
[Inject] private readonly Settings settings;
[Inject] private readonly SoundManager soundManager;
protected override void OnSystemUpdate()
{
Entities.WithNone<EntityDeathEvent>()
.ForEach(
(Entity entity, Transform transform, ref Enemy enemy, ref ActorData actor) =>
{
Vector2 pos = transform.position;
if (actor.Health <= 0)
{
if (EntityManager.HasComponent<EnemyPrefabComponent>(entity))
{
var prefab = EntityManager.GetComponentObject<EnemyPrefabComponent>(entity);
settings.EnemyImpulseSource.GenerateImpulseAt(pos, Vector3.one * settings.ImpulseSourceSize);
prefab.Prefab.OperationHandle.Convert<EnemyPrefab>().Completed += operation =>
{
var particles = particleFactory.Create(new Hash128(operation.Result.DeathParticles.AssetGUID));
particles.Completed += particleOperation =>
{
particleOperation.Result.GetComponent<ParticleSystem>().Emit(new ParticleSystem.EmitParams { position = pos }, 1);
};
foreach (var library in operation.Result.DeathSounds)
{
soundManager.PlayClip(EntityManager, library, pos);
}
foreach (var drop in operation.Result.Drops)
{
var r = Random.value;
if (r < drop.Chance)
{
var count = Random.Range(drop.MinCount, drop.MaxCount);
if (count > 0)
{
var e = EntityManager.CreateEntity();
EntityManager.AddComponentData(
e,
new ItemDropEvent
{
Item = new ItemData(new Hash128(drop.Item.AssetGUID), count),
Pos = pos,
Velocity = Random.insideUnitCircle * settings.ItemDropShootForce,
Inventory = Entity.Null,
ToSlot = -1,
FromSlot = -1
});
}
}
}
};
}
PostUpdateCommands.AddComponent(entity, new EntityDeathEvent());
}
});
}
}

View file

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

View file

@ -0,0 +1,237 @@
using DefaultNamespace;
using DefaultNamespace.Navigation;
using Polycrime;
using System;
using Unity.Entities;
using UnityEngine;
using Zenject;
[UpdateInGroup(typeof(PresentationSystemGroup)), UpdateBefore(typeof(ActorAnimationEventResetSystem))]
public class EnemyDriverSystem : InjectableComponentSystem
{
[Serializable]
public class Settings
{
public float DefaultReachTime;
public float JumpMinHeight;
public float MaxAirForce;
public float MaxForce;
public float MinPlayerDistance;
public float MoveForce;
public Vector3 MovePidParams;
public float NodeMinDistance;
public float RepathCooldown;
public ParticleSystem StabBloodParticles;
public SoundLibrary StabSounds;
public float ViewDistance;
public LayerMask VisibilityLayerMask;
}
[Inject] private Settings settings;
[Inject] private SoundManager soundManager;
protected override void OnSystemUpdate()
{
ManageEnemies();
ManagePathActors();
ManageRangeEnemies();
}
private void ManageEnemies()
{
var timeDelta = Time.DeltaTime;
Entities.ForEach(
(ref ActorNpcData npc) =>
{
npc.AttackCooldown = Mathf.Max(0, npc.AttackCooldown - timeDelta);
npc.ActionCooldown = Mathf.Max(0, npc.ActionCooldown - timeDelta);
npc.JumpingTimer = Mathf.Max(0, npc.JumpingTimer - timeDelta);
});
}
private void ManageRangeEnemies()
{
Entities.ForEach(
(
ActorWeaponPropertiesData weaponComponent,
ref ActorWeaponReferenceData weaponReference,
ref ActorAnimationData animation,
ref Enemy enemy) =>
{
animation.AttackSpeed = weaponComponent.Weapon.Data.RateOfFire;
});
}
private void ManagePathActors()
{
var timeDelta = Time.DeltaTime;
Entities.WithAll<PathNode>()
.ForEach(
(
Entity entity,
Rigidbody2D rigidBody,
ref NavigationAgentData navigationAgent,
ref RigidBody2DData rigidBodyData,
ref ActorNpcData npc,
ref ActorData actor,
ref ActorAnimationData animation) =>
{
var aimCenter = EntityManager.HasComponent<AimCenterData>(entity)
? EntityManager.GetComponentData<AimCenterData>(entity)
: default;
var path = EntityManager.GetBuffer<PathNode>(entity);
//pathHolder.RepathCooldown = Mathf.Max(0, pathHolder.RepathCooldown - timeDelta);
//npc.XPid.SetFactors(settings.MovePidParams);
/*Vector2 targetVelocity = Vector2.zero;
if (pathHolder.Path != null && pathHolder.Path.IsDone())
{
int currentTargetIndex = FindNextTarget(rigidBodyData.Position, pathHolder);
if (currentTargetIndex >= pathHolder.Path.vectorPath.Count)
{
pathHolder.Path = null;
return;
}
Vector2 nextTarget = pathHolder.Path.vectorPath[currentTargetIndex];
Vector2 currentTarget = currentTargetIndex > 0 ? (Vector2)pathHolder.Path.vectorPath[Mathf.Max(currentTargetIndex - 1, 0)] : rigidBodyData.Position;
var nextNode = (PointNode)pathHolder.Path.path[currentTargetIndex];
var currentNode = (PointNode)pathHolder.Path.path[Mathf.Max(currentTargetIndex - 1, 0)];
Vector2 nodeDir = nextTarget - currentTarget;
if (npc.JumpingTimer > 0)
{
actor.Aim = rigidBodyData.Position + new Vector2(nodeDir.x, 0) + aimCenter.Offset;
if (actor.Grounded) npc.JumpingTimer = 0;
}
else
{
float distance = Vector2.Distance(nextTarget, rigidBodyData.Position);
if (distance < settings.NodeMinDistance && currentTargetIndex < pathHolder.Path.vectorPath.Count && actor.Grounded)
{
currentTargetIndex++;
}
else
{
Vector2 rawDelta = (Vector2)nextTarget - rigidBodyData.Position;
if (currentTargetIndex < pathHolder.Path.vectorPath.Count && actor.Grounded)
{
jumpNodesTmp.Clear();
currentNode.gameObject.GetComponents(jumpNodesTmp);
var currentJumpNode = jumpNodesTmp.FirstOrDefault(n => n.IsEnd(nextNode.gameObject));
if (currentJumpNode != null)
{
Jump(currentJumpNode.ReachTime, rigidBody, rigidBodyData.Position, nodeDir, nextTarget, ref npc, ref actor, ref animation, aimCenter);
}
else
{
jumpNodesTmp.Clear();
nextNode.gameObject.GetComponents(jumpNodesTmp);
currentJumpNode = jumpNodesTmp.FirstOrDefault(n => n.IsEnd(currentNode.gameObject));
if (currentJumpNode != null)
{
Jump(currentJumpNode.ReachTime, rigidBody, rigidBodyData.Position, nodeDir, nextTarget, ref npc, ref actor, ref animation, aimCenter);
}
else if (Mathf.Abs(rawDelta.y) >= settings.JumpMinHeight)
{
Jump(settings.DefaultReachTime, rigidBody, rigidBodyData.Position, nodeDir, nextTarget, ref npc, ref actor, ref animation, aimCenter);
}
}
}
if (npc.JumpingTimer <= 0)
{
targetVelocity = rawDelta.normalized * settings.MoveForce;
animation.WalkMultiply = Mathf.Clamp01(Mathf.Abs(targetVelocity.x) / settings.MoveForce);
animation.WalkDir = (Mathf.Sign(rigidBody.transform.right.x) == Mathf.Sign(nodeDir.x) ? -1 : 1) * animation.WalkMultiply;
if (Target.Exists(entity))
{
var target = Target[entity];
if (EntityManager.HasComponent<Transform>(target.Target))
{
var targetTransform = EntityManager.GetComponentObject<Transform>(target.Target);
actor.Aim = distance <= settings.ViewDistance && CanSeeTarget(rigidBody, targetTransform, aimCenter) ? (Vector2)targetTransform.transform.position + aimCenter.Offset : rigidBody.position + new Vector2(nodeDir.x, 0) + aimCenter.Offset * 0.5f;
}
}
}
}
}
pathHolder.CurrentTarget = currentTargetIndex;
}
else
{
targetVelocity = Vector2.zero;
animation.WalkMultiply = 0;
}
npc.XPid = npc.XPid.Update(targetVelocity.x, rigidBodyData.Velocity.x, Time.deltaTime,out var val);
Vector2 delta = Vector2.ClampMagnitude(new Vector2(val, 0), Mathf.Lerp(settings.MaxForce,settings.MaxAirForce,actor.Grounded ? 0 : 1));
rigidBody.AddForce(delta);
*/
var currentNodeIndex = navigationAgent.currentIndex;
var nextNodeIndex = navigationAgent.currentIndex + 1;
if (nextNodeIndex < path.Length)
{
var currentNode = path[currentNodeIndex];
var nextNode = path[nextNodeIndex];
var distance = Vector2.Distance(nextNode.pos, rigidBodyData.Position);
var nodeDir = nextNode.pos - currentNode.pos;
animation.WalkMultiply = 1;
actor.Aim = rigidBodyData.Position + new Vector2(nextNode.pos.x, 0) + aimCenter.Offset;
animation.WalkDir = (Mathf.Sign(rigidBody.transform.right.x) == Mathf.Sign(nodeDir.x) ? -1 : 1) * animation.WalkMultiply;
if (EntityManager.TryGetComponentData<ActorTargetData>(entity, out var target))
{
if (EntityManager.HasComponent<Transform>(target.Target))
{
var targetTransform = EntityManager.GetComponentObject<Transform>(target.Target);
actor.Aim = distance <= settings.ViewDistance && CanSeeTarget(rigidBody, targetTransform, aimCenter)
? (Vector2)targetTransform.transform.position + aimCenter.Offset
: rigidBody.position + new Vector2(nodeDir.x, 0) + aimCenter.Offset * 0.5f;
}
}
}
else
{
animation.WalkMultiply = 0;
}
animation.AttackSpeed = 1;
});
}
private bool CanSeeTarget(Rigidbody2D source, Transform target, AimCenterData aimCenter)
{
var dir = (Vector2)target.position + aimCenter.Offset - (source.position + aimCenter.Offset);
var distance = dir.magnitude;
var hit = Physics2D.Raycast(source.position + aimCenter.Offset, dir / distance, distance, settings.VisibilityLayerMask);
return hit.transform == target;
}
private void Jump(
float reachTime,
Rigidbody2D rigidBody,
Vector2 pos,
Vector2 dir,
Vector2 target,
ref ActorNpcData npc,
ref ActorData actor,
ref ActorAnimationData animation,
AimCenterData aimCenter)
{
npc.JumpingTimer = reachTime;
rigidBody.velocity = TrajectoryMath.CalculateVelocity(pos, target, reachTime, rigidBody.gravityScale);
animation.WalkDir = Mathf.Sign(rigidBody.transform.right.x) == Mathf.Sign(dir.x) ? -1 : 1;
actor.Grounded = false;
actor.Aim = pos + dir + aimCenter.Offset;
animation.WalkMultiply = 0;
animation.Triggers |= AnimationTriggerType.Jump;
}
}

View file

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

View file

@ -0,0 +1,45 @@
using AI;
using Unity.Entities;
namespace DefaultNamespace
{
[UpdateInGroup(typeof(InitializationSystemGroup))]
public class EnemyInitializationSystem : ComponentSystem
{
protected override void OnUpdate()
{
Entities.WithAll<EnemyPrefabComponent>()
.WithNone<EnemyActorGoapInitialized>()
.ForEach(
(Entity entity, GoapAgentData data) =>
{
data.Goals.Add(((int)GoapKeys.Attacks, true));
PostUpdateCommands.AddComponent(entity, new EnemyActorGoapInitialized());
});
Entities.WithNone<ActorGrenadeData>()
.ForEach((Entity entitiy, ActorGrenadeComponent grenade) => { PostUpdateCommands.AddComponent(entitiy, new ActorGrenadeData()); });
Entities.WithNone<ActorData, ActorDataInitialization>()
.ForEach(
(Entity entity, EnemyPrefabComponent prefab) =>
{
prefab.Prefab.OperationHandle.Convert<EnemyPrefab>().Completed += operation =>
{
EntityManager.AddComponentData(entity, new ActorData { Health = operation.Result.MaxHealth });
EntityManager.RemoveComponent<ActorDataInitialization>(entity);
};
PostUpdateCommands.AddComponent(entity, new ActorDataInitialization());
});
}
private struct ActorDataInitialization : ISystemStateComponentData
{
}
private struct EnemyActorGoapInitialized : IComponentData
{
}
}
}

View file

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

View file

@ -0,0 +1,63 @@
using Events;
using Trive.Mono.Utils;
using Unity.Collections;
using Unity.Entities;
using UnityEngine;
using Zenject;
namespace DefaultNamespace
{
[UpdateAfter(typeof(EnemyDeathSystem))]
public class EnemySpawnSystem : InjectableComponentSystem
{
private NativeQueue<int> DeathsQueue = new NativeQueue<int>(Allocator.Persistent);
[Inject] private Unity.Entities.World world;
protected override void OnDestroy()
{
DeathsQueue.Dispose();
}
protected override void OnSystemUpdate()
{
Entities.ForEach(
(Spawner spawner) =>
{
spawner.SpawnTimer = Mathf.Max(0, spawner.SpawnTimer - Time.DeltaTime);
if (spawner.SpawnTimer <= 0 && spawner.CurrentCount < spawner.MaxTotalSpawns)
{
spawner.SpawnTimer = spawner.MaxSpawnInterval;
var spawnCount = Mathf.Min(spawner.MaxTotalSpawns - spawner.CurrentCount, spawner.MaxSpawns);
for (var j = 0; j < spawnCount; j++)
{
var pos = (Vector2)spawner.transform.position + Random.insideUnitCircle * spawner.SpawnRadius;
spawner.EnemyPrefab.Template.InstantiateAsync(pos, Quaternion.identity).Completed += operation =>
{
var entity = operation.Result.gameObject.ConvertToEntity(world);
operation.Result.gameObject.GetComponent<ActorFacade>().Entity = entity;
operation.Result.gameObject.GetComponent<ActorFacade>().World = World;
world.EntityManager.AddComponentData(entity, new SpawnInfo { SpawnerId = spawner.GetInstanceID() });
};
spawner.CurrentCount++;
}
}
});
Entities.WithAllReadOnly<EntityDeathEvent, SpawnInfo>()
.ForEach(entity => { DeathsQueue.Enqueue(EntityManager.GetComponentData<SpawnInfo>(entity).SpawnerId); });
while (DeathsQueue.Count > 0)
{
var enemy = DeathsQueue.Dequeue();
Entities.ForEach(
(Spawner spawner) =>
{
if (spawner.GetInstanceID() == enemy)
{
spawner.CurrentCount = Mathf.Max(spawner.CurrentCount - 1, 0);
}
});
}
}
}
}

View file

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

View file

@ -0,0 +1,51 @@
using AI;
using Unity.Entities;
using UnityEngine;
namespace DefaultNamespace
{
public class EnemyTargetFinderSystem : ComponentSystem
{
protected override void OnUpdate()
{
Entities.ForEach(
(ref Enemy enemy, ref RigidBody2DData actorRigidBody, ref ActorTargetData target) =>
{
if (!EntityManager.Exists(target.Target))
{
var closestDist = float.MaxValue;
var actorPos = actorRigidBody.Position;
var finalTarget = Entity.Null;
Entities.ForEach(
(Entity playerEntity, ref RigidBody2DData rigidBody, ref PlayerData playerData) =>
{
var d = Vector2.SqrMagnitude(actorPos - rigidBody.Position);
if (d < closestDist)
{
closestDist = d;
finalTarget = playerEntity;
}
});
target.Target = finalTarget;
}
});
Entities.ForEach(
(GoapAgentData agent, ref ActorTargetData target) =>
{
if (agent.States != null)
{
var targetVal = (GoapKeys.HasTarget, true);
if (EntityManager.Exists(target.Target))
{
agent.States.Add(targetVal);
}
else
{
agent.States.Remove(targetVal);
}
}
});
}
}
}

View file

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