@ -5,13 +5,24 @@ ClearInvalidTags=False
|
|||||||
AllowEditorTagUnloading=True
|
AllowEditorTagUnloading=True
|
||||||
AllowGameTagUnloading=False
|
AllowGameTagUnloading=False
|
||||||
FastReplication=False
|
FastReplication=False
|
||||||
|
bDynamicReplication=False
|
||||||
InvalidTagCharacters="\"\',"
|
InvalidTagCharacters="\"\',"
|
||||||
NumBitsForContainerSize=6
|
NumBitsForContainerSize=6
|
||||||
NetIndexFirstBitSegment=16
|
NetIndexFirstBitSegment=16
|
||||||
+GameplayTagList=(Tag="Ability.Block.UltimatePlaying",DevComment="大招正在释放中")
|
+GameplayTagList=(Tag="Ability.Block.UltimatePlaying",DevComment="大招正在释放中")
|
||||||
|
+GameplayTagList=(Tag="Ability.Common",DevComment="通用技能")
|
||||||
|
+GameplayTagList=(Tag="Ability.Common.Move",DevComment="移动技能")
|
||||||
+GameplayTagList=(Tag="Ability.Flags.Cooldown",DevComment="技能冷却")
|
+GameplayTagList=(Tag="Ability.Flags.Cooldown",DevComment="技能冷却")
|
||||||
+GameplayTagList=(Tag="Ability.Flags.Recast",DevComment="可以再次释放技能的标记")
|
+GameplayTagList=(Tag="Ability.Flags.Recast",DevComment="可以再次释放技能的标记")
|
||||||
+GameplayTagList=(Tag="Ability.Fox",DevComment="狐狸技能标签")
|
+GameplayTagList=(Tag="Ability.Fox",DevComment="狐狸技能标签")
|
||||||
|
+GameplayTagList=(Tag="Ability.Fox.CastTag",DevComment="可以释放技能的标签")
|
||||||
|
+GameplayTagList=(Tag="Ability.Fox.CastTag.Ultimate1",DevComment="可以使用大招第一阶段")
|
||||||
|
+GameplayTagList=(Tag="Ability.Fox.CastTag.Ultimate2",DevComment="可以使用二阶大招")
|
||||||
|
+GameplayTagList=(Tag="Ability.Fox.CastTag.Ultimate3",DevComment="可以使用第三阶段大招")
|
||||||
|
+GameplayTagList=(Tag="Ability.Fox.StateTag",DevComment="状态标签")
|
||||||
|
+GameplayTagList=(Tag="Ability.Fox.StateTag.Ultimate1",DevComment="正在使用第一阶段大招")
|
||||||
|
+GameplayTagList=(Tag="Ability.Fox.StateTag.Ultimate2",DevComment="正在使用第二阶段大招")
|
||||||
|
+GameplayTagList=(Tag="Ability.Fox.StateTag.Ultimate3",DevComment="正在使用第三阶段大招")
|
||||||
+GameplayTagList=(Tag="Ability.Fox.UltimateStage1",DevComment="一阶大招")
|
+GameplayTagList=(Tag="Ability.Fox.UltimateStage1",DevComment="一阶大招")
|
||||||
+GameplayTagList=(Tag="Ability.Fox.UltimateStage2",DevComment="二阶大招就绪标签")
|
+GameplayTagList=(Tag="Ability.Fox.UltimateStage2",DevComment="二阶大招就绪标签")
|
||||||
+GameplayTagList=(Tag="Ability.Fox.UltimateStage3",DevComment="三阶大招就绪")
|
+GameplayTagList=(Tag="Ability.Fox.UltimateStage3",DevComment="三阶大招就绪")
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/Gas/Ability/Role/Common/GA_MoveAbility.uasset
Normal file
BIN
Content/Gas/Ability/Role/Common/GA_MoveAbility.uasset
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
44
Script/BusyRabbit-CSharp.code-workspace
Normal file
44
Script/BusyRabbit-CSharp.code-workspace
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"name": "BusyRabbit-CSharp",
|
||||||
|
"path": "./ManagedBusyRabbit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ProjectGlue (Generated)",
|
||||||
|
"path": "./BusyRabbit.Glue"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"files.exclude": {
|
||||||
|
"**/bin": true,
|
||||||
|
"**/obj": true,
|
||||||
|
"**/.vs": true,
|
||||||
|
},
|
||||||
|
"search.exclude": {
|
||||||
|
"**/bin": true,
|
||||||
|
"**/obj": true
|
||||||
|
},
|
||||||
|
"dotnet.defaultSolution": "Script/${workspaceFolderBasename}.sln",
|
||||||
|
"omnisharp.enableRoslynAnalyzers": true,
|
||||||
|
"omnisharp.enableEditorConfigSupport": true,
|
||||||
|
"csharp.suppressDotnetRestoreNotification": false
|
||||||
|
},
|
||||||
|
"extensions": {
|
||||||
|
"recommendations": [
|
||||||
|
"ms-dotnettools.csharp",
|
||||||
|
"ms-dotnettools.csdevkit"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"launch": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Attach to Unreal Editor",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "attach",
|
||||||
|
"processName": "UnrealEditor.exe"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
7
Script/BusyRabbit.Glue/AssetTypes.cs
Normal file
7
Script/BusyRabbit.Glue/AssetTypes.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
using UnrealSharp.CoreUObject;
|
||||||
|
|
||||||
|
public static class AssetTypes
|
||||||
|
{
|
||||||
|
public static readonly FPrimaryAssetType Map = new("Map");
|
||||||
|
public static readonly FPrimaryAssetType PrimaryAssetLabel = new("PrimaryAssetLabel");
|
||||||
|
}
|
||||||
@ -1 +1,26 @@
|
|||||||
|
using UnrealSharp.Engine;
|
||||||
|
using UnrealSharp.Attributes;
|
||||||
|
using UnrealSharp.BusyRabbit;
|
||||||
|
using UnrealSharp.GameplayAbilities;
|
||||||
|
using UnrealSharp.CoreUObject;
|
||||||
|
|
||||||
|
namespace GameAbilitySystem.Ability.Common;
|
||||||
// 角色移动
|
// 角色移动
|
||||||
|
|
||||||
|
[UClass]
|
||||||
|
public class UMoveAbility : UBusyGameAbility
|
||||||
|
{
|
||||||
|
protected override void ActivateAbilityFromEvent(FGameplayEventData eventData)
|
||||||
|
{
|
||||||
|
base.ActivateAbilityFromEvent(eventData);
|
||||||
|
if (UGameplayStatics.GetPlayerController(0) is ALevelPlayerController pc)
|
||||||
|
{
|
||||||
|
pc.GetCursorPosition(out FVector2D position);
|
||||||
|
if (eventData.Instigator is ABusyPawnBase pawn)
|
||||||
|
{
|
||||||
|
pawn.MovementComponent.MoveTo(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EndAbility();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,12 +1,314 @@
|
|||||||
// local GameplayStatics = import("GameplayStatics")
|
using Level.Role;
|
||||||
// local AbilitySystemBlueprintLibrary = import("AbilitySystemBlueprintLibrary")
|
using UnrealSharp;
|
||||||
// local BusyGameplayLibrary = import("BusyGameplayLibrary")
|
using UnrealSharp.Attributes;
|
||||||
|
using UnrealSharp.BusyRabbit;
|
||||||
|
using UnrealSharp.CoreUObject;
|
||||||
|
using UnrealSharp.Engine;
|
||||||
|
using UnrealSharp.GameplayAbilities;
|
||||||
|
using UnrealSharp.GameplayTags;
|
||||||
|
using UnrealSharp.SpinePlugin;
|
||||||
|
|
||||||
// --- @class FoxUltimate
|
namespace GameAbilitySystem.Ability.Role.Fox;
|
||||||
// --- @field RecastWindow number
|
|
||||||
// local FoxUltimate = {}
|
|
||||||
|
|
||||||
|
|
||||||
|
[UClass]
|
||||||
|
public class UFoxUltimate : UBusyGameAbility
|
||||||
|
{
|
||||||
|
protected bool bIsEventBinded = false;
|
||||||
|
protected ABusyFoxRole? Owner = null;
|
||||||
|
protected UFoxUltimateDataAsset? FoxData = null;
|
||||||
|
protected UBusyAbilitySystemComponent? ASC = null;
|
||||||
|
protected FActiveGameplayEffectHandle CastStateHandle;
|
||||||
|
protected FActiveGameplayEffectHandle SkillStateHandle;
|
||||||
|
|
||||||
|
protected FActiveGameplayEffectHandle AccelerateHandle; // 大招移动速度增加的Effect
|
||||||
|
protected FActiveGameplayEffectHandle SprintHandle; // 大招三阶移速再次增加的Effect
|
||||||
|
|
||||||
|
[UFunction()]
|
||||||
|
protected void OnGamePlayTagAddOrRemove(FGameplayTag tag, int isAdd)
|
||||||
|
{
|
||||||
|
if (isAdd == 0 && !IsActive)
|
||||||
|
{
|
||||||
|
CommitAbilityCooldown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化技能依赖的属性
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>false->初始化失败</returns>
|
||||||
|
protected bool InitAbilityOnce()
|
||||||
|
{
|
||||||
|
Owner = OwningActorFromActorInfo as ABusyFoxRole;
|
||||||
|
if (Owner == null) return false;
|
||||||
|
|
||||||
|
FoxData = Data as UFoxUltimateDataAsset;
|
||||||
|
|
||||||
|
ASC = AbilitySystemLibrary.GetAbilitySystemComponent(Owner) as UBusyAbilitySystemComponent;
|
||||||
|
if (FoxData == null || ASC == null) return false;
|
||||||
|
|
||||||
|
PrintString("asdafdasdf");
|
||||||
|
|
||||||
|
|
||||||
|
if (bIsEventBinded) return true;
|
||||||
|
TDelegate<GameplayTagAddOrRemoveDelegate> Delegate = new TDelegate<GameplayTagAddOrRemoveDelegate>();
|
||||||
|
Delegate.BindUFunction(this, "OnGamePlayTagAddOrRemove");
|
||||||
|
Owner.BindGameplayTagAddOrRemove(FoxData.SecondStageCastTag, Delegate);
|
||||||
|
Owner.BindGameplayTagAddOrRemove(FoxData.LastStageCastTag, Delegate);
|
||||||
|
bIsEventBinded = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前大招的阶段
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected int GetCurrentAbilityStage()
|
||||||
|
{
|
||||||
|
if (ASC == null || FoxData == null) return 0;
|
||||||
|
if (ASC.HasMatchingGameplayTag(FoxData.LastStageCastTag))
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
if (ASC.HasMatchingGameplayTag(FoxData.SecondStageCastTag))
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else if (ASC.HasMatchingGameplayTag(FoxData.FirstStageCastTag))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ActivateAbilityFromEvent(FGameplayEventData eventData)
|
||||||
|
{
|
||||||
|
base.ActivateAbilityFromEvent(eventData);
|
||||||
|
if (!InitAbilityOnce())
|
||||||
|
{
|
||||||
|
EndAbility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Owner == null || !CommitAbilityCost(Owner))
|
||||||
|
{
|
||||||
|
EndAbility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int stage = GetCurrentAbilityStage();
|
||||||
|
if (stage != 0)
|
||||||
|
{
|
||||||
|
TriggerAbility(stage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EndAbility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当被授予技能时,立刻获得可释放第一段大招的常驻Tag
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actorInfo"></param>
|
||||||
|
/// <param name="spec"></param>
|
||||||
|
public override void OnGiveAbility(FGameplayAbilityActorInfo actorInfo, FGameplayAbilitySpec spec)
|
||||||
|
{
|
||||||
|
base.OnGiveAbility(actorInfo, spec);
|
||||||
|
InitAbilityOnce();
|
||||||
|
|
||||||
|
if (FoxData == null || ASC == null) return;
|
||||||
|
|
||||||
|
UBusyGameplayEffectSubSystem EffectSubSystem = GetGameInstanceSubsystem<UBusyGameplayEffectSubSystem>();
|
||||||
|
if (EffectSubSystem == null) return;
|
||||||
|
|
||||||
|
|
||||||
|
UGameplayEffect effect = EffectSubSystem.GetTagGrantEffectWithDuration(
|
||||||
|
new FGameplayTagContainer(FoxData.FirstStageCastTag),
|
||||||
|
new FGameplayTagContainer(), 0
|
||||||
|
);
|
||||||
|
|
||||||
|
FGameplayEffectSpecHandle handle = UBusyAscLibrary.MakeGameplayEffectSpecHandle(ASC, effect, 1);
|
||||||
|
ASC.ApplyGameplayEffectSpecToSelf(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected bool ApplayCastEffect(FGameplayTag CastTag)
|
||||||
|
{
|
||||||
|
UBusyGameplayEffectSubSystem EffectSubSystem = GetGameInstanceSubsystem<UBusyGameplayEffectSubSystem>();
|
||||||
|
if (ASC == null || EffectSubSystem == null || FoxData == null) return false;
|
||||||
|
|
||||||
|
ASC.RemoveActiveGameplayEffect(CastStateHandle);
|
||||||
|
|
||||||
|
if (CastTag.IsValid)
|
||||||
|
{
|
||||||
|
UGameplayEffect cast_effect = EffectSubSystem.GetTagGrantEffectWithDuration(
|
||||||
|
new FGameplayTagContainer(CastTag),
|
||||||
|
new FGameplayTagContainer(), FoxData.RecastWindow
|
||||||
|
);
|
||||||
|
FGameplayEffectSpecHandle CastSpecHandle = UBusyAscLibrary.MakeGameplayEffectSpecHandle(ASC, cast_effect, 1);
|
||||||
|
CastStateHandle = ASC.ApplyGameplayEffectSpecToSelf(CastSpecHandle);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
protected bool ApplyEffect(FGameplayTag stateTag, FGameplayTag CastTag)
|
||||||
|
{
|
||||||
|
UBusyGameplayEffectSubSystem EffectSubSystem = GetGameInstanceSubsystem<UBusyGameplayEffectSubSystem>();
|
||||||
|
if (ASC == null || EffectSubSystem == null || FoxData == null) return false;
|
||||||
|
|
||||||
|
ApplayCastEffect(CastTag);
|
||||||
|
|
||||||
|
ASC.RemoveActiveGameplayEffect(SkillStateHandle);
|
||||||
|
UGameplayEffect state_effect = EffectSubSystem.GetTagGrantEffectWithDuration(
|
||||||
|
new FGameplayTagContainer(stateTag),
|
||||||
|
new FGameplayTagContainer(), 0
|
||||||
|
);
|
||||||
|
FGameplayEffectSpecHandle stateSpecHandle = UBusyAscLibrary.MakeGameplayEffectSpecHandle(ASC, state_effect, 1);
|
||||||
|
SkillStateHandle = ASC.ApplyGameplayEffectSpecToSelf(stateSpecHandle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
protected bool TriggerAbility(int stage)
|
||||||
|
{
|
||||||
|
if (FoxData == null) return false;
|
||||||
|
if (stage == 1)
|
||||||
|
{
|
||||||
|
if (!ApplyEffect(FoxData.FirstStageTag, FoxData.SecondStageCastTag)) return false;
|
||||||
|
}
|
||||||
|
else if (stage == 2)
|
||||||
|
{
|
||||||
|
if (!ApplyEffect(FoxData.SecondStageTag, new FGameplayTag())) return false;
|
||||||
|
}
|
||||||
|
else if(stage == 3)
|
||||||
|
{
|
||||||
|
if (!ApplyEffect(FoxData.LastStageTag, new FGameplayTag())) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayAnimation(stage);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected string GetAnimationName(FVector2D direction, int stage)
|
||||||
|
{
|
||||||
|
string animation_name_prefix = "";
|
||||||
|
if (direction.X >= 0)
|
||||||
|
{
|
||||||
|
animation_name_prefix = "Ultimate/Right/";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
animation_name_prefix = "Ultimate/Left/";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stage == 1)
|
||||||
|
{
|
||||||
|
return animation_name_prefix + "UltimateStage1";
|
||||||
|
}
|
||||||
|
else if (stage == 2)
|
||||||
|
{
|
||||||
|
return animation_name_prefix + "UltimateStage2";
|
||||||
|
}
|
||||||
|
else if (stage == 3)
|
||||||
|
{
|
||||||
|
return animation_name_prefix + "UltimateStage3";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
[UFunction()]
|
||||||
|
protected void OnAnimationComplete(UTrackEntry Entry)
|
||||||
|
{
|
||||||
|
Entry.AnimationComplete.Remove(OnAnimationComplete);
|
||||||
|
if (ASC != null)
|
||||||
|
{
|
||||||
|
if (ASC.HasMatchingGameplayTag(FoxData.LastStageTag))
|
||||||
|
{
|
||||||
|
CommitAbilityCooldown();
|
||||||
|
}
|
||||||
|
ASC.RemoveActiveGameplayEffect(SkillStateHandle);
|
||||||
|
}
|
||||||
|
EndAbility();
|
||||||
|
}
|
||||||
|
|
||||||
|
[UFunction()]
|
||||||
|
protected void OnTailBeginOverlay(UPrimitiveComponent OverlappedComponent, AActor OtherActor,
|
||||||
|
UPrimitiveComponent OtherComp, int OtherBodyIndex, bool bFromSweep, FHitResult SweepResult)
|
||||||
|
{
|
||||||
|
if (ASC == null || FoxData == null) return;
|
||||||
|
|
||||||
|
bool bIsStage2 = ASC.HasMatchingGameplayTag(FoxData.SecondStageTag);
|
||||||
|
|
||||||
|
if (bIsStage2 && !ASC.HasMatchingGameplayTag(FoxData.LastStageCastTag))
|
||||||
|
{
|
||||||
|
ApplayCastEffect(FoxData.LastStageCastTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[UFunction()]
|
||||||
|
protected void OnAnimationEvent(UTrackEntry Entry, FSpineEvent Event)
|
||||||
|
{
|
||||||
|
if (ASC == null || FoxData == null || Owner == null) return;
|
||||||
|
if (Event.Name == "OnSpeedChange")
|
||||||
|
{
|
||||||
|
AccelerateHandle = MakeAccelerate(FoxData.LastStageSprintSpeedFactor, 1);
|
||||||
|
}
|
||||||
|
else if (Event.Name == "OnSpeedReset")
|
||||||
|
{
|
||||||
|
ASC.RemoveActiveGameplayEffect(AccelerateHandle);
|
||||||
|
}
|
||||||
|
else if (Event.Name == "OnDamageBegin")
|
||||||
|
{
|
||||||
|
Owner.SetTailCollisionEnabled(true);
|
||||||
|
Owner.FoxTailCollision.OnComponentBeginOverlap.Add(OnTailBeginOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (Event.Name == "OnDamageEnd")
|
||||||
|
{
|
||||||
|
Owner.SetTailCollisionEnabled(false);
|
||||||
|
Owner.FoxTailCollision.OnComponentBeginOverlap.Remove(OnTailBeginOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected FActiveGameplayEffectHandle MakeAccelerate(float SpeedFactor, float TotalTime)
|
||||||
|
{
|
||||||
|
GetAbilityEffectSpecHandle("Accelerate", ASC, 1, out FGameplayEffectSpecHandle handle);
|
||||||
|
AbilitySystemLibrary.AssignTagSetByCallerMagnitude(
|
||||||
|
handle, UBusyGameplayLibrary.RequestGameplayTag("Effect.Factor"), SpeedFactor
|
||||||
|
);
|
||||||
|
AbilitySystemLibrary.AssignTagSetByCallerMagnitude(
|
||||||
|
handle, UBusyGameplayLibrary.RequestGameplayTag("Effect.Duration"), TotalTime
|
||||||
|
);
|
||||||
|
return ApplyGameplayEffectSpecToOwner(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected bool PlayAnimation(int stage)
|
||||||
|
{
|
||||||
|
FVector2D AbilityDirection = new FVector2D(0, 1);
|
||||||
|
if (UGameplayStatics.GetPlayerController(0) is ALevelPlayerController PC)
|
||||||
|
{
|
||||||
|
PC.GetCursorDirection(out AbilityDirection);
|
||||||
|
}
|
||||||
|
string AnimationName = GetAnimationName(AbilityDirection, stage);
|
||||||
|
if (AnimationName == "") return false;
|
||||||
|
|
||||||
|
USpineSkeletonAnimationComponent Animation = Owner.SpineAnimationComponent;
|
||||||
|
UTrackEntry AnimEntry = Animation.SetAnimation(0, AnimationName, false);
|
||||||
|
AnimEntry.AnimationEvent.Add(OnAnimationEvent);
|
||||||
|
AnimEntry.AnimationComplete.Add(OnAnimationComplete);
|
||||||
|
|
||||||
|
float TotalTime = AnimEntry.GetAnimationEnd();
|
||||||
|
|
||||||
|
if (stage == 1) MakeAccelerate(FoxData.FirstStageSpeedFactor, TotalTime);
|
||||||
|
else if (stage == 2) MakeAccelerate(FoxData.SecondStageSpeedFactor, TotalTime);
|
||||||
|
else if (stage == 3) MakeAccelerate(FoxData.LastStageNormalSpeedFactor, TotalTime);
|
||||||
|
Owner.MovementComponent.ActivateSprint(AbilityDirection, TotalTime);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// function FoxUltimate:ctor()
|
// function FoxUltimate:ctor()
|
||||||
// self.ultimate_phase = 1 -- 大招阶段
|
// self.ultimate_phase = 1 -- 大招阶段
|
||||||
// self.active_recast_handle = nil
|
// self.active_recast_handle = nil
|
||||||
@ -17,136 +319,6 @@
|
|||||||
// end
|
// end
|
||||||
|
|
||||||
|
|
||||||
// function FoxUltimate:K2_ActivateAbilityFromEvent(EventData)
|
|
||||||
// print("FoxUltimate:K2_ActivateAbilityFromEvent", self.ultimate_phase)
|
|
||||||
|
|
||||||
// if not self:K2_CommitAbilityCost(false) then
|
|
||||||
// return self:K2_EndAbility()
|
|
||||||
// end
|
|
||||||
|
|
||||||
// local owner = self:GetOwningActorFromActorInfo()
|
|
||||||
// self.movement = owner.MovementComponent
|
|
||||||
// self.animation = owner.SpineAnimationComponent
|
|
||||||
// self.asc = AbilitySystemBlueprintLibrary.GetAbilitySystemComponent(owner)
|
|
||||||
// self.recast_tag = BusyGameplayLibrary.RequestGameplayTag("Ability.Flags.Recast")
|
|
||||||
// self.owner = owner
|
|
||||||
|
|
||||||
|
|
||||||
// local asc = self.asc
|
|
||||||
|
|
||||||
// if self.tag_add_or_remove_delegate == nil then
|
|
||||||
// self.tag_add_or_remove_delegate = slua.createDelegate(function(tag, is_add)
|
|
||||||
// if is_add == 0 and not self.bIsActive then
|
|
||||||
// self.ultimate_phase = 1
|
|
||||||
// self:K2_CommitAbilityCooldown(false, false)
|
|
||||||
// end
|
|
||||||
// end)
|
|
||||||
// owner:BindGameplayTagAddOrRemove(self.recast_tag, self.tag_add_or_remove_delegate)
|
|
||||||
// end
|
|
||||||
|
|
||||||
// if self.ultimate_phase == 1 or asc:HasMatchingGameplayTag(self.recast_tag) then
|
|
||||||
// self:TriggerUltimate(asc)
|
|
||||||
// else
|
|
||||||
// self:K2_EndAbility()
|
|
||||||
// end
|
|
||||||
|
|
||||||
|
|
||||||
// end
|
|
||||||
|
|
||||||
// function FoxUltimate:TriggerUltimate(asc)
|
|
||||||
// if self.ultimate_phase == 1 then
|
|
||||||
// -- 第一次释放大招,添加一个可以再次释放的Tag
|
|
||||||
// local _, recast_effect = self:GetAbilityEffectSpecHandle("Recast", asc, 1, nil)
|
|
||||||
// self.active_recast_handle = asc:BP_ApplyGameplayEffectSpecToSelf(recast_effect)
|
|
||||||
// elseif self.ultimate_phase == 2 then
|
|
||||||
// -- 第二次激活,移除可重复释放的tag
|
|
||||||
// self.asc:RemoveActiveGameplayEffect(self.active_recast_handle, -1)
|
|
||||||
// elseif self.ultimate_phase == 3 then
|
|
||||||
// self.asc:RemoveActiveGameplayEffect(self.active_recast_handle, -1)
|
|
||||||
// end
|
|
||||||
|
|
||||||
// -- 播放动画,并监听动画完成的事件
|
|
||||||
// self:PlayAnimation()
|
|
||||||
// end
|
|
||||||
|
|
||||||
|
|
||||||
// function FoxUltimate:GetAnimationName(direction)
|
|
||||||
// local animation_name_prefix
|
|
||||||
// if direction.X >= 0 then
|
|
||||||
// animation_name_prefix = "Ultimate/Right/"
|
|
||||||
// else
|
|
||||||
// animation_name_prefix = "Ultimate/Left/"
|
|
||||||
// end
|
|
||||||
|
|
||||||
// if self.ultimate_phase == 1 then
|
|
||||||
// return animation_name_prefix .. "UltimateStage1"
|
|
||||||
// elseif self.ultimate_phase == 2 then
|
|
||||||
// return animation_name_prefix .. "UltimateStage2"
|
|
||||||
// elseif self.ultimate_phase == 3 then
|
|
||||||
// return animation_name_prefix .. "UltimateStage3"
|
|
||||||
// end
|
|
||||||
// return nil
|
|
||||||
// end
|
|
||||||
|
|
||||||
|
|
||||||
// function FoxUltimate:K2_OnEndAbility(bWasCancelled)
|
|
||||||
// print("FoxUltimate:K2_OnEndAbility")
|
|
||||||
// end
|
|
||||||
|
|
||||||
|
|
||||||
// function FoxUltimate:GetSprintSpeedFactor()
|
|
||||||
// if self.ultimate_phase == 1 then
|
|
||||||
// return 2.5
|
|
||||||
// elseif self.ultimate_phase == 2 then
|
|
||||||
// return 2.8
|
|
||||||
// elseif self.ultimate_phase == 3 then
|
|
||||||
// return 3.0
|
|
||||||
// end
|
|
||||||
// end
|
|
||||||
|
|
||||||
// function FoxUltimate:PlayAnimation()
|
|
||||||
|
|
||||||
// local animation = self.animation
|
|
||||||
// local PC = GameplayStatics.GetPlayerController(self, 0)
|
|
||||||
|
|
||||||
// local result, ability_direction = PC:GetCursorDirection(nil) -- 获取技能的朝向
|
|
||||||
// if not result then
|
|
||||||
// print("FoxUltimate:TriggerPrimaryPhase can't find direction")
|
|
||||||
// return
|
|
||||||
// end
|
|
||||||
// local anim_name = self:GetAnimationName(ability_direction) -- 获取技能动画名称
|
|
||||||
// if not anim_name then
|
|
||||||
// print("FoxUltimate:TriggerPrimaryPhase can't get animation", self.ultimate_phase)
|
|
||||||
// return
|
|
||||||
// end
|
|
||||||
|
|
||||||
// local anim_entry = animation:SetAnimation(0, anim_name, false)
|
|
||||||
// anim_entry.AnimationComplete:Add(function(entry) self:OnAnimationComplete(entry) end)
|
|
||||||
// anim_entry.AnimationEvent:Add(function(entry, event) self:OnAnimationEvent(entry, event) end)
|
|
||||||
|
|
||||||
// local anim_total_time = anim_entry:GetAnimationEnd() -- 获取技能动画时长
|
|
||||||
|
|
||||||
// -- 附加加速buff
|
|
||||||
// self:MakeAccelerate(self:GetSprintSpeedFactor(), anim_total_time)
|
|
||||||
// self.movement:ActivateSprint(ability_direction, anim_total_time)
|
|
||||||
// end
|
|
||||||
|
|
||||||
|
|
||||||
// function FoxUltimate:MakeAccelerate(speed_factor, total_time)
|
|
||||||
// local _, accelerate_effect = self:GetAbilityEffectSpecHandle("Accelerate", self.asc, 1, nil)
|
|
||||||
// AbilitySystemBlueprintLibrary.AssignTagSetByCallerMagnitude(
|
|
||||||
// accelerate_effect,
|
|
||||||
// BusyGameplayLibrary.RequestGameplayTag("Effect.Factor"),
|
|
||||||
// speed_factor
|
|
||||||
// )
|
|
||||||
|
|
||||||
// AbilitySystemBlueprintLibrary.AssignTagSetByCallerMagnitude(
|
|
||||||
// accelerate_effect,
|
|
||||||
// BusyGameplayLibrary.RequestGameplayTag("Effect.Duration"),
|
|
||||||
// total_time
|
|
||||||
// )
|
|
||||||
// return self.asc:BP_ApplyGameplayEffectSpecToSelf(accelerate_effect)
|
|
||||||
// end
|
|
||||||
|
|
||||||
|
|
||||||
// function FoxUltimate:OnAnimationComplete(entry)
|
// function FoxUltimate:OnAnimationComplete(entry)
|
||||||
@ -168,29 +340,4 @@
|
|||||||
// self:K2_EndAbility()
|
// self:K2_EndAbility()
|
||||||
// end
|
// end
|
||||||
|
|
||||||
// function FoxUltimate:OnAnimationEvent(entry, event)
|
|
||||||
// if event.Name == "OnSpeedChange" then
|
|
||||||
// self.active_accelerate_handle = self:MakeAccelerate(8.0, 0.5)
|
|
||||||
// elseif event.Name == "OnSpeedReset" then
|
|
||||||
// self.asc:RemoveActiveGameplayEffect(self.active_accelerate_handle, -1)
|
|
||||||
// elseif event.Name == "OnDamageBegin" then
|
|
||||||
// local collision = self.owner["TailCollision"]
|
|
||||||
// collision:SetCollisionEnabled(1)
|
|
||||||
// self.overlap_delegate_handle = collision.OnComponentBeginOverlap:Add(function()
|
|
||||||
// if not self.asc:HasMatchingGameplayTag(self.recast_tag) then
|
|
||||||
// local _, recast_effect = self:GetAbilityEffectSpecHandle("Recast", self.asc, 1, nil)
|
|
||||||
// self.active_recast_handle = self.asc:BP_ApplyGameplayEffectSpecToSelf(recast_effect)
|
|
||||||
// end
|
|
||||||
// end)
|
|
||||||
// elseif event.Name == "OnDamageEnd" then
|
|
||||||
// self.owner["TailCollision"]:SetCollisionEnabled(0)
|
|
||||||
// if self.overlap_delegate_handle ~= nil then
|
|
||||||
// self.owner["TailCollision"].OnComponentBeginOverlap:Remove(self.overlap_delegate_handle)
|
|
||||||
// self.overlap_delegate_handle = nil
|
|
||||||
// end
|
|
||||||
// end
|
|
||||||
// end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// return Class(nil, nil, FoxUltimate)
|
|
||||||
@ -1,54 +1,82 @@
|
|||||||
// local LevelFoxRole = {}
|
using UnrealSharp.Engine;
|
||||||
// local Vector2D = require("Utils.Vector2D")
|
using UnrealSharp.Attributes;
|
||||||
|
using UnrealSharp.BusyRabbit;
|
||||||
|
using UnrealSharp.CoreUObject;
|
||||||
|
using System.Numerics;
|
||||||
|
using UnrealSharp.SpinePlugin;
|
||||||
|
|
||||||
// function LevelFoxRole:ctor()
|
namespace Level.Role;
|
||||||
|
|
||||||
// end
|
[UClass]
|
||||||
|
public class ABusyFoxRole : ABusyPlayerRole
|
||||||
|
{
|
||||||
|
private string lastAnimation = "";
|
||||||
|
|
||||||
// function LevelFoxRole:ReceiveBeginPlay()
|
[UProperty(DefaultComponent = true, AttachmentComponent = "SpineRoot")]
|
||||||
// self["SpineAnimationComponent"]:SetAnimation(0, "Idle/Front", true)
|
protected USpineBoneFollowerComponent SpineBoneFollower { set; get; } // 用于跟踪尾巴的运动
|
||||||
// self.last_animation = "Idle/Front"
|
|
||||||
|
|
||||||
// self["SpineBoneFollower"].Target = self
|
[UProperty(DefaultComponent = true, AttachmentComponent = "SpineBoneFollower")]
|
||||||
// self["SpineBoneFollower"].BoneName = "tail"
|
public UBoxComponent FoxTailCollision { set; get; } // 尾巴碰撞体组件
|
||||||
// self["SpineBoneFollower"].UseComponentTransform = true
|
|
||||||
// self["SpineBoneFollower"].UseScale = true
|
|
||||||
|
|
||||||
// self["TailCollision"]:SetCollisionEnabled(0)
|
|
||||||
// end
|
|
||||||
|
|
||||||
|
|
||||||
// function LevelFoxRole:OnMoveDirectionChanged(InDirection)
|
[UFunction(FunctionFlags.BlueprintEvent)]
|
||||||
// -- 运动组件更新方向响应函数
|
public void SetTailCollisionEnabled(bool bIsEnable){}
|
||||||
// local cur_animation
|
protected override void BeginPlay()
|
||||||
// if Vector2D.Equals(InDirection, Vector2D.Zero) then -- Idle的情况
|
{
|
||||||
// local forward_direction = self["MovementComponent"]:GetForwardDirection()
|
base.BeginPlay();
|
||||||
// if(forward_direction.Y >= 0) then
|
lastAnimation = "Idle/Front";
|
||||||
// cur_animation = "Idle/Front"
|
SpineAnimationComponent.SetAnimation(0, lastAnimation, true);
|
||||||
// else
|
MovementComponent.MoveDirectionChangedDelegate.Add(OnRoleMoveDirectionChanged);
|
||||||
// cur_animation = "Idle/Back"
|
|
||||||
// end
|
|
||||||
// else
|
|
||||||
// if(InDirection.Y >= 0) then
|
|
||||||
// cur_animation = "Move/Front"
|
|
||||||
// else
|
|
||||||
// cur_animation = "Move/Back"
|
|
||||||
// end
|
|
||||||
// end
|
|
||||||
// if cur_animation ~= self.last_animation then
|
|
||||||
// self["SpineAnimationComponent"]:SetAnimation(0, cur_animation, true)
|
|
||||||
// self.last_animation = cur_animation
|
|
||||||
// end
|
|
||||||
|
|
||||||
// self["SpineAnimationComponent"]:SetTimeScale(1.0)
|
SpineBoneFollower.Target = this;
|
||||||
// end
|
SpineBoneFollower.BoneName = "tail";
|
||||||
|
SpineBoneFollower.UseComponentTransform = true;
|
||||||
|
SpineBoneFollower.UseScale = true;
|
||||||
|
SetTailCollisionEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void EndPlay(EEndPlayReason endPlayReason)
|
||||||
|
{
|
||||||
|
base.EndPlay(endPlayReason);
|
||||||
|
PrintString("haha1");
|
||||||
|
MovementComponent.MoveDirectionChangedDelegate.Remove(OnRoleMoveDirectionChanged);
|
||||||
|
PrintString("haha2");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[UFunction()]
|
||||||
|
protected void OnRoleMoveDirectionChanged(FVector2D direction)
|
||||||
|
{
|
||||||
|
string currAnimation = "";
|
||||||
|
|
||||||
|
if (direction.Equals(Vector2.Zero)) // Idle的情况
|
||||||
|
{
|
||||||
|
var forwardDirection = MovementComponent.ForwardDirection;
|
||||||
|
if (forwardDirection.Y > 0)
|
||||||
|
{
|
||||||
|
currAnimation = "Idle/Front";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currAnimation = "Idle/Back";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (direction.Y >= 0)
|
||||||
|
{
|
||||||
|
currAnimation = "Move/Front";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
currAnimation = "Move/Back";
|
||||||
|
}
|
||||||
|
if (currAnimation != lastAnimation)
|
||||||
|
{
|
||||||
|
lastAnimation = currAnimation;
|
||||||
|
SpineAnimationComponent.SetAnimation(0, currAnimation, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// function LevelFoxRole:OnMove(location)
|
|
||||||
// -- 控制器移动相应函数
|
|
||||||
// self["MovementComponent"]:MoveTo(location)
|
|
||||||
// end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// return Class(nil, nil, LevelFoxRole)
|
|
||||||
@ -15,7 +15,9 @@
|
|||||||
<HintPath>..\..\Plugins\UnrealSharp\Binaries\Managed\net9.0\UnrealSharp.Core.dll</HintPath>
|
<HintPath>..\..\Plugins\UnrealSharp\Binaries\Managed\net9.0\UnrealSharp.Core.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Analyzer Include="..\..\Plugins\UnrealSharp\Binaries\Managed\UnrealSharp.SourceGenerators.dll" />
|
<Analyzer Include="..\..\Plugins\UnrealSharp\Binaries\Managed\UnrealSharp.SourceGenerators.dll" />
|
||||||
<ProjectReference Include="..\BusyRabbit.Glue\BusyRabbit.Glue.csproj" />
|
<ProjectReference Include="..\BusyRabbit.Glue\BusyRabbit.Glue.csproj">
|
||||||
|
<OutputItemType>Analyzer</OutputItemType>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@ -1,5 +1,7 @@
|
|||||||
#include "BlueprintLibrary/BusyAscLibrary.h"
|
#include "BlueprintLibrary/BusyAscLibrary.h"
|
||||||
|
|
||||||
|
#include "AbilitySystemComponent.h"
|
||||||
|
#include "AbilitySystemGlobals.h"
|
||||||
#include "GameplayEffectTypes.h"
|
#include "GameplayEffectTypes.h"
|
||||||
#include "Gas/BusyGameAbility.h"
|
#include "Gas/BusyGameAbility.h"
|
||||||
|
|
||||||
@ -18,3 +20,11 @@ AActor* UBusyAscLibrary::GetEffectInstigator(const FGameplayEffectSpec& Spec)
|
|||||||
return Spec.GetEffectContext().GetInstigator();
|
return Spec.GetEffectContext().GetInstigator();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FGameplayEffectSpecHandle UBusyAscLibrary::MakeGameplayEffectSpecHandle(const UAbilitySystemComponent* Asc, const UGameplayEffect* Effect, const float Level)
|
||||||
|
{
|
||||||
|
const FGameplayEffectContextHandle ContextHandle = Asc->MakeEffectContext();
|
||||||
|
FGameplayEffectSpec && Spec = FGameplayEffectSpec(Effect, ContextHandle, Level);
|
||||||
|
FGameplayEffectSpec* NewSpec = new FGameplayEffectSpec(Effect, ContextHandle, Level);
|
||||||
|
return FGameplayEffectSpecHandle(NewSpec);
|
||||||
|
}
|
||||||
|
|||||||
@ -2,12 +2,26 @@
|
|||||||
#include "AbilitySystemBlueprintLibrary.h"
|
#include "AbilitySystemBlueprintLibrary.h"
|
||||||
#include "AbilitySystemComponent.h"
|
#include "AbilitySystemComponent.h"
|
||||||
|
|
||||||
UBusyGameAbility::UBusyGameAbility()
|
#pragma optimize("", off)
|
||||||
|
void UBusyGameAbility::OnGiveAbility(const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilitySpec& Spec)
|
||||||
{
|
{
|
||||||
|
Super::OnGiveAbility(ActorInfo, Spec);
|
||||||
|
Data = SoftDataAsset.LoadSynchronous();
|
||||||
|
if (Data)
|
||||||
|
{
|
||||||
|
Data->TargetAbility = this;
|
||||||
|
}
|
||||||
|
K2_OnGiveAbility(*ActorInfo, Spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UBusyGameAbility::K2_OnGiveAbility_Implementation(const FGameplayAbilityActorInfo& ActorInfo, const FGameplayAbilitySpec& Spec)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool UBusyGameAbility::GetAbilityEffectSpecHandle(const FName& EffectName, const UAbilitySystemComponent* Asc, const int32 Level,
|
bool UBusyGameAbility::GetAbilityEffectSpecHandle(const FName& EffectName, const UAbilitySystemComponent* Asc, const int32 Level,
|
||||||
FGameplayEffectSpecHandle& Handle) const
|
FGameplayEffectSpecHandle& Handle) const
|
||||||
{
|
{
|
||||||
// 1. 查找对应的GameplayEffectClass
|
// 1. 查找对应的GameplayEffectClass
|
||||||
const TSubclassOf<UGameplayEffect> *EffectClass = AbilityEffects.Find(EffectName);
|
const TSubclassOf<UGameplayEffect> *EffectClass = AbilityEffects.Find(EffectName);
|
||||||
@ -25,13 +39,3 @@ bool UBusyGameAbility::GetAbilityEffectSpecHandle(const FName& EffectName, const
|
|||||||
return Handle.IsValid();
|
return Handle.IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UBusyGameAbility::PostInitProperties()
|
|
||||||
{
|
|
||||||
Super::PostInitProperties();
|
|
||||||
if (SoftDataAsset)
|
|
||||||
{
|
|
||||||
Data = SoftDataAsset.LoadSynchronous();
|
|
||||||
Data->TargetAbility = this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,38 @@
|
|||||||
|
#include "Gas/BusyGameplayEffectSubSystem.h"
|
||||||
|
|
||||||
|
#include "GameplayEffect.h"
|
||||||
|
#include "GameplayEffectComponents/TargetTagsGameplayEffectComponent.h"
|
||||||
|
|
||||||
|
UGameplayEffect* UBusyGameplayEffectSubSystem::GetTagGrantEffectWithDuration(const FGameplayTagContainer& TagsAdd,
|
||||||
|
const FGameplayTagContainer& TagsRemove, const float Duration, const float Period)
|
||||||
|
{
|
||||||
|
UGameplayEffect* Effect = nullptr;
|
||||||
|
if (EffectsPool.IsEmpty())
|
||||||
|
{
|
||||||
|
Effect = NewObject<UGameplayEffect>(this);
|
||||||
|
Effect->Period = Period;
|
||||||
|
if (Duration > 0)
|
||||||
|
{
|
||||||
|
Effect->DurationPolicy = EGameplayEffectDurationType::HasDuration;
|
||||||
|
Effect->DurationMagnitude = FGameplayEffectModifierMagnitude(Duration);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Effect->DurationPolicy = EGameplayEffectDurationType::Infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Effect = EffectsPool.Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
FInheritedTagContainer Container;
|
||||||
|
UTargetTagsGameplayEffectComponent& Component = Effect->FindOrAddComponent<UTargetTagsGameplayEffectComponent>();
|
||||||
|
|
||||||
|
Container.Added = TagsAdd;
|
||||||
|
Container.CombinedTags = TagsAdd;
|
||||||
|
Container.Removed = TagsRemove;
|
||||||
|
Component.SetAndApplyTargetTagChanges(Container);
|
||||||
|
return Effect;
|
||||||
|
}
|
||||||
|
|
||||||
@ -85,8 +85,5 @@ void ABusyPawnBase::BindGameplayTagAddOrRemove(const FGameplayTag& Tag, FGamepla
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABusyPawnBase::InitCollision()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -84,6 +84,7 @@ void UBusyPawnMovement::TickComponent(float DeltaTime, ELevelTick TickType,
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#pragma optimize("", off)
|
||||||
|
|
||||||
void UBusyPawnMovement::MoveTick(const float DeltaTime)
|
void UBusyPawnMovement::MoveTick(const float DeltaTime)
|
||||||
{
|
{
|
||||||
@ -121,9 +122,10 @@ void UBusyPawnMovement::MoveTick(const float DeltaTime)
|
|||||||
}
|
}
|
||||||
if (!NewDirection.Equals(LastMoveDirection))
|
if (!NewDirection.Equals(LastMoveDirection))
|
||||||
{
|
{
|
||||||
Movable->Execute_OnMoveDirectionChanged(Owner, NewDirection);
|
MoveDirectionChangedDelegate.Broadcast(NewDirection);
|
||||||
LastMoveDirection = NewDirection;
|
LastMoveDirection = NewDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UBusyPawnMovement::SprintTick(const float DeltaTime)
|
void UBusyPawnMovement::SprintTick(const float DeltaTime)
|
||||||
|
|||||||
@ -148,41 +148,6 @@ void ALevelPlayerController::SwitchControlledRole(ABusyPlayerRole* Target)
|
|||||||
this->Possess(Target);
|
this->Possess(Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALevelPlayerController::OnMove(const FInputActionValue& Value) const
|
|
||||||
{
|
|
||||||
AActor* ControlledRole = GetControlledRole();
|
|
||||||
if (!ControlledRole) return;
|
|
||||||
|
|
||||||
IBusyControllable *Controllable = Cast<IBusyControllable>(ControlledRole);
|
|
||||||
if (!Controllable) return;
|
|
||||||
|
|
||||||
if (FVector2D Position; GetCursorPosition(Position))
|
|
||||||
{
|
|
||||||
Controllable->Execute_OnMove(ControlledRole, Position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ALevelPlayerController::OnPrimarySkill(const FInputActionValue& Value) const
|
|
||||||
{
|
|
||||||
AActor* ControlledRole = GetControlledRole();
|
|
||||||
if (!ControlledRole) return;
|
|
||||||
|
|
||||||
if (IBusyControllable *Controllable = Cast<IBusyControllable>(ControlledRole))
|
|
||||||
{
|
|
||||||
Controllable->Execute_OnPrimarySkill(ControlledRole);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ALevelPlayerController::OnUltimateSkill(const FInputActionValue& Value) const
|
|
||||||
{
|
|
||||||
AActor* ControlledRole = GetControlledRole();
|
|
||||||
if (!ControlledRole) return;
|
|
||||||
if (IBusyControllable *Controllable = Cast<IBusyControllable>(ControlledRole))
|
|
||||||
{
|
|
||||||
Controllable->Execute_OnUltimateSkill(ControlledRole);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ALevelPlayerController::OnCameraDetach(const FInputActionValue& Value)
|
void ALevelPlayerController::OnCameraDetach(const FInputActionValue& Value)
|
||||||
{
|
{
|
||||||
if (!RoamingCameraActor) return;
|
if (!RoamingCameraActor) return;
|
||||||
@ -223,6 +188,7 @@ void ALevelPlayerController::OnRoleSkillTriggered(FGameplayTag GameplayTag)
|
|||||||
if (UAbilitySystemComponent* Asc = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(ControlledRole))
|
if (UAbilitySystemComponent* Asc = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(ControlledRole))
|
||||||
{
|
{
|
||||||
FGameplayEventData EventData = FGameplayEventData();
|
FGameplayEventData EventData = FGameplayEventData();
|
||||||
|
EventData.Instigator = ControlledRole;
|
||||||
Asc->HandleGameplayEvent(GameplayTag, &EventData);
|
Asc->HandleGameplayEvent(GameplayTag, &EventData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "GameplayEffectTypes.h"
|
||||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
#include "BusyAscLibrary.generated.h"
|
#include "BusyAscLibrary.generated.h"
|
||||||
|
|
||||||
|
class UGameplayEffect;
|
||||||
struct FGameplayEffectSpec;
|
struct FGameplayEffectSpec;
|
||||||
class UBusyAbilityDataAssetBase;
|
class UBusyAbilityDataAssetBase;
|
||||||
|
|
||||||
@ -15,4 +17,7 @@ public:
|
|||||||
|
|
||||||
UFUNCTION(BlueprintCallable)
|
UFUNCTION(BlueprintCallable)
|
||||||
static AActor* GetEffectInstigator(const FGameplayEffectSpec& Spec);
|
static AActor* GetEffectInstigator(const FGameplayEffectSpec& Spec);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable)
|
||||||
|
static FGameplayEffectSpecHandle MakeGameplayEffectSpecHandle(const UAbilitySystemComponent* Asc, const UGameplayEffect* Effect, const float Level);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -12,61 +12,64 @@ class UFoxUltimateDataAsset : public UBusyAbilityDataAssetBase
|
|||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
public:
|
public:
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="一阶消耗", Category="技能消耗")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="一阶消耗", Category="技能消耗", meta=(ScriptName="FirstStageCost"))
|
||||||
float FirstStageCost = 5.f;
|
float FirstStageCost = 5.f;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶消耗", Category="技能消耗")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶消耗", Category="技能消耗", meta=(ScriptName="SecondStageCost"))
|
||||||
float SecondStageCost = 8.f;
|
float SecondStageCost = 8.f;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶消耗", Category="技能消耗")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶消耗", Category="技能消耗", meta=(ScriptName="LastStageCost"))
|
||||||
float LastStageCost = 12.f;
|
float LastStageCost = 12.f;
|
||||||
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="一阶伤害系数", Category="伤害系数")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="一阶伤害系数", Category="伤害系数", meta=(ScriptName="FirstStageDamageFactor"))
|
||||||
float FirstStageDamageFactor = 5.f;
|
float FirstStageDamageFactor = 5.f;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶伤害系数", Category="伤害系数")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶伤害系数", Category="伤害系数", meta=(ScriptName="SecondStageDamageFactor"))
|
||||||
float SecondStageDamageFactor = 8.f;
|
float SecondStageDamageFactor = 8.f;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶伤害系数", Category="伤害系数")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶伤害系数", Category="伤害系数", meta=(ScriptName="LastStageDamageFactor"))
|
||||||
float LastStageDamageFactor = 12.f;
|
float LastStageDamageFactor = 12.f;
|
||||||
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="一阶速度系数", Category="速度系数")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="一阶速度系数", Category="速度系数", meta=(ScriptName="FirstStageSpeedFactor"))
|
||||||
float FirstStageSpeedFactor = 5.f;
|
float FirstStageSpeedFactor = 5.f;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶速度系数", Category="速度系数")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶速度系数", Category="速度系数", meta=(ScriptName="SecondStageSpeedFactor"))
|
||||||
float SecondStageSpeedFactor = 8.f;
|
float SecondStageSpeedFactor = 8.f;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶一段速度系数", Category="速度系数")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶一段速度系数", Category="速度系数", meta=(ScriptName="LastStageNormalSpeedFactor"))
|
||||||
float LastStageNormalSpeedFactor = 12.f;
|
float LastStageNormalSpeedFactor = 12.f;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶二段速度系数", Category="速度系数")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶二段速度系数", Category="速度系数", meta=(ScriptName="LastStageSprintSpeedFactor"))
|
||||||
float LastStageSprintSpeedFactor = 12.f;
|
float LastStageSprintSpeedFactor = 12.f;
|
||||||
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="可释放二阶标签", Category="技能标签")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="可释放一阶标签", Category="技能标签", meta=(ScriptName="FirstStageCastTag"))
|
||||||
FGameplayTag SecondStageRecastTag;
|
FGameplayTag FirstStageCastTag;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="可释放三阶标签", Category="技能标签")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="可释放二阶标签", Category="技能标签", meta=(ScriptName="SecondStageCastTag"))
|
||||||
FGameplayTag LastStageRecastTag;
|
FGameplayTag SecondStageCastTag;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="可释放三阶标签", Category="技能标签", meta=(ScriptName="LastStageCastTag"))
|
||||||
|
FGameplayTag LastStageCastTag;
|
||||||
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="一阶标签", Category="技能标签")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="一阶标签", Category="技能标签", meta=(ScriptName="FirstStageTag"))
|
||||||
FGameplayTag FirstStageTag;
|
FGameplayTag FirstStageTag;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶标签", Category="技能标签")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶标签", Category="技能标签", meta=(ScriptName="SecondStageTag"))
|
||||||
FGameplayTag SecondStageTag;
|
FGameplayTag SecondStageTag;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶标签", Category="技能标签")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶标签", Category="技能标签", meta=(ScriptName="LastStageTag"))
|
||||||
FGameplayTag LastStageTag;
|
FGameplayTag LastStageTag;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="可重新释放时长")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="可重新释放时长", meta=(ScriptName="RecastWindow"))
|
||||||
float RecastWindow = 6.f;
|
float RecastWindow = 6.f;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="冷却时间")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="冷却时间", meta=(ScriptName="CooldownTime"))
|
||||||
float CooldownTime = 15.f;
|
float CooldownTime = 15.f;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -10,16 +10,16 @@ class UBusyGameAbility : public UGameplayAbility
|
|||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
public:
|
public:
|
||||||
|
virtual void OnGiveAbility(const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilitySpec& Spec) override;
|
||||||
UBusyGameAbility();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UFUNCTION(BlueprintCallable)
|
UFUNCTION(BlueprintCallable)
|
||||||
bool GetAbilityEffectSpecHandle(const FName& EffectName, const UAbilitySystemComponent* Asc, const int32 Level, FGameplayEffectSpecHandle& Handle)const;
|
bool GetAbilityEffectSpecHandle(const FName& EffectName, const UAbilitySystemComponent* Asc, const int32 Level, FGameplayEffectSpecHandle& Handle)const;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintNativeEvent)
|
||||||
|
void K2_OnGiveAbility(const FGameplayAbilityActorInfo& ActorInfo, const FGameplayAbilitySpec& Spec);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void PostInitProperties()override;
|
|
||||||
UBusyAbilityDataAssetBase* GetData()const { return Data; }
|
UBusyAbilityDataAssetBase* GetData()const { return Data; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
21
Source/BusyRabbit/Public/Gas/BusyGameplayEffectSubSystem.h
Normal file
21
Source/BusyRabbit/Public/Gas/BusyGameplayEffectSubSystem.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "GameplayTagContainer.h"
|
||||||
|
#include "BusyGameplayEffectSubSystem.generated.h"
|
||||||
|
|
||||||
|
class UGameplayEffect;
|
||||||
|
|
||||||
|
UCLASS(blueprinttype)
|
||||||
|
class UBusyGameplayEffectSubSystem : public UGameInstanceSubsystem
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "GameplayEffectSubSystem")
|
||||||
|
UGameplayEffect* GetTagGrantEffectWithDuration(const FGameplayTagContainer& TagsAdd,
|
||||||
|
const FGameplayTagContainer& TagsRemove, const float Duration, const float Period=0);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UPROPERTY()
|
||||||
|
TArray<UGameplayEffect*> EffectsPool;
|
||||||
|
};
|
||||||
@ -70,10 +70,6 @@ public:
|
|||||||
UFUNCTION(BlueprintCallable)
|
UFUNCTION(BlueprintCallable)
|
||||||
void BindGameplayTagAddOrRemove(const FGameplayTag& Tag, FGameplayTagAddOrRemoveDelegate Delegate)const;
|
void BindGameplayTagAddOrRemove(const FGameplayTag& Tag, FGameplayTagAddOrRemoveDelegate Delegate)const;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void InitCollision();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UPROPERTY(EditDefaultsOnly)
|
UPROPERTY(EditDefaultsOnly)
|
||||||
TObjectPtr<USceneComponent> RootScene; //场景根组件
|
TObjectPtr<USceneComponent> RootScene; //场景根组件
|
||||||
@ -85,8 +81,7 @@ protected:
|
|||||||
UPROPERTY(EditDefaultsOnly)
|
UPROPERTY(EditDefaultsOnly)
|
||||||
TObjectPtr<USpineSkeletonRendererComponent> SpineRenderComponent;
|
TObjectPtr<USpineSkeletonRendererComponent> SpineRenderComponent;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly)
|
|
||||||
TObjectPtr<USpineSkeletonAnimationComponent> SpineAnimationComponent;
|
|
||||||
/*-------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------*/
|
||||||
|
|
||||||
/*-----------------------------GAS相关--------------------------------*/
|
/*-----------------------------GAS相关--------------------------------*/
|
||||||
@ -96,6 +91,9 @@ protected:
|
|||||||
/*-------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------*/
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly)
|
||||||
|
TObjectPtr<USpineSkeletonAnimationComponent> SpineAnimationComponent;
|
||||||
|
|
||||||
/*-------------------------------移动组件------------------------------*/
|
/*-------------------------------移动组件------------------------------*/
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly)
|
UPROPERTY(EditAnywhere, BlueprintReadOnly)
|
||||||
TObjectPtr<UBusyPawnMovement> MovementComponent;
|
TObjectPtr<UBusyPawnMovement> MovementComponent;
|
||||||
|
|||||||
@ -36,7 +36,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class ABusyPlayerRole : public ABusyPawnBase, public IBusyControllable
|
class ABusyPlayerRole : public ABusyPawnBase
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
public:
|
public:
|
||||||
@ -48,7 +48,7 @@ public:
|
|||||||
|
|
||||||
virtual void InitPawnAttributes(const struct FBusyPawnBaseConfig& Config)override;
|
virtual void InitPawnAttributes(const struct FBusyPawnBaseConfig& Config)override;
|
||||||
|
|
||||||
|
virtual void OnMoveDirectionChanged_Implementation(const FVector2D& InDirection) override {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*--------------------相机相关--------------------------*/
|
/*--------------------相机相关--------------------------*/
|
||||||
|
|||||||
@ -34,6 +34,9 @@ enum class EBusyMoveState: uint8
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBusyMoveDirectionChanged, FVector2D, Direction);
|
||||||
|
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UBusyPawnMovement : public UActorComponent
|
class UBusyPawnMovement : public UActorComponent
|
||||||
{
|
{
|
||||||
@ -99,6 +102,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
void SprintTick(const float DeltaTime);
|
void SprintTick(const float DeltaTime);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
|
||||||
|
FBusyMoveDirectionChanged MoveDirectionChangedDelegate;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Movement")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Movement")
|
||||||
EBusyMoveState BusyMoveState = EBusyMoveState::None;
|
EBusyMoveState BusyMoveState = EBusyMoveState::None;
|
||||||
|
|||||||
@ -5,31 +5,6 @@
|
|||||||
#include "LevelPlayerController.generated.h"
|
#include "LevelPlayerController.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
UINTERFACE(MinimalAPI, Blueprintable)
|
|
||||||
class UBusyControllable: public UInterface
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
};
|
|
||||||
|
|
||||||
class IBusyControllable
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
public:
|
|
||||||
// 角色移动
|
|
||||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
|
||||||
void OnMove(const FVector2D& Location);
|
|
||||||
|
|
||||||
// 角色普通技能
|
|
||||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
|
||||||
void OnPrimarySkill();
|
|
||||||
|
|
||||||
// 角色大招
|
|
||||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
|
||||||
void OnUltimateSkill();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ABusyPlayerRole;
|
class ABusyPlayerRole;
|
||||||
struct FInputActionValue;
|
struct FInputActionValue;
|
||||||
|
|
||||||
@ -116,15 +91,6 @@ public: // 输入相关
|
|||||||
TArray<FBusySkillActionConfig> RoleSkillActions;
|
TArray<FBusySkillActionConfig> RoleSkillActions;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UFUNCTION()
|
|
||||||
void OnMove(const FInputActionValue& Value)const;
|
|
||||||
|
|
||||||
UFUNCTION()
|
|
||||||
void OnPrimarySkill(const FInputActionValue& Value)const;
|
|
||||||
|
|
||||||
UFUNCTION()
|
|
||||||
void OnUltimateSkill(const FInputActionValue& Value)const;
|
|
||||||
|
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
void OnCameraDetach(const FInputActionValue& Value);
|
void OnCameraDetach(const FInputActionValue& Value);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user