diff --git a/Config/DefaultEngine.ini b/Config/DefaultEngine.ini index cab2e2a..cabb876 100644 --- a/Config/DefaultEngine.ini +++ b/Config/DefaultEngine.ini @@ -27,4 +27,5 @@ r.DefaultFeature.MotionBlur=False +PropertyRedirects=(OldName="/Script/BusyRabbit.TerrainTileSetConfig.TerrainTileMapping",NewName="/Script/BusyRabbit.TerrainTileSetConfig.n") +PropertyRedirects=(OldName="/Script/BusyRabbit.TerrainLayerComponent.TerrainLayers",NewName="/Script/BusyRabbit.TerrainLayerComponent.TerrainMeshes") +ClassRedirects=(OldName="/Script/BusyRabbit.LevelPlayerController",NewName="/Script/BusyRabbit.LevelPlayerController") ++ClassRedirects=(OldName="/Script/BusyRabbit.StaticResource",NewName="/Script/BusyRabbit.BusyStaticResource") diff --git a/Content/Blueprint/Level/Actor/Holder.uasset b/Content/Blueprint/Level/Actor/Holder.uasset deleted file mode 100644 index ed7c905..0000000 Binary files a/Content/Blueprint/Level/Actor/Holder.uasset and /dev/null differ diff --git a/Content/Blueprint/Level/Actor/RoamingCamera.uasset b/Content/Blueprint/Level/Actor/RoamingCamera.uasset new file mode 100644 index 0000000..b495cd0 Binary files /dev/null and b/Content/Blueprint/Level/Actor/RoamingCamera.uasset differ diff --git a/Content/Blueprint/Level/Actor/Role/BP_Rabbit.uasset b/Content/Blueprint/Level/Actor/Role/BP_Rabbit.uasset index 2de2771..0f8d221 100644 Binary files a/Content/Blueprint/Level/Actor/Role/BP_Rabbit.uasset and b/Content/Blueprint/Level/Actor/Role/BP_Rabbit.uasset differ diff --git a/Content/Blueprint/Level/Actor/Static/BP_Campsite.uasset b/Content/Blueprint/Level/Actor/Static/BP_Campsite.uasset new file mode 100644 index 0000000..25043b8 Binary files /dev/null and b/Content/Blueprint/Level/Actor/Static/BP_Campsite.uasset differ diff --git a/Content/Blueprint/Level/Actor/Static/BP_Tree.uasset b/Content/Blueprint/Level/Actor/Static/BP_Tree.uasset new file mode 100644 index 0000000..3ee1bb1 Binary files /dev/null and b/Content/Blueprint/Level/Actor/Static/BP_Tree.uasset differ diff --git a/Content/Blueprint/Level/GameMode/BP_BusyLevelGameMode.uasset b/Content/Blueprint/Level/GameMode/BP_BusyLevelGameMode.uasset index 8459331..4cbbc43 100644 Binary files a/Content/Blueprint/Level/GameMode/BP_BusyLevelGameMode.uasset and b/Content/Blueprint/Level/GameMode/BP_BusyLevelGameMode.uasset differ diff --git a/Content/Blueprint/Level/GameMode/BP_BusyLevelGameState.uasset b/Content/Blueprint/Level/GameMode/BP_BusyLevelGameState.uasset new file mode 100644 index 0000000..22201a5 Binary files /dev/null and b/Content/Blueprint/Level/GameMode/BP_BusyLevelGameState.uasset differ diff --git a/Content/Blueprint/Level/GameMode/BP_BusyLevelPlayerController.uasset b/Content/Blueprint/Level/GameMode/BP_BusyLevelPlayerController.uasset index 6e70b90..2783e6c 100644 Binary files a/Content/Blueprint/Level/GameMode/BP_BusyLevelPlayerController.uasset and b/Content/Blueprint/Level/GameMode/BP_BusyLevelPlayerController.uasset differ diff --git a/Content/Blueprint/Level/GameMode/BP_BusyLevelPlayerState.uasset b/Content/Blueprint/Level/GameMode/BP_BusyLevelPlayerState.uasset index 0e3a53c..d98dc82 100644 Binary files a/Content/Blueprint/Level/GameMode/BP_BusyLevelPlayerState.uasset and b/Content/Blueprint/Level/GameMode/BP_BusyLevelPlayerState.uasset differ diff --git a/Content/Data/Input/Level/IA_CameraDetach.uasset b/Content/Data/Input/Level/IA_CameraDetach.uasset new file mode 100644 index 0000000..4d1fdee Binary files /dev/null and b/Content/Data/Input/Level/IA_CameraDetach.uasset differ diff --git a/Content/Data/Input/Level/IMC_PlayerInputContext.uasset b/Content/Data/Input/Level/IMC_PlayerInputContext.uasset index ff99710..a509931 100644 Binary files a/Content/Data/Input/Level/IMC_PlayerInputContext.uasset and b/Content/Data/Input/Level/IMC_PlayerInputContext.uasset differ diff --git a/Content/Level/FalconPlain.umap b/Content/Level/FalconPlain.umap index a0fcc07..89ea3a6 100644 Binary files a/Content/Level/FalconPlain.umap and b/Content/Level/FalconPlain.umap differ diff --git a/Content/Level/HomeLand.umap b/Content/Level/HomeLand.umap index aaac49d..064b5e9 100644 Binary files a/Content/Level/HomeLand.umap and b/Content/Level/HomeLand.umap differ diff --git a/Content/Lua/@types/BusyGameplayLibrary.d.lua b/Content/Lua/@types/BusyGameplayLibrary.d.lua new file mode 100644 index 0000000..6d7ddee --- /dev/null +++ b/Content/Lua/@types/BusyGameplayLibrary.d.lua @@ -0,0 +1,3 @@ +--- @class BusyGameplayLibrary +--- @field K2_GetWorld fun(obj:table):table +local BusyGameplayLibrary = {} \ No newline at end of file diff --git a/Content/Lua/@types/UE.d.lua b/Content/Lua/@types/UE.d.lua index 8deed1e..9b37218 100644 --- a/Content/Lua/@types/UE.d.lua +++ b/Content/Lua/@types/UE.d.lua @@ -27,3 +27,9 @@ slua = { KismetSystemLibrary = { K2_ClearTimerHandle = function() end } + + +--- @class GameplayStatics +--- @field GetPlayerController fun(uobj:table,idx:number):table +--- @field GetGameState fun(uobj:table):table +local GameplayStatics diff --git a/Content/Lua/Level/Actor/BusyPlayerRole.lua b/Content/Lua/Level/Actor/BusyPlayerRole.lua deleted file mode 100644 index 68878ea..0000000 --- a/Content/Lua/Level/Actor/BusyPlayerRole.lua +++ /dev/null @@ -1,11 +0,0 @@ -local BusyPlayerRole = {} - -function BusyPlayerRole:UpdateMoveDirection(InDirection) - if(InDirection.Y > 0) then - self["SpineAnimationComponent"]:SetSkin("front/move") - else - self["SpineAnimationComponent"]:SetSkin("back/move") - end -end - -return Class(nil, nil, BusyPlayerRole) diff --git a/Content/Lua/Level/Actor/LevelFoxRole.lua b/Content/Lua/Level/Actor/LevelFoxRole.lua new file mode 100644 index 0000000..d75a09d --- /dev/null +++ b/Content/Lua/Level/Actor/LevelFoxRole.lua @@ -0,0 +1,4 @@ +local LevelFoxRole = {} + + +return Class(nil, nil, LevelFoxRole) \ No newline at end of file diff --git a/Content/Lua/Level/Actor/LevelRabbitRole.lua b/Content/Lua/Level/Actor/LevelRabbitRole.lua new file mode 100644 index 0000000..dca79cd --- /dev/null +++ b/Content/Lua/Level/Actor/LevelRabbitRole.lua @@ -0,0 +1,58 @@ +local LevelRabbitRole = {} + +function LevelRabbitRole:ctor() + self.last_animation = "back/move" +end + +function LevelRabbitRole:ReceiveBeginPlay() + self["SpineAnimationComponent"]:SetSkin("back/move"); + self["SpineAnimationComponent"]:SetAnimation(0, "animation", true); +end + + +function LevelRabbitRole:OnMove(location) + -- 控制器移动相应函数 + self["MovementComponent"]:MoveTo(location) +end + + +function LevelRabbitRole:UpdateMoveDirection(InDirection) + -- 运动组件更新方向响应函数 + local cur_animation + if(InDirection.Y >= 0) then + cur_animation = "front/move" + else + cur_animation = "back/move" + end + if cur_animation ~= self.last_animation then + self["SpineAnimationComponent"]:SetSkin(cur_animation) + self["SpineAnimationComponent"]:SetSlotsToSetupPose() + self.last_animation = cur_animation + end +end + +function LevelRabbitRole:OnDetachCamera() + print(self, "LevelRabbitRole.OnDetachCamera") + + -- 禁用弹簧臂的附着 + self["SpringArmComponent"].bEnableCameraRotationLag = true + self["SpringArmComponent"].CameraRotationLagSpeed = 0 + -- 保持当前位置,停止跟随 + self["SpringArmComponent"].bInheritPitch = true + self["SpringArmComponent"].bInheritYaw = true + self["SpringArmComponent"].bInheritRoll = true + + -- (Pitch=0.000000,Yaw=-90.000000,Roll=0.000000) +end + +function LevelRabbitRole:OnReattachCamera() + print(self, "LevelRabbitRole.OnReattachCamera") +end + + +function LevelRabbitRole:OnMoveCamera(direction) + print(self, "LevelRabbitRole.OnMoveCamera", direction.X, direction.Y) +end + + +return Class(nil, nil, LevelRabbitRole) diff --git a/Content/Lua/Level/Actor/Static/Campsite.lua b/Content/Lua/Level/Actor/Static/Campsite.lua new file mode 100644 index 0000000..86fa9e0 --- /dev/null +++ b/Content/Lua/Level/Actor/Static/Campsite.lua @@ -0,0 +1,4 @@ +local Campsite = {} + + +return Class(nil, nil, Campsite) \ No newline at end of file diff --git a/Content/Lua/Level/LevelGameMode.lua b/Content/Lua/Level/LevelGameMode.lua index 7fca6e4..7c4ee56 100644 --- a/Content/Lua/Level/LevelGameMode.lua +++ b/Content/Lua/Level/LevelGameMode.lua @@ -1,13 +1,36 @@ +local Vector = import("Vector") +local GameplayStatics = import("GameplayStatics") +local BusyGameplayLibrary = import("BusyGameplayLibrary") + +--- 保留到以后做联机内容时拓展 +--- @class LevelGameMode +--- @field GameMapActorClass table local LevelGameMode = {} -function LevelGameMode:K2_PostLogin(new_player_controller) - - local new_player_state = new_player_controller.PlayerState - - local role = new_player_state:CreateRoleRoster(new_player_controller) - - new_player_controller:Possess(role) - +function LevelGameMode:ctor() + self.map_actor = nil end +function LevelGameMode:ReceiveBeginPlay() + print("LevelGameMode:ReceiveBeginPlay", self.GameMapActorClass) + local world = BusyGameplayLibrary.K2_GetWorld(self) + local game_state = GameplayStatics.GetGameState(self) --- @type LevelGameState + + if self.GameMapActorClass then + local map_actor = world:SpawnActor(self.GameMapActorClass, Vector(), nil, nil) + game_state:SetGameMapActor(map_actor) + end +end + +-- function LevelGameMode:K2_PostLogin(new_player_controller) +-- local new_player_state = new_player_controller.PlayerState +-- local role = new_player_state:CreateRoleRoster(new_player_controller) +-- local new_pos = FVector() +-- new_pos.X = 500 +-- new_pos.Y = 500 +-- new_pos.Z = 50 +-- role:K2_SetActorLocation(new_pos, true, nil, false) +-- new_player_controller:Possess(role) +-- end + return Class(nil, nil, LevelGameMode) \ No newline at end of file diff --git a/Content/Lua/Level/LevelGameState.lua b/Content/Lua/Level/LevelGameState.lua new file mode 100644 index 0000000..1499cab --- /dev/null +++ b/Content/Lua/Level/LevelGameState.lua @@ -0,0 +1,9 @@ +--- @class LevelGameState +local LevelGameState = {} + +function LevelGameState:SetGameMapActor(game_map_actor) + self.GameMapActor = game_map_actor +end + + +return Class(nil, nil, LevelGameState) \ No newline at end of file diff --git a/Content/Lua/Level/LevelPlayerState.lua b/Content/Lua/Level/LevelPlayerState.lua new file mode 100644 index 0000000..d5cd983 --- /dev/null +++ b/Content/Lua/Level/LevelPlayerState.lua @@ -0,0 +1,12 @@ +local GameplayStatics = import("GameplayStatics") + +local LevelPlayerState = {} + +function LevelPlayerState:ReceiveBeginPlay() + local pc = GameplayStatics.GetPlayerController(self, 0) + local role = self:CreateRoleRoster(pc) + print("LevelPlayerState:ReceiveBeginPlay", role, self:HasAuthority()) + pc:Possess(role) +end + +return Class(nil, nil, LevelPlayerState) \ No newline at end of file diff --git a/Content/Resource/Spine/PlacedItems/Fire/Fire.uasset b/Content/Resource/Spine/PlacedItems/Fire/Fire.uasset new file mode 100644 index 0000000..713d661 Binary files /dev/null and b/Content/Resource/Spine/PlacedItems/Fire/Fire.uasset differ diff --git a/Content/Resource/Spine/PlacedItems/Fire/FireData.uasset b/Content/Resource/Spine/PlacedItems/Fire/FireData.uasset new file mode 100644 index 0000000..50f7c44 Binary files /dev/null and b/Content/Resource/Spine/PlacedItems/Fire/FireData.uasset differ diff --git a/Content/Resource/Spine/PlacedItems/Fire/Textures/Fire.uasset b/Content/Resource/Spine/PlacedItems/Fire/Textures/Fire.uasset new file mode 100644 index 0000000..f8c0673 Binary files /dev/null and b/Content/Resource/Spine/PlacedItems/Fire/Textures/Fire.uasset differ diff --git a/Content/Resource/Spine/PlacedItems/Tree/Textures/Tree.uasset b/Content/Resource/Spine/PlacedItems/Tree/Textures/Tree.uasset new file mode 100644 index 0000000..dbb2b50 Binary files /dev/null and b/Content/Resource/Spine/PlacedItems/Tree/Textures/Tree.uasset differ diff --git a/Content/Resource/Spine/PlacedItems/Tree/Tree.uasset b/Content/Resource/Spine/PlacedItems/Tree/Tree.uasset new file mode 100644 index 0000000..21dec84 Binary files /dev/null and b/Content/Resource/Spine/PlacedItems/Tree/Tree.uasset differ diff --git a/Content/Resource/Spine/PlacedItems/Tree/TreeData.uasset b/Content/Resource/Spine/PlacedItems/Tree/TreeData.uasset new file mode 100644 index 0000000..ade8eac Binary files /dev/null and b/Content/Resource/Spine/PlacedItems/Tree/TreeData.uasset differ diff --git a/Content/Resource/Spine/Role/Rabbit/Rabbit.uasset b/Content/Resource/Spine/Role/Rabbit/Rabbit.uasset index cf2b3ec..66cdb45 100644 Binary files a/Content/Resource/Spine/Role/Rabbit/Rabbit.uasset and b/Content/Resource/Spine/Role/Rabbit/Rabbit.uasset differ diff --git a/Content/Resource/Spine/Role/Rabbit/RabbitData.uasset b/Content/Resource/Spine/Role/Rabbit/RabbitData.uasset index 4eba779..513c26d 100644 Binary files a/Content/Resource/Spine/Role/Rabbit/RabbitData.uasset and b/Content/Resource/Spine/Role/Rabbit/RabbitData.uasset differ diff --git a/Content/Resource/Spine/Role/Rabbit/Textures/Rabbit.uasset b/Content/Resource/Spine/Role/Rabbit/Textures/Rabbit.uasset index e0e10be..affe58c 100644 Binary files a/Content/Resource/Spine/Role/Rabbit/Textures/Rabbit.uasset and b/Content/Resource/Spine/Role/Rabbit/Textures/Rabbit.uasset differ diff --git a/Source/BusyRabbit/Private/BusyActorManagerSubSystem.cpp b/Source/BusyRabbit/Private/BusyActorManagerSubSystem.cpp index 2421737..a69999b 100644 --- a/Source/BusyRabbit/Private/BusyActorManagerSubSystem.cpp +++ b/Source/BusyRabbit/Private/BusyActorManagerSubSystem.cpp @@ -16,7 +16,6 @@ void UBusyActorManagerSubSystem::OnWorldBeginPlay(UWorld& InWorld) { } void UBusyActorManagerSubSystem::Deinitialize(){ - // ˴LuaʵֵĺܲȲṩٵluaӿڰ Super::Deinitialize(); } @@ -26,7 +25,7 @@ FString UBusyActorManagerSubSystem::GetLuaFilePath_Implementation() const{ bool UBusyActorManagerSubSystem::GetLevelBaseConfig(FBusyLevelBaseConfig& config){ FBusyLevelBaseConfig* Config; - UDataTable *DataTable = UBusyGamePlayLibrary::GetGameDataTable("LevelBaseConfig"); + UDataTable *DataTable = UBusyGameplayLibrary::GetGameDataTable("LevelBaseConfig"); if (!DataTable) return false; Config = DataTable->FindRow( diff --git a/Source/BusyRabbit/Private/BusyGamePlayLibrary.cpp b/Source/BusyRabbit/Private/BusyGamePlayLibrary.cpp index f252196..f850a36 100644 --- a/Source/BusyRabbit/Private/BusyGamePlayLibrary.cpp +++ b/Source/BusyRabbit/Private/BusyGamePlayLibrary.cpp @@ -11,7 +11,7 @@ static inline const UBusyDataAsset* GetGameAsset() { template static bool GetTableConfig(const FString& TableName, const FName& RowName, RowStruct& RowData) { - UDataTable* Table = UBusyGamePlayLibrary::GetGameDataTable(TableName); + UDataTable* Table = UBusyGameplayLibrary::GetGameDataTable(TableName); RowStruct* Config = Table->FindRow( RowName, *FString::Printf(TEXT("GetTableConfig, %s"), *RowName.ToString()), @@ -26,79 +26,59 @@ static bool GetTableConfig(const FString& TableName, const FName& RowName, RowSt } } -UDataTable* UBusyGamePlayLibrary::GetGameDataTable(const FString& TableName){ +UDataTable* UBusyGameplayLibrary::GetGameDataTable(const FString& TableName){ const UBusyDataAsset* GameAsset = GetGameAsset(); if (!GameAsset) return nullptr; auto Table = (GameAsset->DataTableMapping.Find(TableName)); return Table ? Table->Get() : nullptr; } -UClass* UBusyGamePlayLibrary::GetGameClass(const FString& ClassName){ +UClass* UBusyGameplayLibrary::GetGameClass(const FString& ClassName){ const UBusyDataAsset* GameAsset = GetGameAsset(); if (!GameAsset) return nullptr; auto Class = (GameAsset->ClassPathMapping.Find(ClassName)); return Class ? Class->Get() : nullptr; } -UClass* UBusyGamePlayLibrary::GetGameUIClass(const FString& ClassName){ +UClass* UBusyGameplayLibrary::GetGameUIClass(const FString& ClassName){ const UBusyDataAsset* GameAsset = GetGameAsset(); if (!GameAsset) return nullptr; auto Class = (GameAsset->UIPathMapping.Find(ClassName)); return Class ? Class->Get() : nullptr; } -UWorld* UBusyGamePlayLibrary::K2_GetWorld(const UObject* obj){ - return obj->GetWorld(); +UWorld* UBusyGameplayLibrary::K2_GetWorld(const UObject* UObj){ + return UObj->GetWorld(); } -bool UBusyGamePlayLibrary::GetLevelBaseConfig(const FName& RowName, FBusyLevelBaseConfig& RowData){ +bool UBusyGameplayLibrary::GetLevelBaseConfig(const FName& RowName, FBusyLevelBaseConfig& RowData){ return GetTableConfig(TEXT("LevelBaseConfig"), RowName, RowData); } -bool UBusyGamePlayLibrary::GetLevelItemConfig(const FName& RowName, FBusyLevelItemConfig& RowData){ +bool UBusyGameplayLibrary::GetLevelItemConfig(const FName& RowName, FBusyLevelItemConfig& RowData){ return GetTableConfig(TEXT("LevelItems"), RowName, RowData); } -bool UBusyGamePlayLibrary::GetRoleConfig(const FName& RowName, FBusyRoleConfig& RowData){ +bool UBusyGameplayLibrary::GetRoleConfig(const FName& RowName, FBusyRoleConfig& RowData){ return GetTableConfig(TEXT("RoleConfig"), RowName, RowData); } -bool UBusyGamePlayLibrary::GetItemResourceConfig(const FName& RowName, FBusyLevelItemResourceConfig& RowData){ +bool UBusyGameplayLibrary::GetItemResourceConfig(const FName& RowName, FBusyLevelItemResourceConfig& RowData){ return GetTableConfig(TEXT("LevelItemResource"), RowName, RowData); } -bool UBusyGamePlayLibrary::GetLevelItemDescription(const FName& RowName, FBusyLevelItemDescription& RowData){ +bool UBusyGameplayLibrary::GetLevelItemDescription(const FName& RowName, FBusyLevelItemDescription& RowData){ return GetTableConfig(TEXT("LevelItemDesc"), RowName, RowData); } -bool UBusyGamePlayLibrary::GetHomelandItemDescription(const FName& RowName, FBusyHomelandItemDescription& RowData){ +bool UBusyGameplayLibrary::GetHomelandItemDescription(const FName& RowName, FBusyHomelandItemDescription& RowData){ return GetTableConfig(TEXT("HomelandItemDesc"), RowName, RowData); } -bool UBusyGamePlayLibrary::GetItemDescription(const FName& RowName, FBusyItemDescription& RowData){ +bool UBusyGameplayLibrary::GetItemDescription(const FName& RowName, FBusyItemDescription& RowData){ return GetTableConfig(TEXT("ItemDesc"), RowName, RowData); } -bool UBusyGamePlayLibrary::GetCookMaterialStateConfig(const FName& RowName, FBusyCookMaterialStateConfig& RowData){ +bool UBusyGameplayLibrary::GetCookMaterialStateConfig(const FName& RowName, FBusyCookMaterialStateConfig& RowData){ return GetTableConfig(TEXT("CookMaterialStateConfig"), RowName, RowData); } - -FLuaBPVar UBusyGamePlayLibrary::CreateTextureBuffer(UObject* WorldContextObject){ - auto DataTexture = UTexture2D::CreateTransient(512, 1, PF_R32_FLOAT); - DataTexture->Filter = TF_Trilinear; - DataTexture->AddressX = TA_Clamp; - DataTexture->AddressY = TA_Clamp; - DataTexture->UpdateResource(); - return ULuaBlueprintLibrary::CreateVarFromObject(WorldContextObject, DataTexture); -} - -void UBusyGamePlayLibrary::UpdateTextureBuffer(UTexture2D *DataTexture, TArray FloatData){ - DataTexture->GetPlatformData()->Mips[0]; - FTexture2DMipMap& Mip = DataTexture->GetPlatformData()->Mips[0]; - void* Data = Mip.BulkData.Lock(LOCK_READ_WRITE); - - FMemory::Memcpy(Data, FloatData.GetData(), FloatData.Num() * sizeof(float)); - - Mip.BulkData.Unlock(); - DataTexture->UpdateResource(); -} diff --git a/Source/BusyRabbit/Private/Level/Actor/BusyPawnBase.cpp b/Source/BusyRabbit/Private/Level/Actor/BusyPawnBase.cpp index 0298b1d..890874a 100644 --- a/Source/BusyRabbit/Private/Level/Actor/BusyPawnBase.cpp +++ b/Source/BusyRabbit/Private/Level/Actor/BusyPawnBase.cpp @@ -14,9 +14,7 @@ ABusyPawnBase::ABusyPawnBase() SpineRenderComponent = CreateDefaultSubobject(TEXT("SpineRenderComponent")); SpineAnimationComponent = CreateDefaultSubobject(TEXT("SpineAnimationComponent")); AbilitySystemComponent = CreateDefaultSubobject(TEXT("AbilitySystemComponent")); - MovementComponent = CreateDefaultSubobject(TEXT("MovementComponent")); - RootComponent = RootScene; SpineRoot->SetupAttachment(RootScene); @@ -24,20 +22,13 @@ ABusyPawnBase::ABusyPawnBase() SpineRenderComponent->SetupAttachment(SpineRoot); SpineRoot->SetRelativeRotation(FRotator(0, 0, -90)); - - - bReplicates = true; - SetReplicatingMovement(true); - NetUpdateFrequency = 60.0f; - MovementComponent->SetIsReplicated(true); - AbilitySystemComponent->SetIsReplicated(true); } void ABusyPawnBase::BeginPlay() { Super::BeginPlay(); - SpineAnimationComponent->SetSkin(DefaultSkinName); - SpineAnimationComponent->SetAnimation(0, DefaultAnimationName, true); + // SpineAnimationComponent->SetSkin(DefaultSkinName); + // SpineAnimationComponent->SetAnimation(0, DefaultAnimationName, true); } void ABusyPawnBase::UpdateMoveDirection_Implementation(const FVector2D& InDirection) diff --git a/Source/BusyRabbit/Private/Level/Actor/BusyStaticResource.cpp b/Source/BusyRabbit/Private/Level/Actor/BusyStaticResource.cpp new file mode 100644 index 0000000..e7e3182 --- /dev/null +++ b/Source/BusyRabbit/Private/Level/Actor/BusyStaticResource.cpp @@ -0,0 +1,24 @@ +#include "Level/Actor/BusyStaticResource.h" +#include "SpineSkeletonRendererComponent.h" +#include "SpineSkeletonAnimationComponent.h" + +ABusyStaticResource::ABusyStaticResource() +{ + RootScene = CreateDefaultSubobject(TEXT("RootScene")); + SpineRoot = CreateDefaultSubobject(TEXT("SpineRoot")); + + SpineRenderComponent = CreateDefaultSubobject("SpineRenderComponent"); + SpineAnimationComponent = CreateDefaultSubobject("SpineAnimationComponent"); + + SetRootComponent(RootScene); + SpineRoot->SetupAttachment(RootScene); + SpineRenderComponent->SetupAttachment(SpineRoot); + SpineRoot->SetRelativeRotation(FRotator(0, 0, -90)); +} + +void ABusyStaticResource::BeginPlay() +{ + Super::BeginPlay(); + SpineAnimationComponent->SetSkin("default"); + SpineAnimationComponent->SetAnimation(0, "idle", true); +} diff --git a/Source/BusyRabbit/Private/Level/Actor/Components/BusyPawnMovement.cpp b/Source/BusyRabbit/Private/Level/Actor/Components/BusyPawnMovement.cpp index 6a935e1..f64d99d 100644 --- a/Source/BusyRabbit/Private/Level/Actor/Components/BusyPawnMovement.cpp +++ b/Source/BusyRabbit/Private/Level/Actor/Components/BusyPawnMovement.cpp @@ -30,14 +30,11 @@ FVector2D UBusyPawnMovement::GetMoveDirection()const return FVector2D(); } -#pragma optimize("",off) void UBusyPawnMovement::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - if (!GetOwner()->HasAuthority()) return; - AActor* Owner = GetOwner(); const IBusyMovable* Movable = Cast(Owner); if (!Owner || !Movable) return; @@ -66,11 +63,7 @@ void UBusyPawnMovement::TickComponent(float DeltaTime, ELevelTick TickType, if (!NewLocation.Equals(CurrentLocation)) { Owner->SetActorLocation(NewLocation, true); - Owner->ForceNetUpdate(); } - - - // Movable->Execute_UpdateMoveDirection(Owner, GetMoveDirection()); + Movable->Execute_UpdateMoveDirection(Owner, GetMoveDirection()); } -#pragma optimize("",on) diff --git a/Source/BusyRabbit/Private/Level/BusyLevelItem.cpp b/Source/BusyRabbit/Private/Level/BusyLevelItem.cpp index 350c38e..f5349b3 100644 --- a/Source/BusyRabbit/Private/Level/BusyLevelItem.cpp +++ b/Source/BusyRabbit/Private/Level/BusyLevelItem.cpp @@ -32,7 +32,7 @@ void ABusyLevelItem::OnConstruction(const FTransform& Transform){ } void ABusyLevelItem::BeginPlay(){ - UClass* cls = UBusyGamePlayLibrary::GetGameUIClass("PickBar"); + UClass* cls = UBusyGameplayLibrary::GetGameUIClass("PickBar"); if (cls != nullptr) { PickBar->SetWidgetClass(cls); } @@ -81,7 +81,7 @@ void ABusyLevelItem::InitPickBar(){ } void ABusyLevelItem::SetItemDisplay(const FName& ItemID){ - UDataTable* Resource = UBusyGamePlayLibrary::GetGameDataTable(TEXT("LevelItemResource")); + UDataTable* Resource = UBusyGameplayLibrary::GetGameDataTable(TEXT("LevelItemResource")); // 查物品信息 FBusyLevelItemResourceConfig* ResourceConfig = Resource->FindRow( @@ -97,7 +97,7 @@ void ABusyLevelItem::SetItemDisplay(const FName& ItemID){ void ABusyLevelItem::SetLevelItemID(const FName& ItemID){ // 取物品资源表 - UDataTable* ConfigTable = UBusyGamePlayLibrary::GetGameDataTable(TEXT("LevelItems")); + UDataTable* ConfigTable = UBusyGameplayLibrary::GetGameDataTable(TEXT("LevelItems")); // 查物品信息 FBusyLevelItemConfig* ItemConfig = ConfigTable->FindRow( ItemID, TEXT("ABusyLevelItem::SetLevelItemID"), true diff --git a/Source/BusyRabbit/Private/Level/LevelItemReward.cpp b/Source/BusyRabbit/Private/Level/LevelItemReward.cpp index c9ac8a5..5e500b5 100644 --- a/Source/BusyRabbit/Private/Level/LevelItemReward.cpp +++ b/Source/BusyRabbit/Private/Level/LevelItemReward.cpp @@ -26,7 +26,7 @@ void ALevelItemReward::SetRewardID(const FName& CurrentRewardID){ bool bIsFind = false; FBusyLevelItemDescription Desc; if (CurrentRewardID.IsNone()) return; - bIsFind = UBusyGamePlayLibrary::GetLevelItemDescription(CurrentRewardID, Desc); + bIsFind = UBusyGameplayLibrary::GetLevelItemDescription(CurrentRewardID, Desc); if (!bIsFind) return; this->RewardID = CurrentRewardID; this->Sprite->SetFlipbook(Desc.LevelResource.LoadSynchronous()); diff --git a/Source/BusyRabbit/Private/Level/LevelPlayerController.cpp b/Source/BusyRabbit/Private/Level/LevelPlayerController.cpp index 1ea8c05..46dc5d9 100644 --- a/Source/BusyRabbit/Private/Level/LevelPlayerController.cpp +++ b/Source/BusyRabbit/Private/Level/LevelPlayerController.cpp @@ -2,10 +2,18 @@ #include "Level/Actor/BusyPlayerRole.h" #include "EnhancedInput/Public/EnhancedInputSubsystems.h" #include "Level/LevelPlayerState.h" -#include "EnhancedInput/Public/EnhancedInputSubsystems.h" #include "EnhancedInput/Public/EnhancedInputComponent.h" +inline static void BindEnhancedInputAction(UEnhancedInputComponent* EnhancedInput, const UInputAction* Action, UObject* Target, const FName& Callback) +{ + if (Action) + { + EnhancedInput->BindAction(Action, ETriggerEvent::Triggered, Target, Callback); + } +} + + ALevelPlayerController::ALevelPlayerController() { } @@ -19,34 +27,74 @@ void ALevelPlayerController::BeginPlay() InputMode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock); SetInputMode(InputMode); - // 注册输入 - if (!HasAuthority()) + if (RoamingCameraClass) { - const auto Subsystem = ULocalPlayer::GetSubsystem(GetLocalPlayer()); - if (InputMapping && Subsystem) - { - Subsystem->AddMappingContext(InputMapping, 0); - } + RoamingCameraActor = GetWorld()->SpawnActor(RoamingCameraClass); + } +} + +void ALevelPlayerController::SetupInputComponent() +{ + Super::SetupInputComponent(); + // 注册输入 + if (!InputMapping || !InputComponent) return; + + if (const auto Subsystem = ULocalPlayer::GetSubsystem(GetLocalPlayer())) + { + Subsystem->AddMappingContext(InputMapping, 0); + } + + UEnhancedInputComponent* EnhancedInput = CastChecked(InputComponent); + if (!EnhancedInput) return; + + BindEnhancedInputAction(EnhancedInput, MoveAction, this, "OnMove"); + BindEnhancedInputAction(EnhancedInput, CameraDetachAction, this, "OnCameraDetach"); + BindEnhancedInputAction(EnhancedInput, PrimarySkillAction, this, "OnPrimarySkill"); + BindEnhancedInputAction(EnhancedInput, UltimateSkillAction, this, "OnUltimateSkill"); +} + +void ALevelPlayerController::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); + + if (!bCameraDetached || !RoamingCameraActor) return; + + AActor *ControlledRole = GetControlledRole(); + const IBusyMovable *Movable = Cast(GetControlledRole()); + if (!Movable) return; - - if (UEnhancedInputComponent* EnhancedInput = CastChecked(InputComponent)) { - EnhancedInput->BindAction(TouchAction, ETriggerEvent::Triggered, this, FName("OnTouch")); - } + if (float CursorX, CursorY; GetMousePosition(CursorX, CursorY)) + { + + // 获取视口大小 + int32 ViewportSizeX, ViewportSizeY; + GetViewportSize(ViewportSizeX, ViewportSizeY); + + // 计算屏幕中心 + const FVector2D ScreenCenter(ViewportSizeX / 2.0f, ViewportSizeY / 2.0f); + + // 获取漫游相机位置 + const FVector CurrentLocation = RoamingCameraActor->GetActorLocation(); + + // 计算方向向量 + FVector Direction(CursorX - ScreenCenter.X, CursorY - ScreenCenter.Y, 0); + + // 归一化 + Direction.Normalize(); + + const float MoveSpeed = Movable->Execute_GetSpeed(ControlledRole); + const FVector MoveDistance = Direction * DeltaTime * MoveSpeed * RoamingSpeedFactor; + + // 更新漫游相机位置 + RoamingCameraActor->SetActorLocation(CurrentLocation + MoveDistance); } } -void ALevelPlayerController::SetRoleMoveTo_Implementation(const FVector2D& Location) -{ - ABusyPlayerRole* ControlledRole = GetControlledRole(); - if (!ControlledRole) return; - ControlledRole->MovementComponent->MoveTo(Location); -} bool ALevelPlayerController::GetCursorPosition(FVector2D& Position) const { - float CursorX = 0.f, CursorY = 0.f; - if (GetMousePosition(CursorX, CursorY)) + if (float CursorX, CursorY; GetMousePosition(CursorX, CursorY)) { FVector WorldLocation, WorldDirection; if (DeprojectMousePositionToWorld(WorldLocation, WorldDirection)) @@ -73,14 +121,50 @@ ABusyPlayerRole* ALevelPlayerController::GetControlledRole() const void ALevelPlayerController::SwitchControlledRole(ABusyPlayerRole* Target) { - this->SetViewTarget(Target); + this->Possess(Target); } -void ALevelPlayerController::OnTouch(const FInputActionValue& Value) +void ALevelPlayerController::OnMove(const FInputActionValue& Value) const { - FVector2D Position; - if (GetCursorPosition(Position)) + AActor* ControlledRole = GetControlledRole(); + if (!ControlledRole) return; + + IBusyControllable *Controllable = Cast(ControlledRole); + if (!Controllable) return; + + if (FVector2D Position; GetCursorPosition(Position)) { - SetRoleMoveTo(Position); + Controllable->Execute_OnMove(ControlledRole, Position); + } +} + +void ALevelPlayerController::OnPrimarySkill(const FInputActionValue& Value) const +{ +} + +void ALevelPlayerController::OnUltimateSkill(const FInputActionValue& Value) const +{ +} + +void ALevelPlayerController::OnCameraDetach(const FInputActionValue& Value) +{ + if (!RoamingCameraActor) return; + + AActor* ControlledRole = GetControlledRole(); + if (!ControlledRole) return; + + const FVector RoleLocation = ControlledRole->GetActorLocation(); + RoamingCameraActor->SetActorLocation(RoleLocation); + + + if (Value.GetMagnitude() > 0) + { + bCameraDetached = true; + SetViewTarget(RoamingCameraActor); + } + else + { + bCameraDetached = false; + SetViewTarget(ControlledRole); } } diff --git a/Source/BusyRabbit/Private/Level/LevelPlayerState.cpp b/Source/BusyRabbit/Private/Level/LevelPlayerState.cpp index 009c3e1..bbc2687 100644 --- a/Source/BusyRabbit/Private/Level/LevelPlayerState.cpp +++ b/Source/BusyRabbit/Private/Level/LevelPlayerState.cpp @@ -1,5 +1,5 @@ #include "Level/LevelPlayerState.h" -#include "Net/UnrealNetwork.h" +// #include "Net/UnrealNetwork.h" #include "Level/Actor/BusyPlayerRole.h" @@ -11,24 +11,19 @@ void ALevelPlayerState::BeginPlay() Super::BeginPlay(); } - -void ALevelPlayerState::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const -{ - Super::GetLifetimeReplicatedProps(OutLifetimeProps); - - DOREPLIFETIME(ALevelPlayerState, RoleRoster); - DOREPLIFETIME(ALevelPlayerState, ControlledRoleIndex); -} +// +// void ALevelPlayerState::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const +// { +// Super::GetLifetimeReplicatedProps(OutLifetimeProps); +// +// DOREPLIFETIME(ALevelPlayerState, RoleRoster); +// DOREPLIFETIME(ALevelPlayerState, ControlledRoleIndex); +// } AActor* ALevelPlayerState::CreateRoleRoster(class APlayerController* PlayerController) { - if (!HasAuthority()) - { - return nullptr; - } - UWorld* World = PlayerController->GetWorld(); - if (!World) + if (!World || !PlayerController) { return nullptr; } @@ -76,11 +71,3 @@ FVector2D ALevelPlayerState::GetSpawnLocation()const { return FVector2D::ZeroVector; } - -void ALevelPlayerState::SetRoleRoster(const TArray& Roster) -{ - if (HasAuthority()) - { - RoleRoster = Roster; - } -} \ No newline at end of file diff --git a/Source/BusyRabbit/Private/Level/TerrainGenerator.cpp b/Source/BusyRabbit/Private/Level/TerrainGenerator.cpp deleted file mode 100644 index 51d02c2..0000000 --- a/Source/BusyRabbit/Private/Level/TerrainGenerator.cpp +++ /dev/null @@ -1,220 +0,0 @@ -#include "Level/TerrainGenerator.h" -#include "Math/UnrealMathUtility.h" -#include "Math/RandomStream.h" - -UTerrainGenerator::UTerrainGenerator() -{ - NextHandle = 0; -} - - -bool UTerrainGenerator::GenerateWithNodes(TArray& Map, int32 Width, int32 Height, const TArray& ValidLeafNodes) -{ - // 使用区域生长算法生成基础地图 - RegionGrowing(Map, Width, Height, ValidLeafNodes); - - // 应用柏林噪声进行平滑处理 - ApplyPerlinNoiseSmoothing(Map, Width, Height); - - return true; -} - -void UTerrainGenerator::RegionGrowing(TArray& Map, int32 Width, int32 Height, - const TArray& ValidLeafNodes) const -{ - if (ValidLeafNodes.Num() == 0) - { - return; - } - - FRandomStream RandomStream(FMath::Rand()); - - // 计算总权重 - float TotalWeight = 0.0f; - for (int32 Handle : ValidLeafNodes) - { - if (const FTerrainNodeInfo* Node = TerrainNodes.Find(Handle)) - { - TotalWeight += Node->Weight; - } - } - - if (TotalWeight <= 0.0f) - { - return; - } - - // 创建权重分布 - TArray WeightDistribution; - TArray HandleDistribution; - float CurrentWeight = 0.0f; - - for (int32 Handle : ValidLeafNodes) - { - if (const FTerrainNodeInfo* Node = TerrainNodes.Find(Handle)) - { - CurrentWeight += Node->Weight / TotalWeight; - WeightDistribution.Add(CurrentWeight); - HandleDistribution.Add(Handle); - } - } - - // 区域生长算法 - TArray RegionSizes; - RegionSizes.SetNum(ValidLeafNodes.Num()); - - int32 TotalCells = Width * Height; - for (int32 i = 0; i < ValidLeafNodes.Num(); i++) - { - float Ratio = 0.0f; - if (const FTerrainNodeInfo* Node = TerrainNodes.Find(ValidLeafNodes[i])) - { - Ratio = Node->Weight / TotalWeight; - } - RegionSizes[i] = FMath::CeilToInt(TotalCells * Ratio); - } - - // 初始化地图为无效标签 - FGameplayTag InvalidTag; - for (int32 i = 0; i < Map.Num(); i++) - { - Map[i] = InvalidTag; - } - - // 从随机点开始生长 - for (int32 RegionIndex = 0; RegionIndex < ValidLeafNodes.Num(); RegionIndex++) - { - int32 Handle = ValidLeafNodes[RegionIndex]; - FGameplayTag TerrainTag = GetFinalTerrainTag(Handle); - int32 TargetSize = RegionSizes[RegionIndex]; - int32 CurrentSize = 0; - - // 寻找起始点 - int32 StartX, StartY; - do - { - StartX = RandomStream.RandRange(0, Width - 1); - StartY = RandomStream.RandRange(0, Height - 1); - } while (Map[StartY * Width + StartX].IsValid()); - - // 使用队列进行区域生长 - TQueue Queue; - Queue.Enqueue(FIntPoint(StartX, StartY)); - Map[StartY * Width + StartX] = TerrainTag; - CurrentSize++; - - while (!Queue.IsEmpty() && CurrentSize < TargetSize) - { - FIntPoint CurrentPoint; - Queue.Dequeue(CurrentPoint); - - // 检查四个方向 - TArray Directions = { - FIntPoint(1, 0), FIntPoint(-1, 0), - FIntPoint(0, 1), FIntPoint(0, -1) - }; - - for (const FIntPoint& Dir : Directions) - { - FIntPoint Neighbor = CurrentPoint + Dir; - - if (Neighbor.X >= 0 && Neighbor.X < Width && - Neighbor.Y >= 0 && Neighbor.Y < Height) - { - int32 Index = Neighbor.Y * Width + Neighbor.X; - - if (!Map[Index].IsValid()) - { - Map[Index] = TerrainTag; - Queue.Enqueue(Neighbor); - CurrentSize++; - - if (CurrentSize >= TargetSize) - { - break; - } - } - } - } - } - } - - // 填充剩余的空格 - for (int32 i = 0; i < Map.Num(); i++) - { - if (!Map[i].IsValid()) - { - float RandValue = RandomStream.FRand(); - for (int32 j = 0; j < WeightDistribution.Num(); j++) - { - if (RandValue <= WeightDistribution[j]) - { - Map[i] = GetFinalTerrainTag(HandleDistribution[j]); - break; - } - } - } - } -} - -void UTerrainGenerator::ApplyPerlinNoiseSmoothing(TArray& Map, int32 Width, int32 Height) const -{ - FRandomStream RandomStream(FMath::Rand()); - float NoiseScale = 0.1f; - - for (int32 Y = 0; Y < Height; Y++) - { - for (int32 X = 0; X < Width; X++) - { - int32 Index = Y * Width + X; - - // 计算柏林噪声值 - float NoiseValue = FMath::PerlinNoise2D(FVector2D(X * NoiseScale, Y * NoiseScale)); - NoiseValue = (NoiseValue + 1.0f) / 2.0f; // 映射到 0-1 - - // 50%概率根据噪声调整地形 - if (RandomStream.FRand() < 0.5f && NoiseValue > 0.7f) - { - // 查找周围最多的地形 - TMap NeighborCount; - - for (int32 dy = -1; dy <= 1; dy++) - { - for (int32 dx = -1; dx <= 1; dx++) - { - if (dx == 0 && dy == 0) continue; - - int32 NX = X + dx; - int32 NY = Y + dy; - - if (NX >= 0 && NX < Width && NY >= 0 && NY < Height) - { - FGameplayTag NeighborTag = Map[NY * Width + NX]; - NeighborCount.FindOrAdd(NeighborTag)++; - } - } - } - - // 找到最多的邻居地形 - FGameplayTag MostCommonTag; - int32 MaxCount = 0; - - for (const auto& Pair : NeighborCount) - { - if (Pair.Value > MaxCount) - { - MaxCount = Pair.Value; - MostCommonTag = Pair.Key; - } - } - - if (MaxCount > 0) - { - Map[Index] = MostCommonTag; - } - } - } - } -} - - diff --git a/Source/BusyRabbit/Private/Level/TerrainGeneratorBlueprintLibrary.cpp b/Source/BusyRabbit/Private/Level/TerrainGeneratorBlueprintLibrary.cpp deleted file mode 100644 index 04d0d79..0000000 --- a/Source/BusyRabbit/Private/Level/TerrainGeneratorBlueprintLibrary.cpp +++ /dev/null @@ -1,131 +0,0 @@ -#include "Level/TerrainGeneratorBlueprintLibrary.h" -#include "Level/TerrainGenerator.h" -#include "GameplayTagsManager.h" -#include "Engine/Engine.h" - -UTerrainGenerator* UTerrainGeneratorBlueprintLibrary::CreateTerrainGenerator() -{ - return NewObject(); -} - -void UTerrainGeneratorBlueprintLibrary::SetupExampleTerrainConfig(UTerrainGeneratorBase* Generator) -{ - if (!Generator) - { - return; - } - - // 定义地形标签 - FGameplayTag ForestTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Forest")); - FGameplayTag GrasslandTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Grassland")); - FGameplayTag WaterTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Water")); - FGameplayTag SwampTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Swamp")); - FGameplayTag LandTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Land")); - - FGameplayTag SwampLandTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Swamp.Land")); - FGameplayTag SwampWaterTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Swamp.Water")); - FGameplayTag ShallowWaterTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Water.Shallow")); - FGameplayTag DeepWaterTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Water.Deep")); - - // 添加父地形 - int32 ForestHandle = Generator->AddTerrain(ForestTag); - int32 GrasslandHandle = Generator->AddTerrain(GrasslandTag); - int32 WaterHandle = Generator->AddTerrain(WaterTag); - int32 SwampHandle = Generator->AddTerrain(SwampTag); - int32 LandHandle = Generator->AddTerrain(LandTag); - - // 添加子地形 - int32 SwampLandHandle = Generator->AddTerrain(SwampLandTag); - int32 SwampWaterHandle = Generator->AddTerrain(SwampWaterTag); - int32 ShallowWaterHandle = Generator->AddTerrain(ShallowWaterTag); - int32 DeepWaterHandle = Generator->AddTerrain(DeepWaterTag); - - // 绑定父子关系 - Generator->BindChildTerrain(SwampHandle, {SwampLandHandle, SwampWaterHandle}); - Generator->BindChildTerrain(WaterHandle, {ShallowWaterHandle, DeepWaterHandle}); - - // 设置概率 - Generator->SetProbability(ForestHandle, 0.8f); // 森林出现概率80% - Generator->SetProbability(GrasslandHandle, 0.9f); // 草地出现概率90% - Generator->SetProbability(WaterHandle, 0.7f); // 水体出现概率70% - Generator->SetProbability(SwampHandle, 0.6f); // 沼泽出现概率60% - Generator->SetProbability(LandHandle, 1.0f); // 土地总是出现 - - // 设置权重 - Generator->SetWeight(ForestHandle, 9.0f); // 森林权重9 - Generator->SetWeight(GrasslandHandle, 5.0f); // 草地权重5 - Generator->SetWeight(LandHandle, 3.0f); // 土地权重3 - - Generator->SetWeight(SwampLandHandle, 1.0f); // 沼泽陆地权重1 - Generator->SetWeight(SwampWaterHandle, 2.0f); // 沼泽水域权重2 - - Generator->SetWeight(ShallowWaterHandle, 3.0f); // 浅水权重3 - Generator->SetWeight(DeepWaterHandle, 1.0f); // 深水权重1 - - // 设置互斥关系 - Generator->SetExclusive({ForestHandle, SwampWaterHandle}); // 森林和沼泽水域互斥 -} - -TArray UTerrainGeneratorBlueprintLibrary::GenerateMap( - UTerrainGenerator* Generator, - int32 Width, - int32 Height) -{ - TArray Result; - - if (!Generator) - { - return Result; - } - - // 直接返回一维地图数据 - return Generator->GenerateMap(Width, Height); -} - -void UTerrainGeneratorBlueprintLibrary::GetMapDimensions( - UTerrainGenerator* Generator, - int32& Width, - int32& Height) -{ - Width = 256; - Height = 256; - - if (Generator) - { - // 这里可以根据需要从生成器获取实际的尺寸信息 - // 目前返回默认值 - } -} - -FString UTerrainGeneratorBlueprintLibrary::GetTerrainDisplayName(const FGameplayTag& TerrainTag) -{ - if (!TerrainTag.IsValid()) - { - return TEXT("无效地形"); - } - - FString TagName = TerrainTag.ToString(); - - // 从标签中提取显示名称 - if (TagName.StartsWith(TEXT("Terrain."))) - { - TagName.RemoveFromStart(TEXT("Terrain.")); - } - - // 替换下划线为空格 - TagName.ReplaceCharInline(TEXT('.'), TEXT(' ')); - TagName.ReplaceCharInline(TEXT('_'), TEXT(' ')); - - // 首字母大写 - if (TagName.Len() > 0) - { - TagName[0] = FChar::ToUpper(TagName[0]); - } - - return TagName; -} - -bool UTerrainGeneratorBlueprintLibrary::IsValidTerrainTag(const FGameplayTag& TerrainTag) -{ - return TerrainTag.IsValid(); -} diff --git a/Source/BusyRabbit/Private/Level/TerrainGeneratorTest.cpp b/Source/BusyRabbit/Private/Level/TerrainGeneratorTest.cpp deleted file mode 100644 index b00039e..0000000 --- a/Source/BusyRabbit/Private/Level/TerrainGeneratorTest.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "Level/TerrainGenerator.h" -#include "GameplayTagsManager.h" -#include "Engine/Engine.h" - -// 测试地形生成器功能 -void TestTerrainGenerator() -{ - // 创建地形生成器实例 - UTerrainGenerator* Generator = NewObject(); - - // 定义地形标签 - FGameplayTag ForestTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Forest")); - FGameplayTag GrasslandTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Grassland")); - FGameplayTag WaterTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Water")); - FGameplayTag SwampTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Swamp")); - FGameplayTag LandTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Land")); - - FGameplayTag SwampLandTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Swamp.Land")); - FGameplayTag SwampWaterTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Swamp.Water")); - FGameplayTag ShallowWaterTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Water.Shallow")); - FGameplayTag DeepWaterTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Water.Deep")); - - // 添加父地形 - int32 ForestHandle = Generator->AddTerrain(ForestTag); - int32 GrasslandHandle = Generator->AddTerrain(GrasslandTag); - int32 WaterHandle = Generator->AddTerrain(WaterTag); - int32 SwampHandle = Generator->AddTerrain(SwampTag); - int32 LandHandle = Generator->AddTerrain(LandTag); - - // 添加子地形 - int32 SwampLandHandle = Generator->AddTerrain(SwampLandTag); - int32 SwampWaterHandle = Generator->AddTerrain(SwampWaterTag); - int32 ShallowWaterHandle = Generator->AddTerrain(ShallowWaterTag); - int32 DeepWaterHandle = Generator->AddTerrain(DeepWaterTag); - - // 绑定父子关系 - Generator->BindChildTerrain(SwampHandle, {SwampLandHandle, SwampWaterHandle}); - Generator->BindChildTerrain(WaterHandle, {ShallowWaterHandle, DeepWaterHandle}); - - // 设置概率 - Generator->SetProbability(ForestHandle, 1.0f); - Generator->SetProbability(GrasslandHandle, 0.9f); - Generator->SetProbability(WaterHandle, 0.7f); - Generator->SetProbability(SwampHandle, 1.0f); // 设置为1.0确保沼泽总是出现 - Generator->SetProbability(LandHandle, 1.0f); - - // 设置权重 - Generator->SetWeight(ForestHandle, 9.0f); - Generator->SetWeight(GrasslandHandle, 5.0f); - Generator->SetWeight(LandHandle, 3.0f); - Generator->SetWeight(SwampHandle, 2.0f); // 为沼泽父节点设置权重 - - Generator->SetWeight(SwampLandHandle, 1.0f); - Generator->SetWeight(SwampWaterHandle, 2.0f); - - Generator->SetWeight(ShallowWaterHandle, 3.0f); - Generator->SetWeight(DeepWaterHandle, 1.0f); - - // 设置互斥关系 - Generator->SetExclusive({ForestHandle, SwampWaterHandle}); - - // 生成地图 - TArray Map = Generator->GenerateMap(64, 64); - - // 统计地形分布 - TMap TerrainCount; - for (const FGameplayTag& Tag : Map) - { - TerrainCount.FindOrAdd(Tag)++; - } - - // 输出统计结果 - UE_LOG(LogTemp, Log, TEXT("=== 地形生成统计 ===")); - UE_LOG(LogTemp, Log, TEXT("地图大小: %dx%d"), 64, 64); - UE_LOG(LogTemp, Log, TEXT("总格子数: %d"), Map.Num()); - - for (const auto& Pair : TerrainCount) - { - float Percentage = (float)Pair.Value / Map.Num() * 100.0f; - UE_LOG(LogTemp, Log, TEXT("%s: %d (%.1f%%)"), - *Pair.Key.ToString(), Pair.Value, Percentage); - } - - // 验证互斥关系 - bool HasForest = TerrainCount.Contains(ForestTag); - bool HasSwampWater = TerrainCount.Contains(SwampWaterTag); - - if (HasForest && HasSwampWater) - { - UE_LOG(LogTemp, Warning, TEXT("警告: 森林和沼泽水域同时出现,互斥关系可能未正确工作")); - } - else - { - UE_LOG(LogTemp, Log, TEXT("互斥关系验证: 通过")); - } - - // 验证父子关系 - bool HasSwamp = TerrainCount.Contains(SwampTag); - bool HasSwampChildren = TerrainCount.Contains(SwampLandTag) || TerrainCount.Contains(SwampWaterTag); - - if (HasSwamp && !HasSwampChildren) - { - UE_LOG(LogTemp, Warning, TEXT("警告: 沼泽出现但没有子地形")); - } - else if (!HasSwamp && HasSwampChildren) - { - UE_LOG(LogTemp, Warning, TEXT("警告: 沼泽子地形出现但沼泽未出现")); - } - else - { - UE_LOG(LogTemp, Log, TEXT("父子关系验证: 通过")); - } - - UE_LOG(LogTemp, Log, TEXT("=== 测试完成 ===")); -} - -// 控制台命令用于测试 -static FAutoConsoleCommand TestTerrainGeneratorCommand( - TEXT("TestTerrainGenerator"), - TEXT("测试地形生成器功能"), - FConsoleCommandDelegate::CreateStatic(TestTerrainGenerator) -); diff --git a/Source/BusyRabbit/Private/Role/BusyRole.cpp b/Source/BusyRabbit/Private/Role/BusyRole.cpp index d5348fc..8745885 100644 --- a/Source/BusyRabbit/Private/Role/BusyRole.cpp +++ b/Source/BusyRabbit/Private/Role/BusyRole.cpp @@ -59,7 +59,7 @@ void ABusyRole::Tick(float InDeltaSeconds){ } void ABusyRole::SetRole(const FName& Name){ - UDataTable* Table = UBusyGamePlayLibrary::GetGameDataTable("RoleConfig"); + UDataTable* Table = UBusyGameplayLibrary::GetGameDataTable("RoleConfig"); if (Table == nullptr) { return; } diff --git a/Source/BusyRabbit/Private/Role/RoleAnimation.cpp b/Source/BusyRabbit/Private/Role/RoleAnimation.cpp index 3b152ea..dbc1453 100644 --- a/Source/BusyRabbit/Private/Role/RoleAnimation.cpp +++ b/Source/BusyRabbit/Private/Role/RoleAnimation.cpp @@ -62,15 +62,13 @@ void URoleAnimation::PlayPickAnimation(const FName& ItemName, ERoleMoveDirection bool URoleAnimation::GetOwnerRoleInfo(UPaperFlipbookComponent*& Sprite, FBusyRoleAnimationData*& AnimationData){ - // ȡowner ABusyRole* Role = Cast(this->GetOwner()); if (Role == nullptr) { UE_LOG(LogRoleAnimation, Error, TEXT("URoleAnimation::GetPaperFilpBookComponent, Can't get Role")); return false; } - // owner - UDataTable* DataTable = UBusyGamePlayLibrary::GetGameDataTable("RoleAnimation"); + UDataTable* DataTable = UBusyGameplayLibrary::GetGameDataTable("RoleAnimation"); if (DataTable == nullptr) { UE_LOG(LogRoleAnimation, Error, TEXT("URoleAnimation::GetOwnerRoleInfo, Can't get Animation DataTable")) return false; diff --git a/Source/BusyRabbit/Public/BusyGamePlayLibrary.h b/Source/BusyRabbit/Public/BusyGamePlayLibrary.h index b003a29..aab2cf9 100644 --- a/Source/BusyRabbit/Public/BusyGamePlayLibrary.h +++ b/Source/BusyRabbit/Public/BusyGamePlayLibrary.h @@ -18,7 +18,7 @@ * */ UCLASS() -class BUSYRABBIT_API UBusyGamePlayLibrary : public UBlueprintFunctionLibrary +class BUSYRABBIT_API UBusyGameplayLibrary : public UBlueprintFunctionLibrary { GENERATED_BODY() @@ -33,7 +33,7 @@ public: static UClass* GetGameUIClass(const FString& ClassName); UFUNCTION(BlueprintPure) - static UWorld* K2_GetWorld(const UObject* obj); + static UWorld* K2_GetWorld(const UObject* UObj); UFUNCTION(BlueprintPure) static bool GetLevelBaseConfig(const FName& RowName, FBusyLevelBaseConfig& RowData); @@ -58,12 +58,5 @@ public: UFUNCTION(BlueprintPure) static bool GetCookMaterialStateConfig(const FName& RowName, FBusyCookMaterialStateConfig& RowData); - - UFUNCTION(BlueprintPure) - static FLuaBPVar CreateTextureBuffer(UObject* WorldContextObject); - - UFUNCTION(BlueprintCallable) - static void UpdateTextureBuffer(UTexture2D* DataTexture, TArray FloatData); - }; diff --git a/Source/BusyRabbit/Public/Level/Actor/BusyPlayerRole.h b/Source/BusyRabbit/Public/Level/Actor/BusyPlayerRole.h index 54c5230..14ae629 100644 --- a/Source/BusyRabbit/Public/Level/Actor/BusyPlayerRole.h +++ b/Source/BusyRabbit/Public/Level/Actor/BusyPlayerRole.h @@ -1,9 +1,10 @@ #pragma once #include "BusyPawnBase.h" +#include "Level/LevelPlayerController.h" #include "BusyPlayerRole.generated.h" UCLASS() -class ABusyPlayerRole : public ABusyPawnBase +class ABusyPlayerRole : public ABusyPawnBase, public IBusyControllable { GENERATED_BODY() public: @@ -12,21 +13,9 @@ public: protected: /*--------------------相机相关--------------------------*/ - - UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) TObjectPtr SpringArmComponent; UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) TObjectPtr CameraComponent; - - UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) - TObjectPtr Movement; // 移动组件 - - UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) - TObjectPtr RoleAbility; // 技能组件 - - UPROPERTY(BlueprintReadWrite) - TObjectPtr RoleAnimation; - }; diff --git a/Source/BusyRabbit/Public/Level/Actor/BusyStaticResource.h b/Source/BusyRabbit/Public/Level/Actor/BusyStaticResource.h new file mode 100644 index 0000000..43bd18f --- /dev/null +++ b/Source/BusyRabbit/Public/Level/Actor/BusyStaticResource.h @@ -0,0 +1,33 @@ +#pragma once +#include "LuaActor.h" +#include "BusyStaticResource.generated.h" + +class USpineSkeletonRendererComponent; +class USpineSkeletonAnimationComponent; + + +UCLASS(Blueprintable, BlueprintType) +class ABusyStaticResource:public ALuaActor +{ + GENERATED_BODY() +public: + ABusyStaticResource(); + + virtual void BeginPlay() override; + +public: + UPROPERTY(EditAnywhere) + TObjectPtr RootScene; //场景根组件 + + /*----------------------------spine相关组件----------------------------*/ + UPROPERTY(EditDefaultsOnly) + TObjectPtr SpineRoot; + + UPROPERTY(EditDefaultsOnly) + TObjectPtr SpineRenderComponent; + + UPROPERTY(EditAnywhere, BlueprintReadOnly) + TObjectPtr SpineAnimationComponent; + /*-------------------------------------------------------------------*/ + +}; diff --git a/Source/BusyRabbit/Public/Level/LevelPlayerController.h b/Source/BusyRabbit/Public/Level/LevelPlayerController.h index 2d59187..6c7ba84 100644 --- a/Source/BusyRabbit/Public/Level/LevelPlayerController.h +++ b/Source/BusyRabbit/Public/Level/LevelPlayerController.h @@ -3,6 +3,33 @@ #include "LuaPlayerController.h" #include "LevelPlayerController.generated.h" + +UINTERFACE(MinimalAPI, Blueprintable) +class UBusyControllable: public UInterface +{ + GENERATED_BODY() +}; + + +class IBusyControllable +{ + GENERATED_BODY() +public: + // 角色移动 + UFUNCTION(BlueprintNativeEvent, BlueprintCallable) + void OnMove(const FVector2D& Location); + + // 角色普通技能 + UFUNCTION(BlueprintNativeEvent, BlueprintCallable) + void OnPrimarySkill(); + + // 角色大招 + UFUNCTION(BlueprintNativeEvent, BlueprintCallable) + void OnUltimateSkill(); +}; + + +struct FInputActionValue; class ABusyPlayerRole; UCLASS() @@ -14,37 +41,69 @@ public: public: virtual void BeginPlay() override; - - -public: // RPC相关 - UFUNCTION(Server, Reliable) - void SetRoleMoveTo(const FVector2D& Location); - void SetRoleMoveTo_Implementation(const FVector2D& Location); - + virtual void SetupInputComponent() override; + virtual void Tick(float DeltaTime) override; public: UFUNCTION(BlueprintCallable, Category = "Controller") bool GetCursorPosition(FVector2D& Position) const; UFUNCTION(BlueprintCallable, Category = "Controller") - void GetCursorHitResult(TArray& Results) const; + ABusyPlayerRole* GetControlledRole() const; UFUNCTION(BlueprintCallable, Category = "Controller") - ABusyPlayerRole* GetControlledRole() const; + void GetCursorHitResult(TArray& Results) const; UFUNCTION(BlueprintCallable, Category = "Controller") void SwitchControlledRole(ABusyPlayerRole* Target); +public: + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Roaming Camera") + TSubclassOf RoamingCameraClass; + + // 漫游相机移动速度为角色移动速度 * 漫游速度系数 + UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName="漫游速度系数", Category = "Roaming Camera") + float RoamingSpeedFactor = 3.0; public: // 输入相关 UPROPERTY(EditDefaultsOnly, Category = "Input") TObjectPtr InputMapping; UPROPERTY(EditDefaultsOnly, Category = "Input") - TObjectPtr TouchAction; + TObjectPtr MoveAction; // 鼠标右键移动 + + UPROPERTY(EditDefaultsOnly, Category = "Input") + TObjectPtr SelectAction; // 鼠标左键选择 + UPROPERTY(EditDefaultsOnly, Category = "Input") + TObjectPtr PrimarySkillAction; // 基础技能 + + UPROPERTY(EditDefaultsOnly, Category = "Input") + TObjectPtr UltimateSkillAction; // 大招 + + UPROPERTY(EditDefaultsOnly, Category = "Input") + TObjectPtr CameraDetachAction; // 相机脱离 + + +public: + UFUNCTION() + void OnMove(const FInputActionValue& Value)const; UFUNCTION() - void OnTouch(const FInputActionValue& Value); + void OnPrimarySkill(const FInputActionValue& Value)const; + + UFUNCTION() + void OnUltimateSkill(const FInputActionValue& Value)const; + + UFUNCTION() + void OnCameraDetach(const FInputActionValue& Value); + + +protected: + UPROPERTY() + AActor* RoamingCameraActor = nullptr; + +private: + bool bCameraDetached = false; }; diff --git a/Source/BusyRabbit/Public/Level/LevelPlayerState.h b/Source/BusyRabbit/Public/Level/LevelPlayerState.h index b6362b3..cf9bb9e 100644 --- a/Source/BusyRabbit/Public/Level/LevelPlayerState.h +++ b/Source/BusyRabbit/Public/Level/LevelPlayerState.h @@ -15,7 +15,7 @@ class ALevelPlayerState : public ALuaPlayerState public: virtual void BeginPlay() override; - virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; + // virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; public: // 给蓝图初始化的接口 UFUNCTION(BlueprintCallable) @@ -27,19 +27,6 @@ public: // 给蓝图的Get接口 ABusyPlayerRole* GetControlledRole() const; - -public: // 给蓝图的Set接口 - UFUNCTION(BlueprintCallable) - void SetRoleRoster(const TArray& Roster); - - -public: - - -public: - - - protected: virtual FVector2D GetSpawnLocation()const; @@ -48,11 +35,10 @@ public: TArray> RoleClasses; protected: - UPROPERTY(Replicated, BlueprintReadOnly) + UPROPERTY(BlueprintReadOnly) int ControlledRoleIndex = -1; - - UPROPERTY(Replicated, BlueprintReadOnly) + UPROPERTY(BlueprintReadOnly) TArray RoleRoster; }; diff --git a/Source/BusyRabbit/Public/Level/TerrainGenerator.h b/Source/BusyRabbit/Public/Level/TerrainGenerator.h deleted file mode 100644 index f5ef4a9..0000000 --- a/Source/BusyRabbit/Public/Level/TerrainGenerator.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "CoreMinimal.h" -#include "GameplayTagContainer.h" -#include "Generator/TerrainGeneratorBase.h" -#include "TerrainGenerator.generated.h" - - - -UCLASS(BlueprintType, Blueprintable) -class BUSYRABBIT_API UTerrainGenerator : public UTerrainGeneratorBase -{ - GENERATED_BODY() - -public: - UTerrainGenerator(); - - virtual bool GenerateWithNodes( - TArray& Map, int32 Width, int32 Height, - const TArray& ValidLeafNodes - )override; - -private: - void RegionGrowing(TArray& Map, int32 Width, int32 Height, - const TArray& ValidLeafNodes) const; - - void ApplyPerlinNoiseSmoothing(TArray& Map, int32 Width, int32 Height) const; - -}; diff --git a/Source/BusyRabbit/Public/Level/TerrainGeneratorBlueprintLibrary.h b/Source/BusyRabbit/Public/Level/TerrainGeneratorBlueprintLibrary.h deleted file mode 100644 index 95a660c..0000000 --- a/Source/BusyRabbit/Public/Level/TerrainGeneratorBlueprintLibrary.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "CoreMinimal.h" -#include "Kismet/BlueprintFunctionLibrary.h" -#include "GameplayTagContainer.h" -#include "TerrainGeneratorBlueprintLibrary.generated.h" - -// 蓝图函数库,方便在蓝图中使用地形生成�? -UCLASS() -class BUSYRABBIT_API UTerrainGeneratorBlueprintLibrary : public UBlueprintFunctionLibrary -{ - GENERATED_BODY() - -public: - // 创建地形生成器实�? - UFUNCTION(BlueprintCallable, Category = "Terrain Generator") - static class UTerrainGenerator* CreateTerrainGenerator(); - - // 快速设置示例地形配�? - UFUNCTION(BlueprintCallable, Category = "Terrain Generator") - static void SetupExampleTerrainConfig(class UTerrainGeneratorBase* UTerrainGenerator); - - // 生成地图并返回一维数组(蓝图不支持嵌套TArray�? - UFUNCTION(BlueprintCallable, Category = "Terrain Generator") - static TArray GenerateMap( - class UTerrainGenerator* Generator, - int32 Width = 256, - int32 Height = 256 - ); - - // 获取地图尺寸信息(用于在蓝图中解析一维数组) - UFUNCTION(BlueprintCallable, Category = "Terrain Generator") - static void GetMapDimensions( - class UTerrainGenerator* Generator, - int32& Width, - int32& Height - ); - - // 获取地形标签的显示名�? - UFUNCTION(BlueprintCallable, Category = "Terrain Generator") - static FString GetTerrainDisplayName(const FGameplayTag& TerrainTag); - - // 检查地形标签是否有�? - UFUNCTION(BlueprintCallable, Category = "Terrain Generator") - static bool IsValidTerrainTag(const FGameplayTag& TerrainTag); -};