Files
Cielonos/Assets/Scripts/MainGame/Characters/Automata/AI/Actions/PlayFuncAnim.cs
SoulliesOfficial 0902ca8a9e Bezi回来了
2026-04-28 15:46:32 -04:00

150 lines
5.6 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.Collections.Generic;
using Cielonos.MainGame.Characters;
using Cielonos.MainGame.FunctionalAnimation;
using Opsive.BehaviorDesigner.Runtime.Tasks;
using Opsive.BehaviorDesigner.Runtime.Tasks.Actions;
using Opsive.GraphDesigner.Runtime;
using Opsive.GraphDesigner.Runtime.Variables;
using Opsive.Shared.Utility;
using SLSUtilities.FunctionalAnimation;
using UnityEngine;
namespace Cielonos.MainGame.Characters.AI
{
[Description("让角色播放一个功能动画,播放过程中会检测打断情况。")]
[NodeIcon("Assets/Sprites/Icon/Play.png")]
[Category("Cielonos")]
public class PlayFuncAnim : AutomataActionBase
{
protected CharacterBase target;
[Tooltip("是否选择其他目标,默认目标为玩家。")]
public bool isOtherTarget = false;
[Tooltip("如果选择了其他目标,则需要指定目标对象。")]
public SharedVariable<GameObject> targetGameObject;
private AnimationSubcontrollerBase animationSc => self.animationSc;
private FunctionalAnimationSubmodule funcAnimSm;
private RuntimeFuncAnim funcAnim;
private float currentPlayTime => funcAnimSm.currentPlayTime;
private float currentTotalPlayTime => funcAnimSm.currentTotalPlayTime;
[Header("Animation Settings")]
[Tooltip("要播放的功能动画名称。")]
public string animationName;
[Tooltip("是否选择其他功能动画子模块,默认子模块为全身动作子模块。")]
public bool isOtherFuncAnimSm = false;
[Tooltip("如果选择了其他功能动画子模块,则需要指定子模块名称。")]
public string funcAnimSmName = "";
[Tooltip("动画过渡时间,单位秒。")]
public float transitionDuration = 0.1f;
[Tooltip("如果勾选此项当动画被打断返回Success执行下一步否则返回Failure重新执行此步骤。")]
public bool disruptionReturnSuccess = true;
[Tooltip("是否在开始播放动画时转向目标。")]
public bool willTurnToTargetAtStart = true;
[Tooltip("是否在播放过程中持续转向目标。")]
public bool willTurnToTargetDuringPlaying = false;
[Tooltip("是否调整根吸附以贴近目标。")]
public bool willAdjustAdsorption = true;
[Tooltip("是否持续调整根吸附以贴近目标,直到动画结束。")]
public bool willKeepAdjustingAdsorption = false;
[Tooltip("根吸附调整的最小距离。")]
public float adsorptionMinDistance = 2;
[Header("Other Settings")]
[Tooltip("是否记录此动作到动作记录子模块中。")]
public bool willRecordAction = true;
private bool successPlayed = false;
private bool frameBuffer;
public override void OnAwake()
{
base.OnAwake();
funcAnimSm = isOtherFuncAnimSm ? null : animationSc.fullBodyFuncAnimSm;
target = isOtherTarget ? targetGameObject.Value.GetComponent<CharacterBase>() : MainGameManager.Player;
}
public override void OnStart()
{
successPlayed = funcAnimSm.Play(animationName);
frameBuffer = false;
if (successPlayed)
{
funcAnim = funcAnimSm.currentRuntimeFuncAnim;
if (willTurnToTargetAtStart)
{
self.movementSc.SmartTurnToTarget(target);
}
if (willAdjustAdsorption)
{
if (!willKeepAdjustingAdsorption)
{
funcAnim.AddUpdateUntilEvent(new SetRootAdsorptionAdjustment.Once(target, adsorptionMinDistance));
}
else
{
funcAnim.AddUpdateEvent(new SetRootAdsorptionAdjustment.Keep(target, adsorptionMinDistance));
}
}
if (willRecordAction)
{
self.actionRecordSm.AddRecord(animationName);
}
}
}
public override TaskStatus OnUpdate()
{
if (!successPlayed)
{
if (!frameBuffer)
{
frameBuffer = true;
return TaskStatus.Running;
}
else
{
return TaskStatus.Failure;
}
}
if (funcAnimSm.currentRuntimeFuncAnim == funcAnim && funcAnimSm.CheckDisruption(DisruptionType.NormalAction))
{
if (!frameBuffer)
{
frameBuffer = true;
return TaskStatus.Running;
}
else
{
return TaskStatus.Success;
}
}
if (funcAnim.isDisrupted || funcAnimSm.currentRuntimeFuncAnim != funcAnim)
{
//if (self.isDuringGetHit) return TaskStatus.Running;
if (!frameBuffer)
{
frameBuffer = true;
return TaskStatus.Running;
}
else
{
return disruptionReturnSuccess ? TaskStatus.Success : TaskStatus.Failure;
}
}
if (willTurnToTargetDuringPlaying)
{
self.movementSc.TurnToTargetByAngle(target, 360f);
}
return TaskStatus.Running;
}
}
}