狐狸技能临时版

This commit is contained in:
2025-10-13 11:57:19 +08:00
parent 8c612d19e2
commit 696cdd1d11
27 changed files with 319 additions and 198 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -8,6 +8,8 @@ end
function LevelFoxRole:ReceiveBeginPlay()
self["SpineAnimationComponent"]:SetAnimation(0, "Idle/Front", true)
self.last_animation = "Idle/Front"
self:InitMoveSpeed(300)
self:InitHealth(500, 500)
end
@ -32,6 +34,8 @@ function LevelFoxRole:OnMoveDirectionChanged(InDirection)
self["SpineAnimationComponent"]:SetAnimation(0, cur_animation, true)
self.last_animation = cur_animation
end
self["SpineAnimationComponent"]:SetTimeScale(1.0)
end
@ -40,5 +44,32 @@ function LevelFoxRole:OnMove(location)
self["MovementComponent"]:MoveTo(location)
end
function LevelFoxRole:OnUltimateSkill()
print("LevelFoxRole:OnUltimateSkill")
local sprint_distance = 600
local sprint_speed_rate = 3.8
-- 获取角色朝向
local forward_direction = self["MovementComponent"]:GetForwardDirection()
self["MovementComponent"]:SprintTo(sprint_distance, sprint_speed_rate)
local anim_comp = self["SpineAnimationComponent"]
if forward_direction.X >= 0 then
anim_comp:SetAnimation(0, "Ultimate/Right/UltimateStage1", false)
else
anim_comp:SetAnimation(0, "Ultimate/Left/UltimateStage1", false)
end
local anim_entry = anim_comp:GetCurrent(0)
local anim_total_time = anim_entry:GetAnimationEnd()
local sprint_time = sprint_distance / (self:GetSpeed() * sprint_speed_rate)
anim_comp:SetTimeScale(anim_total_time / sprint_time)
print("hahhh", anim_total_time, sprint_time)
end
return Class(nil, nil, LevelFoxRole)

View File

@ -7,6 +7,8 @@ end
function LevelRabbitRole:ReceiveBeginPlay()
self["SpineAnimationComponent"]:SetSkin("back/move")
self["SpineAnimationComponent"]:SetAnimation(0, "animation", true)
self:InitMoveSpeed(380)
end

View File

@ -1,21 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "BusyBonfire.h"
#include "Components/CapsuleComponent.h"
#include "Components/InventoryComponent.h"
ABusyBonfire::ABusyBonfire(){
LuaFilePath = TEXT("GamePlay/Bonefire/Bonfire");
Inventory = CreateDefaultSubobject<UInventoryComponent>("Inventory");
SceneComp = CreateDefaultSubobject<USceneComponent>(TEXT("RootScene"));
CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>(TEXT("BonfireCapsule"));
CapsuleComp->SetCollisionResponseToAllChannels(ECR_Ignore);
CapsuleComp->SetupAttachment(SceneComp);
this->RootComponent = SceneComp;
}

View File

@ -1,8 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "BusyCharacter.h"
FString ABusyCharacter::GetLuaFilePath_Implementation()const {
return LuaFilePath;
}

View File

@ -1,44 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "BusyLevelLogicSubSystem.h"
#include "Kismet/GameplayStatics.h"
UBusyLevelLogicSubSystem::UBusyLevelLogicSubSystem(){
}
void UBusyLevelLogicSubSystem::Initialize(FSubsystemCollectionBase& Collection){
Super::Initialize(Collection);
ReceiveSubSystemInitialize();
}
bool UBusyLevelLogicSubSystem::ShouldCreateSubsystem(UObject* Outer) const{
if (!Super::ShouldCreateSubsystem(Outer)) {
return false;
}
auto s = UGameplayStatics::GetCurrentLevelName(Outer);
return UGameplayStatics::GetCurrentLevelName(Outer) != "HomeLand";
}
void UBusyLevelLogicSubSystem::Tick(float DeltaTime){
Super::Tick(DeltaTime);
ReceiveSubSystemTick(DeltaTime);
}
FString UBusyLevelLogicSubSystem::GetLuaFilePath_Implementation() const {
return TEXT("GamePlay/Level/BusyLevelLogicSubSystem");
}
void UBusyLevelLogicSubSystem::OnWorldBeginPlay(UWorld& InWorld){
Super::OnWorldBeginPlay(InWorld);
// ReceiveWorldBeginPlay();
}
void UBusyLevelLogicSubSystem::Deinitialize(){
// Super::Deinitialize();
}
TStatId UBusyLevelLogicSubSystem::GetStatId() const{
return Super::GetStatID();
}

View File

@ -3,7 +3,7 @@
#include "SpineSkeletonRendererComponent.h"
#include "SpineSkeletonAnimationComponent.h"
#include "Level/Actor/Components/BusyPawnMovement.h"
#include "SpineBoneFollowerComponent.h"
ABusyPawnBase::ABusyPawnBase()
{
@ -27,13 +27,39 @@ ABusyPawnBase::ABusyPawnBase()
void ABusyPawnBase::BeginPlay()
{
Super::BeginPlay();
// SpineAnimationComponent->SetSkin(DefaultSkinName);
// SpineAnimationComponent->SetAnimation(0, DefaultAnimationName, true);
// for (UClass* AbilityClass : Row->DefaultAbilities) {
// if (AbilityClass) {
// AbilitySystemComponent->GiveAbility(FGameplayAbilitySpec(AbilityClass));
// }
// }
}
float ABusyPawnBase::GetSpeed_Implementation()const
{
return 280;
if (Attribute)
{
return Attribute->GetMoveSpeed();
}
return 200;
}
void ABusyPawnBase::InitMoveSpeed(const float MoveSpeed)const
{
if (Attribute)
{
Attribute->InitMoveSpeed(MoveSpeed);
}
}
void ABusyPawnBase::InitHealth(const float Health, const float MaxHealth) const
{
if (Attribute)
{
Attribute->InitHealth(Health);
Attribute->InitMaxHealth(MaxHealth);
}
}

View File

@ -1,5 +1,4 @@
#include "Level/Actor/BusyPlayerRole.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
@ -15,4 +14,20 @@ ABusyPlayerRole::ABusyPlayerRole()
CameraComponent->SetProjectionMode(ECameraProjectionMode::Orthographic);
SpringArmComponent->SetRelativeRotation(FRotator(0, -90.0, 0.0));
Attribute = CreateDefaultSubobject<UBusyPlayerRoleAttributeSet>(TEXT("Attribute"));
InitMoveSpeed(200);
InitHealth(100, 100);
}
void ABusyPlayerRole::BeginPlay()
{
Super::BeginPlay();
InitRoleAttributes();
}
void ABusyPlayerRole::InitRoleAttributes()
{
}

View File

@ -10,6 +10,18 @@ UBusyPawnMovement::UBusyPawnMovement()
void UBusyPawnMovement::MoveTo(const FVector2D& Target)
{
MoveTargetLocation = Target;
BusyMoveState = EBusyMoveState::Move;
}
void UBusyPawnMovement::SprintTo(const float Distance, const float SpeedRate)
{
if (const AActor* Owner = GetOwner())
{
SprintDistance = Distance;
SprintSpeedRate = SpeedRate;
BusyMoveState = EBusyMoveState::Sprint;
SprintStartLocation = FVector2D(Owner->GetActorLocation());
}
}
FVector2D UBusyPawnMovement::GetMoveDirection()const
@ -40,6 +52,25 @@ void UBusyPawnMovement::TickComponent(float DeltaTime, ELevelTick TickType,
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
switch (BusyMoveState)
{
case EBusyMoveState::None:
break;
case EBusyMoveState::Move:
MoveTick(DeltaTime);
break;
case EBusyMoveState::Sprint:
SprintTick(DeltaTime);
break;
case EBusyMoveState::Knockback:
break;
}
}
void UBusyPawnMovement::MoveTick(const float DeltaTime)
{
AActor* Owner = GetOwner();
const IBusyMovable* Movable = Cast<IBusyMovable>(Owner);
if (!Owner || !Movable) return;
@ -56,20 +87,17 @@ void UBusyPawnMovement::TickComponent(float DeltaTime, ELevelTick TickType,
}
else
{
if (MoveDirection.Normalize())
{
NewLocation = CurrentLocation + FVector(MoveDirection * MoveDistance, 0);
}
else
{
NewLocation = CurrentLocation;
}
MoveDirection.Normalize();
NewLocation = CurrentLocation + FVector(MoveDirection * MoveDistance, 0);
}
if (!NewLocation.Equals(CurrentLocation))
if (NewLocation.Equals(CurrentLocation))
{
BusyMoveState = EBusyMoveState::None;
}
else
{
Owner->SetActorLocation(NewLocation, true);
}
FVector2D &&NewDirection=GetMoveDirection();
if (!NewDirection.Equals(FVector2D::Zero(), 0.01))
{
@ -82,4 +110,24 @@ void UBusyPawnMovement::TickComponent(float DeltaTime, ELevelTick TickType,
}
}
void UBusyPawnMovement::SprintTick(const float DeltaTime)
{
AActor* Owner = GetOwner();
const IBusyMovable* Movable = Cast<IBusyMovable>(Owner);
if (!Owner || !Movable) return;
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;
Owner->SetActorLocation(FVector(NewLocation, CurrentLocation.Z), true);
if (FVector2D::Distance(NewLocation, SprintStartLocation) >= SprintDistance)
{
BusyMoveState = EBusyMoveState::None; // 这里不对,需要栈来做
}
}

View File

@ -141,10 +141,23 @@ void ALevelPlayerController::OnMove(const FInputActionValue& Value) const
void ALevelPlayerController::OnPrimarySkill(const FInputActionValue& Value) const
{
AActor* ControlledRole = GetControlledRole();
if (!ControlledRole) return;
if (IBusyControllable *Controllable = Cast<IBusyControllable>(ControlledRole))
{
Controllable->Execute_OnPrimarySkill(ControlledRole);
}
}
void ALevelPlayerController::OnUltimateSkill(const FInputActionValue& Value) const
{
AActor* ControlledRole = GetControlledRole();
if (!ControlledRole) return;
if (IBusyControllable *Controllable = Cast<IBusyControllable>(ControlledRole))
{
Controllable->Execute_OnUltimateSkill(ControlledRole);
}
}
void ALevelPlayerController::OnCameraDetach(const FInputActionValue& Value)

View File

@ -1,29 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "LuaActor.h"
#include "BusyBonfire.generated.h"
/**
*
*/
UCLASS()
class BUSYRABBIT_API ABusyBonfire : public ALuaActor
{
GENERATED_BODY()
public:
ABusyBonfire();
public:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
TObjectPtr<class UCapsuleComponent> CapsuleComp;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
TObjectPtr<class USceneComponent> SceneComp;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
TObjectPtr<class UInventoryComponent> Inventory; // <20>ֿ<EFBFBD>
};

View File

@ -1,26 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "slua.h"
#include "CoreMinimal.h"
#include "PaperZDCharacter.h"
#include "BusyCharacter.generated.h"
/**
*
*/
UCLASS()
class BUSYRABBIT_API ABusyCharacter : public APaperZDCharacter, public ILuaOverriderInterface
{
GENERATED_BODY()
public:
virtual FString GetLuaFilePath_Implementation() const override;
//UFUNCTION(BlueprintNativeEvent)
//FString GetLuaFilePath()const;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
FString LuaFilePath;
};

View File

@ -1,53 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "LuaOverriderInterface.h"
#include "Subsystems/WorldSubsystem.h"
#include "BusyLevelLogicSubSystem.generated.h"
/**
*
*/
UCLASS()
class BUSYRABBIT_API UBusyLevelLogicSubSystem : public UTickableWorldSubsystem, public ILuaOverriderInterface
{
GENERATED_BODY()
public:
UBusyLevelLogicSubSystem();
public:
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual bool ShouldCreateSubsystem(UObject* Outer) const override;
virtual void Tick(float DeltaTime) override;
virtual FString GetLuaFilePath_Implementation() const override;
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ؿ<EFBFBD><D8BF><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ã<EFBFBD>
virtual void OnWorldBeginPlay(UWorld& InWorld)override;
// <20><><EFBFBD>٣<EFBFBD><D9A3>ؿ<EFBFBD>ж<EFBFBD><D0B6>ʱ<EFBFBD><CAB1><EFBFBD>ã<EFBFBD>
virtual void Deinitialize() override;
virtual TStatId GetStatId() const override;
public: // <20><>Ҫ<EFBFBD><D2AA>ͼʵ<CDBC>ֽӿ<D6BD>
UFUNCTION(BlueprintImplementableEvent)
void ReceiveSubSystemInitialize();
UFUNCTION(BlueprintImplementableEvent)
void ReceiveWorldBeginPlay();
UFUNCTION(BlueprintImplementableEvent)
void ReceiveSubSystemTick(float DeltaTime);
};

View File

@ -12,6 +12,37 @@ class USpineSkeletonAnimationComponent;
class UBusyPawnMovementComponent;
#define MY_ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
UCLASS(Blueprintable, BlueprintType)
class UBusyPawnAttributeSet : public UAttributeSet
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData Health;
MY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, Health);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData MaxHealth;
MY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, MaxHealth);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData MoveSpeed;
MY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, MoveSpeed);
};
#undef MY_ATTRIBUTE_ACCESSORS
UCLASS()
class ABusyPawnBase : public ALuaPawn, public IBusyMovable
{
@ -23,6 +54,13 @@ public:
virtual float GetSpeed_Implementation()const override;
protected:
UFUNCTION(BlueprintCallable)
void InitMoveSpeed(const float MoveSpeed)const;
UFUNCTION(BlueprintCallable)
void InitHealth(const float Health, const float MaxHealth)const;
protected:
UPROPERTY(EditDefaultsOnly)
TObjectPtr<USceneComponent> RootScene; //场景根组件
@ -55,7 +93,12 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadOnly)
TObjectPtr<UBusyPawnMovement> MovementComponent;
/*-------------------------------------------------------------------*/
protected:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
TObjectPtr<UBusyPawnAttributeSet> Attribute = nullptr;
protected:
UPROPERTY(EditAnywhere)

View File

@ -3,6 +3,32 @@
#include "Level/LevelPlayerController.h"
#include "BusyPlayerRole.generated.h"
#define MY_ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
UCLASS(Blueprintable, BlueprintType)
class UBusyPlayerRoleAttributeSet: public UBusyPawnAttributeSet
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="饱食度")
FGameplayAttributeData Hunger;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="最大饱食度")
FGameplayAttributeData MaxHunger;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="饱食度消耗速度")
FGameplayAttributeData HungerConsume;
};
#undef MY_ATTRIBUTE_ACCESSORS
UCLASS()
class ABusyPlayerRole : public ABusyPawnBase, public IBusyControllable
{
@ -11,6 +37,12 @@ public:
ABusyPlayerRole();
virtual void BeginPlay() override;
protected:
void InitRoleAttributes();
protected:
/*--------------------相机相关--------------------------*/
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)

View File

@ -21,6 +21,19 @@ public:
};
UENUM(Blueprintable, BlueprintType)
enum class EBusyMoveState: uint8
{
// 静止
None = 0,
// 正常移动
Move = 1,
// 冲刺
Sprint = 2,
// 被击退
Knockback = 3,
};
UCLASS()
class UBusyPawnMovement : public ULuaActorComponent
@ -33,6 +46,14 @@ public:
UFUNCTION(BlueprintCallable)
void MoveTo(const FVector2D& Target);
/**
* 沿着当前角色的朝向,以若干倍的速度冲刺一定距离的长度
* @param Distance
* @param SpeedRate
*/
UFUNCTION(BlueprintCallable)
void SprintTo(const float Distance, const float SpeedRate);
/**
* 获取当前移动的方向
* @return 返回朝向的单位向量,如果没动返回(0,0)
@ -49,6 +70,24 @@ public:
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)override;
/**
* 处理移动的Tick
* @param DeltaTime 距离上一帧的时间
*/
void MoveTick(const float DeltaTime);
/**
* 处理冲刺的Tick
* @param DeltaTime 距离上一帧的时间
*/
void SprintTick(const float DeltaTime);
protected:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Movement")
EBusyMoveState BusyMoveState = EBusyMoveState::None;
protected:
UPROPERTY(EditAnywhere, BlueprintReadOnly)
FVector2D MoveTargetLocation;
@ -58,5 +97,12 @@ protected:
UPROPERTY(EditAnywhere, BlueprintReadOnly)
FVector2D ForwardDirection;
protected: // 冲刺相关
float SprintSpeedRate = 1.f;
float SprintDistance = 100.f;
FVector2D SprintStartLocation;
};

View File

@ -21,7 +21,7 @@ enum class EBusyRoleState : uint8{
};
USTRUCT(BlueprintType)
struct FBusyRoleConfig : public FTableRowBase {
struct FBusyRoleConfig: public FTableRowBase {
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "角色的生命值")

View File

@ -0,0 +1,46 @@
#pragma once
#include "BusyPawnConfig.generated.h"
class UGameplayAbility;
USTRUCT(BlueprintType)
struct FBusyPawnBaseConfig : public FTableRowBase
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="生命值")
float Health;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="攻击力")
float Damage;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="防御力")
float Defense;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="移动速度")
float MoveSpeed;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="技能列表")
TArray<TSubclassOf<UGameplayAbility>> DefaultAbilities;
};
USTRUCT(BlueprintType)
struct FBusyEnemyBaseConfig : public FBusyPawnBaseConfig
{
GENERATED_BODY()
};
USTRUCT(BlueprintType)
struct FBusyRoleBaseConfig : public FBusyPawnBaseConfig
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="饱食度")
float Hunger;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="饱食度消耗速率")
float HungerConsume;
};