Files
Net.Like.Xue.Tokyo/Packages-Local/Com.Project.B.Unity/CharacterController/PlayerFootstepController.cs

106 lines
2.9 KiB
C#
Raw Normal View History

2025-06-24 23:49:13 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
using BITKit;
using BITKit.Pool;
using Net.BITKit.VFX;
using UnityEngine;
namespace Project.B.CharacterController
{
public class PlayerFootstepController:IDisposable
{
private readonly IPoolService _poolService;
private readonly VFXService _vfxService;
private readonly ICharacterController _characterController;
private readonly ITicker _ticker;
private readonly Animator _animator;
private readonly ValidHandle _isBusy = new();
private readonly IntervalUpdate _intervalUpdate = new(0.32f);
private Transform _leftFoot;
private Transform _rightFoot;
private readonly List<string> _tags = new()
{
"footstep"
};
public PlayerFootstepController(ICharacterController characterController, ITicker ticker, VFXService vfxService, IPoolService poolService, Animator animator)
{
_characterController = characterController;
_ticker = ticker;
_vfxService = vfxService;
_poolService = poolService;
_animator = animator;
_ticker.Add(OnTick);
_characterController.OnStateChanged += OnStateChanged;
}
private void OnStateChanged(ICharacterState arg1, ICharacterState arg2)
{
_intervalUpdate.Interval = 1f / arg2 switch
{
ICharacterSprint=>7,
ICharacterStateRun=>5,
_ =>3
};
_intervalUpdate.Reset();
}
private async void OnTick(float obj)
{
if(_isBusy.Allow)return;
if(_intervalUpdate.AllowUpdate is false)return;
using var wait = _isBusy.GetHandle();
if(_characterController.IsGrounded is false)return;
Vector3 planerVelocity = _characterController.Velocity;
planerVelocity.y = 0;
if(planerVelocity.GetLength()<2)return;
var vfx = _vfxService.GetPrefab(_tags).gameObject;
if(!vfx)return;
vfx =await _poolService.Spawn<GameObject>(vfx.name, vfx);
if (!_leftFoot)
{
_leftFoot = _animator.GetBoneTransform(HumanBodyBones.LeftFoot);
}
if (!_rightFoot)
{
_rightFoot = _animator.GetBoneTransform(HumanBodyBones.RightFoot);
}
if (_leftFoot && _rightFoot)
{
vfx.transform.position = _leftFoot.position.y < _rightFoot.position.y ? _leftFoot.position : _rightFoot.position;
}
else
{
vfx.transform.position = _characterController.Position;
}
}
public void Dispose()
{
_ticker.Remove(OnTick);
}
}
}