Files
Cielonos/Assets/Scripts/MainGame/Characters/Player/PlayerAnimationSubcontroller.cs
SoulliesOfficial 33b1795c1f 更新
2026-01-03 18:19:39 -05:00

171 lines
7.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Linq;
using Cielonos.UI;
using FIMSpace.FProceduralAnimation;
using MoreMountains.FeedbacksForThirdParty;
using RootMotion.FinalIK;
using SLSFramework.General;
using SLSUtilities.FunctionalAnimation;
using UnityEngine;
using UnityEngine.InputSystem;
namespace Cielonos.MainGame.Characters
{
public partial class PlayerAnimationSubcontroller : AnimationSubcontrollerBase, IPlayerSubcontroller
{
public Player player => owner as Player;
public AnimatorOverrideController animatorOverride;
public LegsAnimator legsAnimator;
public override void Initialize()
{
base.Initialize();
player.operationSc.OnDash += delegate(Vector3 inputDirection)
{
Vector3 cameraForward = player.viewSc.playerCamera.transform.forward.Flatten();
player.landMovementSc.TurnToDirection(inputDirection);
Vector3 playerForward = player.transform.forward.Flatten();
Vector3 dashCameraRotation = CalculateDashAngles(playerForward, cameraForward);
player.feedbackSc["Dash"].feedback.GetFeedbackOfType<MMF_CinemachineRotation>().RotationAmplitude = dashCameraRotation;
player.feedbackSc["Dash"].feedback.GetFeedbackOfType<MMF_RadialBlur>().TargetCenter = player.GetNormalizedScreenPosition();
fullBodyFuncAnimSm.Play("Dash");
};
player.operationSc.OnDodge += delegate
{
Vector3 playerBackward = -player.transform.forward.Flatten();
Vector3 cameraForward = player.viewSc.playerCamera.transform.forward.Flatten();
Vector3 dodgeCameraRotation = CalculateDashAngles(playerBackward, cameraForward);
player.feedbackSc["Dodge"].feedback.GetFeedbackOfType<MMF_CinemachineRotation>().RotationAmplitude = dodgeCameraRotation;
player.feedbackSc["Dodge"].feedback.GetFeedbackOfType<MMF_RadialBlur>().TargetCenter = player.GetNormalizedScreenPosition();
fullBodyFuncAnimSm.Play("Dodge");
};
}
protected override void Update()
{
base.Update();
player.inputSc.preinputSubmodule.Update(isDuringPreinput, isAtActionDisruption);
}
protected override void LateUpdate()
{
base.LateUpdate();
}
public override void RegisterDefaultFunctions()
{
base.RegisterDefaultFunctions();
registeredFunctions.Add("DashStart", anim =>
{
player.landMovementSc.isDashing = true;
player.landMovementSc.dashMoveMultiplier = anim.funcAnimData.variableCollection.GetVariable<float>("DashMoveMultiplier");
player.selfTimeSm.ModifyTimeScale(0.1f, 1.25f);
player.audioSc.PlayDashSound();
player.feedbackSc["Dash"]?.Play();
//player.renderSc.dashTrails.ForEach(ds => ds.active = true);
//player.renderSc.dashTrails.ForEach(ds => ds.Restart());
DodgeSource defaultDodge = new DodgeSource(owner, null, "DefaultDodge", 0, "NormalDodge", "PerfectDodge", Mathf.Infinity, 0.2f);
defaultDodge.onPerfectDodge = () =>
{
player.feedbackSc["PerfectDodge"].feedback.GetFeedbackOfType<MMF_RadialBlur>().TargetCenter = player.GetNormalizedScreenPosition();
player.feedbackSc["PerfectDodge"].feedback.GetFeedbackOfType<MMF_AdvancedVignette>().Center = player.GetNormalizedScreenPosition();
};
player.reactionSc.dodgeSm.ApplyDodge(defaultDodge);
});
registeredFunctions.Add("DashEnd", anim =>
{
player.landMovementSc.isDashing = false;
player.landMovementSc.dashMoveMultiplier = 1;
player.landMovementSc.isSprinting = true;
//player.renderSc.dashTrails.ForEach(ds => ds.active = false);
player.reactionSc.dodgeSm.RemoveDodge("DefaultDodge");
});
registeredFunctions.Add("DodgeStart", anim =>
{
player.landMovementSc.isDashing = true;
player.landMovementSc.dashMoveMultiplier = anim.funcAnimData.variableCollection.GetVariable<float>("DashMoveMultiplier");
player.audioSc.PlayDashSound();
player.feedbackSc["Dodge"]?.Play();
//player.renderSc.dashTrails.ForEach(ds => ds.active = true);
//player.renderSc.dashTrails.ForEach(ds => ds.Restart());
DodgeSource defaultDodge = new DodgeSource(owner, null, "DefaultDodge", 0, "NormalDodge", "PerfectDodge", Mathf.Infinity, 0.2f);
defaultDodge.onPerfectDodge = () =>
{
player.feedbackSc["PerfectDodge"].feedback.GetFeedbackOfType<MMF_RadialBlur>().TargetCenter = player.GetNormalizedScreenPosition();
player.feedbackSc["PerfectDodge"].feedback.GetFeedbackOfType<MMF_AdvancedVignette>().Center = player.GetNormalizedScreenPosition();
};
player.reactionSc.dodgeSm.ApplyDodge(defaultDodge);
});
registeredFunctions.Add("DodgeEnd", anim =>
{
player.landMovementSc.isDashing = false;
player.landMovementSc.dashMoveMultiplier = 1;
//player.renderSc.dashTrails.ForEach(ds => ds.active = false);
player.reactionSc.dodgeSm.RemoveDodge("DefaultDodge");
});
}
}
public partial class PlayerAnimationSubcontroller
{
public bool isDuringPreinput;
public bool isAtActionDisruption;
protected override void UpdateIntervalInfo()
{
base.UpdateIntervalInfo();
isDuringPreinput = currentIntervals.Any(interval => interval.intervalType == IntervalType.Preinput);
isAtActionDisruption = lastFrameIntervals.SwitchOut(currentIntervals, (interval) => interval.intervalType == IntervalType.Preinput);
}
}
public partial class PlayerAnimationSubcontroller
{
/// <summary>
/// 计算冲刺时的摄像机倾斜角度
/// </summary>
/// <param name="dashDir">冲刺输入的平整化方向 (y=0, normalized)</param>
/// <param name="camFwd">摄像机的平整化前方 (y=0, normalized)</param>
/// <returns>Vector3(Pitch角度, 0, Roll角度)</returns>
public Vector3 CalculateDashAngles(Vector3 dashDir, Vector3 camFwd)
{
// 1. 确保输入向量是归一化的(以防万一)
Vector3 d = dashDir.normalized;
Vector3 f = camFwd.normalized;
// 2. 通过叉乘获取摄像机的水平右方向 (camRight)
// 在左手坐标系UnityUp x Forward = Right
Vector3 r = Vector3.Cross(Vector3.up, f);
// 3. 计算投影权重 (范围在 -1 到 1 之间)
// forwardWeight: 1表示完全同向-1表示完全反向
float forwardWeight = Vector3.Dot(d, f);
// sideWeight: 1表示向右冲-1表示向左冲
float sideWeight = Vector3.Dot(d, r);
// 4. 定义倾斜强度系数 (控制在 1.5度 左右)
const float tiltIntensity = 1.5f;
// 5. 计算最终角度
// x 轴旋转 (Pitch):正值向下倾斜(向前冲),负值向上倾斜(向后退)
float pitch = forwardWeight * tiltIntensity;
// z 轴旋转 (Dutch/Roll)
// 注意:向右冲时(sideWeight=1),通常相机向左倾斜(z为负值)更有动感
float roll = -sideWeight * tiltIntensity;
return new Vector3(pitch, 0, roll);
}
}
}