feat: add team touch system

This commit is contained in:
Bragin Stepan
2026-03-13 15:29:57 +05:00
parent f9b0996922
commit 96058b6c58
12 changed files with 104 additions and 14 deletions

View File

@@ -1,4 +1,4 @@
using _Project.Develop.Runtime.Configs.Gameplay.Entities; using _Project.Develop.Runtime.Configs.Gameplay.Entities;
using _Project.Develop.Runtime.Logic.Gameplay.Features.Attack.Systems; using _Project.Develop.Runtime.Logic.Gameplay.Features.Attack.Systems;
using _Project.Develop.Runtime.Logic.Gameplay.Features.Attack.Systems.Shoot; using _Project.Develop.Runtime.Logic.Gameplay.Features.Attack.Systems.Shoot;
using _Project.Develop.Runtime.Logic.Gameplay.Features.Damage; using _Project.Develop.Runtime.Logic.Gameplay.Features.Damage;
@@ -7,6 +7,7 @@ using _Project.Develop.Runtime.Logic.Gameplay.Features.Input;
using _Project.Develop.Runtime.Logic.Gameplay.Features.Lifetime.Systems; using _Project.Develop.Runtime.Logic.Gameplay.Features.Lifetime.Systems;
using _Project.Develop.Runtime.Logic.Gameplay.Features.Movement; using _Project.Develop.Runtime.Logic.Gameplay.Features.Movement;
using _Project.Develop.Runtime.Logic.Gameplay.Features.Sensors.Systems; using _Project.Develop.Runtime.Logic.Gameplay.Features.Sensors.Systems;
using _Project.Develop.Runtime.Logic.Gameplay.Features.Teams;
using _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.Systems; using _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.Systems;
using _Project.Develop.Runtime.Utilities; using _Project.Develop.Runtime.Utilities;
using _Project.Develop.Runtime.Utilities.Conditions; using _Project.Develop.Runtime.Utilities.Conditions;
@@ -305,7 +306,7 @@ namespace _Project.Develop.Runtime.Entities
return entity; return entity;
} }
public Entity CreateProjectile(Vector3 position, Vector3 direction, float damage) public Entity CreateProjectile(Vector3 position, Vector3 direction, float damage, Entity owner)
{ {
Entity entity = CreateEmpty(); Entity entity = CreateEmpty();
@@ -320,10 +321,12 @@ namespace _Project.Develop.Runtime.Entities
.AddMoveSpeed(new ReactiveVariable<float>(16)) .AddMoveSpeed(new ReactiveVariable<float>(16))
.AddRotationSpeed(new ReactiveVariable<float>(9999)) .AddRotationSpeed(new ReactiveVariable<float>(9999))
.AddBodyContactDamage(new ReactiveVariable<float>(damage)) .AddBodyContactDamage(new ReactiveVariable<float>(damage))
.AddTeam(new ReactiveVariable<Teams>(owner.Team.Value))
.AddIsDead() .AddIsDead()
.AddIsMoving() .AddIsMoving()
.AddDeathMask(Layers.CharactersMask | Layers.EnvironmentMask) .AddDeathMask(Layers.CharactersMask | Layers.EnvironmentMask)
.AddIsTouchDeathMask(); .AddIsTouchDeathMask()
.AddIsTouchAnotherTeam();
ICompositeCondition canMove = new CompositeCondition() ICompositeCondition canMove = new CompositeCondition()
.Add(new FuncCondition(() => entity.IsDead.Value == false)); .Add(new FuncCondition(() => entity.IsDead.Value == false));
@@ -331,7 +334,8 @@ namespace _Project.Develop.Runtime.Entities
ICompositeCondition canRotate = new CompositeCondition() ICompositeCondition canRotate = new CompositeCondition()
.Add(new FuncCondition(() => entity.IsDead.Value == false)); .Add(new FuncCondition(() => entity.IsDead.Value == false));
ICompositeCondition mustDie = new CompositeCondition() ICompositeCondition mustDie = new CompositeCondition(LogicOperationsUtils.Or)
.Add(new FuncCondition(() => entity.IsTouchAnotherTeam.Value))
.Add(new FuncCondition(() => entity.IsTouchDeathMask.Value)); .Add(new FuncCondition(() => entity.IsTouchDeathMask.Value));
ICompositeCondition mustSelfRelease = new CompositeCondition() ICompositeCondition mustSelfRelease = new CompositeCondition()
@@ -354,6 +358,7 @@ namespace _Project.Develop.Runtime.Entities
.AddSystem(new DeathMaskTouchDetectorSystem()) .AddSystem(new DeathMaskTouchDetectorSystem())
.AddSystem(new DeathSwitcherSystem()) .AddSystem(new DeathSwitcherSystem())
.AddSystem(new AnotherTeamTouchDetectorSystem())
.AddSystem(new DisableCollidersOnDeathSystem()) .AddSystem(new DisableCollidersOnDeathSystem())
.AddSystem(new SelfReleaseSystem(_entitiesLifeContext)); .AddSystem(new SelfReleaseSystem(_entitiesLifeContext));

View File

@@ -0,0 +1,19 @@
using _Project.Develop.Runtime.Logic.Gameplay.Features.Teams;
using _Project.Develop.Runtime.Utils.ReactiveManagement;
namespace _Project.Develop.Runtime.Entities
{
public static class EntitiesHelper
{
public static bool AreOnSameTeam(Entity first, Entity second)
{
if (first.TryGetTeam(out ReactiveVariable<Teams> firstTeam) &&
second.TryGetTeam(out ReactiveVariable<Teams> secondTeam))
{
return firstTeam.Value == secondTeam.Value;
}
return false;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 240aa716b4304420b9ff4ef3cbb14b6b
timeCreated: 1773396722

View File

@@ -1,4 +1,4 @@
using System; using System;
using _Project.Develop.Runtime.Entities; using _Project.Develop.Runtime.Entities;
using _Project.Develop.Runtime.Utilities.Conditions; using _Project.Develop.Runtime.Utilities.Conditions;
using _Project.Develop.Runtime.Utils.ReactiveManagement; using _Project.Develop.Runtime.Utils.ReactiveManagement;
@@ -14,15 +14,21 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Attack.Systems
private ReactiveVariable<bool> _inAttackProcess; private ReactiveVariable<bool> _inAttackProcess;
private ICompositeCondition _canStartAttack; private ICompositeCondition _canStartAttack;
private Entity _entity;
private ReactiveVariable<Entity> _currentTarget;
private IDisposable _attackRequestDisposable; private IDisposable _attackRequestDisposable;
public void OnInit(Entity entity) public void OnInit(Entity entity)
{ {
_entity = entity;
_startAttackRequest = entity.StartAttackRequest; _startAttackRequest = entity.StartAttackRequest;
_startAttackEvent = entity.StartAttackEvent; _startAttackEvent = entity.StartAttackEvent;
_inAttackProcess = entity.InAttackProcess; _inAttackProcess = entity.InAttackProcess;
_canStartAttack = entity.CanStartAttack; _canStartAttack = entity.CanStartAttack;
if (entity.TryGetCurrentTarget(out var currentTarget))
_currentTarget = currentTarget;
_attackRequestDisposable = _startAttackRequest.Subscribe(OnAttackRequest); _attackRequestDisposable = _startAttackRequest.Subscribe(OnAttackRequest);
} }
@@ -30,6 +36,15 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Attack.Systems
{ {
if (_canStartAttack.Evaluate()) if (_canStartAttack.Evaluate())
{ {
if (_currentTarget != null && _currentTarget.Value != null)
{
if (EntitiesHelper.AreOnSameTeam(_entity, _currentTarget.Value))
{
Debug.Log("Не могу атаковать своего!");
return;
}
}
_inAttackProcess.Value = true; _inAttackProcess.Value = true;
_startAttackEvent.Invoke(); _startAttackEvent.Invoke();
Debug.Log("Старт атаки"); Debug.Log("Старт атаки");

View File

@@ -1,4 +1,4 @@
using System; using System;
using _Project.Develop.Runtime.Entities; using _Project.Develop.Runtime.Entities;
using _Project.Develop.Runtime.Utils.ReactiveManagement; using _Project.Develop.Runtime.Utils.ReactiveManagement;
using _Project.Develop.Runtime.Utils.ReactiveManagement.Event; using _Project.Develop.Runtime.Utils.ReactiveManagement.Event;
@@ -38,7 +38,7 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Attack.Systems.Shoot
private void OnAttackDelayEnd() private void OnAttackDelayEnd()
{ {
_entitiesFactory.CreateProjectile(_shootPoint.position, _shootPoint.forward, _damage.Value); _entitiesFactory.CreateProjectile(_shootPoint.position, _shootPoint.forward, _damage.Value, _entity);
} }
public void OnDispose() public void OnDispose()

View File

@@ -1,4 +1,4 @@
using _Project.Develop.Runtime.Entities; using _Project.Develop.Runtime.Entities;
using _Project.Develop.Runtime.Utilities.Conditions; using _Project.Develop.Runtime.Utilities.Conditions;
using _Project.Develop.Runtime.Utils.ReactiveManagement; using _Project.Develop.Runtime.Utils.ReactiveManagement;
using _Project.Develop.Runtime.Utils.ReactiveManagement.Event; using _Project.Develop.Runtime.Utils.ReactiveManagement.Event;

View File

@@ -1,4 +1,4 @@
using System; using System;
using _Project.Develop.Runtime.Entities; using _Project.Develop.Runtime.Entities;
using _Project.Develop.Runtime.Utilities.Conditions; using _Project.Develop.Runtime.Utilities.Conditions;
using _Project.Develop.Runtime.Utils.ReactiveManagement; using _Project.Develop.Runtime.Utils.ReactiveManagement;

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using _Project.Develop.Runtime.Entities; using _Project.Develop.Runtime.Entities;
using _Project.Develop.Runtime.Utilities; using _Project.Develop.Runtime.Utilities;
using _Project.Develop.Runtime.Utils.ReactiveManagement; using _Project.Develop.Runtime.Utils.ReactiveManagement;
@@ -33,6 +33,9 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Damage
if(_processedEntities.Contains(contactEntity) == false) if(_processedEntities.Contains(contactEntity) == false)
{ {
_processedEntities.Add(contactEntity); _processedEntities.Add(contactEntity);
if (EntitiesHelper.AreOnSameTeam(contactEntity, _entity))
continue;
if (contactEntity.TryGetTakeDamageRequest(out ReactiveEvent<float> takeDamageRequest)) if (contactEntity.TryGetTakeDamageRequest(out ReactiveEvent<float> takeDamageRequest))
takeDamageRequest.Invoke(_damage.Value); takeDamageRequest.Invoke(_damage.Value);

View File

@@ -0,0 +1,39 @@
using _Project.Develop.Runtime.Entities;
using _Project.Develop.Runtime.Utilities;
using _Project.Develop.Runtime.Utils.ReactiveManagement;
namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Sensors.Systems
{
public class AnotherTeamTouchDetectorSystem : IInitializableSystem, IUpdatableSystem
{
private Buffer<Entity> _contacts;
private ReactiveVariable<bool> _isTouchAnotherTeam;
private ReactiveVariable<Teams.Teams> _sourceTeam;
public void OnInit(Entity entity)
{
_contacts = entity.ContactEntitiesBuffer;
_isTouchAnotherTeam = entity.IsTouchAnotherTeam;
_sourceTeam = entity.Team;
}
public void OnUpdate(float deltaTime)
{
for (int i = 0; i < _contacts.Count; i++)
{
Entity contact = _contacts.Items[i];
if (contact.TryGetTeam(out ReactiveVariable<Teams.Teams> anotherTeam))
{
if (_sourceTeam.Value != anotherTeam.Value)
{
_isTouchAnotherTeam.Value = true;
return;
}
}
}
_isTouchAnotherTeam.Value = false;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 54420a8777b740ce9a5300530cd661be
timeCreated: 1773397526

View File

@@ -64,6 +64,9 @@ namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Teleport.Systems
&& contactEntity != _entity && contactEntity != _entity
&& contactEntity.TryGetTakeDamageRequest(out ReactiveEvent<float> takeDamageRequest)) && contactEntity.TryGetTakeDamageRequest(out ReactiveEvent<float> takeDamageRequest))
{ {
if (EntitiesHelper.AreOnSameTeam(contactEntity, _entity))
continue;
takeDamageRequest.Invoke(_damage); takeDamageRequest.Invoke(_damage);
} }
} }

View File

@@ -17,9 +17,9 @@ MonoBehaviour:
<RotationSpeed>k__BackingField: 900 <RotationSpeed>k__BackingField: 900
<MaxHealth>k__BackingField: 100 <MaxHealth>k__BackingField: 100
<TeleportDamage>k__BackingField: 50 <TeleportDamage>k__BackingField: 50
<TeleportDamageRadius>k__BackingField: 6 <TeleportDamageRadius>k__BackingField: 4
<TeleportEnergyCast>k__BackingField: 50 <TeleportEnergyCast>k__BackingField: 20
<TeleportSearchRadius>k__BackingField: 50 <TeleportSearchRadius>k__BackingField: 4
<TeleportCooldownTime>k__BackingField: 3 <TeleportCooldownTime>k__BackingField: 3
<MaxEnergy>k__BackingField: 60 <MaxEnergy>k__BackingField: 60
<RegenEnergyAmount>k__BackingField: 10 <RegenEnergyAmount>k__BackingField: 10