226 lines
8.6 KiB
C#
226 lines
8.6 KiB
C#
![]() |
using System;
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
using System.Runtime.Remoting;
|
||
|
using BITKit;
|
||
|
using BITKit.Entities;
|
||
|
using BITKit.Pool;
|
||
|
using Cysharp.Threading.Tasks;
|
||
|
using Net.Project.B.Health;
|
||
|
using Net.Project.B.Inventory;
|
||
|
using Net.Project.B.Weapon;
|
||
|
using NodeCanvas.Framework;
|
||
|
using Project.B.Item;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.Rendering;
|
||
|
|
||
|
namespace Project.B.CharacterController
|
||
|
{
|
||
|
public class PlayerModelController:IDisposable
|
||
|
{
|
||
|
private readonly IEntitiesService _entitiesService;
|
||
|
|
||
|
private readonly Animator _animator;
|
||
|
private readonly IPlayerInventory _playerInventory;
|
||
|
private readonly IPlayerWeaponInventory _weaponInventory;
|
||
|
private readonly IPlayerCharacterController _playerCharacterController;
|
||
|
private readonly IHealthService _healthService;
|
||
|
private readonly IBlackboard _blackboard;
|
||
|
private readonly IEntity _entity;
|
||
|
private readonly GameObject _gameObject;
|
||
|
private readonly IPoolService _poolService;
|
||
|
|
||
|
|
||
|
private readonly IFixedTicker _fixedTicker;
|
||
|
|
||
|
private readonly ValidHandle _allowArm = new();
|
||
|
private readonly ValidHandle _allowModel = new();
|
||
|
|
||
|
private readonly Renderer[] _armMeshes;
|
||
|
|
||
|
private Vector3 _savedVelocity;
|
||
|
|
||
|
private readonly GameObject _parachuteModel;
|
||
|
|
||
|
private readonly Dictionary<int, ScriptableItem> _items;
|
||
|
|
||
|
private GameObject PlayerModel =>_blackboard.GetVariable<GameObject>("player_model").value;
|
||
|
|
||
|
|
||
|
public PlayerModelController(IBlackboard blackboard, IHealthService healthService, IEntity entity, IPlayerCharacterController playerCharacterController, IPlayerWeaponInventory weaponInventory, IPoolService poolService, GameObject gameObject, IFixedTicker fixedTicker, Animator animator, IPlayerInventory playerInventory, IEntitiesService entitiesService)
|
||
|
{
|
||
|
_blackboard = blackboard;
|
||
|
_healthService = healthService;
|
||
|
_entity = entity;
|
||
|
_playerCharacterController = playerCharacterController;
|
||
|
_weaponInventory = weaponInventory;
|
||
|
_poolService = poolService;
|
||
|
_gameObject = gameObject;
|
||
|
_fixedTicker = fixedTicker;
|
||
|
_animator = animator;
|
||
|
_playerInventory = playerInventory;
|
||
|
_entitiesService = entitiesService;
|
||
|
|
||
|
playerCharacterController.AllowTpsCamera.AddListener(OnToggleTPSCamera);
|
||
|
OnToggleTPSCamera(playerCharacterController.AllowTpsCamera.Allow);
|
||
|
|
||
|
|
||
|
|
||
|
_parachuteModel = _blackboard.GetVariable<GameObject>("model_parachute")?.value;
|
||
|
|
||
|
_armMeshes = _blackboard.GetVariable<List<Renderer>>("player_arm_model").value.ToArray();
|
||
|
|
||
|
_allowArm.AddListener(x =>
|
||
|
{
|
||
|
foreach (var renderer in _armMeshes)
|
||
|
{
|
||
|
renderer.enabled = x;
|
||
|
}
|
||
|
});
|
||
|
_allowModel.AddListener(PlayerModel.SetActive);
|
||
|
|
||
|
_allowModel.Invoke();
|
||
|
|
||
|
_fixedTicker.Add(OnTick);
|
||
|
|
||
|
_healthService.OnHealthChanged += OnHealthChanged;
|
||
|
|
||
|
_playerCharacterController.CharacterController.OnStateChanged += OnStateChanged;
|
||
|
|
||
|
_playerCharacterController.DisableModel.AddListener(x=>_allowModel.SetDisableElements(1651,x));
|
||
|
|
||
|
_weaponInventory.StateMachine.OnStateChanged += OnWeaponChanged;
|
||
|
|
||
|
OnStateChanged(null, playerCharacterController.CharacterController.CurrentState);
|
||
|
|
||
|
_items = _entitiesService.QueryComponents<ScriptableItem>().ToArray().ToDictionary(x => x.Id, x => x);
|
||
|
}
|
||
|
|
||
|
private void OnWeaponChanged(IPlayerWeaponController arg1, IPlayerWeaponController arg2)
|
||
|
{
|
||
|
_allowArm.SetElements(_weaponInventory,arg2 is not null);
|
||
|
|
||
|
var disable = false;
|
||
|
|
||
|
if (arg2 is not null && _playerInventory.Container is RuntimeItemContainer runtimeItemContainer && runtimeItemContainer.Items.TryGetValue(arg2.Identifier,out var item))
|
||
|
{
|
||
|
if (_items.TryGetValue(item.ScriptableId, out var scriptableItem))
|
||
|
{
|
||
|
if (scriptableItem.ControllerClass is PlayerHandheldControllerClass)
|
||
|
{
|
||
|
disable = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_allowArm.SetDisableElements(1231123,disable);
|
||
|
}
|
||
|
|
||
|
private void OnTick(float obj)
|
||
|
{
|
||
|
if (_playerCharacterController.CharacterController.CurrentState is not null)
|
||
|
{
|
||
|
_savedVelocity = _playerCharacterController.CharacterController.Velocity;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnStateChanged(ICharacterState arg1, ICharacterState arg2)
|
||
|
{
|
||
|
var hidePlayer = arg2 is ICharacterSeating { SeatNode: { HidePlayer: true } };
|
||
|
_allowModel.SetDisableElements(6415651568,hidePlayer);
|
||
|
_allowArm.SetDisableElements(6415651568,hidePlayer);
|
||
|
|
||
|
|
||
|
_allowModel.SetElements(_playerCharacterController, arg2 is not null);
|
||
|
|
||
|
if(_parachuteModel)
|
||
|
_parachuteModel.SetActive(arg2 is ICharacterParachute);
|
||
|
|
||
|
if (_weaponInventory.StateMachine.CurrentState is null)
|
||
|
_allowArm.SetElements(this, arg2 switch
|
||
|
{
|
||
|
ICharacterStateStepUp=>false,
|
||
|
ICharacterStateCrouched => false,
|
||
|
ICharacterKnocked => false,
|
||
|
_ => true,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
private async void OnHealthChanged(int arg1, int arg2, int arg3, object arg4)
|
||
|
{
|
||
|
if(arg1!=_entity.Id)return;
|
||
|
|
||
|
_allowModel.SetDisableElements(_healthService,arg3<0);
|
||
|
|
||
|
var _hipsGameObject = _animator.GetBoneTransform(HumanBodyBones.Hips).gameObject;
|
||
|
|
||
|
if (arg3 >= 0)
|
||
|
{
|
||
|
_hipsGameObject.gameObject.SetActive(true);
|
||
|
|
||
|
_blackboard.RemoveVariable("player_ragdoll");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_hipsGameObject.gameObject.SetActive(false);
|
||
|
|
||
|
var myRenderer = PlayerModel.GetComponentsInChildren<Renderer>(true).ToDictionary(x => x.name, x=>x);
|
||
|
|
||
|
var ragdoll =await _poolService.Spawn<GameObject>("player_ragdoll");
|
||
|
|
||
|
ragdoll.transform.SetPositionAndRotation(_gameObject.transform.position,
|
||
|
_gameObject.transform.rotation);
|
||
|
|
||
|
var ragdollTransforms = ragdoll.GetComponentsInChildren<Transform>().ToDictionary(x => x.name, x => x);
|
||
|
foreach (var (name, sourceTransform) in _hipsGameObject.GetComponentsInChildren<Transform>()
|
||
|
.ToDictionary(x => x.name, x => x))
|
||
|
{
|
||
|
if (ragdollTransforms.TryGetValue(name, out var targetTransform))
|
||
|
{
|
||
|
targetTransform.position = sourceTransform.position;
|
||
|
targetTransform.rotation = sourceTransform.rotation;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var ragdollRenderer = ragdoll.GetComponentsInChildren<Renderer>().ToDictionary(x => x.name, x=>x);
|
||
|
|
||
|
foreach (var (name,myMeshRenderer) in myRenderer)
|
||
|
{
|
||
|
if (ragdollRenderer.TryGetValue(name, out var ragdollMeshRenderer))
|
||
|
{
|
||
|
ragdollMeshRenderer.material = myMeshRenderer.material;
|
||
|
}
|
||
|
}
|
||
|
_blackboard.SetVariableValue("player_ragdoll", ragdoll);
|
||
|
await UniTask.NextFrame();
|
||
|
if(!ragdoll)return;
|
||
|
if (ragdoll.TryGetComponent<Rigidbody>(out var ragdollRigidbody) && ragdollRigidbody is {isKinematic:false})
|
||
|
{
|
||
|
ragdollRigidbody.velocity = _savedVelocity;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
private void OnToggleTPSCamera(bool obj)
|
||
|
{
|
||
|
foreach (var x in _blackboard.GetVariable<List<Renderer>>("fps_model").GetValue())
|
||
|
{
|
||
|
x.enabled = !obj;
|
||
|
}
|
||
|
foreach (var x in _blackboard.GetVariable<List<Renderer>>("tps_model").GetValue())
|
||
|
{
|
||
|
x.shadowCastingMode = obj ? ShadowCastingMode.On : ShadowCastingMode.ShadowsOnly;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void Dispose()
|
||
|
{
|
||
|
_healthService.OnHealthChanged -= OnHealthChanged;
|
||
|
_fixedTicker.Remove(OnTick);
|
||
|
}
|
||
|
}
|
||
|
}
|