通过GAS实现狐狸的技能,还差碰撞、参数配置化、消耗和冷却
This commit is contained in:
@ -8,11 +8,14 @@ FastReplication=False
|
||||
InvalidTagCharacters="\"\',"
|
||||
NumBitsForContainerSize=6
|
||||
NetIndexFirstBitSegment=16
|
||||
+GameplayTagList=(Tag="Ability.Block.UltimatePlaying",DevComment="大招正在释放中")
|
||||
+GameplayTagList=(Tag="Ability.Flags.Recast",DevComment="可以再次释放技能的标记")
|
||||
+GameplayTagList=(Tag="Ability.Role.AttributeConsume",DevComment="角色属性损耗debuff")
|
||||
+GameplayTagList=(Tag="Ability.Role.EatFood",DevComment="干饭")
|
||||
+GameplayTagList=(Tag="Ability.Role.Pick",DevComment="角色采集物品")
|
||||
+GameplayTagList=(Tag="Ability.Role.Recover",DevComment="角色状态恢复技能")
|
||||
+GameplayTagList=(Tag="Ability.Role.Roll",DevComment="角色无敌翻滚")
|
||||
+GameplayTagList=(Tag="Ability.Role.Ultimate",DevComment="角色大招")
|
||||
+GameplayTagList=(Tag="Buff.Indispersible.HungerConsume",DevComment="饥饿值消耗,不可被驱散")
|
||||
+GameplayTagList=(Tag="Buff.RoleConsume.Health",DevComment="角色因饥饿掉血的debuff")
|
||||
+GameplayTagList=(Tag="Buff.RoleConsume.Hunger",DevComment="角色每秒钟的饥饿消耗")
|
||||
@ -25,6 +28,8 @@ NetIndexFirstBitSegment=16
|
||||
+GameplayTagList=(Tag="CookProcess.Diced",DevComment="切丁")
|
||||
+GameplayTagList=(Tag="CookProcess.Mashed",DevComment="切泥")
|
||||
+GameplayTagList=(Tag="CookProcess.Sliced",DevComment="切片操作")
|
||||
+GameplayTagList=(Tag="Effect.Duration",DevComment="效果的持续时长")
|
||||
+GameplayTagList=(Tag="Effect.Factor",DevComment="效果的乘法系数")
|
||||
+GameplayTagList=(Tag="GameItem.Building",DevComment="建筑物")
|
||||
+GameplayTagList=(Tag="GameItem.Food",DevComment="游戏内的可食用物品")
|
||||
+GameplayTagList=(Tag="Ingredient",DevComment="烹饪食材")
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/Gas/Ability/Role/Fox/GA_FoxUltimate.uasset
Normal file
BIN
Content/Gas/Ability/Role/Fox/GA_FoxUltimate.uasset
Normal file
Binary file not shown.
BIN
Content/Gas/Effects/Role/Fox/GE_Accelerate.uasset
Normal file
BIN
Content/Gas/Effects/Role/Fox/GE_Accelerate.uasset
Normal file
Binary file not shown.
BIN
Content/Gas/Effects/Role/Fox/GE_UltimateRecast.uasset
Normal file
BIN
Content/Gas/Effects/Role/Fox/GE_UltimateRecast.uasset
Normal file
Binary file not shown.
@ -1,3 +1,4 @@
|
||||
--- @class BusyGameplayLibrary
|
||||
--- @field K2_GetWorld fun(obj:table):table
|
||||
--- @field RequestGameplayTag fun(TagName:string):GameplayTag
|
||||
local BusyGameplayLibrary = {}
|
||||
@ -29,7 +29,14 @@ KismetSystemLibrary = {
|
||||
}
|
||||
|
||||
|
||||
--- @class GameplayTag
|
||||
local GameplayTag
|
||||
|
||||
--- @class GameplayStatics
|
||||
--- @field GetPlayerController fun(uobj:table,idx:number):table
|
||||
--- @field GetGameState fun(uobj:table):table
|
||||
local GameplayStatics
|
||||
|
||||
--- @class AbilitySystemBlueprintLibrary
|
||||
--- @field AssignTagSetByCallerMagnitude fun(SpecHandle:table, DataTag:GameplayTag, Magnitude:number)
|
||||
local AbilitySystemBlueprintLibrary
|
||||
|
||||
4
Content/Lua/Gas/Ability/Common/MoveAbility.lua
Normal file
4
Content/Lua/Gas/Ability/Common/MoveAbility.lua
Normal file
@ -0,0 +1,4 @@
|
||||
local MoveAbility = {}
|
||||
|
||||
|
||||
return Class(nil, nil, MoveAbility)
|
||||
153
Content/Lua/Gas/Ability/Role/Fox/FoxUltimate.lua
Normal file
153
Content/Lua/Gas/Ability/Role/Fox/FoxUltimate.lua
Normal file
@ -0,0 +1,153 @@
|
||||
local GameplayStatics = import("GameplayStatics")
|
||||
local AbilitySystemBlueprintLibrary = import("AbilitySystemBlueprintLibrary")
|
||||
local BusyGameplayLibrary = import("BusyGameplayLibrary")
|
||||
|
||||
--- @class FoxUltimate
|
||||
--- @field RecastWindow number
|
||||
local FoxUltimate = {}
|
||||
|
||||
|
||||
function FoxUltimate:ctor()
|
||||
self.ultimate_phase = 1 -- 大招阶段
|
||||
self.active_recast_handle = nil
|
||||
self.active_accelerate_handle = nil
|
||||
end
|
||||
|
||||
|
||||
function FoxUltimate:K2_ActivateAbilityFromEvent(EventData)
|
||||
print("FoxUltimate:K2_ActivateAbilityFromEvent", self.ultimate_phase)
|
||||
|
||||
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")
|
||||
|
||||
local asc = self.asc
|
||||
|
||||
if self.ultimate_phase == 1 or asc:HasMatchingGameplayTag(self.recast_tag) then
|
||||
print("triggered")
|
||||
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)
|
||||
local _, recast_effect = self:GetAbilityEffectSpecHandle("Recast", asc, 1, nil)
|
||||
self.active_recast_handle = asc:BP_ApplyGameplayEffectSpecToSelf(recast_effect)
|
||||
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)
|
||||
self.ultimate_phase = self.ultimate_phase + 1
|
||||
entry.AnimationComplete:Clear()
|
||||
entry.AnimationEvent:Clear()
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
return Class(nil, nil, FoxUltimate)
|
||||
4
Content/Lua/Gas/Ability/Role/Rabbit/RabbitUltimate.lua
Normal file
4
Content/Lua/Gas/Ability/Role/Rabbit/RabbitUltimate.lua
Normal file
@ -0,0 +1,4 @@
|
||||
local RabbitUltimate = {}
|
||||
|
||||
|
||||
return Class(nil, nil, RabbitUltimate)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -78,3 +78,20 @@ bool UBusyGameplayLibrary::GetItemDescription(const FName& RowName, FBusyItemDes
|
||||
bool UBusyGameplayLibrary::GetCookMaterialStateConfig(const FName& RowName, FBusyCookMaterialStateConfig& RowData){
|
||||
return GetTableConfig<FBusyCookMaterialStateConfig>(TEXT("CookMaterialStateConfig"), RowName, RowData);
|
||||
}
|
||||
|
||||
FGameplayTag UBusyGameplayLibrary::RequestGameplayTag(const FName& TagName)
|
||||
{
|
||||
return FGameplayTag::RequestGameplayTag(TagName);
|
||||
}
|
||||
|
||||
#pragma optimize("",off)
|
||||
FGameplayTagContainer UBusyGameplayLibrary::RequestGameplayTags(const TArray<FName>& TagNames)
|
||||
{
|
||||
TArray<FGameplayTag> GameplayTags;
|
||||
for (const FName& TagName : TagNames)
|
||||
{
|
||||
GameplayTags.Add(FGameplayTag::RequestGameplayTag(TagName));
|
||||
}
|
||||
return FGameplayTagContainer::CreateFromArray(GameplayTags);
|
||||
}
|
||||
#pragma optimize("",on)
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
#include "LuaCppBinding.h"
|
||||
#include "AbilitySystemComponent.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
using slua::lua_State, slua::LuaObject, slua::LuaStruct;
|
||||
using namespace slua;
|
||||
|
||||
|
||||
#pragma optimize( "", off )
|
||||
|
||||
|
||||
bool HasMatchingGameplayTag(const UAbilitySystemComponent& Asc, const FName& TagName)
|
||||
{
|
||||
// return Asc.HasMatchingGameplayTag(FGameplayTag::RequestGameplayTag(TagName));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
extern void RegisterAbilitySystemComponentExtension() {
|
||||
REG_EXTENSION_METHOD_LAMBDA(UAbilitySystemComponent, "AHasMatchingGameplayTag", false,
|
||||
[](UAbilitySystemComponent* ASC, const FName& Tag) -> bool {
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#pragma optimize( "", on)
|
||||
|
||||
@ -1,30 +1,6 @@
|
||||
#include "LuaCppBinding.h"
|
||||
|
||||
using namespace slua;
|
||||
|
||||
//static int LuaBinding_FindRow(lua_State* L) {
|
||||
// UDataTable* DataTable = LuaObject::checkUD<UDataTable>(L, 1);
|
||||
// FName RowName = LuaObject::checkValue<FName>(L, 2);
|
||||
//
|
||||
// UScriptStruct* RowStruct = (UScriptStruct*)DataTable->GetRowStruct();
|
||||
//
|
||||
// uint8* RowData = DataTable->FindRowUnchecked(RowName);
|
||||
//
|
||||
// if (RowData && RowStruct) {
|
||||
// // <20><><EFBFBD><EFBFBD> LuaStruct <20><>װ<EFBFBD><D7B0>
|
||||
// uint32 size = RowStruct->GetStructureSize() ? RowStruct->GetStructureSize() : 1;
|
||||
// uint8* buf = (uint8*)FMemory::Malloc(size);
|
||||
// RowStruct->InitializeStruct(buf);
|
||||
// RowStruct->CopyScriptStruct(buf, RowData);
|
||||
//
|
||||
// LuaStruct* ls = new LuaStruct();
|
||||
// ls->Init(buf, size, RowStruct, false);
|
||||
// return LuaObject::push(L, ls);
|
||||
// }
|
||||
// else {
|
||||
// return LuaObject::pushNil(L);
|
||||
// }
|
||||
//}
|
||||
|
||||
static int LuaBinding_FindRow(lua_State* L) {
|
||||
UDataTable* DataTable = LuaObject::checkUD<UDataTable>(L, 1);
|
||||
@ -37,24 +13,13 @@ static int LuaBinding_FindRow(lua_State* L) {
|
||||
LuaStruct* luaStruct = new LuaStruct();
|
||||
luaStruct->Init((uint8*)TableRow, rowStruct->GetStructureSize(), (UScriptStruct*)rowStruct, true);
|
||||
|
||||
LuaObject::addLink(L, TableRow); // ȷ<><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
LuaObject::addLink(L, TableRow);
|
||||
|
||||
//auto ret = LuaObject::push(L, luaStruct);
|
||||
return LuaObject::pushReference<LuaStruct*>(L, luaStruct, TableRow);
|
||||
}
|
||||
|
||||
|
||||
//FTableRowBase* tableRow = DataTable->FindRow<FTableRowBase>(RowName, TEXT(""));
|
||||
//
|
||||
//UScriptStruct* rowStruct = DataTable->GetRowStruct();
|
||||
//
|
||||
//LuaStruct* luaStruct = new LuaStruct();
|
||||
//luaStruct->Init((uint8*)tableRow, rowStruct->GetStructureSize(), rowStruct, true);
|
||||
//
|
||||
//int ret = LuaObject::push(L, luaStruct);
|
||||
|
||||
|
||||
|
||||
extern void RegisterDataTableExtension() {
|
||||
REG_EXTENSION_METHOD_IMP(UDataTable, "FindRow", { return LuaBinding_FindRow(L); });
|
||||
}
|
||||
|
||||
33
Source/BusyRabbit/Private/Gas/BusyGameAbility.cpp
Normal file
33
Source/BusyRabbit/Private/Gas/BusyGameAbility.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
#include "Gas/BusyGameAbility.h"
|
||||
#include "AbilitySystemBlueprintLibrary.h"
|
||||
#include "AbilitySystemComponent.h"
|
||||
|
||||
UBusyGameAbility::UBusyGameAbility()
|
||||
{
|
||||
bHasBlueprintActivateFromEvent = true;
|
||||
}
|
||||
|
||||
FString UBusyGameAbility::GetLuaFilePath_Implementation()const
|
||||
{
|
||||
return LuaFilePath;
|
||||
}
|
||||
|
||||
bool UBusyGameAbility::GetAbilityEffectSpecHandle(const FName& EffectName, const UAbilitySystemComponent* Asc, const int32 Level,
|
||||
FGameplayEffectSpecHandle& Handle) const
|
||||
{
|
||||
// 1. 查找对应的GameplayEffectClass
|
||||
const TSubclassOf<UGameplayEffect> *EffectClass = AbilityEffects.Find(EffectName);
|
||||
if (!EffectClass) return false;
|
||||
|
||||
// 2. 创建并设置GameplayEffect上下文
|
||||
FGameplayEffectContextHandle EffectContextHandle = Asc->MakeEffectContext();
|
||||
|
||||
// 3. 将当前对象设置为效果来源
|
||||
EffectContextHandle.AddSourceObject(this);
|
||||
|
||||
// 4. 创建GameplayEffectSpecHandle
|
||||
Handle = Asc->MakeOutgoingSpec(*EffectClass, 1.f, EffectContextHandle); // 这里的1.f是等级
|
||||
|
||||
return Handle.IsValid();
|
||||
}
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
#include "Level/Actor/BusyPawnBase.h"
|
||||
|
||||
#include "BusyGameplayLibrary.h"
|
||||
#include "Components/SphereComponent.h"
|
||||
#include "SpineSkeletonRendererComponent.h"
|
||||
#include "SpineSkeletonAnimationComponent.h"
|
||||
#include "Gas/BusyGameAbility.h"
|
||||
#include "Level/Actor/Components/BusyPawnMovement.h"
|
||||
#include "Tables/BusyPawnConfig.h"
|
||||
|
||||
DEFINE_LOG_CATEGORY(LogBusyPawn)
|
||||
|
||||
@ -30,38 +34,46 @@ void ABusyPawnBase::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
// for (UClass* AbilityClass : Row->DefaultAbilities) {
|
||||
// if (AbilityClass) {
|
||||
// AbilitySystemComponent->GiveAbility(FGameplayAbilitySpec(AbilityClass));
|
||||
// }
|
||||
// }
|
||||
if (const UDataTable* DataTable = UBusyGameplayLibrary::GetGameDataTable("LevelRoleBaseConfig"))
|
||||
{
|
||||
const FBusyPawnBaseConfig* Config = DataTable->FindRow<FBusyPawnBaseConfig>(
|
||||
PawnName, FString::Printf(TEXT("ABusyPawnBase::BeginPlay Find %s in LevelRoleBaseConfig"), *PawnName.ToString())
|
||||
);
|
||||
if (Config)
|
||||
{
|
||||
InitPawnAbilities(*+Config);
|
||||
InitPawnAttributes(*Config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float ABusyPawnBase::GetSpeed_Implementation()const
|
||||
{
|
||||
if (Attribute)
|
||||
if (Attributes)
|
||||
{
|
||||
return Attribute->GetMoveSpeed();
|
||||
return Attributes->GetMoveSpeed();
|
||||
}
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
void ABusyPawnBase::InitMoveSpeed(const float MoveSpeed)const
|
||||
void ABusyPawnBase::InitPawnAttributes(const FBusyPawnBaseConfig& Config)
|
||||
{
|
||||
if (Attribute)
|
||||
if (Attributes)
|
||||
{
|
||||
Attribute->InitMoveSpeed(MoveSpeed);
|
||||
Attributes->InitHealth(Config.Health);
|
||||
Attributes->InitMaxHealth(Config.Health);
|
||||
Attributes->InitMoveSpeed(Config.MoveSpeed);
|
||||
Attributes->InitDamage(Config.Damage);
|
||||
Attributes->InitDefense(Config.Defense);
|
||||
}
|
||||
}
|
||||
|
||||
void ABusyPawnBase::InitHealth(const float Health, const float MaxHealth) const
|
||||
void ABusyPawnBase::InitPawnAbilities(const FBusyPawnBaseConfig& Config)const
|
||||
{
|
||||
if (Attribute)
|
||||
for (const TSubclassOf<UGameplayAbility>& Ability : Config.DefaultAbilities)
|
||||
{
|
||||
Attribute->InitHealth(Health);
|
||||
Attribute->InitMaxHealth(MaxHealth);
|
||||
AbilitySystemComponent->GiveAbility(FGameplayAbilitySpec(Ability));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -19,46 +19,31 @@ ABusyPlayerRole::ABusyPlayerRole()
|
||||
|
||||
SpringArmComponent->SetRelativeRotation(FRotator(0, -90.0, 0.0));
|
||||
|
||||
Attribute = CreateDefaultSubobject<UBusyPlayerRoleAttributeSet>(TEXT("Attribute"));
|
||||
|
||||
InitMoveSpeed(200);
|
||||
InitHealth(100, 100);
|
||||
Attributes = CreateDefaultSubobject<UBusyPlayerRoleAttributeSet>(TEXT("Attribute"));
|
||||
}
|
||||
|
||||
void ABusyPlayerRole::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
InitRoleAttributes();
|
||||
}
|
||||
|
||||
bool ABusyPlayerRole::InitRoleAttributes()
|
||||
void ABusyPlayerRole::InitPawnAttributes(const struct FBusyPawnBaseConfig& Config)
|
||||
{
|
||||
if (!PawnName.IsValid()) return false;
|
||||
const UDataTable* ConfigTable = UBusyGameplayLibrary::GetGameDataTable(TEXT("LevelRoleBaseConfig"));
|
||||
if (!ConfigTable)
|
||||
{
|
||||
UE_LOG(LogBusyPawn, Log, TEXT("ABusyPlayerRole::InitRoleAttributes Can't find config table: LevelRoleBaseConfig"))
|
||||
return false;
|
||||
}
|
||||
|
||||
const FBusyRoleBaseConfig* Result = ConfigTable->FindRow<FBusyRoleBaseConfig>(
|
||||
PawnName,
|
||||
*FString::Printf(TEXT("ABusyPlayerRole::InitRoleAttributes, PawnName: %ls"), *PawnName.ToString())
|
||||
);
|
||||
if (Result)
|
||||
{
|
||||
UBusyPlayerRoleAttributeSet* RoleAttributes = Cast<UBusyPlayerRoleAttributeSet>(Attribute);
|
||||
RoleAttributes->InitHealth(Result->Health);
|
||||
RoleAttributes->InitMaxHealth(Result->Health);
|
||||
RoleAttributes->InitMoveSpeed(Result->MoveSpeed);
|
||||
|
||||
RoleAttributes->InitHunger(Result->Hunger);
|
||||
RoleAttributes->InitMaxHunger(Result->Hunger);
|
||||
RoleAttributes->InitHungerConsume(Result->HungerConsume);
|
||||
Super::InitPawnAttributes(Config);
|
||||
UBusyPlayerRoleAttributeSet* RoleAttributes = Cast<UBusyPlayerRoleAttributeSet>(Attributes);
|
||||
|
||||
RoleAttributes->InitDamage(Result->Damage);
|
||||
RoleAttributes->InitDefense(Result->Defense);
|
||||
return true;
|
||||
if (RoleAttributes && Config.StaticStruct() == FBusyRoleBaseConfig::StaticStruct())
|
||||
{
|
||||
const FBusyRoleBaseConfig* RoleConfig = static_cast<const FBusyRoleBaseConfig*>(&Config);
|
||||
RoleAttributes->InitHunger(RoleConfig->Hunger);
|
||||
RoleAttributes->InitMaxHunger(RoleConfig->Hunger);
|
||||
RoleAttributes->InitHungerConsume(RoleConfig->HungerConsume);
|
||||
}
|
||||
else
|
||||
{
|
||||
UE_LOG(LogBusyPawn, Warning, TEXT("ABusyPlayerRole::InitPawnAttributes Failed, RoleAttribute: %p, ConfigName: %s"),
|
||||
RoleAttributes, *Config.StaticStruct()->GetFName().ToString()
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,22 @@ void UBusyPawnMovement::SprintTo(const float Distance, const float SpeedRate)
|
||||
}
|
||||
}
|
||||
|
||||
void UBusyPawnMovement::ActivateSprint(const FVector2D& Direction, const float TotalTime)
|
||||
{
|
||||
SprintSpeed = 0.f;
|
||||
SprintDirection = Direction;
|
||||
SprintTotalTime = SprintRemainTime = TotalTime;
|
||||
BusyMoveState = EBusyMoveState::Sprint;
|
||||
}
|
||||
|
||||
void UBusyPawnMovement::ActivateSprintWithSpeed(const FVector2D& Direction, const float TotalTime, const float Speed)
|
||||
{
|
||||
SprintSpeed = Speed;
|
||||
SprintDirection = Direction;
|
||||
SprintTotalTime = SprintRemainTime = TotalTime;
|
||||
BusyMoveState = EBusyMoveState::Sprint;
|
||||
}
|
||||
|
||||
FVector2D UBusyPawnMovement::GetMoveDirection()const
|
||||
{
|
||||
if (AActor *Owner = GetOwner())
|
||||
@ -119,14 +135,24 @@ void UBusyPawnMovement::SprintTick(const float DeltaTime)
|
||||
const FVector CurrentLocation = Owner->GetActorLocation();
|
||||
const FVector2D CurrentLocation2D = FVector2D(CurrentLocation);
|
||||
|
||||
const float MoveDistance = DeltaTime * Movable->Execute_GetSpeed(Owner) * SprintSpeedRate;
|
||||
const FVector2D NewLocation = CurrentLocation2D + ForwardDirection * MoveDistance;
|
||||
float SprintDeltaTime = DeltaTime;
|
||||
if (SprintRemainTime <= DeltaTime)
|
||||
{
|
||||
SprintDeltaTime = SprintRemainTime;
|
||||
SprintRemainTime = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
SprintRemainTime -= DeltaTime;
|
||||
}
|
||||
|
||||
const float MoveDistance = SprintDeltaTime * (SprintSpeed == 0.f ? Movable->Execute_GetSpeed(Owner) : SprintSpeed);
|
||||
const FVector2D NewLocation = CurrentLocation2D + SprintDirection * MoveDistance;
|
||||
Owner->SetActorLocation(FVector(NewLocation, CurrentLocation.Z), true);
|
||||
|
||||
if (FVector2D::Distance(NewLocation, SprintStartLocation) >= SprintDistance)
|
||||
if (SprintRemainTime == 0.f)
|
||||
{
|
||||
BusyMoveState = EBusyMoveState::None; // 这里不对,需要栈来做
|
||||
BusyMoveState = EBusyMoveState::None;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "Level/LevelPlayerController.h"
|
||||
#include "Level/Actor/BusyPlayerRole.h"
|
||||
#include "AbilitySystemBlueprintLibrary.h"
|
||||
#include "EnhancedInput/Public/EnhancedInputSubsystems.h"
|
||||
#include "Level/LevelPlayerState.h"
|
||||
#include "EnhancedInput/Public/EnhancedInputComponent.h"
|
||||
@ -52,6 +53,14 @@ void ALevelPlayerController::SetupInputComponent()
|
||||
BindEnhancedInputAction(EnhancedInput, PrimarySkillAction, this, "OnPrimarySkill");
|
||||
BindEnhancedInputAction(EnhancedInput, UltimateSkillAction, this, "OnUltimateSkill");
|
||||
BindEnhancedInputAction(EnhancedInput, SwitchRoleAction, this, "OnSwitchRole");
|
||||
|
||||
for (const FBusySkillActionConfig& ActionConfig : RoleSkillActions)
|
||||
{
|
||||
EnhancedInput->BindAction(ActionConfig.InputAction, ETriggerEvent::Triggered, this,
|
||||
&ALevelPlayerController::OnRoleSkillTriggered,
|
||||
ActionConfig.ActionTag
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void ALevelPlayerController::Tick(float DeltaTime)
|
||||
@ -107,6 +116,20 @@ bool ALevelPlayerController::GetCursorPosition(FVector2D& Position) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ALevelPlayerController::GetCursorDirection(FVector2D& Direction) const
|
||||
{
|
||||
const AActor *ControlledRole = GetControlledRole();
|
||||
if (!ControlledRole) return false;
|
||||
|
||||
if (FVector2D CursorPosition; GetCursorPosition(CursorPosition))
|
||||
{
|
||||
FVector2D &&RoleLocation = FVector2D(ControlledRole->GetActorLocation());
|
||||
Direction = (CursorPosition - RoleLocation).GetSafeNormal();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ALevelPlayerController::GetCursorHitResult(TArray<AActor*>& Results) const
|
||||
{
|
||||
}
|
||||
@ -192,3 +215,14 @@ void ALevelPlayerController::OnSwitchRole(const FInputActionValue& Value)
|
||||
SwitchControlledRole(ControlledRole);
|
||||
}
|
||||
}
|
||||
|
||||
void ALevelPlayerController::OnRoleSkillTriggered(FGameplayTag GameplayTag)
|
||||
{
|
||||
AActor* ControlledRole = GetControlledRole();
|
||||
if (!ControlledRole) return;
|
||||
if (UAbilitySystemComponent* Asc = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(ControlledRole))
|
||||
{
|
||||
FGameplayEventData EventData = FGameplayEventData();
|
||||
Asc->HandleGameplayEvent(GameplayTag, &EventData);
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,4 +53,12 @@ public:
|
||||
UFUNCTION(BlueprintPure)
|
||||
static bool GetCookMaterialStateConfig(const FName& RowName, FBusyCookMaterialStateConfig& RowData);
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintPure)
|
||||
static FGameplayTag RequestGameplayTag(const FName& TagName);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
static FGameplayTagContainer RequestGameplayTags(const TArray<FName>& TagNames);
|
||||
|
||||
|
||||
};
|
||||
|
||||
30
Source/BusyRabbit/Public/Gas/BusyGameAbility.h
Normal file
30
Source/BusyRabbit/Public/Gas/BusyGameAbility.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include "slua.h"
|
||||
#include "Abilities/GameplayAbility.h"
|
||||
#include "BusyGameAbility.generated.h"
|
||||
|
||||
|
||||
|
||||
UCLASS(Blueprintable, BlueprintType)
|
||||
class UBusyGameAbility : public UGameplayAbility, public ILuaOverriderInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
|
||||
UBusyGameAbility();
|
||||
|
||||
virtual FString GetLuaFilePath_Implementation()const override;
|
||||
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable)
|
||||
bool GetAbilityEffectSpecHandle(const FName& EffectName, const UAbilitySystemComponent* Asc, const int32 Level, FGameplayEffectSpecHandle& Handle)const;
|
||||
|
||||
|
||||
public:
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
FString LuaFilePath;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, DisplayName="技能效果")
|
||||
TMap<FName, TSubclassOf<UGameplayEffect>> AbilityEffects;
|
||||
};
|
||||
@ -6,6 +6,7 @@
|
||||
|
||||
|
||||
class USphereComponent;
|
||||
struct FBusyPawnBaseConfig;
|
||||
class USpineBoneFollowerComponent;
|
||||
class USpineSkeletonRendererComponent;
|
||||
class USpineSkeletonAnimationComponent;
|
||||
@ -63,14 +64,9 @@ public:
|
||||
virtual float GetSpeed_Implementation()const override;
|
||||
|
||||
public:
|
||||
virtual bool InitRoleAttributes() { return false; }
|
||||
virtual void InitPawnAttributes(const FBusyPawnBaseConfig& Config);
|
||||
virtual void InitPawnAbilities(const FBusyPawnBaseConfig& Config) const;
|
||||
|
||||
protected:
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void InitMoveSpeed(const float MoveSpeed)const;
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void InitHealth(const float Health, const float MaxHealth)const;
|
||||
|
||||
protected:
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
@ -111,7 +107,7 @@ public:
|
||||
|
||||
protected:
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TObjectPtr<UBusyPawnAttributeSet> Attribute = nullptr;
|
||||
TObjectPtr<UBusyPawnAttributeSet> Attributes = nullptr;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
@ -46,7 +46,8 @@ public:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
|
||||
virtual bool InitRoleAttributes()override;
|
||||
virtual void InitPawnAttributes(const struct FBusyPawnBaseConfig& Config)override;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
@ -9,7 +9,7 @@ class UBusyAbilitySystemComponent : public UAbilitySystemComponent, public ILuaO
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
virtual FString GetLuaFilePath_Implementation() const override;
|
||||
virtual FString GetLuaFilePath_Implementation() const override;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
@ -54,6 +54,23 @@ public:
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SprintTo(const float Distance, const float SpeedRate);
|
||||
|
||||
/**
|
||||
* 以角色自身的速度向某个方向进行冲刺,受角色速度变化的影响
|
||||
* @param Direction 冲刺方向
|
||||
* @param TotalTime 冲刺的时间(s)
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void ActivateSprint(const FVector2D &Direction, const float TotalTime);
|
||||
|
||||
/**
|
||||
* 以指定速度向某个方向冲刺,无视角色速度
|
||||
* @param Direction
|
||||
* @param TotalTime
|
||||
* @param Speed
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void ActivateSprintWithSpeed(const FVector2D &Direction, const float TotalTime, const float Speed);
|
||||
|
||||
/**
|
||||
* 获取当前移动的方向
|
||||
* @return 返回朝向的单位向量,如果没动返回(0,0)
|
||||
@ -97,10 +114,17 @@ protected:
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly)
|
||||
FVector2D ForwardDirection;
|
||||
|
||||
// 冲刺相关
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
protected: // 冲刺相关
|
||||
|
||||
FVector2D SprintDirection; // 冲刺的方向
|
||||
float SprintTotalTime; // 冲刺总时长
|
||||
float SprintRemainTime; // 冲刺的剩余时间
|
||||
float SprintSpeed; // 指定的冲刺速度, 为0表示使用自己的速度
|
||||
|
||||
|
||||
float SprintSpeedRate = 1.f;
|
||||
float SprintDistance = 100.f;
|
||||
FVector2D SprintStartLocation;
|
||||
|
||||
@ -1,16 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "LuaPlayerController.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "InputAction.h"
|
||||
#include "LevelPlayerController.generated.h"
|
||||
|
||||
|
||||
|
||||
UINTERFACE(MinimalAPI, Blueprintable)
|
||||
class UBusyControllable: public UInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
|
||||
class IBusyControllable
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@ -29,8 +31,22 @@ public:
|
||||
};
|
||||
|
||||
|
||||
struct FInputActionValue;
|
||||
class ABusyPlayerRole;
|
||||
struct FInputActionValue;
|
||||
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FBusySkillActionConfig
|
||||
{
|
||||
GENERATED_BODY()
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly)
|
||||
FGameplayTag ActionTag;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly)
|
||||
UInputAction* InputAction;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
UCLASS()
|
||||
class ALevelPlayerController : public ALuaPlayerController
|
||||
@ -48,6 +64,14 @@ public:
|
||||
UFUNCTION(BlueprintCallable, Category = "Controller")
|
||||
bool GetCursorPosition(FVector2D& Position) const;
|
||||
|
||||
/**
|
||||
* 获取光标相对于所控制的人物的方向
|
||||
* @param Direction
|
||||
* @return false -> 获取失败, 没有角色或者鼠标不在游戏内
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Controller")
|
||||
bool GetCursorDirection(FVector2D& Direction) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Controller")
|
||||
ABusyPlayerRole* GetControlledRole() const;
|
||||
|
||||
@ -88,6 +112,10 @@ public: // 输入相关
|
||||
UPROPERTY(EditDefaultsOnly, Category = "Input")
|
||||
TObjectPtr<class UInputAction> SwitchRoleAction; // 切换控制的角色
|
||||
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category = "Input")
|
||||
TArray<FBusySkillActionConfig> RoleSkillActions;
|
||||
|
||||
public:
|
||||
UFUNCTION()
|
||||
void OnMove(const FInputActionValue& Value)const;
|
||||
@ -104,6 +132,9 @@ public:
|
||||
UFUNCTION()
|
||||
void OnSwitchRole(const FInputActionValue& Value);
|
||||
|
||||
UFUNCTION()
|
||||
void OnRoleSkillTriggered(FGameplayTag GameplayTag);
|
||||
|
||||
|
||||
protected:
|
||||
UPROPERTY()
|
||||
|
||||
Reference in New Issue
Block a user