Files
Cielonos/Assets/Scripts/MainGame/Characters/Player/PlayerAnimationSubcontroller.cs
2025-12-22 18:36:29 -05:00

158 lines
7.2 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 dashDirection)
{
player.landMovementSc.TurnToDirection(dashDirection);
Vector3 cameraForward = player.viewSc.playerCamera.transform.forward.Flatten();
Vector3 dashCameraRotation = CalculateDashAngles(dashDirection, 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 dodgeDirection = Vector3.back;
Vector3 cameraForward = player.viewSc.playerCamera.transform.forward.Flatten();
Vector3 dodgeCameraRotation = CalculateDashAngles(dodgeDirection, 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">世界空间的冲刺向量 (如 Vector3.forward)</param>
/// <param name="camForwardNoY">相机的前方 (y被设为0并归一化)</param>
/// <returns>x为Pitch(俯仰), z为Dutch(侧倾)</returns>
public Vector3 CalculateDashAngles(Vector3 dashDir, Vector3 camForwardNoY)
{
// 1. 获取相机的右方
Vector3 camRight = Vector3.Cross(Vector3.up, camForwardNoY);
// 2. 将冲刺方向投影到相机的 前/后 和 左/右 轴上
float forwardDot = Vector3.Dot(dashDir, camForwardNoY); // 1为前-1为后
float rightDot = Vector3.Dot(dashDir, camRight); // 1为右-1为左
// 3. 计算目标侧倾值
float targetDutch = forwardDot * 1f;
// 4. 计算目标俯仰值(注意取反,使得向前冲刺时相机向下俯仰)
float targetPitch = -rightDot * 2.0f;
return new Vector3(targetPitch, 0, targetDutch);
}
}
}