{"id":514,"date":"2024-10-07T19:36:20","date_gmt":"2024-10-07T11:36:20","guid":{"rendered":"https:\/\/www.vanforever.com.cn\/?p=514"},"modified":"2024-10-08T22:52:11","modified_gmt":"2024-10-08T14:52:11","slug":"ue-gas%e5%ad%a6%e4%b9%a0%e4%b9%8b%e8%b7%af","status":"publish","type":"post","link":"https:\/\/www.vanforever.com.cn\/?p=514","title":{"rendered":"UE GAS\u5b66\u4e60\u4e4b\u8def"},"content":{"rendered":"<div  class='collapse-block shadow-sm collapse-block-transparent collapsed hide-border-left'><div class='collapse-block-title'><span class='collapse-block-title-inner'>\u67e5\u770b\u7279\u8272\u56fe\u7247<\/span><i class='collapse-icon fa fa-angle-down'><\/i><\/div><div class='collapse-block-body' style='display:none;'><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/Vanforever\/20240610\/wallhaven-9dp83w_3840x2400.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large\" data-original=\"https:\/\/pic.vanforever.com.cn\/Vanforever\/20240610\/wallhaven-9dp83w_3840x2400.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" width=\"3840\" height=\"2400\" \/><\/div><\/div><\/div>\n<h1 id=\"uegas\u5b66\u4e60\u4e4b\u8def\">UEGAS\u5b66\u4e60\u4e4b\u8def<\/h1>\n<h2 id=\"\u5f00\u59cbgas\u5b66\u4e60\u4ee5\u53ca\u51b2\u523a\u529f\u80fd\">\u5f00\u59cbGAS\u5b66\u4e60\u4ee5\u53ca\u51b2\u523a\u529f\u80fd<\/h2>\n<p>\u9996\u5148\u6211\u4eec\u521b\u5efa\u4e24\u4e2a\u7c7b\uff0c\u4e00\u4e2a\u4ee5ActorComponent\u4e3a\u57fa\u7c7b\uff0c\u4e00\u4e2a\u4ee5Object\u4e3a\u57fa\u7c7b<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091801.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091801.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091802.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091802.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u6309\u4e0bAlt + O\u53ef\u4ee5\u76f4\u63a5\u5728\u5934\u6587\u4ef6\u548ccpp\u4e2d\u6765\u56de\u5207\u6362<\/p>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SActionComponent.h\n\/\/ Fill out your copyright notice in the Description page of Project Settings.\n\n#pragma once\n\n#include \"CoreMinimal.h\"\n#include \"Components\/ActorComponent.h\"\n#include \"SActionComponent.generated.h\"\n\n\nclass USAction;\n\nUCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )\nclass ACTIONROGUELIKE_API USActionComponent : public UActorComponent\n{\n\tGENERATED_BODY()\n\npublic:\t\n\tUFUNCTION(BlueprintCallable,Category=\"Actions\")\n\tvoid AddAction(TSubclassOf&lt;USAction&gt; ActionClass);\n\n\tUFUNCTION(BlueprintCallable,Category=\"Actions\")\n\tbool StartActionByName(AActor* Instigator,FName ActionName);\n\n\tUFUNCTION(BlueprintCallable,Category=\"Actions\")\n\tbool StopActionByName(AActor* Instigator,FName ActionName);\n    \n\t\/\/ Sets default values for this component's properties\n\tUSActionComponent();\n\nprotected:\n\n\tUPROPERTY()\n\tTArray&lt;USAction*&gt; Actions;\n\n\t\n\t\/\/ Called when the game starts\n\tvirtual void BeginPlay() override;\n\npublic:\t\n\t\/\/ Called every frame\n\tvirtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;\n\n\t\t\n};\n\n\/\/SActionComponent.cpp\n#include \"SActionComponent.h\"\n#include \"SAction.h\"\n\n\nUSActionComponent::USActionComponent()\n{\n\tPrimaryComponentTick.bCanEverTick = true;\n\n}\n\n\nvoid USActionComponent::BeginPlay()\n{\n\tSuper::BeginPlay();\n}\n\n\n\nvoid USActionComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)\n{\n\tSuper::TickComponent(DeltaTime, TickType, ThisTickFunction);\n\n}\n\nvoid USActionComponent::AddAction(TSubclassOf&lt;USAction&gt; ActionClass)\n{\n\tif(!ensure(ActionClass))\n\t{\n\t\treturn;\n\t}\n\n\tUSAction* NewAction  = NewObject&lt;USAction&gt;(this,ActionClass);\n\tif(ensure(NewAction))\n\t{\n\t\tActions.Add(NewAction);\n\t}\n\t\n}\n\nbool USActionComponent::StartActionByName(AActor* Instigator, FName ActionName)\n{\n\tfor(USAction* Action : Actions)\n\t{\n\t\tif(Action &amp;&amp; Action-&gt;ActionName == ActionName)\n\t\t{\n\t\t\tAction-&gt;StartAction(Instigator);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nbool USActionComponent::StopActionByName(AActor* Instigator, FName ActionName)\n{\n\tfor(USAction* Action : Actions)\n\t{\n\t\tif(Action &amp;&amp; Action-&gt;ActionName == ActionName)\n\t\t{\n\t\t\tAction-&gt;StopAction(Instigator);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n\n\n\n\/\/SAction.h\n\/\/ Fill out your copyright notice in the Description page of Project Settings.\n\n#pragma once\n\n#include \"CoreMinimal.h\"\n#include \"UObject\/NoExportTypes.h\"\n#include \"SAction.generated.h\"\n\n\/**\n * \n *\/\nUCLASS(Blueprintable)\nclass ACTIONROGUELIKE_API USAction : public UObject\n{\n\tGENERATED_BODY()\n\n\npublic:\n\tUFUNCTION(BlueprintNativeEvent,Category=\"Action\")\n\tvoid StartAction(AActor* Instigator);\n\n\tUFUNCTION(BlueprintNativeEvent,Category=\"Action\")\n\tvoid StopAction(AActor* Instigator);\n\n\tUPROPERTY(EditDefaultsOnly,Category=\"Action\")\n\tFName ActionName;\n\t\n};\n\n\n\/\/SAction.cpp\n\/\/ Fill out your copyright notice in the Description page of Project Settings.\n\n\n#include \"SAction.h\"\n\nvoid USAction::StartAction_Implementation(AActor* Instigator)\n{\n\tUE_LOG(LogTemp,Log,TEXT(\"Running: %s\") , *GetNameSafe(this));\n}\n\nvoid USAction::StopAction_Implementation(AActor* Instigator)\n{\n\tUE_LOG(LogTemp,Log,TEXT(\"Stopped: %s\") , *GetNameSafe(this));\n\n}\n\n\/\/Scharacter.h\nprotected:\n\tUPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category=\"Components\")\n\tUSActionComponent* ActionComp;\n\npublic:\n\tvoid SprintStart();\n\tvoid SprintStop();\n\n\/\/Scharacter.cpp\nASCharacter::ASCharacter()\n{\n\tActionComp = CreateDefaultSubobject&lt;USActionComponent&gt;(\"ActionComp\");\n}\n\nvoid ASCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)\n{\n\tPlayerInputComponent-&gt;BindAction(\"Sprint\",IE_Pressed,this,&amp;ASCharacter::SprintStart);\n\tPlayerInputComponent-&gt;BindAction(\"Sprint\",IE_Released,this,&amp;ASCharacter::SprintStop);\n\n}\n\nvoid ASCharacter::SprintStart()\n{\n\tActionComp-&gt;StartActionByName(this,\"Sprint\");\n}\n\nvoid ASCharacter::SprintStop()\n{\n\tActionComp-&gt;StopActionByName(this,\"Sprint\");\n}\n\n<\/code><\/pre>\n<p>\u4ee5SAction\u4e3a\u57fa\u7c7b\u521b\u5efa\u84dd\u56fe<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091803.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091803.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5728\u84dd\u56fe\u4e2d\u91cd\u8f7d\u51fd\u6570<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091804.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091804.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5728\u6309\u952e\u6620\u5c04\u4e2d\u81ea\u5b9a\u4e49<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091805.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091805.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5728Sprint\u84dd\u56fe\u4e2d\u6dfb\u52a0\u4e0b\u56fe\u7684\u5185\u5bb9<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091806.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091806.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u540c\u65f6\u4e5f\u8981\u6ce8\u610f\u521d\u59cb\u91cf\u7684\u8bbe\u7f6e<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091807.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091807.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5728PlayCharacter\u4e2d\u4e3a\u89d2\u8272\u6dfb\u52a0\u51b2\u523a\u7684\u7c7b<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091808.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091808.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<h2 id=\"\u521b\u5efa\u6295\u5c04\u7269\u653b\u51fb\">\u521b\u5efa\u6295\u5c04\u7269\u653b\u51fb<\/h2>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SAction_ProjectileAttack.h\n\/\/ Fill out your copyright notice in the Description page of Project Settings.\n\n#pragma once\n\n#include \"CoreMinimal.h\"\n#include \"SAction.h\"\n#include \"SAction_ProjectileAttack.generated.h\"\n\n\/**\n * \n *\/\nUCLASS()\nclass ACTIONROGUELIKE_API USAction_ProjectileAttack : public USAction\n{\n\tGENERATED_BODY()\n\n\tUPROPERTY(EditAnywhere, Category = \"Attack\")\n\tTSubclassOf&lt;AActor&gt; ProjectileClass;\n\n\tUPROPERTY(VisibleAnywhere, Category = \"Effects\")\n\tFName HandSocketName;\n\n\tUPROPERTY(EditDefaultsOnly, Category = \"Attack\")\n\tfloat AttackAnimDelay;\n\n\tUPROPERTY(EditAnywhere, Category = \"Attack\")\n\tUAnimMontage* AttackAnim;\n\n\t\/* Particle System played during attack animation *\/\n\tUPROPERTY(EditAnywhere, Category = \"Attack\")\n\tUParticleSystem* CastingEffect;\n\n\tUFUNCTION()\n\tvoid AttackDelay_Elapsed(ACharacter* InstigatorCharacter);\n\npublic:\n\n\tvirtual void StartAction_Implementation(AActor* Instigator) override;\n\n\tUSAction_ProjectileAttack();\n\t\n};\n\n\n\n\n\/\/SAction_ProjectileAttack.cpp\n\/\/ Fill out your copyright notice in the Description page of Project Settings.\n\n\n#include \"SAction_ProjectileAttack.h\"\n\n#include \"GameFramework\/Character.h\"\n#include \"Kismet\/GameplayStatics.h\"\n\nUSAction_ProjectileAttack::USAction_ProjectileAttack()\n{\n\tHandSocketName = \"Muzzle_01\";\n\tAttackAnimDelay = 0.2f;\n}\n\n\n\nvoid USAction_ProjectileAttack::StartAction_Implementation(AActor* Instigator)\n{\n\tSuper::StartAction_Implementation(Instigator);\n\n\tACharacter* Character = Cast&lt;ACharacter&gt;(Instigator);\n\n\tif(Character)\n\t{\n\t\tCharacter-&gt;PlayAnimMontage(AttackAnim);\n\t\tUGameplayStatics::SpawnEmitterAttached(CastingEffect, Character-&gt;GetMesh(), HandSocketName, FVector::ZeroVector, FRotator::ZeroRotator, EAttachLocation::SnapToTarget);\n\n\t\tFTimerHandle TimerHandle_AttackDelay;\n\t\tFTimerDelegate Delegate;\n\t\tDelegate.BindUFunction(this, \"AttackDelay_Elapsed\", Character);\n\n\t\tGetWorld()-&gt;GetTimerManager().SetTimer(TimerHandle_AttackDelay, Delegate, AttackAnimDelay, false);\n\t}\n}\n\nvoid USAction_ProjectileAttack::AttackDelay_Elapsed(ACharacter* InstigatorCharacter)\n{\n\t\n\tif (ensureAlways(ProjectileClass))\n\t{\n\t\tFVector HandLocation = InstigatorCharacter-&gt;GetMesh()-&gt;GetSocketLocation(HandSocketName);\n\n\t\tFActorSpawnParameters SpawnParams;\n\t\tSpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;\n\t\tSpawnParams.Instigator = InstigatorCharacter;\n\n\t\tFCollisionShape Shape;\n\t\tShape.SetSphere(20.0f);\n\n\t\t\/\/ Ignore Player\n\t\tFCollisionQueryParams Params;\n\t\tParams.AddIgnoredActor(InstigatorCharacter);\n\n\t\tFCollisionObjectQueryParams ObjParams;\n\t\tObjParams.AddObjectTypesToQuery(ECC_WorldDynamic);\n\t\tObjParams.AddObjectTypesToQuery(ECC_WorldStatic);\n\t\tObjParams.AddObjectTypesToQuery(ECC_Pawn);\n\n\t\tFVector TraceStart = InstigatorCharacter-&gt;GetPawnViewLocation();\n\n\t\t\/\/ endpoint far into the look-at distance (not too far, still adjust somewhat towards crosshair on a miss)\n\t\tFVector TraceEnd = TraceStart + (InstigatorCharacter-&gt;GetControlRotation().Vector() * 5000);\n\n\t\tFHitResult Hit;\n\t\t\/\/ returns true if we got to a blocking hit\n\t\tif (GetWorld()-&gt;SweepSingleByObjectType(Hit, TraceStart, TraceEnd, FQuat::Identity, ObjParams, Shape, Params))\n\t\t{\n\t\t\t\/\/ Overwrite trace end with impact point in world\n\t\t\tTraceEnd = Hit.ImpactPoint;\n\t\t}\n\n\t\t\/\/ find new direction\/rotation from Hand pointing to impact point in world.\n\t\tFRotator ProjRotation = FRotationMatrix::MakeFromX(TraceEnd - HandLocation).Rotator();\n\n\t\tFTransform SpawnTM = FTransform(ProjRotation, HandLocation);\n\t\tGetWorld()-&gt;SpawnActor&lt;AActor&gt;(ProjectileClass, SpawnTM, SpawnParams);\n\t}\n\n\tStopAction(InstigatorCharacter);\n}\n\n\/\/SAction.h\npublic:\n\tUWorld* GetWorld() const override;\n\n\/\/SAction.cpp\nUWorld* USAction::GetWorld() const\n{\n\t\/\/ Outer is set when creating action via NewObject&lt;T&gt;\n\tUActorComponent* Comp = Cast&lt;UActorComponent&gt;(GetOuter());\n\tif (Comp)\n\t{\n\t\treturn Comp-&gt;GetWorld();\n\t}\n\n\treturn nullptr;\n}\n\n\/\/SCharacter.cpp\n\/\/\u8fd9\u4e2aCpp\u4e2d\u51fd\u6570\u7684\u5185\u5bb9\u5373\u662f\u5168\u90e8\u7684\u5185\u5bb9\n\/\/ Fill out your copyright notice in the Description page of Project Settings.\n\n\n#include \"SCharacter.h\"\n\n#include \"SActionComponent.h\"\n#include \"SAttributeComponent.h\"\n#include \"SDashProjectile.h\"\n#include \"SInteractionComponent.h\"\n#include \"Chaos\/ChaosPerfTest.h\"\n#include \"GameFramework\/CharacterMovementComponent.h\"\n\n\/\/ Sets default values\nASCharacter::ASCharacter()\n{\n \t\/\/ Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.\n\tPrimaryActorTick.bCanEverTick = true;\n\n\tSpringArmComp = CreateDefaultSubobject&lt;USpringArmComponent&gt;(\"SpringarmComp\");\n\tSpringArmComp-&gt;SetupAttachment(RootComponent);\n\tSpringArmComp-&gt;bUsePawnControlRotation = true;\n\n\tCameraComp = CreateDefaultSubobject&lt;UCameraComponent&gt;(\"CameraComp\");\n\tCameraComp-&gt;SetupAttachment(SpringArmComp);\n\n\tInteractionComp = CreateDefaultSubobject&lt;USInteractionComponent&gt;(\"InteractionComp\");\n\n\tAttributeComp = CreateDefaultSubobject&lt;USAttributeComponent&gt;(\"AttributeComp\");\n\n\tActionComp = CreateDefaultSubobject&lt;USActionComponent&gt;(\"ActionComp\");\n\n\tGetCharacterMovement()-&gt;bOrientRotationToMovement = true;\n\t\n\tbUseControllerRotationYaw = false;\n\n\tTimeToHitParamName = \"TimeToHit\";\n\t\n\n}\n\nvoid ASCharacter::HealSelf(float Amount)\n{\n\tAttributeComp-&gt;ApplyHealthChange(this,Amount);\n}\n\nvoid ASCharacter::PostInitializeComponents()\n{\n\tSuper::PostInitializeComponents();\n\n\tAttributeComp-&gt;OnHealthChanged.AddDynamic(this,&amp;ASCharacter::OnHealthChanged);\n\t\n}\n\nFVector ASCharacter::GetPawnViewLocation() const\n{\n\treturn CameraComp-&gt;GetComponentLocation();\n}\n\n\/\/ Called when the game starts or when spawned\nvoid ASCharacter::BeginPlay()\n{\n\tSuper::BeginPlay();\n\t\n}\n\n\/\/ Called every frame\nvoid ASCharacter::Tick(float DeltaTime)\n{\n\tSuper::Tick(DeltaTime);\n\n}\n\nvoid ASCharacter::MoveForward(float value)\n{\n\tFRotator ControlRot = GetControlRotation();\n\tControlRot.Pitch = 0.0f;\n\tControlRot.Roll = 0.0f;\n\t\n\tAddMovementInput(ControlRot.Vector(),value);\n}\n\nvoid ASCharacter::MoveRight(float value)\n{\n\n\tFRotator ControlRot = GetControlRotation();\n\tControlRot.Pitch = 0.0f;\n\tControlRot.Roll = 0.0f;\n\t\n\tFVector RightVector = FRotationMatrix(ControlRot).GetScaledAxis(EAxis::Y);\n\t\n\tAddMovementInput(RightVector,value);\n}\n\nvoid ASCharacter::SprintStart()\n{\n\tActionComp-&gt;StartActionByName(this,\"Sprint\");\n}\n\nvoid ASCharacter::SprintStop()\n{\n\tActionComp-&gt;StopActionByName(this,\"Sprint\");\n}\n\n\nvoid ASCharacter::PrimaryAttack()\n{\t\n\tActionComp-&gt;StartActionByName(this, \"PrimaryAttack\");\n}\n\nvoid ASCharacter::BlackHoleAttack()\n{\n\t\n\tActionComp-&gt;StartActionByName(this, \"Blackhole\");\n}\n\nvoid ASCharacter::DashAttack()\n{\n\tActionComp-&gt;StartActionByName(this, \"Dash\");\n}\n\nvoid ASCharacter::PrimaryInteract()\n{\n\tif(InteractionComp)\n\t{\n\t\tInteractionComp-&gt;PrimaryInteract();\n\t}\n\t\n}\n\n\nvoid ASCharacter::OnHealthChanged(AActor* InstigatorActor, USAttributeComponent* OwningComp, float NewHealth,\n\tfloat Delta)\n{\n\t\/\/Die\n\tif(NewHealth &lt;= 0.0f &amp;&amp; Delta &lt;0.0f)\n\t{\n\t\tAPlayerController* PC = Cast&lt;APlayerController&gt;(GetController());\n\t\tDisableInput(PC);\n\t}\n\n\t\/\/ Damaged\n\tif (Delta &lt; 0.0f)\n\t{\n\t\tGetMesh()-&gt;SetScalarParameterValueOnMaterials(TimeToHitParamName, GetWorld()-&gt;TimeSeconds);\n\t}\n}\n\n\n\n\n\n\/\/ Called to bind functionality to input\nvoid ASCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)\n{\n\tSuper::SetupPlayerInputComponent(PlayerInputComponent);\n\n\tPlayerInputComponent-&gt;BindAxis(\"MoveForward\",this,&amp;ASCharacter::MoveForward);\n\tPlayerInputComponent-&gt;BindAxis(\"MoveRight\",this,&amp;ASCharacter::MoveRight);\n\n\tPlayerInputComponent-&gt;BindAxis(\"Turn\",this,&amp;APawn::AddControllerYawInput);\n\tPlayerInputComponent-&gt;BindAxis(\"LookUp\",this,&amp;APawn::AddControllerPitchInput);\n\n\tPlayerInputComponent-&gt;BindAction(\"Jump\",IE_Pressed,this,&amp;ACharacter::Jump);\n\t\n\tPlayerInputComponent-&gt;BindAction(\"PrimaryAttack\",IE_Pressed,this,&amp;ASCharacter::PrimaryAttack);\n\tPlayerInputComponent-&gt;BindAction(\"PrimaryInteract\",IE_Pressed,this,&amp;ASCharacter::PrimaryInteract);\n\n\tPlayerInputComponent-&gt;BindAction(\"BlackHoleAttack\",IE_Pressed,this,&amp;ASCharacter::BlackHoleAttack);\n\n\tPlayerInputComponent-&gt;BindAction(\"DashAttack\",IE_Pressed,this,&amp;ASCharacter::DashAttack);\n\n\tPlayerInputComponent-&gt;BindAction(\"Sprint\",IE_Pressed,this,&amp;ASCharacter::SprintStart);\n\tPlayerInputComponent-&gt;BindAction(\"Sprint\",IE_Released,this,&amp;ASCharacter::SprintStop);\n\n}\n\n\n\n\/\/SCharacter.h\n\/\/ Fill out your copyright notice in the Description page of Project Settings.\n\n#pragma once\n\n#include \"CoreMinimal.h\"\n#include \"Camera\/CameraComponent.h\"\n#include \"GameFramework\/Character.h\"\n#include \"GameFramework\/SpringArmComponent.h\"\n#include \"SCharacter.generated.h\"\n\n\nclass USActionComponent;\nclass USAttributeComponent;\nclass USInteractionComponent;\nclass UCameraComponent;\nclass USpringArmComponent;\nclass UAnimMontage;\n\nUCLASS()\nclass ACTIONROGUELIKE_API ASCharacter : public ACharacter\n{\n\tGENERATED_BODY() \npublic:\n\tASCharacter();\n\n\tUFUNCTION(Exec)\n\tvoid HealSelf(float Amount = 100);\n\nprotected:\n\n\tUPROPERTY(VisibleAnywhere,Category=\"Effects\")\n\tFName TimeToHitParamName;\n\n\tUPROPERTY(VisibleAnywhere)\n\tUCameraComponent* CameraComp;\n\n\tUPROPERTY(VisibleAnywhere)\n\tUSpringArmComponent* SpringArmComp;\n\n\tUPROPERTY(VisibleAnywhere)\n\tUSInteractionComponent* InteractionComp;\n\n\tUPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category=\"Components\")\n\tUSAttributeComponent* AttributeComp;\n\n\tUPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category=\"Components\")\n\tUSActionComponent* ActionComp;\n\n\t\/\/ Called when the game starts or when spawned\n\tvirtual void BeginPlay() override;\n\npublic:\t\n\t\/\/ Called every frame\n\tvirtual void Tick(float DeltaTime) override;\n\n\tvoid MoveForward(float value);\n\t\n\tvoid MoveRight(float value);\n\t\n\tvoid SprintStart();\n\t\n\tvoid SprintStop();\n\t\n\tvoid PrimaryAttack();\n\t\n\tvoid PrimaryInteract();\n\t\n\tvoid BlackHoleAttack();\n\t\n\tvoid DashAttack();\n\n\tUFUNCTION()\n\tvoid OnHealthChanged(AActor* InstigatorActor, USAttributeComponent* OwningComp, float NewHealth,float Delta);\n\n\tvirtual void PostInitializeComponents() override;\n\n\tvirtual FVector GetPawnViewLocation() const override;\n\n\t\n\t\/\/ Called to bind functionality to input\n\tvirtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;\n\n\n\t\n\t\n};\n\n<\/code><\/pre>\n<p>\u65b0\u5efa\u84dd\u56fe<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091809.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091809.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5728\u84dd\u56fe\u4e2d\u53ef\u4ee5\u4fee\u6539\u6211\u4eec\u60f3\u8981\u7684\u6295\u5c04\u7269\u7c7b\uff0c\u7279\u6548\uff0c\u52a8\u753b<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091810.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091810.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5728\u6211\u4eec\u7684\u89d2\u8272\u84dd\u56fe\u4e2d\u8fde\u7ebf\uff0c\u6dfb\u52a0\u6211\u4eec\u521a\u521a\u8bbe\u7f6e\u7684\u6280\u80fd<\/p>\n<p>\u8fd9\u91cc\u56fe\u4e2d\u7684\u7ea2\u6846\u4e2d\u8c03\u7528\u7684\u7c7b\u6709\u4e9b\u9519\u8bef\uff0c\u5e94\u8be5\u662fAction_MagicProjectile<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091811.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091811.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SActorComponents.h\nprotected:\n\t\/* Granted abilities at game start *\/\n\tUPROPERTY(EditAnywhere, Category = \"Actions\")\n\tTArray&lt;TSubclassOf&lt;USAction&gt;&gt; DefaultActions;\n\n\n\n\/\/SActorComponents.cpp\nvoid USActionComponent::BeginPlay()\n{\n\tSuper::BeginPlay();\n\n\tfor (TSubclassOf&lt;USAction&gt; ActionClass : DefaultActions)\n\t{\n\t\tAddAction(ActionClass);\n\t}\n}\n<\/code><\/pre>\n<p>\u5728\u4f18\u5316\u5b8c\u6211\u4eecScharacter\u7684\u67b6\u6784\u540e\uff0c\u5982\u4e4b\u524d\u4e00\u6837\uff0c\u6211\u4eec\u5c06\u6211\u4eec\u7684Dash,BlackHole\u6dfb\u52a0\u8fdb\u53bb,\u6211\u4eec\u8fd9\u4e00\u6b21\u4e0d\u4f7f\u7528\u5b50\u7c7b\uff0c\u6211\u4eec\u4f7f\u7528Duplicate<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091812.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091812.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u8fd9\u4e00\u6b21\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u6570\u7ec4\u76f4\u63a5\u6dfb\u52a0\u6211\u4eec\u7684\u6280\u80fd\u4e86<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091813.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091813.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u4e0a\u56fe\u4e2d\u7684\u84dd\u56fe\u5185\u5bb9\u5c31\u53ef\u4ee5\u5220\u9664\u4e86<\/p>\n<p>\u65e0\u610f\u95f4\u89e3\u51b3\u4e86\u4e4b\u524d\u6536\u5230\u653b\u51fb\u6ca1\u6709\u53cd\u9988\u7684\u60c5\u51b5<\/p>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SCharacter.h\n\tUPROPERTY(VisibleAnywhere,Category=\"Effects\")\n\tFName TimeToHitParamName;\n\n\/\/SCharacter.cpp\nASCharacter::ASCharacter()\n{\n\tTimeToHitParamName = \"TimeToHit\";\n}\n\nvoid ASCharacter::OnHealthChanged(AActor* InstigatorActor, USAttributeComponent* OwningComp, float NewHealth,\n\tfloat Delta)\n{\n\t\/\/ Damaged\n\tif (Delta &lt; 0.0f)\n\t{\n\t\tGetMesh()-&gt;SetScalarParameterValueOnMaterials(TimeToHitParamName, GetWorld()-&gt;TimeSeconds);\n\t}\n}\n\u5728SAICharacter\u4e2d\u7684bug\u5728\u4e8e\u5b57\u6bcd\u6572\u9519\u4e86\n    \n\/\/SAICharacter.cpp\nTimeToHitParamName = \"TimeToHit\";\n\u4e4b\u524d\u662fTimeOfHit\n<\/code><\/pre>\n<p>\u672c\u8282\u8bfe\u7684\u5185\u5bb9\u5c31\u7ed3\u675f\u4e86\uff0c\u4f46\u662f\u73b0\u5728\u4ecd\u6709\u4e00\u4e2a\u95ee\u9898\u505c\u7559\uff0c\u90a3\u5c31\u662f\u6211\u4eec\u53ef\u4ee5\u540c\u65f6\u6309\u4e0b\u5f88\u591a\u6309\u952e\uff0c\u8fd9\u5c06\u4f1a\u5bfc\u81f4\u6211\u4eec\u6295\u5c04\u7269\u5341\u5206\u6df7\u4e71<\/p>\n<h2 id=\"\u8bbe\u7f6e\u6e38\u620f\u4e2d\u7684tags\">\u8bbe\u7f6e\u6e38\u620f\u4e2d\u7684Tags<\/h2>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SActionComponent.h\nUPROPERTY(EditAnywhere,BlueprintReadWrite,Category=\"Tags\")\nFGameplayTagContainer ActiveGameplayTags;\n\n\/\/SActionComponent.cpp\nvoid USActionComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)\n{\n\tSuper::TickComponent(DeltaTime, TickType, ThisTickFunction);\n\tFString DebugMsg = GetNameSafe(GetOwner()) + \" : \" + ActiveGameplayTags.ToStringSimple();\n\tGEngine-&gt;AddOnScreenDebugMessage(-1, 0.0f, FColor::White, DebugMsg);\n}\n\n\/\/SAction.h\nprotected:\n\tUFUNCTION(BlueprintCallable, Category = \"Action\")\n\tUSActionComponent* GetOwningComponent() const;\n\n\t\/* Tags added to owning actor when activated, removed when action stops *\/\n\tUPROPERTY(EditDefaultsOnly, Category = \"Tags\")\n\tFGameplayTagContainer GrantsTags;\n\n\t\/* Action can only start if OwningActor has none of these Tags applied *\/\n\tUPROPERTY(EditDefaultsOnly, Category = \"Tags\")\n\tFGameplayTagContainer BlockedTags;\n\n\/\/SAction.cpp\nUSActionComponent* USAction::GetOwningComponent() const\n{\n\treturn Cast&lt;USActionComponent&gt;(GetOuter());\n}\n\nvoid USAction::StartAction_Implementation(AActor* Instigator)\n{\n\tUE_LOG(LogTemp,Log,TEXT(\"Running: %s\") , *GetNameSafe(this));\n\tUSActionComponent* Comp = GetOwningComponent();\t\n\tComp-&gt;ActiveGameplayTags.AppendTags(GrantsTags);\n\t\n}\n\nvoid USAction::StopAction_Implementation(AActor* Instigator)\n{\n\tUE_LOG(LogTemp,Log,TEXT(\"Stopped: %s\") , *GetNameSafe(this));\n\n\tUSActionComponent* Comp = GetOwningComponent();\n\tComp-&gt;ActiveGameplayTags.RemoveTags(GrantsTags);\n\n}\n<\/code><\/pre>\n<p>\u5728Gameplay Tag\u4e2d\u65b0\u5efaAction.Attacking Action.Sprinting<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091814.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091814.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u4e3aSprint\u8bbe\u7f6eGrant Tags\u548cBlocked Tags<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091815.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091815.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u4e3aAttack\u8bbe\u7f6eGrant Tags\u548cBlocked Tags<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091816.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091816.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5269\u4e0b\u7684Dash\u548cBlackHole\u4e5f\u505a\u540c\u6837\u7684\u5904\u7406<\/p>\n<p>\u63a5\u4e0b\u6765\u5f53\u6211\u4eecAttack\u6216\u8005Sprint\u7684\u65f6\u5019\uff0c\u5de6\u4e0a\u89d2\u5c31\u4f1a\u6709\u76f8\u5173\u7684\u63d0\u793a\uff0c\u4f46\u662f\u73b0\u5728\u6211\u4eec\u8fd8\u6ca1\u6709\u5b9e\u73b0\uff0c\u5f53Sprint\u65f6\u65e0\u6cd5Attack\uff0c\u672c\u8282\u8bfe\u5230\u6b64\u7ed3\u675f\u3002<\/p>\n<h2 id=\"\u5728\u7cfb\u7edf\u4e2d\u6bd4\u8f83tags\">\u5728\u7cfb\u7edf\u4e2d\u6bd4\u8f83Tags<\/h2>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SAction.h\npublic:\n\tUFUNCTION(BlueprintCallable, Category = \"Action\")\n\tbool IsRunning() const;\n\t\n\tUFUNCTION(BlueprintNativeEvent, Category = \"Action\")\n\tbool CanStart(AActor* Instigator);\n\nprotected:\n\tbool bIsRunning;\n\n\/\/SAction.cpp\nbool USAction::CanStart_Implementation(AActor* Instigator)\n{\n    if (IsRunning())\n\t{\n\t\treturn false;\n\t}\n    \n\tUSActionComponent* Comp = GetOwningComponent();\n\n\tif (Comp-&gt;ActiveGameplayTags.HasAny(BlockedTags))\n\t{\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool USAction::IsRunning() const\n{\n\treturn bIsRunning;\n}\n\n\nvoid USAction::StartAction_Implementation(AActor* Instigator)\n{\n\tbIsRunning = true;\t\n}\n\nvoid USAction::StopAction_Implementation(AActor* Instigator)\n{\n    ensureAlways(bIsRunning);\n\n\tbIsRunning = false;\n}\n\n\n\/\/SActionComponent.cpp\nbool USActionComponent::StartActionByName(AActor* Instigator, FName ActionName)\n{\n\tfor(USAction* Action : Actions)\n\t{\n\t\tif(Action &amp;&amp; Action-&gt;ActionName == ActionName)\n\t\t{\n\t\t\tif (!Action-&gt;CanStart(Instigator))\n\t\t\t{\n\t\t\t\tFString FailedMsg = FString::Printf(TEXT(\"Failed to run: %s\"), *ActionName.ToString());\n\t\t\t\tGEngine-&gt;AddOnScreenDebugMessage(-1, 2.0f, FColor::Red, FailedMsg);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t\n\t\t\tAction-&gt;StartAction(Instigator);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nbool USActionComponent::StopActionByName(AActor* Instigator, FName ActionName)\n{\n\tfor(USAction* Action : Actions)\n\t{\n\t\tif(Action &amp;&amp; Action-&gt;ActionName == ActionName)\n\t\t{\n\t\t\tif (Action-&gt;IsRunning())\n\t\t\t{\n\t\t\t\tAction-&gt;StopAction(Instigator);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n<\/code><\/pre>\n<p>\u5c06\u6211\u4eecAttackAction\u4e2d\u7684BlockedTag\u4e5f\u5c06AttackTag\u6dfb\u52a0\u4e0a\uff0c\u8fd9\u6837\u53ea\u80fd\u540c\u65f6\u6267\u884c\u4e00\u4e2a\u653b\u51fb<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091817.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091817.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<h2 id=\"\u7c7bdoom\u98ce\u683c\u7684\u95e8\u548c\u94a5\u5319\u5361\u7cfb\u7edf\">\u7c7bDOOM\u98ce\u683c\u7684\u95e8\u548c\u94a5\u5319\u5361\u7cfb\u7edf<\/h2>\n<p>\u5728GamePlayTag\u4e2d\u521b\u5efaKeyCard\u7684Tag<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091818.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091818.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5982\u56fe\u4e0b\u4fee\u6539LeverBP\u7684\u84dd\u56fe<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091819.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091819.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u4fee\u6539TreasureChest\u4e2d\u7684\u84dd\u56fe<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091820.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091820.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u6211\u4eec\u5c06Lever\u7684KeyCard\u8bbe\u7f6e\u4e3aBlue,\u5176\u4f59\u4e24\u4e2a\u7bb1\u5b50\u4e00\u4e2a\u4e3aBlue,\u4e00\u4e2a\u4e3aRed,\u5728\u62c9\u4e0b\u628a\u624b\u540e\uff0cBlue\u7684\u7bb1\u5b50\u80fd\u6b63\u5e38\u88ab\u73a9\u5bb6\u6253\u5f00<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091821.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091821.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<h2 id=\"\u4f7f\u7528tags\u5f39\u53cd\u653b\u51fb\">\u4f7f\u7528Tags\u5f39\u53cd\u653b\u51fb<\/h2>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SMagicProjectile.h\n\tUPROPERTY(EditDefaultsOnly, Category = \"Damage\")\n\tFGameplayTag ParryTag;\n\t\n\/\/SMagicProjectile.cpp\nvoid ASMagicProjectile::OnActorOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,\n\tUPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult&amp; SweepResult)\n{\n\tif(OtherActor &amp;&amp; OtherActor != GetInstigator())\n\t{\n\t\t\/\/FName Muzzle = \"Muzzle_01\";\n\n\t\t\/\/static FGameplayTag Tag = FGameplayTag::RequestGameplayTag(\"Status.Parrying\");\n\n\t\tUSActionComponent* ActionComp = Cast&lt;USActionComponent&gt;(OtherActor-&gt;GetComponentByClass(USActionComponent::StaticClass()));\n\t\tif (ActionComp &amp;&amp; ActionComp-&gt;ActiveGameplayTags.HasTag(ParryTag))\n\t\t{\n\t\t\tMovementComp-&gt;Velocity = -MovementComp-&gt;Velocity;\n\n\t\t\tSetInstigator(Cast&lt;APawn&gt;(OtherActor));\n\t\t\treturn;\n\t\t}\n\t\tif(USGameplayFunctionLibrary::ApplyDirctionalDamage(GetInstigator(),OtherActor,DamageAmount,SweepResult))\n\t\t{\n\t\t\tDestroy();\n\t\t}\n\t\t \n\t}\n}\n<\/code><\/pre>\n<p>\u521b\u5efa\u65b0\u7684Tag Status.Parrying<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091822.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091822.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5c06MagicProjectileBP\u7684Parry Tag\u8bbe\u7f6e\u4e3aStatus.Parring<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091823.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091823.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5c06SCharacter\u7684Tag\u4e5f\u8bbe\u7f6e\u4e3aStatus.Parring \u5f53Bots\u7684\u5b50\u5f39\u5c04\u4e2d\u73a9\u5bb6\u65f6\uff0c\u4f1a\u4ea7\u751f\u53cd\u5f39<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091824.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091824.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SAICharacter.h\nprotected:\n\tUPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = \"Components\")\n\tUSActionComponent* ActionComp;\n\n\n\/\/SAICharacter.cpp\nASAICharacter::ASAICharacter()\n{\n\tActionComp = CreateDefaultSubobject&lt;USActionComponent&gt;(\"ActionComp\");\t\n}\n<\/code><\/pre>\n<p>\u63a5\u4e0b\u6765\u6211\u4eec\u4e5f\u7ed9MinionRangedBP(\u673a\u5668\u4eba)\u6dfb\u52a0\u4e00\u4e2a\u76f8\u540c\u7684Tag,\u90a3\u4e48\u5b50\u5f39\u5c31\u4f1a\u5728\u6211\u4eec\u548c\u673a\u5668\u4eba\u4e4b\u95f4\u4e92\u76f8\u5f39\u5c04<\/p>\n<p>\u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u84dd\u56fe,Action_Parry<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091825.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091825.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SAction.h\nUFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = \"Action\")\nvoid StopAction(AActor* Instigator);\n\n<\/code><\/pre>\n<p>\u4fee\u6539Action_Parry\u7684\u84dd\u56fe\u5982\u4e0b,\u7136\u540e\u5c06\u4e4b\u524d\u6211\u4eec\u5728SCharacter\u548cMinionRangedBP\u84dd\u56fe\u4e2d\u8bbe\u7f6e\u7684TAG\u5220\u9664<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091826.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091826.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5728\u4e4b\u524d\u7684\u6570\u7ec4\u4e2d\u6dfb\u52a0Action_Parry<\/p>\n<p>\u5728\u8bbe\u7f6e\u4e2d\u7684Input\u4e2d\u6dfb\u52a0\u65b0\u7684\u6309\u952e\uff0c\u800c\u8fd9\u4e00\u6b21\u6211\u4eec\u5c06\u901a\u8fc7\u84dd\u56fe\u53bb\u5b9e\u73b0<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091827.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091827.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5982\u4e0b\u5728\u84dd\u56fe\u4e2d\u5b9e\u73b0<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091828.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091828.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5728DamagePopup_Widget\u4e2d\u521b\u5efa\u83b7\u53d6\u53d7\u5230\u4f24\u5bb3\u84dd\u56fe<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091829.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091829.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5728MinionRangedBP\u4e2d\u8bbe\u7f6e\u84dd\u56fe\uff0c\u5f53\u751f\u547d\u53d7\u4f24\u65f6\uff0c\u4ea7\u751f\u53d7\u5230\u4f24\u5bb3\u7684\u6570\u5b57<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091830.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240918\/2024091830.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<h2 id=\"\u71c3\u70e7\u6548\u679cbuff\">\u71c3\u70e7\u6548\u679cBUFF<\/h2>\n<p>\u9996\u5148\u4ee5SAction\u4e3a\u57fa\u7c7b\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u7c7b<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240919\/2024091901.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240919\/2024091901.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SActionEffect.h\n\/\/ Fill out your copyright notice in the Description page of Project Settings.\n\n#pragma once\n\n#include \"CoreMinimal.h\"\n#include \"SAction.h\"\n#include \"SActionEffect.generated.h\"\n\n\/**\n * \n *\/\nUCLASS()\nclass ACTIONROGUELIKE_API USActionEffect : public USAction\n{\n\tGENERATED_BODY()\n\npublic:\n\n\tvoid StartAction_Implementation(AActor* Instigator) override;\n\n\tvoid StopAction_Implementation(AActor* Instigator) override;\n\nprotected:\n\n\tUPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = \"Effect\")\n\tfloat Duration;\n\n\t\/* Time between 'ticks' to apply effect *\/\n\tUPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = \"Effect\")\n\tfloat Period;\n\n\tFTimerHandle PeriodHandle;\n\tFTimerHandle DurationHandle;\n\n\tUFUNCTION(BlueprintNativeEvent, Category = \"Effect\")\n\tvoid ExecutePeriodicEffect(AActor* Instigator);\n\npublic:\n\n\tUSActionEffect();\n};\n\n\n\n\/\/SActionEffect.cpp\n<\/code><\/pre>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SActionComponent.h\n\tUFUNCTION(BlueprintCallable,Category=\"Actions\")\n\tvoid AddAction(AActor* Instigator, TSubclassOf&lt;USAction&gt; ActionClass);\n\n\tUFUNCTION(BlueprintCallable, Category = \"Actions\")\n\tvoid RemoveAction(USAction* ActionToRemove);\n\n\n\/\/SActionComponent.cpp\nvoid USActionComponent::BeginPlay()\n{\n\tSuper::BeginPlay();\n\n\tfor (TSubclassOf&lt;USAction&gt; ActionClass : DefaultActions)\n\t{\n\t\tAddAction(GetOwner(),ActionClass);\n\t}\n}\n\nvoid USActionComponent::AddAction(AActor* Instigator,TSubclassOf&lt;USAction&gt; ActionClass)\n{\n\tif(!ensure(ActionClass))\n\t{\n\t\treturn;\n\t}\n\n\tUSAction* NewAction  = NewObject&lt;USAction&gt;(this,ActionClass);\n\tif(ensure(NewAction))\n\t{\n\t\tActions.Add(NewAction);\n\n\t\tif (NewAction-&gt;bAutoStart &amp;&amp; ensure(NewAction-&gt;CanStart(Instigator)))\n\t\t{\n\t\t\tNewAction-&gt;StartAction(Instigator);\n\t\t}\n\t}\n\t\n}\n\nvoid USActionComponent::RemoveAction(USAction* ActionToRemove)\n{\n\tif (!ensure(ActionToRemove &amp;&amp; !ActionToRemove-&gt;IsRunning()))\n\t{\n\t\treturn;\n\t}\n\n\tActions.Remove(ActionToRemove);\n}\n\n<\/code><\/pre>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SAction.h\npublic:\n\t\/* Start immediately when added to an action component *\/\n\tUPROPERTY(EditDefaultsOnly, Category = \"Action\")\n\tbool bAutoStart;\n<\/code><\/pre>\n<p>\u5728 Actions\u6587\u4ef6\u5939\u4e2d\u521b\u5efa\u65b0\u7684\u84dd\u56fe<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240919\/2024091902.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240919\/2024091902.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5982\u4e0b\u56fe\u4e2d\u8bbe\u7f6e\u84dd\u56fe\u5185\u5bb9\u548cclass\u7684\u9ed8\u8ba4\u503c<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240919\/2024091903.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240919\/2024091903.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SMagicProjectile.h\n\tUPROPERTY(EditDefaultsOnly, Category = \"Damage\")\n\tTSubclassOf&lt;USActionEffect&gt; BurningActionClass;\n\n\n\n\/\/SMagicProjectile.cpp\nif(USGameplayFunctionLibrary::ApplyDirctionalDamage(GetInstigator(),OtherActor,DamageAmount,SweepResult))\n\t\t{\n\t\t\tDestroy();\n\n\t\t\tif (ActionComp)\n\t\t\t{\n\t\t\t\tActionComp-&gt;AddAction(GetInstigator(), BurningActionClass);\n\t\t\t}\n\t\t}\n<\/code><\/pre>\n<p>\u5728MagicProjectileBP\u4e2d\uff0c\u5c06BuringActionClass\u8bbe\u7f6e<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240919\/2024091904.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240919\/2024091904.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<h2 id=\"\u4f7f\u7528ui\u53cd\u9988\u6539\u5584\u4ea4\u4e92\">\u4f7f\u7528UI\u53cd\u9988\u6539\u5584\u4ea4\u4e92<\/h2>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SInteractionComponent.h\nprotected:\n\tvoid FindBestInteractable();\n\n\/\/SInteractionComponent.cpp\n\/\/ Fill out your copyright notice in the Description page of Project Settings.\n\n\n#include \"SInteractionComponent.h\"\n\n#include \"SGameplayInterface.h\"\n#include \"SWorldUserWidget.h\"\n#include \"Blueprint\/UserWidget.h\"\n#include \"Evaluation\/Blending\/MovieSceneBlendType.h\"\n\n\nstatic TAutoConsoleVariable&lt;bool&gt; CVarDebugDrawInteraction(TEXT(\"su.InteractionDebugDraw\"), false, TEXT(\"Enable Debug Lines for Interact Component.\"), ECVF_Cheat);\n\n\n\/\/ Sets default values for this component's properties\nUSInteractionComponent::USInteractionComponent()\n{\n\t\/\/ Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features\n\t\/\/ off to improve performance if you don't need them.\n\tPrimaryComponentTick.bCanEverTick = true;\n\tTraceRadius = 30.0f;\n\tTraceDistance = 500.0f;\n\tCollisionChannel = ECC_WorldDynamic;\n\n\t\/\/ ...\n}\n\n\n\/\/ Called when the game starts\nvoid USInteractionComponent::BeginPlay()\n{\n\tSuper::BeginPlay();\n\n\t\/\/ ...\n\t\n}\n\n\n\n\n\/\/ Called every frame\nvoid USInteractionComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)\n{\n\tSuper::TickComponent(DeltaTime, TickType, ThisTickFunction);\n\n\tFindBestInteractable();\n}\n\nvoid USInteractionComponent::FindBestInteractable()\n{\n\tbool bDebugDraw = CVarDebugDrawInteraction.GetValueOnGameThread();\n\t\n\tFCollisionObjectQueryParams ObjectQueryParams;\n\tObjectQueryParams.AddObjectTypesToQuery(CollisionChannel);\n\n\tAActor* MyOwner =  GetOwner();\n\n\tFVector EyeLocation;\n\tFRotator EyeRotation;\n\tMyOwner-&gt;GetActorEyesViewPoint(EyeLocation,EyeRotation);\n\t\n\t\/*FHitResult Hit;\n\tbool bBlockingHit = GetWorld()-&gt;LineTraceSingleByObjectType(Hit,EyeLocation,End,ObjectQueryParams);*\/\n\n\tFVector End = EyeLocation + (EyeRotation.Vector() * TraceDistance);\n\t\n\tFCollisionShape Shape;\n\tTArray&lt;FHitResult&gt; Hits;\n\t\n\tShape.SetSphere(TraceRadius);\n\tbool bBlockingHit = GetWorld()-&gt;SweepMultiByObjectType(Hits,EyeLocation,End,FQuat::Identity,ObjectQueryParams,Shape);\n\tFColor LineColor = bBlockingHit ? FColor::Green : FColor::Red;\n\n\tFocusedActor = nullptr;\n\t\n\tfor(FHitResult Hit : Hits)\n\t{\n\t\tif(bDebugDraw)\n\t\t{\n\t\t\tDrawDebugSphere(GetWorld(),Hit.ImpactPoint,TraceRadius,32,LineColor,false,2.0f);\n\t\t}  \n\t\tAActor* HitActor =  Hit.GetActor();\n\t\tif(HitActor)\n\t\t{\n\t\t\tif(HitActor-&gt;Implements&lt;USGameplayInterface&gt;())\n\t\t\t{\n\t\t\t\tFocusedActor = HitActor;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t  \n\t}\n\n\tif (FocusedActor)\n\t{\n\t\tif (DefaultWidgetInstance == nullptr &amp;&amp; ensure(DefaultWidgetClass))\n\t\t{\n\t\t\tDefaultWidgetInstance = CreateWidget&lt;USWorldUserWidget&gt;(GetWorld(), DefaultWidgetClass);\n\t\t}\n\n\t\tif (DefaultWidgetInstance)\n\t\t{\n\t\t\tDefaultWidgetInstance-&gt;AttachedActor = FocusedActor;\n\n\t\t\tif (!DefaultWidgetInstance-&gt;IsInViewport())\n\t\t\t{\n\t\t\t\tDefaultWidgetInstance-&gt;AddToViewport();\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\tif (DefaultWidgetInstance)\n\t\t{\n\t\t\tDefaultWidgetInstance-&gt;RemoveFromParent();\n\t\t}\n\t}\n\t\n\tif(bDebugDraw)\n\t{\n\t\tDrawDebugLine(GetWorld(),EyeLocation,End,LineColor,false,2.0f,0,2.0f);\n\t}\n}\nvoid USInteractionComponent::PrimaryInteract()\n{\n\tif (FocusedActor == nullptr)\n\t{\n\t\tGEngine-&gt;AddOnScreenDebugMessage(-1, 1.0f, FColor::Red, \"No Focus Actor to interact.\");\n\t\treturn;\n\t}\n\n\tAPawn* MyPawn = Cast&lt;APawn&gt;(GetOwner());\n\n\tISGameplayInterface::Execute_Interact(FocusedActor, MyPawn);\n\n}\n\n<\/code><\/pre>\n<p>\u521b\u5efa\u65b0\u7684\u84dd\u56fe<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240922\/2024092201.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240922\/2024092201.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240922\/2024092202.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240922\/2024092202.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u5728SCharacter\u4e2d\u5c06\u9ed8\u8ba4\u7c7b\u8bbe\u7f6e<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240922\/2024092203.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240922\/2024092203.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u8fd9\u65f6\u5019\u6211\u4eec\u9760\u8fd1\u53ef\u4ee5\u4e92\u52a8\u7269\u4f53\u65f6\u5c31\u6709\u63d0\u793a\u4e86<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240922\/2024092204.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240922\/2024092204.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<h2 id=\"\u6012\u6c14\u8b66\u89c9\u7ec4\u4ef6\u53cd\u4f24\u6548\u679c\">\u6012\u6c14\uff0c&#8221;\u8b66\u89c9&#8221;\u7ec4\u4ef6,\u53cd\u4f24\u6548\u679c<\/h2>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SAttributeComponent.h\n\n\nDECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FOnHealthChanged, AActor*, InstigatorActor, USAttributeComponent*, OwningComp, float, NewHealth, float, Delta);\n\nDECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FOnAttributeChanged, AActor*, InstigatorActor, USAttributeComponent*, OwningComp, float, NewValue, float, Delta);\n\n\n\n\nprotected:\n\tUPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = \"Attributes\")\n\tfloat Rage;\n\n\tUPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = \"Attributes\")\n\tfloat RageMax;\n\npublic:\n\n\tUFUNCTION(BlueprintCallable, Category = \"Attributes\")\n\tbool Kill(AActor* InstigatorActor);\n\t\n\tUFUNCTION(BlueprintCallable, Category = \"Attributes\")\n\tbool IsAlive() const;\n\t\n\tUFUNCTION(NetMulticast, Reliable) \/\/ @FIXME: mark as unreliable once we moved the 'state' our of scharacter\n\tvoid MulticastHealthChanged(AActor* InstigatorActor, float NewHealth, float Delta);\n\n\tUFUNCTION(BlueprintCallable, Category = \"Attributes\")\n\tbool IsFullHealth() const;\n\n\tUFUNCTION(BlueprintCallable, Category = \"Attributes\")\n\tfloat GetHealthMax() const;\n\n\tUFUNCTION(BlueprintCallable, Category = \"Attributes\")\n\tfloat GetHealth() const;\n\t\n\tUPROPERTY(BlueprintAssignable, Category = \"Attributes\")\n\tFOnHealthChanged OnHealthChanged;\n\t\n\tUFUNCTION(BlueprintCallable,Category=\"Attributes\")\n\tbool ApplyHealthChange(AActor* InstigatorActor,float Delta);\n\n\tUPROPERTY(BlueprintAssignable, Category = \"Attributes\")\n\tFOnAttributeChanged OnRageChanged;\n\t\n\tUFUNCTION(BlueprintCallable)\n\tfloat GetRage() const;\n\n\tUFUNCTION(BlueprintCallable, Category = \"Attributes\")\n\tbool ApplyRage(AActor* InstigatorActor, float Delta);\n\n\/\/SAttributeComponent.cpp\nUSAttributeComponent::USAttributeComponent()\n{\n\tRage = 0;\n\tRageMax = 100;\n}\n<\/code><\/pre>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SCharacter.cpp\nvoid ASCharacter::OnHealthChanged(AActor* InstigatorActor, USAttributeComponent* OwningComp, float NewHealth,\n\tfloat Delta)\n{\n\t\/\/Die\n\tif(NewHealth &lt;= 0.0f &amp;&amp; Delta &lt;0.0f)\n\t{\n\t\tAPlayerController* PC = Cast&lt;APlayerController&gt;(GetController());\n\t\tDisableInput(PC);\n\t}\n\n\t\/\/ Damaged\n\tif (Delta &lt; 0.0f)\n\t{\n\t\tGetMesh()-&gt;SetScalarParameterValueOnMaterials(TimeToHitParamName, GetWorld()-&gt;TimeSeconds);\n\n\t\t\/\/ Rage added equal to damage received (Abs to turn into positive rage number)\n\t\tfloat RageDelta = FMath::Abs(Delta);\n\t\tAttributeComp-&gt;ApplyRage(InstigatorActor, RageDelta);\n\t}\n}\n<\/code><\/pre>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SAICharacter.h\nprotected:\n\n\t\/* Widget to display when bot first sees a player. *\/\n\tUPROPERTY(EditDefaultsOnly, Category = \"UI\")\n\tTSubclassOf&lt;UUserWidget&gt; SpottedWidgetClass;\n\t\n\tUSWorldUserWidget* ActiveHealthBar;\n \n\tUPROPERTY(EditDefaultsOnly,Category=\"UI\")\n\tTSubclassOf&lt;UUserWidget&gt; HealthBarWidgetClass;\n\n\n\t\/* Material parameter for Hitflashes *\/\n\tUPROPERTY(VisibleAnywhere,Category=\"Effects\")\n\tFName TimeToHitParamName;\n\n\t\/* Key for AI Blackboard 'TargetActor' *\/\n\tUPROPERTY(VisibleAnywhere, Category = \"Effects\")\n\tFName TargetActorKey;\n\n\tUFUNCTION(BlueprintCallable, Category = \"AI\")\n\tvoid SetTargetActor(AActor* NewTarget);\n\n\tUFUNCTION(BlueprintCallable, Category = \"AI\")\n\tAActor* GetTargetActor() const;\n\n\n\/\/SAICharacter.cpp\nASAICharacter::ASAICharacter()\n{\n\tTargetActorKey = \"TargetActor\";\n}\n\nvoid ASAICharacter::SetTargetActor(AActor* NewTarget)\n{\n\tAAIController* AIC = Cast&lt;AAIController&gt;(GetController());\n\tif(AIC)\n\t{\n\t\tAIC-&gt;GetBlackboardComponent()-&gt;SetValueAsObject(\"TargetActorKey\",NewTarget);\n\t}\n}\n\nAActor* ASAICharacter::GetTargetActor() const\n{\n\tAAIController* AIC = Cast&lt;AAIController&gt;(GetController());\n\tif (AIC)\n\t{\n\t\treturn Cast&lt;AActor&gt;(AIC-&gt;GetBlackboardComponent()-&gt;GetValueAsObject(TargetActorKey));\n\t}\n\n\treturn nullptr;\n}\n\nvoid ASAICharacter::OnPawnSeen(APawn* Pawn)\n{\n\t\/\/ Ignore if target already set\n\tif (GetTargetActor() != Pawn)\n\t{\n\t\tSetTargetActor(Pawn);\n\t\/*\n\tDrawDebugString(GetWorld(),GetActorLocation(),\"PlayerSpotted\",nullptr,FColor::White,4.0f,true);\n\t*\/\n\t\tUSWorldUserWidget* NewWidget = CreateWidget&lt;USWorldUserWidget&gt;(GetWorld(), SpottedWidgetClass);\n\t\tif (NewWidget)\n\t\t{\n\t\t\tNewWidget-&gt;AttachedActor = this;\n\t\t\t\/\/ Index of 10 (or anything higher than default of 0) places this on top of any other widget.\n\t\t\t\/\/ May end up behind the minion health bar otherwise.\n\t\t\tNewWidget-&gt;AddToViewport(10);\n\t\t}\n\t}\n\t\n}\n<\/code><\/pre>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SActionComponent.h\npublic:\n\/* Returns first occurance of action matching the class provided *\/\n\tUFUNCTION(BlueprintCallable, Category = \"Actions\")\n\tUSAction* GetAction(TSubclassOf&lt;USAction&gt; ActionClass) const;\n\n\/\/SActionComponent.cpp\nUSAction* USActionComponent::GetAction(TSubclassOf&lt;USAction&gt; ActionClass) const\n{\n\tfor (USAction* Action : Actions)\n\t{\n\t\tif (Action &amp;&amp; Action-&gt;IsA(ActionClass))\n\t\t{\n\t\t\treturn Action;\n\t\t}\n\t}\n\n\treturn nullptr;\n}\n<\/code><\/pre>\n<p>\u521b\u5efa\u4e24\u4e2a\u65b0\u7c7b\u8d1f\u8d23\u53cd\u4f24\u6548\u679c\u548c\u836f\u6c34\u74f6\u5728Action\u4e0a\u7684\u63a7\u5236<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240925\/2024092501.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240925\/2024092501.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SActionEffect_Thorns.h\n\/\/ Fill out your copyright notice in the Description page of Project Settings.\n\n#pragma once\n\n#include \"CoreMinimal.h\"\n#include \"SActionEffect.h\"\n#include \"SActionEffect_Thorns.generated.h\"\n\n\/**\n * \n *\/\nUCLASS()\nclass ACTIONROGUELIKE_API USActionEffect_Thorns : public USActionEffect\n{\n\tGENERATED_BODY()\n\n\nprotected:\n\tUPROPERTY(EditDefaultsOnly, Category = \"Thorns\")\n\tfloat ReflectFraction;\n\n\tUFUNCTION()\n\tvoid OnHealthChanged(AActor* InstigatorActor, USAttributeComponent* OwningComp, float NewHealth, float Delta);\n\npublic:\n\tvoid StartAction_Implementation(AActor* Instigator) override;\n\n\tvoid StopAction_Implementation(AActor* Instigator) override;\n\n\tUSActionEffect_Thorns();\n};\n\n\/\/SActionEffect_Thorns.cpp\n\/\/ Fill out your copyright notice in the Description page of Project Settings.\n\n\n#include \"SActionEffect_Thorns.h\"\n\n#include \"SActionComponent.h\"\n#include \"SAttributeComponent.h\"\n#include \"SGameplayFunctionLibrary.h\"\n\n\nUSActionEffect_Thorns::USActionEffect_Thorns()\n{\n\tReflectFraction = 0.2f;\n\n\tDuration = 0.0f;\n\tPeriod = 0.0f;\n}\n\nvoid USActionEffect_Thorns::OnHealthChanged(AActor* InstigatorActor, USAttributeComponent* OwningComp, float NewHealth,\n\tfloat Delta)\n{\n\tAActor* OwningActor = GetOwningComponent()-&gt;GetOwner();\n\n\t\/\/ Damage Only\n\tif (Delta &lt; 0.0f &amp;&amp; OwningActor != InstigatorActor)\n\t{\n\t\t\/\/ Round to nearest to avoid 'ugly' damage numbers and tiny reflections\n\t\tint32 ReflectedAmount = FMath::RoundToInt(Delta * ReflectFraction);\n\t\tif (ReflectedAmount == 0)\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\t\/\/ Flip to positive, so we don't end up healing ourselves when passed into damage\n\t\tReflectedAmount = FMath::Abs(ReflectedAmount);\n\n\t\t\/\/ Return damage sender...\n\t\tUSGameplayFunctionLibrary::ApplyDamage(OwningActor, InstigatorActor, ReflectedAmount);\n\t}\t\n}\n\nvoid USActionEffect_Thorns::StartAction_Implementation(AActor* Instigator)\n{\n\tSuper::StartAction_Implementation(Instigator);\n\t\n\t\/\/ Start listening\n\tUSAttributeComponent* Attributes = USAttributeComponent::GetAttributes(GetOwningComponent()-&gt;GetOwner());\n\tif (Attributes)\n\t{\n\t\tAttributes-&gt;OnHealthChanged.AddDynamic(this, &amp;USActionEffect_Thorns::OnHealthChanged);\n\t}\n}\n\nvoid USActionEffect_Thorns::StopAction_Implementation(AActor* Instigator)\n{\n\tSuper::StopAction_Implementation(Instigator);\n\n\t\/\/ Stop listening\n\tUSAttributeComponent* Attributes = USAttributeComponent::GetAttributes(GetOwningComponent()-&gt;GetOwner());\n\tif (Attributes)\n\t{\n\t\tAttributes-&gt;OnHealthChanged.RemoveDynamic(this, &amp;USActionEffect_Thorns::OnHealthChanged);\n\t}\n}\n\n<\/code><\/pre>\n<pre><code class=\"language-cpp\" lang=\"cpp\">\/\/SPowerup_Action.h\n\/\/ Fill out your copyright notice in the Description page of Project Settings.\n\n#pragma once\n\n#include \"CoreMinimal.h\"\n#include \"SPowerupActor.h\"\n#include \"SPowerup_Action.generated.h\"\n\n\/**\n * \n *\/\nUCLASS()\nclass ACTIONROGUELIKE_API ASPowerup_Action : public ASPowerupActor\n{\n\tGENERATED_BODY()\n\nprotected:\n\tUPROPERTY(EditAnywhere, Category = \"Powerup\")\n\tTSubclassOf&lt;USAction&gt; ActionToGrant;\n\npublic:\n\tvoid Interact_Implementation(APawn* InstigatorPawn) override;\n\n};\n\n\/\/SPowerup_Action.cpp\n\/\/ Fill out your copyright notice in the Description page of Project Settings.\n\n\n#include \"SPowerup_Action.h\"\n\n#include \"SAction.h\"\n#include \"SActionComponent.h\"\n\nclass USActionComponent;\n\nvoid ASPowerup_Action::Interact_Implementation(APawn* InstigatorPawn)\n{\n\tSuper::Interact_Implementation(InstigatorPawn);\n\n\t\/\/ Make sure we have instigator &amp; that action class was set up\n\tif (!ensure(InstigatorPawn &amp;&amp; ActionToGrant))\n\t{\n\t\treturn;\n\t}\n\n\tUSActionComponent* ActionComp = Cast&lt;USActionComponent&gt;(InstigatorPawn-&gt;GetComponentByClass(USActionComponent::StaticClass()));\n\t\/\/ Check if Player already has action class\n\tif (ActionComp)\n\t{\n\t\tif (ActionComp-&gt;GetAction(ActionToGrant))\n\t\t{\n\t\t\t\/\/UE_LOG(LogTemp, Log, TEXT(\"Instigator already has action of class: %s\"), *GetNameSafe(ActionToGrant));\n\t\t\tFString DebugMsg = FString::Printf(TEXT(\"Action '%s' already known.\"), *GetNameSafe(ActionToGrant));\n\t\t\tGEngine-&gt;AddOnScreenDebugMessage(-1, 2.0f, FColor::Red, DebugMsg);\n\t\t\treturn;\n\t\t}\n\n\t\t\/\/ Give new Ability\n\t\tActionComp-&gt;AddAction(InstigatorPawn, ActionToGrant);\t\n\t\tHideAndCooldownPowerup();\n\t}\n}\n\n<\/code><\/pre>\n<p>\u5728Action_Blackhole\u4e2d\u4fee\u6539\u84dd\u56fe<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240925\/2024092502.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240925\/2024092502.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u8fd9\u662f\u91cd\u8f7d\u51fd\u6570Can Start\u7684\u84dd\u56fe<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240925\/2024092503.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240925\/2024092503.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n<p>\u4e3a\u6211\u4eec\u7684\u6012\u6c14\u503c\u521b\u5efa\u4e00\u4e2a\u65b0\u7684Widget\uff0c\u7136\u540e\u84dd\u56fe\u5982\u4e0b\u8fde\u63a5<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240925\/2024092504.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/pic.vanforever.com.cn\/UE\/GAS\/20240925\/2024092504.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" \/><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>UEGAS\u5b66\u4e60\u4e4b\u8def \u5f00\u59cbGAS\u5b66\u4e60\u4ee5\u53ca\u51b2\u523a\u529f\u80fd \u9996\u5148\u6211\u4eec\u521b\u5efa\u4e24\u4e2a\u7c7b\uff0c\u4e00\u4e2a\u4ee5ActorComponent\u4e3a\u57fa\u7c7b\uff0c [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,27],"tags":[5],"class_list":["post-514","post","type-post","status-publish","format-standard","hentry","category-ue","category-cs193u","tag-ue"],"_links":{"self":[{"href":"https:\/\/www.vanforever.com.cn\/index.php?rest_route=\/wp\/v2\/posts\/514","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.vanforever.com.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.vanforever.com.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.vanforever.com.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vanforever.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=514"}],"version-history":[{"count":3,"href":"https:\/\/www.vanforever.com.cn\/index.php?rest_route=\/wp\/v2\/posts\/514\/revisions"}],"predecessor-version":[{"id":517,"href":"https:\/\/www.vanforever.com.cn\/index.php?rest_route=\/wp\/v2\/posts\/514\/revisions\/517"}],"wp:attachment":[{"href":"https:\/\/www.vanforever.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=514"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.vanforever.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=514"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.vanforever.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=514"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}