BITFALL/Assets/Artists/Scripts/Entities/Character/EntityCharacter.cs

210 lines
7.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using BITFALL.Cosmetic;
using BITFALL.Entities.Equipment;
using BITFALL.Player.Movement;
using BITKit.PlayerCamera;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Rendering;
namespace BITKit.Entities.Player.Character
{
public class EntityCharacter : 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> tpvRendererGroup = 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 Renderer[] _tpvRendererGroup;
private readonly ValidHandle allowFPVOverride = new();
public override void OnAwake()
{
base.OnAwake();
if(cosmeticService is not null)
cosmeticService.OnCosmeticsChanged += Rebuild;
}
public override void OnStart()
{
if (_health is not null)
{
_health.OnSetAlive += _ => UpdateMeshState();
_health.OnDamageRelease += OnDamageRelease;
}
if (_cameraService is not null)
_cameraService.OnCameraActivated += _ => UpdateMeshState();
if (_entityOverride is not null)
_entityOverride.OnOverride += _ =>
{
UpdateMeshState();
allowFPVOverride.SetElements(_entityOverride, _);
};
_tpvRendererGroup = tpvRendererGroup.SelectMany(x => x.GetComponentsInChildren<Renderer>(true)).ToArray();
if (_equipment is not null)
{
_equipment.OnEquipAddressable += _ => { allowFPVOverride.RemoveElement(_equipment); };
_equipment.OnUnEquipAddressable += _ => { allowFPVOverride.AddElement(_equipment); };
}
if (_movement is not null)
{
_movement.OnStateChanged += OnNewState;
OnNewState(null, _movement.CurrentState);
void OnNewState(IEntityMovementState oldState, IEntityMovementState newState)
{
allowFPVOverride.SetDisableElements(_movement, newState switch
{
IPlayerEdgeClimbState => false,
IPlayerClimbState => false,
IPlayerVaultState => false,
IPlayerKnockdownState => false,
IPlayerSlideState => false,
IPlayerFixedState => false,
IPlayerLinkState => false,
_ => true,
});
}
}
allowFPVOverride.AddListener(value =>
{
foreach (var x in fpvOverrideRenderers)
{
x.enabled = value;
}
});
// if (_equipment is not null)
// allowFPVOverride.AddElement(_equipment);
Rebuild();
}
public override void OnPlayerInitialized()
{
UpdateMeshState();
}
public override void OnPlayerDispose()
{
SetFPV(false);
}
// private void OnSetHP(int hp)
// {
// UnityEntity.Invoke<string>(Constant.Animation.Play, getDamage.Value);
// }
private void OnDamageRelease(DamageMessage damageMessage)
{
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 _tpvRendererGroup)
{
x.shadowCastingMode =
_entityOverride is not null
? _entityOverride.IsOvering ? ShadowCastingMode.On : shadowMode
: shadowMode;
}
}
[BIT]
private async void Rebuild()
{
await UniTask.Delay(100);
await UniTask.SwitchToMainThread();
if (destroyCancellationToken.IsCancellationRequested) return;
fpvRenderer.Clear();
tpvRenderer.Clear();
fpvOverrideRenderers.Clear();
tpvRendererGroup.Clear();
foreach (var _tag in GetComponentsInChildren<Tag>(true))
{
if (_tag.TryGetComponent<Renderer>(out var _renderer) is false) continue;
var tags = _tag.GetTags();
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);
if (tags.Contains(Player_Mesh_Type_TPV_Group))
tpvRendererGroup.Add(_renderer);
}
UpdateMeshState();
allowFPVOverride.Invoke();
}
}
}