BITFALL/Assets/Artists/Scripts/Entities/Equipment/EntityEquipment.cs

475 lines
16 KiB
C#
Raw Normal View History

2023-10-20 19:31:12 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BITKit;
using BITKit.Animations;
using BITKit.StateMachine;
using System.Linq;
2023-10-29 15:27:13 +08:00
using System.Security.Permissions;
2024-03-23 18:07:54 +08:00
using Animancer;
2023-10-31 18:07:15 +08:00
using AYellowpaper.SerializedCollections;
2023-10-20 19:31:12 +08:00
using BITFALL;
using BITFALL.Entities.Equipment;
2023-12-03 17:35:43 +08:00
using BITFALL.Entities.Inventory;
using BITFALL.Guns.Modify;
2023-10-20 19:31:12 +08:00
using BITFALL.Player.Equip;
2023-12-03 17:35:43 +08:00
using BITFALL.Props;
2023-10-20 19:31:12 +08:00
using BITKit.Entities.Melee;
2023-10-29 15:27:13 +08:00
using BITKit.Entities.VFX;
2023-12-03 17:35:43 +08:00
using BITKit.UX;
2023-10-20 19:31:12 +08:00
using Cinemachine;
using Cysharp.Threading.Tasks;
2023-11-02 20:58:55 +08:00
using Unity.Mathematics;
2023-10-20 19:31:12 +08:00
namespace BITKit.Entities
{
public abstract class BITEquipBase<T> : StateBasedMonoBehaviour<T>, IEquipBase where T : IState
{
2024-03-23 18:07:54 +08:00
public const string C_Weapon = "c_weapon";
2024-03-24 02:05:16 +08:00
public string[] SearchKey { get; set; }
2023-10-20 19:31:12 +08:00
[Header(Constant.Header.Settings)]
2023-10-24 23:37:59 +08:00
[SerializeField] protected AssetableItem item;
2024-02-21 01:40:53 +08:00
2023-10-20 19:31:12 +08:00
2024-03-25 16:08:26 +08:00
//[Header(Constant.Header.Property)]
//[SerializeField] public SerializedDictionary<string,AnimationProperty> animationProperties;
2024-03-23 18:07:54 +08:00
2023-10-20 19:31:12 +08:00
[Header(Constant.Header.Components)]
2024-03-23 18:07:54 +08:00
[SerializeField] private AnimancerComponent animancerComponent;
2024-03-25 16:08:26 +08:00
[SerializeField] private AnimancerComponent additionalAnimancerComponent;
2023-10-29 15:27:13 +08:00
[SerializeField] protected EntityVFXPlayer vfxPlayer;
2023-10-20 19:31:12 +08:00
[SerializeField] private Renderer[] renderers;
2023-10-24 23:37:59 +08:00
[SerializeField] protected Transform cameraTransform;
2023-12-03 17:35:43 +08:00
[SerializeField] protected Prop_Modify _modify;
2023-10-20 19:31:12 +08:00
[Header(Constant.Header.Services)]
[SerializeReference,SubclassSelector] protected IMeleeService meleeService;
2024-03-23 18:07:54 +08:00
[Inject] private IMotionMatchingService motionMatchingService = new ScriptableMotionMatchingSingleton();
2023-10-20 19:31:12 +08:00
2024-03-23 18:07:54 +08:00
public IEntity Entity { get; set; }
2023-10-29 15:27:13 +08:00
public Entity UnityEntity=>Entity as Entity;
2024-03-23 18:07:54 +08:00
public AnimancerComponent AnimancerComponent=>animancerComponent;
2024-03-25 16:08:26 +08:00
public AnimancerComponent AdditionalAnimancerComponent=>additionalAnimancerComponent;
2024-03-23 18:07:54 +08:00
public IMotionMatchingService MotionMatchingService=>motionMatchingService;
2023-12-03 17:35:43 +08:00
public IBasicItem Item
{
get => _item;
2023-12-15 00:08:02 +08:00
set
{
OnApply?.Invoke(_item = value);
OnItemApplied(value);
}
2023-12-03 17:35:43 +08:00
}
private IBasicItem _item;
2024-03-25 16:08:26 +08:00
//public IDictionary<string, float> AnimationProperties = null;
[Inject(true),NonSerialized]
public InputActionGroup inputActionGroup;
2023-10-20 19:31:12 +08:00
protected readonly ValidHandle AllowRendering = new();
2023-10-20 22:46:14 +08:00
public virtual string AddressablePath => item.AddressablePath;
2023-10-20 19:31:12 +08:00
protected virtual Vector3 meleeForce => Transform.forward;
public bool IsEntered { get; set; }
2023-10-24 23:37:59 +08:00
private Quaternion _initialCameraRotation;
2023-12-03 17:35:43 +08:00
protected event Action<IBasicItem> OnApply;
2023-10-20 19:31:12 +08:00
2023-11-30 00:23:23 +08:00
[Inject] protected IEntityOverride _entityOverride;
2023-12-03 17:35:43 +08:00
[Inject(true)] protected IEntityInventory _inventory;
[Inject(true)] protected IUXPopup _uxPopup;
2024-03-24 02:05:16 +08:00
public override void Initialize()
{
SearchKey = new []{C_Weapon,item.Name};
base.Initialize();
}
2023-10-20 19:31:12 +08:00
public virtual void Entry()
{
2024-03-23 18:07:54 +08:00
if (animancerComponent)
2024-03-25 16:08:26 +08:00
{
animancerComponent.enabled = true;
2024-03-23 18:07:54 +08:00
animancerComponent.Animator.enabled = true;
2024-03-25 16:08:26 +08:00
}
if (additionalAnimancerComponent)
{
additionalAnimancerComponent.enabled = true;
additionalAnimancerComponent.Animator.enabled = true;
}
2023-10-31 18:07:15 +08:00
2023-10-20 19:31:12 +08:00
AllowRendering.AddElement(this);
//inputActionGroup.allowInput.AddElement(this);
2023-10-29 15:27:13 +08:00
if (vfxPlayer)
vfxPlayer.enabled = true;
2023-10-20 19:31:12 +08:00
}
2023-10-29 15:27:13 +08:00
2023-10-20 19:31:12 +08:00
public virtual UniTask EntryAsync()
{
return UniTask.CompletedTask;
}
2023-11-15 23:54:54 +08:00
public virtual void Entered()
{
}
2023-10-20 19:31:12 +08:00
public virtual void Exit()
{
2023-10-29 15:27:13 +08:00
if (vfxPlayer)
vfxPlayer.enabled = false;
2023-10-20 19:31:12 +08:00
}
2023-10-31 18:07:15 +08:00
2023-10-20 19:31:12 +08:00
public virtual UniTask ExitAsync()
{
AllowRendering.RemoveElement(this);
2023-11-15 23:54:54 +08:00
return UniTask.CompletedTask;
}
public virtual async void Exited()
{
2024-03-23 18:07:54 +08:00
if (!cameraTransform) return;
await UniTask.NextFrame(destroyCancellationToken);
cameraTransform.localPosition = default;
cameraTransform.localRotation = _initialCameraRotation;
2024-03-25 16:08:26 +08:00
if (animancerComponent)
{
animancerComponent.enabled = false;
animancerComponent.Animator.enabled = false;
}
if(AdditionalAnimancerComponent)
{
AdditionalAnimancerComponent.enabled = false;
AdditionalAnimancerComponent.Stop();
AdditionalAnimancerComponent.Animator.enabled = false;
}
2023-10-20 19:31:12 +08:00
}
2023-10-24 23:37:59 +08:00
2023-10-20 19:31:12 +08:00
public virtual void OnAwake()
{
2024-03-25 16:08:26 +08:00
//AnimationProperties= animationProperties.ToDictionary(x=>x.Key,x=>x.Value.Value);
if (renderers is null or { Length: 0 })
{
renderers = GetComponentsInChildren<Renderer>(true);
}
2024-03-22 20:16:32 +08:00
foreach (var x in StateDictionary.Values)
{
Entity.Inject(x);
}
2024-03-05 17:34:41 +08:00
2023-12-03 17:35:43 +08:00
AllowRendering.AddListener(x =>
{
renderers.ForEach(y => { y.enabled = x; });
if (_modify)
_modify.AllowModify.SetDisableElements(this, !x);
2023-12-03 17:35:43 +08:00
});
2024-03-23 18:07:54 +08:00
if (animancerComponent)
animancerComponent.Animator.enabled = false;
2023-10-20 19:31:12 +08:00
AllowRendering.Invoke();
2023-11-15 23:54:54 +08:00
if (cameraTransform)
2023-10-24 23:37:59 +08:00
_initialCameraRotation = cameraTransform.localRotation;
2023-10-20 19:31:12 +08:00
Initialize();
2024-03-22 20:16:32 +08:00
inputActionGroup?.allowInput.Invoke();
2023-11-21 18:05:18 +08:00
if (vfxPlayer)
vfxPlayer.enabled = false;
2023-11-30 00:23:23 +08:00
_entityOverride.OnOverride += OnOverride;
2023-12-03 17:35:43 +08:00
OnApply += (x) =>
{
if (!_modify) return;
if (x is not null && x.TryGetProperty<GunModify>(out var modify))
{
_modify.Modify(modify);
}
else
{
_modify.ClearModify();
}
};
if (_modify)
_modify.ClearModify();
2023-11-30 00:23:23 +08:00
}
private void OnOverride(bool obj)
{
if (inputActionGroup is not null)
inputActionGroup.allowInput.SetDisableElements("Override", obj);
AllowRendering.SetDisableElements("Override", obj);
2023-10-20 19:31:12 +08:00
}
public virtual void OnDestroy()
{
2023-12-15 00:08:02 +08:00
inputActionGroup?.Dispose();
2023-10-20 19:31:12 +08:00
}
public virtual void OnStart() { }
2024-03-05 17:34:41 +08:00
public virtual void OnUpdate(float deltaTime)
{
2024-03-25 16:08:26 +08:00
// foreach (var pair in animationProperties)
// {
// AnimationProperties[pair.Key] = pair.Value.Value;
// }
2024-03-05 17:34:41 +08:00
}
2023-10-20 19:31:12 +08:00
public virtual bool IsSupportItem(IBasicItem item) =>item is not null && item.AddressablePath == AddressablePath;
public virtual void PlayAudio(string eventName) { }
public virtual void EquipEvent(string eventName){}
public virtual void AnimationEvent(string eventName)
{
if (IsEntered is false) return;
2023-10-24 23:37:59 +08:00
if (item is not AssetableEquip equip) return;
2023-10-20 19:31:12 +08:00
switch (eventName)
{
case "Melee":
case "Attack":
meleeService.Melee(new MeleeCommand
{
2023-11-15 23:54:54 +08:00
2023-10-20 19:31:12 +08:00
PlayerId = Entity.Id,
Position = Transform.position,
2023-10-24 23:37:59 +08:00
Force = meleeForce * equip.MeleeForce,
Range = equip.MeleeRange,
2023-10-30 01:25:53 +08:00
Damage = equip.MeleeDamage,
Forward = UnityEntity.transform.forward
2023-10-20 19:31:12 +08:00
});
break;
case "HeavyAttack":
meleeService.Melee(new MeleeCommand
{
PlayerId = Entity.Id,
Position = Transform.position,
2023-10-24 23:37:59 +08:00
Force = meleeForce * equip.HeavyMeleeForce,
Range = equip.HeavyMeleeRange,
Damage = equip.HeavyMeleeDamage,
2023-10-30 01:25:53 +08:00
Forward = UnityEntity.transform.forward
2023-10-20 19:31:12 +08:00
});
break;
}
}
2023-12-15 00:08:02 +08:00
protected virtual void OnItemApplied(IBasicItem item)
{
}
2023-10-20 19:31:12 +08:00
}
[CustomType(typeof(IEquipService))]
[CustomType(typeof(IEntityEquipment))]
2023-10-30 01:25:53 +08:00
public class EntityEquipment : EntityBehavior,IEquipService,IEntityEquipment
2023-10-20 19:31:12 +08:00
{
public IOptional<float> Zoom { get; } = new Optional<float>(){Value = 1};
2024-02-21 01:40:53 +08:00
[SerializeField] protected Optional<int> allowAnimationFOV;
[SerializeField] private int layer;
2023-10-31 18:07:15 +08:00
public float Stable { get; set; }
2023-12-17 02:03:13 +08:00
public float Aim { get; set; }
2023-10-31 18:07:15 +08:00
public bool AllowAttack { get; set; }
public bool AllowScope { get; set; }
2023-10-20 19:31:12 +08:00
[SerializeField] private CinemachineVirtualCamera virtualCamera;
2023-10-29 15:27:13 +08:00
[SerializeField] private Optional<int> overrideIndex;
2023-10-20 19:31:12 +08:00
2023-11-02 20:58:55 +08:00
[SerializeField] private Optional<GameObject> optionalScope;
2023-11-30 00:23:23 +08:00
public IBasicItem CurrentItem { get; private set; }
2023-10-20 19:31:12 +08:00
public event Action<IBasicItem> OnEquip;
2023-10-29 15:27:13 +08:00
public event Action<IBasicItem> OnUnEquip;
public event Action<string> OnEquipAddressable;
public event Action<string> OnUnEquipAddressable;
private readonly EntryGroup<IEquipBase> equips = new();
2023-10-20 19:31:12 +08:00
protected IEquipBase entryComplete;
2023-10-29 15:27:13 +08:00
[Inject(true)] private IHealth _health;
2024-02-21 01:40:53 +08:00
[Inject(true)] private IEntityOverride _entityOverride;
2023-11-15 23:54:54 +08:00
public IValidHandle AllowEquip { get; } =new ValidHandle();
2024-02-21 01:40:53 +08:00
private readonly PrioritySelector<int> _prioritySelector = new();
2023-10-29 15:27:13 +08:00
public override void OnAwake()
2023-10-20 19:31:12 +08:00
{
2023-10-29 15:27:13 +08:00
base.OnAwake();
2024-02-21 01:40:53 +08:00
foreach (var x in GetComponentsInChildren<IEquipBase>(true))
{
Register(x);
}
2023-10-20 19:31:12 +08:00
equips.OnEntry += OnEntry;
equips.OnExit += OnExit;
2023-11-15 23:54:54 +08:00
AllowEquip.AddListener(OnAllowEquip);
2023-10-29 15:27:13 +08:00
if (_health is not null)
{
_health.OnSetAlive += x =>
{
2023-11-15 23:54:54 +08:00
AllowEquip.SetElements(this,x);
2023-10-29 15:27:13 +08:00
if (x is false)
2023-11-15 23:54:54 +08:00
{
2023-11-30 00:23:23 +08:00
CurrentItem = null;
2023-10-29 15:27:13 +08:00
EntryEquip(-1);
2023-11-15 23:54:54 +08:00
}
2023-10-29 15:27:13 +08:00
};
}
}
2023-11-15 23:54:54 +08:00
private void OnAllowEquip(bool allow)
{
if (allow)
{
2023-11-30 00:23:23 +08:00
EntryEquip(CurrentItem);
2023-11-15 23:54:54 +08:00
}
else
{
EntryEquip(-1);
}
}
2023-10-29 15:27:13 +08:00
public override void OnStart()
{
base.OnStart();
2023-10-20 19:31:12 +08:00
foreach (var x in equips.list)
{
x.OnStart();
}
2023-11-15 23:54:54 +08:00
if (overrideIndex.Allow && (_health?.IsAlive ?? true))
{
EntryEquip(overrideIndex.Value);
}
2023-10-20 19:31:12 +08:00
}
private void OnExit(IEquipBase obj)
{
2023-10-29 15:27:13 +08:00
OnUnEquipAddressable?.Invoke(obj.AddressablePath);
OnUnEquip?.Invoke(obj.Item);
//Debug.Log($"已退出:{obj.Item.Name}");
2023-10-20 19:31:12 +08:00
}
private void OnEntry(IEquipBase obj)
{
2023-10-29 15:27:13 +08:00
OnEquipAddressable?.Invoke(obj.AddressablePath);
2023-11-30 00:23:23 +08:00
obj.Item = CurrentItem;
2023-10-20 19:31:12 +08:00
OnEquip?.Invoke(obj.Item);
2023-10-29 15:27:13 +08:00
//Debug.Log($"已进入:{obj.Item.Name}");
2023-10-20 19:31:12 +08:00
}
public override void OnUpdate(float deltaTime)
{
2024-02-21 01:40:53 +08:00
equips.Entry(_prioritySelector.Current);
if (equips.index is not -1)
{
equips.list[equips.index].Item = CurrentItem;
}
2023-10-20 19:31:12 +08:00
if (equips.TryGetEntried(out entryComplete))
{
entryComplete.OnUpdate(deltaTime);
}
if (virtualCamera is not null)
{
2023-12-17 02:03:13 +08:00
var targetFov =
2023-11-02 20:58:55 +08:00
Mathf.Lerp(
virtualCamera.m_Lens.FieldOfView,
Zoom.Allow ?
Mathf.Rad2Deg * CalcZoomFOV(Mathf.Deg2Rad * 60f, Zoom.Value) : PlayerConfig.Singleton.Fov,
16*deltaTime
);
2024-02-21 01:40:53 +08:00
if (_entityOverride is {IsOvering:true} && allowAnimationFOV.Allow)
{
virtualCamera.m_Lens.FieldOfView =
Mathf.Lerp(virtualCamera.m_Lens.FieldOfView,allowAnimationFOV.Value,5*deltaTime);
}
else
{
virtualCamera.m_Lens.FieldOfView = Mathf.Lerp(PlayerConfig.Singleton.Fov, targetFov, Aim);
}
2023-11-02 20:58:55 +08:00
float CalcZoomFOV(float baseFOV, float zoom)
{
return 2.0f * Mathf.Atan(Mathf.Tan(baseFOV / 2.0f) / zoom);
}
}
if (optionalScope.Allow)
{
optionalScope.Value.SetActive(AllowScope);
2023-10-20 19:31:12 +08:00
}
2023-10-29 15:27:13 +08:00
2023-11-15 23:54:54 +08:00
2023-10-20 19:31:12 +08:00
}
2024-02-21 01:40:53 +08:00
public int FindIndex(Func<string, bool> factory)
{
return equips.list.FindIndex(x => factory.Invoke(x.AddressablePath));
}
2023-10-20 19:31:12 +08:00
public bool IsSupportItem(IBasicItem item)=> equips.list.Any(x => x.IsSupportItem(item));
2024-02-21 01:40:53 +08:00
//public void EntryEquip(int index)=> equips.Entry(index);
public void EntryEquip(int index) => _prioritySelector.Set(0, index);
2023-10-20 19:31:12 +08:00
public void EntryEquip(IBasicItem item)
{
2023-11-30 00:23:23 +08:00
CurrentItem = item;
2024-02-21 01:40:53 +08:00
//equips.Entry(x=>x.IsSupportItem(item));
// if (equips.list.TryGetAny(x => x.IsSupportItem(item), out var nextEquip))
// {
// nextEquip.Item = item;
// }
var index = equips.list.FindIndex(x => x.IsSupportItem(item));
_prioritySelector.Set(0, index);
}
public void SetEquipPriority(int priority, IBasicItem item)
{
var index = equips.list.FindIndex(x => x.IsSupportItem(item));
_prioritySelector.Set(priority, index);
}
public void SetEquipPriority(int priority, int index)
{
_prioritySelector.Set(priority, index);
}
public void RemoveEquipPriority(int priority)
{
_prioritySelector.Remove(priority);
}
public void Register(IEquipBase equipBase)
{
equips.list.Add(equipBase);
Entity.Inject(equipBase);
equipBase.Entity = Entity;
equipBase.OnAwake();
foreach (var x in equipBase.As<MonoBehaviour>().GetComponentsInChildren<Transform>())
2023-11-21 18:05:18 +08:00
{
2024-02-21 01:40:53 +08:00
x.gameObject.layer = layer;
}
foreach (var x in equipBase.As<MonoBehaviour>().GetComponentsInChildren<Renderer>())
{
if (x is SkinnedMeshRenderer skinnedMeshRenderer)
{
skinnedMeshRenderer.updateWhenOffscreen = true;
}
x.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
2023-11-21 18:05:18 +08:00
}
2023-10-20 19:31:12 +08:00
}
2024-02-21 01:40:53 +08:00
public void UnRegister(IEquipBase equipBase)
{
equips.list.Remove(equipBase);
}
2023-10-20 19:31:12 +08:00
}
}