2023-08-27 02:58:19 +08:00
|
|
|
using System;
|
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
using BITKit;
|
|
|
|
using BITKit.Entities;
|
|
|
|
using BITKit.Entities.Melee;
|
|
|
|
using Cysharp.Threading.Tasks;
|
|
|
|
using Cysharp.Threading.Tasks.Triggers;
|
|
|
|
using Unity.Collections;
|
|
|
|
using UnityEngine;
|
|
|
|
using UnityEngine.VFX;
|
|
|
|
|
|
|
|
namespace BITFALL.Melee
|
|
|
|
{
|
|
|
|
[Serializable]
|
|
|
|
public class MeleeServiceSingleton : IMeleeService
|
|
|
|
{
|
|
|
|
public void Melee(MeleeCommand command) => MeleeService.Melee(command);
|
|
|
|
}
|
|
|
|
public struct MeleeDamageMessage:IDamageType{}
|
|
|
|
public class MeleeService : MonoBehaviour,IMeleeService
|
|
|
|
{
|
|
|
|
internal static MeleeService Singleton;
|
|
|
|
[RuntimeInitializeOnLoadMethod]
|
|
|
|
private static void Initialize()
|
|
|
|
{
|
|
|
|
Queue.Clear();
|
|
|
|
}
|
|
|
|
private static readonly Queue<MeleeCommand> Queue = new();
|
|
|
|
public static void Melee(MeleeCommand command)=>Queue.Enqueue(command);
|
|
|
|
[SerializeField] private LayerMask detectLayer;
|
|
|
|
private void Awake()
|
|
|
|
{
|
|
|
|
Singleton = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void FixedUpdate()
|
|
|
|
{
|
|
|
|
if (Queue.TryDequeue(out var command) is false) return;
|
|
|
|
|
|
|
|
var colliders = Physics.OverlapSphere(command.Position, command.Range,detectLayer);
|
|
|
|
var damaged= new List<IEntity>();
|
|
|
|
foreach (var x in colliders.Where(x=>x.GetComponent<IDamagable>() is not null))
|
|
|
|
{
|
|
|
|
var damageable = x.GetComponent<IDamagable>();
|
2023-09-01 14:33:54 +08:00
|
|
|
if (damaged.Contains(damageable.Entity) || damageable.Entity.Id == command.PlayerId)
|
2023-08-27 02:58:19 +08:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
damaged.Add(damageable.Entity);
|
|
|
|
damageable.GiveDamage(new DamageMessage()
|
|
|
|
{
|
|
|
|
initiator = UnityEntitiesService.Get(command.PlayerId) as IEntity,
|
|
|
|
damageType = new MeleeDamageMessage
|
|
|
|
{
|
|
|
|
|
|
|
|
},
|
|
|
|
target = damageable.Entity,
|
|
|
|
damage = 64,
|
|
|
|
hit = damageable,
|
|
|
|
});
|
|
|
|
var direction = (damageable.Rigidbody.position - (Vector3)command.Position).normalized;
|
|
|
|
damageable.Rigidbody.AddForceAtPositionAsync(direction * 512 ,command.Position,ForceMode.Impulse).Forget();
|
|
|
|
|
|
|
|
if (x.TryGetComponent<ITag>(out var _tag))
|
|
|
|
{
|
|
|
|
DI.Get<VFXService>().Spawn(new Location
|
|
|
|
{
|
|
|
|
position = x.transform.position,
|
|
|
|
rotation = Quaternion.identity,
|
|
|
|
forward = direction
|
|
|
|
},_tag.GetTags());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IMeleeService.Melee(MeleeCommand command) => Melee(command);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|