267 lines
9.3 KiB
C#
267 lines
9.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using BITFALL.Cosmetic;
|
|
using BITFALL.Entities.Equipment;
|
|
using BITFALL.HotFix;
|
|
using BITFALL.Player.Movement;
|
|
using BITKit.PlayerCamera;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
using UnityEngine.Animations.Rigging;
|
|
using UnityEngine.Rendering;
|
|
namespace BITKit.Entities.Player.Character
|
|
{
|
|
public class PlayerCharacter : EntityPlayerBehavior
|
|
{
|
|
[DictionaryReferenceConfig(nameof(Player_Mesh_Type_FPV))]
|
|
public const string Player_Mesh_Type_FPV = nameof(Player_Mesh_Type_FPV);
|
|
|
|
[DictionaryReferenceConfig(nameof(Player_Mesh_Type_TPV))]
|
|
public const string Player_Mesh_Type_TPV = nameof(Player_Mesh_Type_TPV);
|
|
|
|
[DictionaryReferenceConfig(nameof(Player_Mesh_Type_FPVOverride))]
|
|
public const string Player_Mesh_Type_FPVOverride = nameof(Player_Mesh_Type_FPVOverride);
|
|
|
|
[DictionaryReferenceConfig(nameof(Player_Mesh_Type_TPV_Group))]
|
|
public const string Player_Mesh_Type_TPV_Group = nameof(Player_Mesh_Type_TPV_Group);
|
|
|
|
private readonly List<Renderer> fpvRenderer = new();
|
|
private readonly List<Renderer> tpvRenderer = new();
|
|
private readonly List<Renderer> fpvOverrideRenderers = new();
|
|
private readonly List<Renderer> tpvOverrideRenderers = new();
|
|
|
|
[Header(Constant.Header.Reference)]
|
|
[SerializeReference, SubclassSelector] public IReference getDamage;
|
|
|
|
[Inject(true)] private ICosmeticService cosmeticService;
|
|
|
|
[Inject(true)] private IHealth _health;
|
|
|
|
[Inject(true)] private IPlayerCameraService _cameraService;
|
|
|
|
[Inject(true)] private IEntityOverride _entityOverride;
|
|
|
|
[Inject(true)] private IEntityEquipment _equipment;
|
|
|
|
[Inject(true)] private IEntityMovement _movement;
|
|
|
|
private readonly ValidHandle allowFPVOverride = new();
|
|
private readonly IntervalUpdate _freezeInterval=new (0.01f);
|
|
private bool _isDirty;
|
|
private bool _lock;
|
|
|
|
private void OnCosmeticsChange()
|
|
{
|
|
_lock = true;
|
|
}
|
|
|
|
public override void OnAwake()
|
|
{
|
|
if (cosmeticService is not null)
|
|
{
|
|
cosmeticService.OnCosmeticsChange += OnCosmeticsChange;
|
|
cosmeticService.OnCosmeticsChanged += OnCosmeticsChanged;
|
|
}
|
|
|
|
if (_health is not null)
|
|
{
|
|
_health.OnSetAlive += SetDirty;
|
|
_health.OnDamageRelease += OnDamageRelease;
|
|
}
|
|
if (_cameraService is not null)
|
|
_cameraService.OnCameraActivated += SetDirty;
|
|
|
|
if (_entityOverride is not null)
|
|
_entityOverride.OnOverride += _ =>
|
|
{
|
|
UpdateMeshState();
|
|
allowFPVOverride.SetElements(_entityOverride, _);
|
|
};
|
|
|
|
|
|
|
|
if (_equipment is not null)
|
|
{
|
|
_equipment.OnEquipAddressable += OnEquipmentOnOnEquipAddressable;
|
|
_equipment.OnUnEquipAddressable += OnEquipmentOnOnUnEquipAddressable;
|
|
|
|
void OnEquipmentOnOnUnEquipAddressable(string _)
|
|
{
|
|
allowFPVOverride.AddElement(_equipment);
|
|
allowFPVOverride.RemoveDisableElements(_equipment);
|
|
}
|
|
void OnEquipmentOnOnEquipAddressable(string _)
|
|
{
|
|
allowFPVOverride.RemoveElement(_equipment);
|
|
allowFPVOverride.AddDisableElements(_equipment);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
if (_movement is not null)
|
|
{
|
|
_movement.OnStateChanged += OnNewState;
|
|
|
|
OnNewState(null, _movement.CurrentState);
|
|
|
|
void OnNewState(IEntityMovementState oldState, IEntityMovementState newState)
|
|
{
|
|
var allow = newState switch
|
|
{
|
|
IPlayerEdgeClimbState => true,
|
|
IPlayerClimbState => true,
|
|
IPlayerVaultState => true,
|
|
IPlayerKnockdownState => true,
|
|
IPlayerSlideState => true,
|
|
IPlayerFixedState => true,
|
|
IPlayerLinkState => true,
|
|
IPlayerCrawlState=>true,
|
|
_ => false,
|
|
};
|
|
allowFPVOverride.SetElements(_movement,allow);
|
|
allowFPVOverride.SetDisableElements(_movement,!allow);
|
|
}
|
|
}
|
|
|
|
allowFPVOverride.AddListener(value =>
|
|
{
|
|
foreach (var x in fpvOverrideRenderers)
|
|
{
|
|
try
|
|
{
|
|
x.enabled = value;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
BIT4Log.LogException(e);
|
|
}
|
|
|
|
}
|
|
});
|
|
}
|
|
|
|
public override void OnDestroyComponent()
|
|
{
|
|
base.OnDestroyComponent();
|
|
if (cosmeticService is null) return;
|
|
cosmeticService.OnCosmeticsChange -= OnCosmeticsChange;
|
|
cosmeticService.OnCosmeticsChanged -= OnCosmeticsChanged;
|
|
}
|
|
|
|
public override void OnUpdate(float deltaTime)
|
|
{
|
|
if (!_isDirty || _lock || !_freezeInterval.AllowUpdateWithoutReset) return;
|
|
_isDirty = false;
|
|
UpdateMeshState();
|
|
}
|
|
|
|
private void OnDamageRelease(DamageMessage damageMessage)
|
|
{
|
|
if (getDamage is not null)
|
|
UnityEntity.Invoke<string>(Constant.Animation.Play, getDamage.Value);
|
|
}
|
|
|
|
private void UpdateMeshState()
|
|
{
|
|
allowFPVOverride.Invoke();
|
|
switch (_health, _cameraService)
|
|
{
|
|
case (null, null):
|
|
SetFPV(false);
|
|
allowFPVOverride.Invoke(false);
|
|
break;
|
|
case (null, not null):
|
|
SetFPV(_cameraService.IsCameraActivated);
|
|
break;
|
|
case (not null, null):
|
|
SetFPV(_health.IsAlive);
|
|
break;
|
|
case (not null, not null):
|
|
SetFPV(_health.IsAlive && _cameraService.IsCameraActivated);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
private void SetFPV(bool isFpv)
|
|
{
|
|
var shadowMode = isFpv ?
|
|
ShadowCastingMode.ShadowsOnly :
|
|
ShadowCastingMode.On;
|
|
foreach (var x in fpvRenderer)
|
|
{
|
|
x.enabled = isFpv;
|
|
}
|
|
foreach (var x in tpvRenderer)
|
|
{
|
|
x.shadowCastingMode = shadowMode;
|
|
}
|
|
foreach (var x in tpvOverrideRenderers)
|
|
{
|
|
x.shadowCastingMode =
|
|
_entityOverride is not null
|
|
? _entityOverride.IsOvering ? ShadowCastingMode.On : shadowMode
|
|
: shadowMode;
|
|
}
|
|
if (_health is not null && TryGetComponent<RigBuilder>(out var rigBuilder))
|
|
{
|
|
rigBuilder.enabled = _health.IsAlive;
|
|
}
|
|
}
|
|
[BIT]
|
|
private void OnCosmeticsChanged()
|
|
{
|
|
_lock = true;
|
|
BITAppForUnity.ThrowIfNotPlaying();
|
|
fpvRenderer.Clear();
|
|
tpvRenderer.Clear();
|
|
fpvOverrideRenderers.Clear();
|
|
tpvOverrideRenderers.Clear();
|
|
|
|
var _tpvOverrideRenderers = new List<Transform>();
|
|
foreach (var _tag in GetComponentsInChildren<Tag>(true))
|
|
{
|
|
var tags = _tag.GetTags();
|
|
if (tags.Contains(Player_Mesh_Type_TPV_Group))
|
|
_tpvOverrideRenderers.Add(_tag.transform);
|
|
if (_tag.TryGetComponent<Renderer>(out var _renderer) is false) continue;
|
|
if (tags.Contains(Player_Mesh_Type_FPV))
|
|
fpvRenderer.Add(_renderer);
|
|
if (tags.Contains(Player_Mesh_Type_TPV))
|
|
tpvRenderer.Add(_renderer);
|
|
if (tags.Contains(Player_Mesh_Type_FPVOverride))
|
|
fpvOverrideRenderers.Add(_renderer);
|
|
}
|
|
|
|
var tpvRenderers = _tpvOverrideRenderers.SelectMany(x => x.GetComponentsInChildren<Renderer>(true));
|
|
tpvOverrideRenderers.Clear();
|
|
tpvOverrideRenderers.AddRange(tpvRenderers);
|
|
UpdateMeshState();
|
|
allowFPVOverride.Invoke();
|
|
_lock = false;
|
|
_isDirty = false;
|
|
|
|
|
|
if (TryGetComponent<RigBuilder>(out var rigBuilder))
|
|
{
|
|
rigBuilder.Clear();
|
|
foreach (var rig in GetComponentsInChildren<Rig>())
|
|
{
|
|
rigBuilder.layers.Add(new RigLayer(rig));
|
|
}
|
|
rigBuilder.enabled = true;
|
|
rigBuilder.Build();
|
|
GetComponent<Animator>().Rebind();
|
|
}
|
|
}
|
|
|
|
private void SetDirty(bool any) => SetDirty();
|
|
private void SetDirty()
|
|
{
|
|
_freezeInterval.Reset();
|
|
_isDirty = true;
|
|
}
|
|
}
|
|
} |