Хуже, чем были раньше, но лучше, чем ничего. Плавность переходов имеется, и на том спасибо
78 lines
2.3 KiB
C#
78 lines
2.3 KiB
C#
using UnityEngine;
|
|
|
|
namespace Code.Gameplay.Character.Controller.Abilities
|
|
{
|
|
public class WallLeanMechanic
|
|
{
|
|
private readonly float _leanAngle;
|
|
private readonly float _threshold;
|
|
private readonly float _smoothSpeed;
|
|
|
|
private Transform _model;
|
|
|
|
public WallLeanMechanic(
|
|
float leanAngle,
|
|
float threshold,
|
|
float smoothSpeed)
|
|
{
|
|
_leanAngle = leanAngle;
|
|
_threshold = threshold;
|
|
_smoothSpeed = smoothSpeed;
|
|
}
|
|
|
|
public void SetModel(Transform model) => _model = model;
|
|
|
|
public void Update(bool isWallRunning, Vector3 wallNormal, Vector3 characterForward)
|
|
{
|
|
if (!_model)
|
|
{
|
|
_model.localRotation = Quaternion.identity;
|
|
return;
|
|
}
|
|
|
|
var targetRotation = Quaternion.identity;
|
|
|
|
if (isWallRunning)
|
|
{
|
|
var n = new Vector3(wallNormal.x, 0f, wallNormal.z).normalized;
|
|
if (n.sqrMagnitude < 0.001f) n = Vector3.forward;
|
|
|
|
var bodyRight = Vector3.Cross(Vector3.up, characterForward).normalized;
|
|
var side = Vector3.Dot(n, bodyRight);
|
|
var front = Vector3.Dot(n, characterForward);
|
|
|
|
var axis = Vector3.right;
|
|
var angle = 0f;
|
|
|
|
if (side > _threshold)
|
|
{
|
|
axis = Vector3.forward;
|
|
angle = -_leanAngle;
|
|
}
|
|
else if (side < -_threshold)
|
|
{
|
|
axis = Vector3.forward;
|
|
angle = _leanAngle;
|
|
}
|
|
else if (front > _threshold)
|
|
{
|
|
axis = Vector3.right;
|
|
angle = -_leanAngle;
|
|
}
|
|
else if (front < -_threshold)
|
|
{
|
|
axis = Vector3.right;
|
|
angle = _leanAngle;
|
|
}
|
|
|
|
targetRotation = Quaternion.AngleAxis(angle, axis);
|
|
}
|
|
|
|
_model.localRotation = Quaternion.Slerp(
|
|
_model.localRotation,
|
|
targetRotation,
|
|
1f - Mathf.Exp(-_smoothSpeed * Time.deltaTime)
|
|
);
|
|
}
|
|
}
|
|
} |