| @ -5,13 +5,24 @@ ClearInvalidTags=False | ||||
| AllowEditorTagUnloading=True | ||||
| AllowGameTagUnloading=False | ||||
| FastReplication=False | ||||
| bDynamicReplication=False | ||||
| InvalidTagCharacters="\"\'," | ||||
| NumBitsForContainerSize=6 | ||||
| NetIndexFirstBitSegment=16 | ||||
| +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.Recast",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.UltimateStage2",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") | ||||
| // local AbilitySystemBlueprintLibrary = import("AbilitySystemBlueprintLibrary") | ||||
| // local BusyGameplayLibrary = import("BusyGameplayLibrary") | ||||
| using Level.Role; | ||||
| using UnrealSharp; | ||||
| using UnrealSharp.Attributes; | ||||
| using UnrealSharp.BusyRabbit; | ||||
| using UnrealSharp.CoreUObject; | ||||
| using UnrealSharp.Engine; | ||||
| using UnrealSharp.GameplayAbilities; | ||||
| using UnrealSharp.GameplayTags; | ||||
| using UnrealSharp.SpinePlugin; | ||||
|  | ||||
| // --- @class FoxUltimate | ||||
| // --- @field RecastWindow number | ||||
| // local FoxUltimate = {} | ||||
| namespace GameAbilitySystem.Ability.Role.Fox; | ||||
|  | ||||
|  | ||||
| [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() | ||||
| //     self.ultimate_phase = 1  -- 大招阶段 | ||||
| //     self.active_recast_handle = nil | ||||
| @ -17,136 +319,6 @@ | ||||
| // 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) | ||||
| @ -168,29 +340,4 @@ | ||||
| //     self:K2_EndAbility() | ||||
| // 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 = {} | ||||
| // local Vector2D = require("Utils.Vector2D") | ||||
| using UnrealSharp.Engine; | ||||
| 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() | ||||
| // 	self["SpineAnimationComponent"]:SetAnimation(0, "Idle/Front", true) | ||||
| //     self.last_animation = "Idle/Front" | ||||
|     [UProperty(DefaultComponent = true, AttachmentComponent = "SpineRoot")] | ||||
|     protected USpineBoneFollowerComponent SpineBoneFollower { set; get; }    // 用于跟踪尾巴的运动 | ||||
|  | ||||
| //     self["SpineBoneFollower"].Target = self | ||||
| //     self["SpineBoneFollower"].BoneName = "tail" | ||||
| //     self["SpineBoneFollower"].UseComponentTransform = true | ||||
| //     self["SpineBoneFollower"].UseScale = true | ||||
|  | ||||
| //     self["TailCollision"]:SetCollisionEnabled(0) | ||||
| // end | ||||
|     [UProperty(DefaultComponent = true, AttachmentComponent = "SpineBoneFollower")] | ||||
|     public UBoxComponent FoxTailCollision { set; get; }   // 尾巴碰撞体组件 | ||||
|  | ||||
|  | ||||
| // function LevelFoxRole:OnMoveDirectionChanged(InDirection) | ||||
| //     -- 运动组件更新方向响应函数 | ||||
| //     local cur_animation | ||||
| //     if Vector2D.Equals(InDirection, Vector2D.Zero) then -- Idle的情况 | ||||
| //         local forward_direction = self["MovementComponent"]:GetForwardDirection() | ||||
| //         if(forward_direction.Y >= 0) then | ||||
| //             cur_animation = "Idle/Front" | ||||
| //         else | ||||
| //             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 | ||||
|     [UFunction(FunctionFlags.BlueprintEvent)] | ||||
|     public void SetTailCollisionEnabled(bool bIsEnable){} | ||||
|     protected override void BeginPlay() | ||||
|     { | ||||
|         base.BeginPlay(); | ||||
|         lastAnimation = "Idle/Front"; | ||||
|         SpineAnimationComponent.SetAnimation(0, lastAnimation, true); | ||||
|         MovementComponent.MoveDirectionChangedDelegate.Add(OnRoleMoveDirectionChanged); | ||||
|  | ||||
| //     self["SpineAnimationComponent"]:SetTimeScale(1.0) | ||||
| // end | ||||
|         SpineBoneFollower.Target = this; | ||||
|         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> | ||||
|     </Reference> | ||||
|     <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> | ||||
|  | ||||
| </Project> | ||||
| @ -1,5 +1,7 @@ | ||||
| #include "BlueprintLibrary/BusyAscLibrary.h" | ||||
|  | ||||
| #include "AbilitySystemComponent.h" | ||||
| #include "AbilitySystemGlobals.h" | ||||
| #include "GameplayEffectTypes.h" | ||||
| #include "Gas/BusyGameAbility.h" | ||||
|  | ||||
| @ -18,3 +20,11 @@ AActor* UBusyAscLibrary::GetEffectInstigator(const FGameplayEffectSpec& Spec) | ||||
| 	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,10 +2,24 @@ | ||||
| #include "AbilitySystemBlueprintLibrary.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, | ||||
|                                                   FGameplayEffectSpecHandle& Handle) const | ||||
| { | ||||
| @ -25,13 +39,3 @@ bool UBusyGameAbility::GetAbilityEffectSpecHandle(const FName& EffectName, const | ||||
| 	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) | ||||
| { | ||||
| @ -121,9 +122,10 @@ void UBusyPawnMovement::MoveTick(const float DeltaTime) | ||||
| 	} | ||||
| 	if (!NewDirection.Equals(LastMoveDirection)) | ||||
| 	{ | ||||
| 		Movable->Execute_OnMoveDirectionChanged(Owner, NewDirection); | ||||
| 		MoveDirectionChangedDelegate.Broadcast(NewDirection); | ||||
| 		LastMoveDirection = NewDirection; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| void UBusyPawnMovement::SprintTick(const float DeltaTime) | ||||
|  | ||||
| @ -148,41 +148,6 @@ void ALevelPlayerController::SwitchControlledRole(ABusyPlayerRole* 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) | ||||
| { | ||||
| 	if (!RoamingCameraActor) return; | ||||
| @ -223,6 +188,7 @@ void ALevelPlayerController::OnRoleSkillTriggered(FGameplayTag GameplayTag) | ||||
| 	if (UAbilitySystemComponent* Asc = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(ControlledRole)) | ||||
| 	{ | ||||
| 		FGameplayEventData EventData = FGameplayEventData(); | ||||
| 		EventData.Instigator = ControlledRole; | ||||
| 		Asc->HandleGameplayEvent(GameplayTag, &EventData); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -1,7 +1,9 @@ | ||||
| #pragma once | ||||
| #include "GameplayEffectTypes.h" | ||||
| #include "Kismet/BlueprintFunctionLibrary.h" | ||||
| #include "BusyAscLibrary.generated.h" | ||||
|  | ||||
| class UGameplayEffect; | ||||
| struct FGameplayEffectSpec; | ||||
| class UBusyAbilityDataAssetBase; | ||||
|  | ||||
| @ -15,4 +17,7 @@ public: | ||||
|  | ||||
| 	UFUNCTION(BlueprintCallable) | ||||
| 	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() | ||||
| public: | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="一阶消耗", Category="技能消耗") | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="一阶消耗", Category="技能消耗", meta=(ScriptName="FirstStageCost")) | ||||
| 	float FirstStageCost = 5.f; | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶消耗", Category="技能消耗") | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶消耗", Category="技能消耗", meta=(ScriptName="SecondStageCost")) | ||||
| 	float SecondStageCost = 8.f; | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶消耗", Category="技能消耗") | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶消耗", Category="技能消耗", meta=(ScriptName="LastStageCost")) | ||||
| 	float LastStageCost = 12.f; | ||||
|  | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="一阶伤害系数", Category="伤害系数") | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="一阶伤害系数", Category="伤害系数", meta=(ScriptName="FirstStageDamageFactor")) | ||||
| 	float FirstStageDamageFactor = 5.f; | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶伤害系数", Category="伤害系数") | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶伤害系数", Category="伤害系数", meta=(ScriptName="SecondStageDamageFactor")) | ||||
| 	float SecondStageDamageFactor = 8.f; | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶伤害系数", Category="伤害系数") | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶伤害系数", Category="伤害系数", meta=(ScriptName="LastStageDamageFactor")) | ||||
| 	float LastStageDamageFactor = 12.f; | ||||
|  | ||||
| 	 | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="一阶速度系数", Category="速度系数") | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="一阶速度系数", Category="速度系数", meta=(ScriptName="FirstStageSpeedFactor")) | ||||
| 	float FirstStageSpeedFactor = 5.f; | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶速度系数", Category="速度系数") | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶速度系数", Category="速度系数", meta=(ScriptName="SecondStageSpeedFactor")) | ||||
| 	float SecondStageSpeedFactor = 8.f; | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶一段速度系数", Category="速度系数") | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶一段速度系数", Category="速度系数", meta=(ScriptName="LastStageNormalSpeedFactor")) | ||||
| 	float LastStageNormalSpeedFactor = 12.f; | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶二段速度系数", Category="速度系数") | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶二段速度系数", Category="速度系数", meta=(ScriptName="LastStageSprintSpeedFactor")) | ||||
| 	float LastStageSprintSpeedFactor = 12.f; | ||||
|  | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="可释放二阶标签", Category="技能标签") | ||||
| 	FGameplayTag SecondStageRecastTag; | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="可释放一阶标签", Category="技能标签", meta=(ScriptName="FirstStageCastTag")) | ||||
| 	FGameplayTag FirstStageCastTag; | ||||
| 	 | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="可释放三阶标签", Category="技能标签") | ||||
| 	FGameplayTag LastStageRecastTag; | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="可释放二阶标签", Category="技能标签", meta=(ScriptName="SecondStageCastTag")) | ||||
| 	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; | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶标签", Category="技能标签") | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="二阶标签", Category="技能标签", meta=(ScriptName="SecondStageTag")) | ||||
| 	FGameplayTag SecondStageTag; | ||||
| 	 | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶标签", Category="技能标签") | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="三阶标签", Category="技能标签", meta=(ScriptName="LastStageTag")) | ||||
| 	FGameplayTag LastStageTag; | ||||
|  | ||||
|  | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="可重新释放时长") | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="可重新释放时长", meta=(ScriptName="RecastWindow")) | ||||
| 	float RecastWindow = 6.f; | ||||
| 	 | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="冷却时间") | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="冷却时间", meta=(ScriptName="CooldownTime")) | ||||
| 	float CooldownTime = 15.f; | ||||
| 	 | ||||
| }; | ||||
| @ -10,16 +10,16 @@ class UBusyGameAbility : public UGameplayAbility | ||||
| { | ||||
| 	GENERATED_BODY() | ||||
| public: | ||||
|  | ||||
| 	UBusyGameAbility(); | ||||
| 	virtual void OnGiveAbility(const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilitySpec& Spec) override; | ||||
| 	 | ||||
| public: | ||||
| 	UFUNCTION(BlueprintCallable) | ||||
| 	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: | ||||
| 	virtual void PostInitProperties()override; | ||||
| 	UBusyAbilityDataAssetBase* GetData()const { return Data; } | ||||
|  | ||||
| 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) | ||||
| 	void BindGameplayTagAddOrRemove(const FGameplayTag& Tag, FGameplayTagAddOrRemoveDelegate Delegate)const; | ||||
|  | ||||
|  | ||||
| protected: | ||||
| 	void InitCollision(); | ||||
|  | ||||
| protected: | ||||
| 	UPROPERTY(EditDefaultsOnly) | ||||
| 	TObjectPtr<USceneComponent> RootScene;  //场景根组件 | ||||
| @ -85,8 +81,7 @@ protected: | ||||
| 	UPROPERTY(EditDefaultsOnly) | ||||
| 	TObjectPtr<USpineSkeletonRendererComponent> SpineRenderComponent; | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly) | ||||
| 	TObjectPtr<USpineSkeletonAnimationComponent> SpineAnimationComponent; | ||||
|  | ||||
| 	/*-------------------------------------------------------------------*/ | ||||
|  | ||||
| 	/*-----------------------------GAS相关--------------------------------*/ | ||||
| @ -96,6 +91,9 @@ protected: | ||||
| 	/*-------------------------------------------------------------------*/ | ||||
|  | ||||
| public: | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly) | ||||
| 	TObjectPtr<USpineSkeletonAnimationComponent> SpineAnimationComponent; | ||||
| 	 | ||||
| 	/*-------------------------------移动组件------------------------------*/ | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly) | ||||
| 	TObjectPtr<UBusyPawnMovement> MovementComponent; | ||||
|  | ||||
| @ -36,7 +36,7 @@ public: | ||||
|  | ||||
|  | ||||
| UCLASS() | ||||
| class ABusyPlayerRole : public ABusyPawnBase, public IBusyControllable | ||||
| class ABusyPlayerRole : public ABusyPawnBase | ||||
| { | ||||
| 	GENERATED_BODY() | ||||
| public: | ||||
| @ -48,7 +48,7 @@ public: | ||||
|  | ||||
| 	virtual void InitPawnAttributes(const struct FBusyPawnBaseConfig& Config)override; | ||||
| 	 | ||||
|  | ||||
| 	virtual void OnMoveDirectionChanged_Implementation(const FVector2D& InDirection) override {} | ||||
|  | ||||
| protected: | ||||
| 	/*--------------------相机相关--------------------------*/ | ||||
|  | ||||
| @ -34,6 +34,9 @@ enum class EBusyMoveState: uint8 | ||||
| }; | ||||
|  | ||||
|  | ||||
| DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBusyMoveDirectionChanged, FVector2D, Direction); | ||||
|  | ||||
|  | ||||
| UCLASS() | ||||
| class UBusyPawnMovement : public UActorComponent | ||||
| { | ||||
| @ -99,6 +102,11 @@ public: | ||||
| 	 */ | ||||
| 	void SprintTick(const float DeltaTime); | ||||
|  | ||||
|  | ||||
| public: | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement") | ||||
| 	FBusyMoveDirectionChanged MoveDirectionChangedDelegate; | ||||
| 	 | ||||
| protected: | ||||
| 	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Movement") | ||||
| 	EBusyMoveState BusyMoveState = EBusyMoveState::None; | ||||
|  | ||||
| @ -5,31 +5,6 @@ | ||||
| #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; | ||||
| struct FInputActionValue; | ||||
|  | ||||
| @ -116,15 +91,6 @@ public: // 输入相关 | ||||
| 	TArray<FBusySkillActionConfig> RoleSkillActions; | ||||
|  | ||||
| public: | ||||
| 	UFUNCTION() | ||||
| 	void OnMove(const FInputActionValue& Value)const; | ||||
|  | ||||
| 	UFUNCTION() | ||||
| 	void OnPrimarySkill(const FInputActionValue& Value)const; | ||||
|  | ||||
| 	UFUNCTION() | ||||
| 	void OnUltimateSkill(const FInputActionValue& Value)const; | ||||
|  | ||||
| 	UFUNCTION() | ||||
| 	void OnCameraDetach(const FInputActionValue& Value); | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user