158 lines
7.2 KiB
C#
158 lines
7.2 KiB
C#
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 dashCameraRotation = CalculateDashAngles(inputDirection, 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);
|
||
}
|
||
}
|
||
} |