mirror of
https://github.com/Bragin-Stepan/project-entity.git
synced 2026-04-19 13:09:41 +00:00
Compare commits
2 Commits
7737ee3158
...
11e28b1e09
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11e28b1e09 | ||
|
|
c04b0a259a |
@@ -32,6 +32,7 @@ namespace Assets._Project.Develop.Runtime.Infrastructure.EntryPoint
|
||||
container.RegisterAsSingle(CreateSceneSwitcherService);
|
||||
|
||||
container.RegisterAsSingle(CreateInputFactory);
|
||||
container.RegisterAsSingle(CreateInputStateMachine);
|
||||
container.RegisterAsSingle<IPlayerInput>(CreatePlayerInput);
|
||||
container.RegisterAsSingle<IUIInput>(CreateUIInput);
|
||||
|
||||
@@ -65,6 +66,7 @@ namespace Assets._Project.Develop.Runtime.Infrastructure.EntryPoint
|
||||
private static ResourcesAssetsLoader CreateResourcesAssetsLoader(DIContainer c) => new();
|
||||
|
||||
private static InputFactory CreateInputFactory(DIContainer c) => new();
|
||||
private static InputStateMachine CreateInputStateMachine(DIContainer c) => new(c);
|
||||
|
||||
private static TimerServiceFactory CreateTimerServiceFactory(DIContainer c) => new (c);
|
||||
|
||||
|
||||
@@ -52,13 +52,13 @@ namespace _Project.Develop.Runtime.Entities
|
||||
.AddInDeathProcess()
|
||||
.AddDeathProcessInitialTime(new ReactiveVariable<float>(2))
|
||||
.AddDeathProcessCurrentTime()
|
||||
.AddAttackProcessInitialTime(new ReactiveVariable<float>(3))
|
||||
.AddAttackProcessInitialTime(new ReactiveVariable<float>(1))
|
||||
.AddAttackProcessCurrentTime()
|
||||
.AddInAttackProcess()
|
||||
.AddStartAttackRequest()
|
||||
.AddStartAttackEvent()
|
||||
.AddEndAttackEvent()
|
||||
.AddAttackDelayTime(new ReactiveVariable<float>(2))
|
||||
.AddAttackDelayTime(new ReactiveVariable<float>(1))
|
||||
.AddAttackDelayEndEvent()
|
||||
.AddInstantAttackDamage(new ReactiveVariable<float>(50))
|
||||
.AddAttackCanceledEvent()
|
||||
@@ -102,9 +102,6 @@ namespace _Project.Develop.Runtime.Entities
|
||||
.AddMustCancelAttack(mustCancelAttack);
|
||||
|
||||
entity
|
||||
.AddSystem(new AttackByInputSystem(_playerInput))
|
||||
.AddSystem(new MoveDirectionByInputSystem(_playerInput))
|
||||
.AddSystem(new RotateDirectionByMoveInputSystem(_playerInput))
|
||||
.AddSystem(new RigidbodyMovementSystem())
|
||||
.AddSystem(new RigidbodyRotationSystem())
|
||||
|
||||
@@ -213,7 +210,7 @@ namespace _Project.Develop.Runtime.Entities
|
||||
.AddMaxHealth(new ReactiveVariable<float>(150))
|
||||
.AddCurrentHealth(new ReactiveVariable<float>(150))
|
||||
|
||||
.AddTeleportTarget(entity.Transform)
|
||||
.AddTeleportSource(entity.Transform)
|
||||
.AddTeleportToPoint(entity.Transform)
|
||||
.AddStartTeleportEvent()
|
||||
.AddStartTeleportRequest()
|
||||
@@ -229,6 +226,10 @@ namespace _Project.Develop.Runtime.Entities
|
||||
.AddTeleportEnergyCost(new ReactiveVariable<int>(20))
|
||||
.AddTeleportSearchRadius(new ReactiveVariable<float>(6))
|
||||
|
||||
.AddTeleportCooldownInitialTime(new ReactiveVariable<float>(3))
|
||||
.AddTeleportCooldownCurrentTime()
|
||||
.AddInTeleportCooldown()
|
||||
|
||||
.AddCurrentEnergy(new ReactiveVariable<int>(60))
|
||||
.AddMaxEnergy(new ReactiveVariable<int>(60))
|
||||
.AddUseEnergyEvent()
|
||||
@@ -256,6 +257,7 @@ namespace _Project.Develop.Runtime.Entities
|
||||
|
||||
ICompositeCondition canStartTeleport = new CompositeCondition()
|
||||
.Add(new FuncCondition(() => entity.IsDead.Value == false))
|
||||
.Add(new FuncCondition(() => entity.InTeleportCooldown.Value == false))
|
||||
.Add(new FuncCondition(() => entity.CurrentEnergy.Value >= entity.TeleportEnergyCost.Value));
|
||||
|
||||
ICompositeCondition mustDie = new CompositeCondition()
|
||||
@@ -289,6 +291,7 @@ namespace _Project.Develop.Runtime.Entities
|
||||
.AddSystem(new FindRandomPointForTeleportSystem())
|
||||
.AddSystem(new EndTeleportSystem())
|
||||
.AddSystem(new InstantTeleportSystem())
|
||||
.AddSystem(new TeleportCooldownTimerSystem())
|
||||
.AddSystem(new DealDamageAfterTeleportSystem(_collidersRegistryService))
|
||||
|
||||
.AddSystem(new BodyContactsDetectingSystem())
|
||||
|
||||
@@ -78,13 +78,13 @@ namespace _Project.Develop.Runtime.Entities
|
||||
return AddComponent(new Assets._Project.Develop.Runtime.Gameplay.Common.NavMeshAgentComponent() {Value = value});
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportTarget TeleportTargetC => GetComponent<_Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportTarget>();
|
||||
public _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportSource TeleportSourceC => GetComponent<_Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportSource>();
|
||||
|
||||
public UnityEngine.Transform TeleportTarget => TeleportTargetC.Value;
|
||||
public UnityEngine.Transform TeleportSource => TeleportSourceC.Value;
|
||||
|
||||
public bool TryGetTeleportTarget(out UnityEngine.Transform value)
|
||||
public bool TryGetTeleportSource(out UnityEngine.Transform value)
|
||||
{
|
||||
bool result = TryGetComponent(out _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportTarget component);
|
||||
bool result = TryGetComponent(out _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportSource component);
|
||||
if(result)
|
||||
value = component.Value;
|
||||
else
|
||||
@@ -92,9 +92,9 @@ namespace _Project.Develop.Runtime.Entities
|
||||
return result;
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Entities.Entity AddTeleportTarget(UnityEngine.Transform value)
|
||||
public _Project.Develop.Runtime.Entities.Entity AddTeleportSource(UnityEngine.Transform value)
|
||||
{
|
||||
return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportTarget() {Value = value});
|
||||
return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportSource() {Value = value});
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportToPoint TeleportToPointC => GetComponent<_Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportToPoint>();
|
||||
@@ -327,6 +327,78 @@ namespace _Project.Develop.Runtime.Entities
|
||||
return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportEnergyCost() {Value = value});
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportCooldownInitialTime TeleportCooldownInitialTimeC => GetComponent<_Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportCooldownInitialTime>();
|
||||
|
||||
public _Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Single> TeleportCooldownInitialTime => TeleportCooldownInitialTimeC.Value;
|
||||
|
||||
public bool TryGetTeleportCooldownInitialTime(out _Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Single> value)
|
||||
{
|
||||
bool result = TryGetComponent(out _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportCooldownInitialTime component);
|
||||
if(result)
|
||||
value = component.Value;
|
||||
else
|
||||
value = default(_Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Single>);
|
||||
return result;
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Entities.Entity AddTeleportCooldownInitialTime()
|
||||
{
|
||||
return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportCooldownInitialTime() { Value = new _Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Single>() });
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Entities.Entity AddTeleportCooldownInitialTime(_Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Single> value)
|
||||
{
|
||||
return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportCooldownInitialTime() {Value = value});
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportCooldownCurrentTime TeleportCooldownCurrentTimeC => GetComponent<_Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportCooldownCurrentTime>();
|
||||
|
||||
public _Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Single> TeleportCooldownCurrentTime => TeleportCooldownCurrentTimeC.Value;
|
||||
|
||||
public bool TryGetTeleportCooldownCurrentTime(out _Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Single> value)
|
||||
{
|
||||
bool result = TryGetComponent(out _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportCooldownCurrentTime component);
|
||||
if(result)
|
||||
value = component.Value;
|
||||
else
|
||||
value = default(_Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Single>);
|
||||
return result;
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Entities.Entity AddTeleportCooldownCurrentTime()
|
||||
{
|
||||
return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportCooldownCurrentTime() { Value = new _Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Single>() });
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Entities.Entity AddTeleportCooldownCurrentTime(_Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Single> value)
|
||||
{
|
||||
return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportCooldownCurrentTime() {Value = value});
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.InTeleportCooldown InTeleportCooldownC => GetComponent<_Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.InTeleportCooldown>();
|
||||
|
||||
public _Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Boolean> InTeleportCooldown => InTeleportCooldownC.Value;
|
||||
|
||||
public bool TryGetInTeleportCooldown(out _Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Boolean> value)
|
||||
{
|
||||
bool result = TryGetComponent(out _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.InTeleportCooldown component);
|
||||
if(result)
|
||||
value = component.Value;
|
||||
else
|
||||
value = default(_Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Boolean>);
|
||||
return result;
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Entities.Entity AddInTeleportCooldown()
|
||||
{
|
||||
return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.InTeleportCooldown() { Value = new _Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Boolean>() });
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Entities.Entity AddInTeleportCooldown(_Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Boolean> value)
|
||||
{
|
||||
return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.InTeleportCooldown() {Value = value});
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportDamage TeleportDamageC => GetComponent<_Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.TeleportDamage>();
|
||||
|
||||
public _Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<System.Single> TeleportDamage => TeleportDamageC.Value;
|
||||
@@ -1682,5 +1754,29 @@ namespace _Project.Develop.Runtime.Entities
|
||||
return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.Attack.InAttackCooldown() {Value = value});
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Logic.Gameplay.Features.AI.CurrentTarget CurrentTargetC => GetComponent<_Project.Develop.Runtime.Logic.Gameplay.Features.AI.CurrentTarget>();
|
||||
|
||||
public _Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<_Project.Develop.Runtime.Entities.Entity> CurrentTarget => CurrentTargetC.Value;
|
||||
|
||||
public bool TryGetCurrentTarget(out _Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<_Project.Develop.Runtime.Entities.Entity> value)
|
||||
{
|
||||
bool result = TryGetComponent(out _Project.Develop.Runtime.Logic.Gameplay.Features.AI.CurrentTarget component);
|
||||
if(result)
|
||||
value = component.Value;
|
||||
else
|
||||
value = default(_Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<_Project.Develop.Runtime.Entities.Entity>);
|
||||
return result;
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Entities.Entity AddCurrentTarget()
|
||||
{
|
||||
return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.AI.CurrentTarget() { Value = new _Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<_Project.Develop.Runtime.Entities.Entity>() });
|
||||
}
|
||||
|
||||
public _Project.Develop.Runtime.Entities.Entity AddCurrentTarget(_Project.Develop.Runtime.Utils.ReactiveManagement.ReactiveVariable<_Project.Develop.Runtime.Entities.Entity> value)
|
||||
{
|
||||
return AddComponent(new _Project.Develop.Runtime.Logic.Gameplay.Features.AI.CurrentTarget() {Value = value});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
using _Project.Develop.Runtime.Entities;
|
||||
using _Project.Develop.Runtime.Utils.ReactiveManagement;
|
||||
|
||||
namespace _Project.Develop.Runtime.Logic.Gameplay.Features.AI
|
||||
{
|
||||
public class CurrentTarget : IEntityComponent { public ReactiveVariable<Entity> Value; }
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 78216e3102e549f39cb690e777d00e88
|
||||
timeCreated: 1772470309
|
||||
@@ -0,0 +1,16 @@
|
||||
using Assets._Project.Develop.Runtime.Utilities.StateMachineCore;
|
||||
|
||||
namespace _Project.Develop.Runtime.Logic.Gameplay.Features.AI
|
||||
{
|
||||
public class AIParallelState : ParallelState<IUpdatableState>, IUpdatableState
|
||||
{
|
||||
public AIParallelState(params IUpdatableState[] states) : base(states)
|
||||
{ }
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
foreach (IUpdatableState state in States)
|
||||
state.Update(deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0ae2666ed0a43d590866fff4686222a
|
||||
timeCreated: 1772538444
|
||||
@@ -3,23 +3,27 @@ using System.Collections.Generic;
|
||||
using _Project.Develop.Runtime.Entities;
|
||||
using _Project.Develop.Runtime.Logic.Gameplay.Features.AI.States;
|
||||
using _Project.Develop.Runtime.Utilities.Conditions;
|
||||
using _Project.Develop.Runtime.Utils.InputManagement;
|
||||
using _Project.Develop.Runtime.Utils.ReactiveManagement;
|
||||
using Assets._Project.Develop.Runtime.Infrastructure.DI;
|
||||
using Assets._Project.Develop.Runtime.Utilities.Timer;
|
||||
using UnityEngine;
|
||||
|
||||
namespace _Project.Develop.Runtime.Logic.Gameplay.Features.AI
|
||||
{
|
||||
public class BrainsFactory
|
||||
{
|
||||
private readonly DIContainer _container;
|
||||
|
||||
private readonly EntitiesLifeContext _entitiesLifeContext;
|
||||
private readonly AIBrainsContext _aiBrainsContext;
|
||||
private readonly TimerServiceFactory _timerServiceFactory;
|
||||
private readonly IPlayerInput _playerInput;
|
||||
|
||||
public BrainsFactory(DIContainer container)
|
||||
{
|
||||
_container = container;
|
||||
_aiBrainsContext = _container.Resolve<AIBrainsContext>();
|
||||
_timerServiceFactory = _container.Resolve<TimerServiceFactory>();
|
||||
_playerInput = container.Resolve<IPlayerInput>();
|
||||
_aiBrainsContext = container.Resolve<AIBrainsContext>();
|
||||
_timerServiceFactory = container.Resolve<TimerServiceFactory>();
|
||||
_entitiesLifeContext = container.Resolve<EntitiesLifeContext>();
|
||||
}
|
||||
|
||||
public StateMachineBrain CreateGhostBrain(Entity entity)
|
||||
@@ -32,6 +36,58 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features.AI
|
||||
return brain;
|
||||
}
|
||||
|
||||
public StateMachineBrain CreateWizardBrain(Entity entity)
|
||||
{
|
||||
AIStateMachine stateMachine = CreateRandomTeleportStateMachine(entity);
|
||||
StateMachineBrain brain = new (stateMachine);
|
||||
|
||||
_aiBrainsContext.SetFor(entity, brain);
|
||||
|
||||
return brain;
|
||||
}
|
||||
|
||||
public StateMachineBrain CreateDangerWizardBrain(Entity entity)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public StateMachineBrain CreateMainHeroBrain(Entity entity, ITargetSelector targetSelector)
|
||||
{
|
||||
AIStateMachine combatState = CreateAutoAttackStateMachine(entity);
|
||||
PlayerInputMovementState movementState = new (entity, _playerInput);
|
||||
|
||||
ReactiveVariable<Entity> currentTarget = entity.CurrentTarget;
|
||||
|
||||
ICompositeCondition fromMovementToCombatStateCondition = new CompositeCondition()
|
||||
.Add(new FuncCondition(() => currentTarget.Value != null))
|
||||
.Add(new FuncCondition(() => _playerInput.Move.Value == Vector2.zero));
|
||||
|
||||
ICompositeCondition fromCombatToMovementStateCondition = new CompositeCondition(LogicOperationsUtils.Or)
|
||||
.Add(new FuncCondition(() => currentTarget.Value == null))
|
||||
.Add(new FuncCondition(() => _playerInput.Move.Value != Vector2.zero));
|
||||
|
||||
AIStateMachine behaviour = new ();
|
||||
|
||||
behaviour.AddState(combatState);
|
||||
behaviour.AddState(movementState);
|
||||
|
||||
behaviour.AddTransition(combatState, movementState, fromCombatToMovementStateCondition);
|
||||
behaviour.AddTransition(movementState, combatState, fromMovementToCombatStateCondition);
|
||||
|
||||
FindTargetState findTargetState = new (_entitiesLifeContext, entity, targetSelector);
|
||||
AIParallelState parallelState = new (findTargetState, behaviour);
|
||||
|
||||
AIStateMachine rootStateMachine = new ();
|
||||
|
||||
rootStateMachine.AddState(parallelState);
|
||||
|
||||
StateMachineBrain brain = new (rootStateMachine);
|
||||
|
||||
_aiBrainsContext.SetFor(entity, brain);
|
||||
|
||||
return brain;
|
||||
}
|
||||
|
||||
private AIStateMachine CreateRandomMovementStateMachine(Entity entity)
|
||||
{
|
||||
List<IDisposable> disposables = new ();
|
||||
@@ -60,5 +116,75 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features.AI
|
||||
|
||||
return stateMachine;
|
||||
}
|
||||
|
||||
private AIStateMachine CreateAutoAttackStateMachine(Entity entity)
|
||||
{
|
||||
RotateToTargetState rotateToTargetState = new (entity);
|
||||
AttackTriggerState attackTriggerState = new (entity);
|
||||
|
||||
ICondition canAttack = entity.CanStartAttack;
|
||||
Transform transform = entity.Transform;
|
||||
ReactiveVariable<Entity> currentTarget = entity.CurrentTarget;
|
||||
|
||||
ICompositeCondition fromRotateToAttackCondition = new CompositeCondition()
|
||||
.Add(canAttack)
|
||||
.Add(new FuncCondition(() =>
|
||||
{
|
||||
Entity target = currentTarget.Value;
|
||||
|
||||
if (target == null)
|
||||
return false;
|
||||
|
||||
float angleToTarget = Quaternion.Angle(
|
||||
transform.rotation,
|
||||
Quaternion.LookRotation(target.Transform.position - transform.position));
|
||||
|
||||
return angleToTarget < 1f;
|
||||
}
|
||||
));
|
||||
|
||||
ReactiveVariable<bool> inAttackProcess = entity.InAttackProcess;
|
||||
|
||||
ICondition fromAttackToRotateStateCondition = new FuncCondition(() => inAttackProcess.Value == false);
|
||||
|
||||
AIStateMachine stateMachine = new ();
|
||||
|
||||
stateMachine.AddState(rotateToTargetState);
|
||||
stateMachine.AddState(attackTriggerState);
|
||||
|
||||
stateMachine.AddTransition(rotateToTargetState, attackTriggerState, fromRotateToAttackCondition);
|
||||
stateMachine.AddTransition(attackTriggerState, rotateToTargetState, fromAttackToRotateStateCondition);
|
||||
|
||||
return stateMachine;
|
||||
}
|
||||
|
||||
private AIStateMachine CreateRandomTeleportStateMachine(Entity entity)
|
||||
{
|
||||
TeleportTriggerState teleportTriggerState = new (entity);
|
||||
EmptyState emptyState = new ();
|
||||
|
||||
ICompositeCondition fromIdleToTeleportCondition = new CompositeCondition()
|
||||
.Add(entity.CanStartTeleport);
|
||||
|
||||
ICompositeCondition fromTeleportToIdleCondition = new CompositeCondition()
|
||||
.Add(new FuncCondition(() => entity.InTeleportProcess.Value == false));
|
||||
|
||||
AIStateMachine stateMachine = new ();
|
||||
|
||||
stateMachine.AddState(teleportTriggerState);
|
||||
stateMachine.AddState(emptyState);
|
||||
|
||||
stateMachine.AddTransition(emptyState, teleportTriggerState, fromIdleToTeleportCondition);
|
||||
stateMachine.AddTransition(teleportTriggerState, emptyState, fromTeleportToIdleCondition);
|
||||
|
||||
return stateMachine;
|
||||
}
|
||||
|
||||
private AIStateMachine CreateToTargetTeleportStateMachine(Entity entity)
|
||||
{
|
||||
TeleportTriggerState teleportTriggerState = new (entity);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using _Project.Develop.Runtime.Entities;
|
||||
using _Project.Develop.Runtime.Utils.ReactiveManagement.Event;
|
||||
using Assets._Project.Develop.Runtime.Utilities.StateMachineCore;
|
||||
|
||||
namespace _Project.Develop.Runtime.Logic.Gameplay.Features.AI.States
|
||||
{
|
||||
public class AttackTriggerState : State, IUpdatableState
|
||||
{
|
||||
private ReactiveEvent _request;
|
||||
|
||||
public AttackTriggerState(Entity entity)
|
||||
{
|
||||
_request = entity.StartAttackRequest;
|
||||
}
|
||||
|
||||
public override void Enter()
|
||||
{
|
||||
base.Enter();
|
||||
_request.Invoke();
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d58a80b452346bda2d968af0f76fdfa
|
||||
timeCreated: 1772469124
|
||||
@@ -0,0 +1,28 @@
|
||||
using _Project.Develop.Runtime.Entities;
|
||||
using _Project.Develop.Runtime.Utils.ReactiveManagement;
|
||||
using Assets._Project.Develop.Runtime.Utilities.StateMachineCore;
|
||||
|
||||
namespace _Project.Develop.Runtime.Logic.Gameplay.Features.AI.States
|
||||
{
|
||||
public class FindTargetState : State, IUpdatableState
|
||||
{
|
||||
private ITargetSelector _targetSelector;
|
||||
private EntitiesLifeContext _entitiesLifeContext;
|
||||
private ReactiveVariable<Entity> _currentTarget;
|
||||
|
||||
public FindTargetState(
|
||||
EntitiesLifeContext entitiesLifeContext,
|
||||
Entity entity,
|
||||
ITargetSelector targetSelector)
|
||||
{
|
||||
_currentTarget = entity.CurrentTarget;
|
||||
_targetSelector = targetSelector;
|
||||
_entitiesLifeContext = entitiesLifeContext;
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
_currentTarget.Value = _targetSelector.SelectTargetFrom(_entitiesLifeContext.Entities);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c92a70ea84c48f49ae461eae381a1ce
|
||||
timeCreated: 1772539593
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using _Project.Develop.Runtime.Entities;
|
||||
|
||||
namespace _Project.Develop.Runtime.Logic.Gameplay.Features.AI.States
|
||||
{
|
||||
public interface ITargetSelector
|
||||
{
|
||||
public Entity SelectTargetFrom(IEnumerable<Entity> targets);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 15c5398fa2f84d109f74fbe2cd14bcda
|
||||
timeCreated: 1772538651
|
||||
@@ -0,0 +1,64 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using _Project.Develop.Runtime.Entities;
|
||||
using _Project.Develop.Runtime.Logic.Gameplay.Features.Damage;
|
||||
using _Project.Develop.Runtime.Utilities.Conditions;
|
||||
using UnityEngine;
|
||||
|
||||
namespace _Project.Develop.Runtime.Logic.Gameplay.Features.AI.States
|
||||
{
|
||||
public class NearestDamageableTargetSelector : ITargetSelector
|
||||
{
|
||||
private readonly Entity _source;
|
||||
private readonly Transform _sourceTransform;
|
||||
|
||||
public NearestDamageableTargetSelector(Entity entity)
|
||||
{
|
||||
_source = entity;
|
||||
_sourceTransform = entity.Transform;
|
||||
}
|
||||
|
||||
public Entity SelectTargetFrom(IEnumerable<Entity> targets)
|
||||
{
|
||||
IEnumerable<Entity> selectedTargets = FindSelectedTargets(targets);
|
||||
|
||||
IEnumerable<Entity> enumerable = selectedTargets.ToList();
|
||||
|
||||
if (enumerable.Any() == false)
|
||||
return null;
|
||||
|
||||
Entity closetsTarget = enumerable.First();
|
||||
float minDistance = GetDistanceTo(closetsTarget);
|
||||
|
||||
foreach (Entity target in enumerable)
|
||||
{
|
||||
float distance = GetDistanceTo(target);
|
||||
|
||||
if (distance < minDistance)
|
||||
{
|
||||
minDistance = distance;
|
||||
closetsTarget = target;
|
||||
}
|
||||
}
|
||||
|
||||
return closetsTarget;
|
||||
}
|
||||
|
||||
private IEnumerable<Entity> FindSelectedTargets(IEnumerable<Entity> targets)
|
||||
{
|
||||
return targets.Where(target =>
|
||||
{
|
||||
bool result = target.HasComponent<TakeDamageRequest>();
|
||||
|
||||
if (target.TryGetCanApplyDamage(out ICompositeCondition value))
|
||||
result = result && value.Evaluate();
|
||||
|
||||
result = result && (target != _source);
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
private float GetDistanceTo(Entity target) => (_sourceTransform.position - target.Transform.position).magnitude;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5efdb899e3ea4373b66f0610ea05b5c5
|
||||
timeCreated: 1772538727
|
||||
@@ -0,0 +1,37 @@
|
||||
using _Project.Develop.Runtime.Entities;
|
||||
using _Project.Develop.Runtime.Utils.InputManagement;
|
||||
using _Project.Develop.Runtime.Utils.ReactiveManagement;
|
||||
using Assets._Project.Develop.Runtime.Utilities.StateMachineCore;
|
||||
using UnityEngine;
|
||||
|
||||
namespace _Project.Develop.Runtime.Logic.Gameplay.Features.AI.States
|
||||
{
|
||||
public class PlayerInputMovementState : State, IUpdatableState
|
||||
{
|
||||
private readonly IPlayerInput _playerInput;
|
||||
|
||||
private ReactiveVariable<Vector3> _rotateDirection;
|
||||
private ReactiveVariable<Vector3> _moveDirection;
|
||||
|
||||
public PlayerInputMovementState(Entity entity, IPlayerInput playerInput)
|
||||
{
|
||||
_playerInput = playerInput;
|
||||
|
||||
_rotateDirection = entity.RotateDirection;
|
||||
_moveDirection = entity.MoveDirection;
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
_moveDirection.Value = new Vector3(_playerInput.Move.Value.x, 0, _playerInput.Move.Value.y);
|
||||
_rotateDirection.Value = new Vector3(_playerInput.Move.Value.x, 0, _playerInput.Move.Value.y);
|
||||
}
|
||||
|
||||
public override void Exit()
|
||||
{
|
||||
base.Exit();
|
||||
|
||||
_moveDirection.Value = Vector3.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 449f5d14d62348c5a770bd34869f384f
|
||||
timeCreated: 1772468559
|
||||
@@ -0,0 +1,28 @@
|
||||
using _Project.Develop.Runtime.Entities;
|
||||
using _Project.Develop.Runtime.Utils.ReactiveManagement;
|
||||
using Assets._Project.Develop.Runtime.Utilities.StateMachineCore;
|
||||
using UnityEngine;
|
||||
|
||||
namespace _Project.Develop.Runtime.Logic.Gameplay.Features.AI.States
|
||||
{
|
||||
public class RotateToTargetState : State, IUpdatableState
|
||||
{
|
||||
private ReactiveVariable<Vector3> _rotateDirection;
|
||||
private ReactiveVariable<Entity> _currentTarget;
|
||||
|
||||
private Transform _transform;
|
||||
|
||||
public RotateToTargetState(Entity entity)
|
||||
{
|
||||
_rotateDirection = entity.RotateDirection;
|
||||
_currentTarget = entity.CurrentTarget;
|
||||
_transform = entity.Transform;
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (_currentTarget.Value != null)
|
||||
_rotateDirection.Value = (_currentTarget.Value.Transform.position - _transform.position).normalized;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a16d8f8d923476b9a5544d64f3b469e
|
||||
timeCreated: 1772473180
|
||||
@@ -0,0 +1,25 @@
|
||||
using _Project.Develop.Runtime.Entities;
|
||||
using _Project.Develop.Runtime.Utils.ReactiveManagement.Event;
|
||||
using Assets._Project.Develop.Runtime.Utilities.StateMachineCore;
|
||||
|
||||
namespace _Project.Develop.Runtime.Logic.Gameplay.Features.AI.States
|
||||
{
|
||||
public class TeleportTriggerState : State, IUpdatableState
|
||||
{
|
||||
private ReactiveEvent _request;
|
||||
|
||||
public TeleportTriggerState(Entity entity)
|
||||
{
|
||||
_request = entity.StartTeleportRequest;
|
||||
}
|
||||
|
||||
public override void Enter()
|
||||
{
|
||||
base.Enter();
|
||||
_request.Invoke();
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 399ae3c830b94229a8b94350eca901d2
|
||||
timeCreated: 1772543966
|
||||
@@ -9,7 +9,7 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.Systems
|
||||
{
|
||||
public class FindRandomPointForTeleportSystem : IInitializableSystem, IDisposableSystem
|
||||
{
|
||||
private Transform _target;
|
||||
private Transform _source;
|
||||
private Transform _toPoint;
|
||||
|
||||
private ReactiveEvent _findPointRequest;
|
||||
@@ -21,7 +21,7 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.Systems
|
||||
|
||||
public void OnInit(Entity entity)
|
||||
{
|
||||
_target = entity.TeleportTarget;
|
||||
_source = entity.TeleportSource;
|
||||
_toPoint = entity.TeleportToPoint;
|
||||
_radius = entity.TeleportSearchRadius;
|
||||
_findPointRequest = entity.FindTeleportPointRequest;
|
||||
@@ -37,7 +37,7 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.Systems
|
||||
|
||||
private void OnFindPointRequest()
|
||||
{
|
||||
_toPoint.position = GetRandomPointInRadius(_target.position, _radius.Value);
|
||||
_toPoint.position = GetRandomPointInRadius(_source.position, _radius.Value);
|
||||
_findPointEvent.Invoke();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.Systems
|
||||
|
||||
public void OnInit(Entity entity)
|
||||
{
|
||||
_target = entity.TeleportTarget;
|
||||
_target = entity.TeleportSource;
|
||||
_toPoint = entity.TeleportToPoint;
|
||||
_endTeleportEvent = entity.EndTeleportEvent;
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using _Project.Develop.Runtime.Entities;
|
||||
using _Project.Develop.Runtime.Utils.ReactiveManagement;
|
||||
using _Project.Develop.Runtime.Utils.ReactiveManagement.Event;
|
||||
|
||||
namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.Systems
|
||||
{
|
||||
public class TeleportCooldownTimerSystem : IInitializableSystem, IUpdatableSystem, IDisposableSystem
|
||||
{
|
||||
private ReactiveVariable<float> _currentTime;
|
||||
private ReactiveVariable<float> _initialTime;
|
||||
private ReactiveVariable<bool> _inTeleportCooldown;
|
||||
|
||||
private ReactiveEvent _endTeleportEvent;
|
||||
|
||||
private IDisposable _endTeleportEventDisposable;
|
||||
|
||||
public void OnInit(Entity entity)
|
||||
{
|
||||
_currentTime = entity.TeleportCooldownCurrentTime;
|
||||
_initialTime = entity.TeleportCooldownInitialTime;
|
||||
_inTeleportCooldown = entity.InTeleportCooldown;
|
||||
_endTeleportEvent = entity.EndTeleportEvent;
|
||||
|
||||
_endTeleportEventDisposable = _endTeleportEvent.Subscribe(OnEndTeleport);
|
||||
}
|
||||
|
||||
private void OnEndTeleport()
|
||||
{
|
||||
_currentTime.Value = _initialTime.Value;
|
||||
_inTeleportCooldown.Value = true;
|
||||
}
|
||||
|
||||
public void OnUpdate(float deltaTime)
|
||||
{
|
||||
if (_inTeleportCooldown.Value == false)
|
||||
return;
|
||||
|
||||
_currentTime.Value -= deltaTime;
|
||||
|
||||
if (CooldownIsOver())
|
||||
_inTeleportCooldown.Value = false;
|
||||
}
|
||||
|
||||
private bool CooldownIsOver() => _currentTime.Value <= 0;
|
||||
|
||||
public void OnDispose()
|
||||
{
|
||||
_endTeleportEventDisposable.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 203bcf3a28764fb7bfac1482c48bad2f
|
||||
timeCreated: 1772546509
|
||||
@@ -6,7 +6,7 @@ using UnityEngine;
|
||||
|
||||
namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport
|
||||
{
|
||||
public class TeleportTarget : IEntityComponent { public Transform Value; }
|
||||
public class TeleportSource : IEntityComponent { public Transform Value; }
|
||||
public class TeleportToPoint : IEntityComponent { public Transform Value; }
|
||||
public class TeleportSearchRadius : IEntityComponent { public ReactiveVariable<float> Value; }
|
||||
|
||||
@@ -23,6 +23,10 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport
|
||||
|
||||
public class TeleportEnergyCost : IEntityComponent { public ReactiveVariable<int> Value; }
|
||||
|
||||
public class TeleportCooldownInitialTime : IEntityComponent { public ReactiveVariable<float> Value; }
|
||||
public class TeleportCooldownCurrentTime : IEntityComponent { public ReactiveVariable<float> Value; }
|
||||
public class InTeleportCooldown : IEntityComponent { public ReactiveVariable<bool> Value; }
|
||||
|
||||
public class TeleportDamage : IEntityComponent { public ReactiveVariable<float> Value; }
|
||||
public class TeleportDamageRadius : IEntityComponent { public ReactiveVariable<float> Value; }
|
||||
public class TeleportDamageMask : IEntityComponent { public LayerMask Value; }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using _Project.Develop.Runtime.Entities;
|
||||
using _Project.Develop.Runtime.Logic.Gameplay.Features.AI;
|
||||
using _Project.Develop.Runtime.Logic.Gameplay.Features.AI.States;
|
||||
using _Project.Develop.Runtime.Utils.InputManagement;
|
||||
using Assets._Project.Develop.Runtime.Infrastructure.DI;
|
||||
using UnityEngine;
|
||||
@@ -14,7 +15,7 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features
|
||||
private BrainsFactory _brainsFactory;
|
||||
|
||||
private Entity _hero;
|
||||
private Entity _ghost;
|
||||
private Entity _enemy;
|
||||
|
||||
private bool _isRunning;
|
||||
|
||||
@@ -29,10 +30,12 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features
|
||||
|
||||
public void Run()
|
||||
{
|
||||
_hero = _entitiesFactory.CreateTeleportWizard(Vector3.zero);
|
||||
_ghost = _entitiesFactory.CreateGhost(Vector3.zero + Vector3.forward * 5);
|
||||
_hero = _entitiesFactory.CreateHero(Vector3.zero);
|
||||
_hero.AddCurrentTarget();
|
||||
_brainsFactory.CreateMainHeroBrain(_hero, new NearestDamageableTargetSelector(_hero));
|
||||
|
||||
_brainsFactory.CreateGhostBrain(_ghost);
|
||||
_enemy = _entitiesFactory.CreateTeleportWizard(Vector3.zero + Vector3.forward * 5);
|
||||
_brainsFactory.CreateWizardBrain(_enemy);
|
||||
|
||||
_isRunning = true;
|
||||
}
|
||||
@@ -45,11 +48,11 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
if (_hero == null)
|
||||
if (_hero == null || _enemy == null)
|
||||
return;
|
||||
|
||||
GUI.Label(new Rect(10, 20, 200, 50), $"Health: {_hero.CurrentHealth.Value}/{_hero.MaxHealth.Value}");
|
||||
GUI.Label(new Rect(10, 40, 200, 50), $"Energy: {_hero.CurrentEnergy.Value}/{_hero.MaxEnergy.Value}");
|
||||
GUI.Label(new Rect(10, 40, 200, 50), $"Energy: {_enemy.CurrentEnergy.Value}/{_enemy.MaxEnergy.Value}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using _Project.Develop.Runtime.Utilities.Conditions;
|
||||
using _Project.Develop.Runtime.Utils.InputManagement.States;
|
||||
using Assets._Project.Develop.Runtime.Infrastructure.DI;
|
||||
using Assets._Project.Develop.Runtime.Utilities.StateMachineCore;
|
||||
|
||||
namespace _Project.Develop.Runtime.Utils.InputManagement
|
||||
{
|
||||
public class InputStateMachine : StateMachine<IState>, IInitializable, IDisposable
|
||||
{
|
||||
private readonly IPlayerInput _playerInput;
|
||||
private readonly IUIInput _uiInput;
|
||||
|
||||
public InputStateMachine(List<IDisposable> disposables) : base(disposables)
|
||||
{ }
|
||||
|
||||
public InputStateMachine(DIContainer container) : base(new List<IDisposable>())
|
||||
{
|
||||
_playerInput = container.Resolve<IPlayerInput>();
|
||||
_uiInput = container.Resolve<IUIInput>();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
PlayerInputState playerInputState = new(_playerInput);
|
||||
UIInputState uiInputState = new(_uiInput);
|
||||
|
||||
ICompositeCondition playerToUiStateCondition = new CompositeCondition(LogicOperationsUtils.Or)
|
||||
.Add(new FuncCondition(() => _uiInput.IsEnabled));
|
||||
// .Add(new FuncCondition(() => _playerHorseInput.IsEnabled));
|
||||
|
||||
ICompositeCondition uiToPlayerStateCondition = new CompositeCondition(LogicOperationsUtils.Or)
|
||||
.Add(new FuncCondition(() => _playerInput.IsEnabled));
|
||||
// .Add(new FuncCondition(() => _playerHorseInput.IsEnabled));
|
||||
|
||||
AddState(playerInputState);
|
||||
AddState(uiInputState);
|
||||
|
||||
AddTransition(playerInputState, uiInputState, playerToUiStateCondition);
|
||||
AddTransition(uiInputState, playerInputState, uiToPlayerStateCondition);
|
||||
|
||||
Enter();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1a3543621b74566aa3f737018932731
|
||||
timeCreated: 1772547242
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60ce6781167b4204a72055d939441a5b
|
||||
timeCreated: 1772547589
|
||||
@@ -0,0 +1,26 @@
|
||||
using Assets._Project.Develop.Runtime.Utilities.StateMachineCore;
|
||||
|
||||
namespace _Project.Develop.Runtime.Utils.InputManagement.States
|
||||
{
|
||||
public class PlayerInputState : State
|
||||
{
|
||||
private readonly IPlayerInput _playerInput;
|
||||
|
||||
public PlayerInputState(IPlayerInput playerInput)
|
||||
{
|
||||
_playerInput = playerInput;
|
||||
}
|
||||
|
||||
public override void Enter()
|
||||
{
|
||||
base.Enter();
|
||||
_playerInput.Enable();
|
||||
}
|
||||
|
||||
public override void Exit()
|
||||
{
|
||||
_playerInput.Disable();
|
||||
base.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0efa0cca886c45e295d4adcb82d59f8b
|
||||
timeCreated: 1770556305
|
||||
@@ -0,0 +1,26 @@
|
||||
using Assets._Project.Develop.Runtime.Utilities.StateMachineCore;
|
||||
|
||||
namespace _Project.Develop.Runtime.Utils.InputManagement.States
|
||||
{
|
||||
public class UIInputState : State
|
||||
{
|
||||
private readonly IUIInput _uiInput;
|
||||
|
||||
public UIInputState(IUIInput uiInput)
|
||||
{
|
||||
_uiInput = uiInput;
|
||||
}
|
||||
|
||||
public override void Enter()
|
||||
{
|
||||
base.Enter();
|
||||
_uiInput.Enable();
|
||||
}
|
||||
|
||||
public override void Exit()
|
||||
{
|
||||
_uiInput.Disable();
|
||||
base.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2cac35b3aedd43b1959f82e36c30ac47
|
||||
timeCreated: 1770556297
|
||||
@@ -3,17 +3,24 @@ using System.Collections.Generic;
|
||||
|
||||
namespace _Project.Develop.Runtime.Utils.ReactiveManagement
|
||||
{
|
||||
public class ReactiveVariable<T> : IReadOnlyVariable<T> where T : IEquatable<T>
|
||||
public class ReactiveVariable<T> : IReadOnlyVariable<T>
|
||||
{
|
||||
private readonly List<Subscriber<T, T>> _subscribers = new List<Subscriber<T, T>>();
|
||||
private readonly List<Subscriber<T, T>> _toAddList = new List<Subscriber<T, T>>();
|
||||
private readonly List<Subscriber<T, T>> _toRemoveList = new List<Subscriber<T, T>>();
|
||||
|
||||
public ReactiveVariable() => _value = default(T);
|
||||
|
||||
public ReactiveVariable(T value) => _value = value;
|
||||
private readonly List<Subscriber<T, T>> _subscribers = new ();
|
||||
private readonly List<Subscriber<T, T>> _toAddList = new ();
|
||||
private readonly List<Subscriber<T, T>> _toRemoveList = new ();
|
||||
|
||||
private T _value;
|
||||
private IEqualityComparer<T> _comparer;
|
||||
|
||||
public ReactiveVariable() : this(default) { }
|
||||
|
||||
public ReactiveVariable(T value) : this(value, EqualityComparer<T>.Default){ }
|
||||
|
||||
public ReactiveVariable(T value, IEqualityComparer<T> comparer)
|
||||
{
|
||||
_value = value;
|
||||
_comparer = comparer;
|
||||
}
|
||||
|
||||
public T Value
|
||||
{
|
||||
@@ -23,14 +30,14 @@ namespace _Project.Develop.Runtime.Utils.ReactiveManagement
|
||||
T oldValue = _value;
|
||||
_value = value;
|
||||
|
||||
if (_value.Equals(oldValue) == false)
|
||||
if (_comparer.Equals(oldValue, value) == false)
|
||||
Invoke(oldValue, _value);
|
||||
}
|
||||
}
|
||||
|
||||
public IDisposable Subscribe(Action<T, T> action)
|
||||
{
|
||||
Subscriber<T, T> subscriber = new Subscriber<T, T>(action, RemoveSubscriber);
|
||||
Subscriber<T, T> subscriber = new (action, RemoveSubscriber);
|
||||
_toAddList.Add(subscriber);
|
||||
|
||||
return subscriber;
|
||||
|
||||
@@ -654,8 +654,8 @@ Camera:
|
||||
near clip plane: 0.3
|
||||
far clip plane: 1000
|
||||
field of view: 60
|
||||
orthographic: 0
|
||||
orthographic size: 5
|
||||
orthographic: 1
|
||||
orthographic size: 14.12
|
||||
m_Depth: -1
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
@@ -680,7 +680,7 @@ Transform:
|
||||
m_GameObject: {fileID: 1496566168}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0.34130225, y: -0, z: -0, w: 0.9399536}
|
||||
m_LocalPosition: {x: 0, y: 11.01, z: -12.32}
|
||||
m_LocalPosition: {x: -0.8, y: 41.4, z: -39.5}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
|
||||
Reference in New Issue
Block a user