106 lines
2.9 KiB
C#
106 lines
2.9 KiB
C#
![]() |
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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|