联机版实现,先备份
This commit is contained in:
@ -47,8 +47,8 @@ UClass* UBusyGamePlayLibrary::GetGameUIClass(const FString& ClassName){
|
||||
return Class ? Class->Get() : nullptr;
|
||||
}
|
||||
|
||||
UWorld* UBusyGamePlayLibrary::K2_GetWorld(UObject* obj){
|
||||
return Cast<UWorld>(obj->GetOuter());
|
||||
UWorld* UBusyGamePlayLibrary::K2_GetWorld(const UObject* obj){
|
||||
return obj->GetWorld();
|
||||
}
|
||||
|
||||
bool UBusyGamePlayLibrary::GetLevelBaseConfig(const FName& RowName, FBusyLevelBaseConfig& RowData){
|
||||
@ -84,7 +84,6 @@ bool UBusyGamePlayLibrary::GetCookMaterialStateConfig(const FName& RowName, FBus
|
||||
}
|
||||
|
||||
FLuaBPVar UBusyGamePlayLibrary::CreateTextureBuffer(UObject* WorldContextObject){
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
auto DataTexture = UTexture2D::CreateTransient(512, 1, PF_R32_FLOAT);
|
||||
DataTexture->Filter = TF_Trilinear;
|
||||
DataTexture->AddressX = TA_Clamp;
|
||||
@ -94,15 +93,12 @@ FLuaBPVar UBusyGamePlayLibrary::CreateTextureBuffer(UObject* WorldContextObject)
|
||||
}
|
||||
|
||||
void UBusyGamePlayLibrary::UpdateTextureBuffer(UTexture2D *DataTexture, TArray<float> FloatData){
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ա<EFBFBD>д<EFBFBD><D0B4>
|
||||
DataTexture->GetPlatformData()->Mips[0];
|
||||
FTexture2DMipMap& Mip = DataTexture->GetPlatformData()->Mips[0];
|
||||
void* Data = Mip.BulkData.Lock(LOCK_READ_WRITE);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD><DDB8>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD>
|
||||
FMemory::Memcpy(Data, FloatData.GetData(), FloatData.Num() * sizeof(float));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Mip.BulkData.Unlock();
|
||||
DataTexture->UpdateResource();
|
||||
}
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Gas/BusyAbilitySystemComponent.h"
|
||||
|
||||
@ -7,21 +7,30 @@
|
||||
|
||||
ABusyPawnBase::ABusyPawnBase()
|
||||
{
|
||||
|
||||
RootScene = CreateDefaultSubobject<USceneComponent>(TEXT("RootScene"));
|
||||
SpineRoot = CreateDefaultSubobject<USceneComponent>(TEXT("SpineRoot"));
|
||||
SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
|
||||
SpineRenderComponent = CreateDefaultSubobject<USpineSkeletonRendererComponent>(TEXT("SpineRenderComponent"));
|
||||
SpineAnimationComponent = CreateDefaultSubobject<USpineSkeletonAnimationComponent>(TEXT("SpineAnimationComponent"));
|
||||
AbilitySystemComponent = CreateDefaultSubobject<UBusyAbilitySystemComponent>(TEXT("AbilitySystemComponent"));
|
||||
|
||||
MovementComponent = CreateDefaultSubobject<UBusyPawnMovement>(TEXT("MovementComponent"));
|
||||
|
||||
|
||||
RootComponent = RootScene;
|
||||
SpineRoot->SetupAttachment(RootScene);
|
||||
SphereComponent->SetupAttachment(SpineRoot);
|
||||
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()
|
||||
@ -40,3 +49,4 @@ float ABusyPawnBase::GetSpeed_Implementation()const
|
||||
{
|
||||
return 280;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
#include "Level/Actor/Components/BusyAbilitySystemComponent.h"
|
||||
|
||||
FString UBusyAbilitySystemComponent::GetLuaFilePath_Implementation() const
|
||||
{
|
||||
return LuaFilePath;
|
||||
}
|
||||
@ -30,10 +30,14 @@ 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<IBusyMovable>(Owner);
|
||||
if (!Owner || !Movable) return;
|
||||
@ -61,8 +65,12 @@ void UBusyPawnMovement::TickComponent(float DeltaTime, ELevelTick TickType,
|
||||
}
|
||||
if (!NewLocation.Equals(CurrentLocation))
|
||||
{
|
||||
Owner->SetActorLocation(NewLocation, true);
|
||||
Owner->SetActorLocation(NewLocation, true);
|
||||
Owner->ForceNetUpdate();
|
||||
}
|
||||
Movable->Execute_UpdateMoveDirection(Owner, GetMoveDirection());
|
||||
}
|
||||
|
||||
|
||||
// Movable->Execute_UpdateMoveDirection(Owner, GetMoveDirection());
|
||||
}
|
||||
#pragma optimize("",on)
|
||||
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
#include "Level/BusyLevelItem.h"
|
||||
#include "Components/CapsuleComponent.h"
|
||||
#include "Components/WidgetComponent.h"
|
||||
#include "Gas/BusyAbilitySystemComponent.h"
|
||||
#include "BusyGamePlayLibrary.h"
|
||||
|
||||
ABusyLevelItem::ABusyLevelItem(): CurrentItemID("100001") {
|
||||
@ -16,7 +15,6 @@ ABusyLevelItem::ABusyLevelItem(): CurrentItemID("100001") {
|
||||
|
||||
PickBar = CreateDefaultSubobject<UWidgetComponent>(TEXT("PickBar"));
|
||||
LevelItemAttribute = CreateDefaultSubobject<UBusyLevelItemAttributeSet>("LevelItemAttribute");
|
||||
AbilityComponent = CreateDefaultSubobject<UBusyAbilitySystemComponent>("RoleAbility");
|
||||
|
||||
InitSprite();
|
||||
InitCapsule();
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
#include "Level/LevelPlayerController.h"
|
||||
#include "Level/Actor/BusyPlayerRole.h"
|
||||
#include "EnhancedInput/Public/EnhancedInputSubsystems.h"
|
||||
#include "Level/LevelPlayerState.h"
|
||||
#include "EnhancedInput/Public/EnhancedInputSubsystems.h"
|
||||
#include "EnhancedInput/Public/EnhancedInputComponent.h"
|
||||
|
||||
|
||||
ALevelPlayerController::ALevelPlayerController()
|
||||
{
|
||||
@ -16,11 +20,27 @@ void ALevelPlayerController::BeginPlay()
|
||||
SetInputMode(InputMode);
|
||||
|
||||
// 注册输入
|
||||
const auto Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer());
|
||||
if (InputMapping && Subsystem)
|
||||
if (!HasAuthority())
|
||||
{
|
||||
Subsystem->AddMappingContext(InputMapping, 0);
|
||||
const auto Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer());
|
||||
if (InputMapping && Subsystem)
|
||||
{
|
||||
Subsystem->AddMappingContext(InputMapping, 0);
|
||||
}
|
||||
|
||||
|
||||
if (UEnhancedInputComponent* EnhancedInput = CastChecked<UEnhancedInputComponent>(InputComponent)) {
|
||||
EnhancedInput->BindAction(TouchAction, ETriggerEvent::Triggered, this, FName("OnTouch"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ALevelPlayerController::SetRoleMoveTo_Implementation(const FVector2D& Location)
|
||||
{
|
||||
ABusyPlayerRole* ControlledRole = GetControlledRole();
|
||||
if (!ControlledRole) return;
|
||||
ControlledRole->MovementComponent->MoveTo(Location);
|
||||
}
|
||||
|
||||
bool ALevelPlayerController::GetCursorPosition(FVector2D& Position) const
|
||||
@ -42,11 +62,25 @@ void ALevelPlayerController::GetCursorHitResult(TArray<AActor*>& Results) const
|
||||
{
|
||||
}
|
||||
|
||||
void ALevelPlayerController::GetControlledRole() const
|
||||
ABusyPlayerRole* ALevelPlayerController::GetControlledRole() const
|
||||
{
|
||||
if (const ALevelPlayerState* PS = GetPlayerState<ALevelPlayerState>())
|
||||
{
|
||||
return PS->GetControlledRole();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ALevelPlayerController::SwitchControlledRole(ABusyPlayerRole* Target)
|
||||
{
|
||||
this->SetViewTarget(Target);
|
||||
}
|
||||
|
||||
void ALevelPlayerController::OnTouch(const FInputActionValue& Value)
|
||||
{
|
||||
FVector2D Position;
|
||||
if (GetCursorPosition(Position))
|
||||
{
|
||||
SetRoleMoveTo(Position);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
#include "Level/LevelPlayerState.h"
|
||||
|
||||
#include "Level/LevelPlayerController.h"
|
||||
#include "Net/UnrealNetwork.h"
|
||||
#include "Level/Actor/BusyPlayerRole.h"
|
||||
|
||||
|
||||
@ -10,38 +9,62 @@ DEFINE_LOG_CATEGORY(LogLevelPlayerState);
|
||||
void ALevelPlayerState::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
UWorld* World = GetWorld();
|
||||
const auto PC = Cast<ALevelPlayerController>(GetPlayerController());
|
||||
|
||||
if (!World || !PC)
|
||||
{
|
||||
UE_LOG(LogLevelPlayerState, Error, TEXT("ALevelPlayerController::BeginPlay() failed!"));
|
||||
return;
|
||||
}
|
||||
|
||||
FVector2D SpawnLocation = GetSpawnLocation();
|
||||
for (auto PawnClass : RoleClasses)
|
||||
{
|
||||
FTransform SpawnTransform;
|
||||
FActorSpawnParameters Params;
|
||||
SpawnTransform.SetLocation(FVector(SpawnLocation, 50));
|
||||
if (auto *NewRole = Cast<ABusyPlayerRole>(World->SpawnActor(PawnClass, nullptr, Params)))
|
||||
{
|
||||
Roles.Add(NewRole);
|
||||
}
|
||||
}
|
||||
|
||||
if (Roles.IsValidIndex(0))
|
||||
{
|
||||
PC->SwitchControlledRole(Roles[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void ALevelPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& 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)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const FVector Location = FVector(GetSpawnLocation(), 10);
|
||||
FActorSpawnParameters SpawnParameters;
|
||||
|
||||
for (const auto RoleClass : RoleClasses)
|
||||
{
|
||||
SpawnParameters.Owner = PlayerController;
|
||||
ABusyPlayerRole* NewRole = World->SpawnActor<ABusyPlayerRole>(
|
||||
RoleClass, Location,
|
||||
FRotator(), SpawnParameters
|
||||
);
|
||||
RoleRoster.Add(NewRole);
|
||||
}
|
||||
|
||||
if (RoleRoster.IsValidIndex(0))
|
||||
{
|
||||
ControlledRoleIndex = 0;
|
||||
return RoleRoster[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
ControlledRoleIndex = -1;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ABusyPlayerRole* ALevelPlayerState::GetControlledRole() const
|
||||
{
|
||||
if (Roles.IsValidIndex(ControlledRoleIndex))
|
||||
if (RoleRoster.IsValidIndex(ControlledRoleIndex))
|
||||
{
|
||||
return Roles[ControlledRoleIndex];
|
||||
return RoleRoster[ControlledRoleIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -53,3 +76,11 @@ FVector2D ALevelPlayerState::GetSpawnLocation()const
|
||||
{
|
||||
return FVector2D::ZeroVector;
|
||||
}
|
||||
|
||||
void ALevelPlayerState::SetRoleRoster(const TArray<ABusyPlayerRole*>& Roster)
|
||||
{
|
||||
if (HasAuthority())
|
||||
{
|
||||
RoleRoster = Roster;
|
||||
}
|
||||
}
|
||||
@ -1,275 +0,0 @@
|
||||
#include "Level/PaperTerrainMapActor.h"
|
||||
|
||||
#include "Level/TerrainGenerator.h"
|
||||
#include "Level/TerrainGeneratorBlueprintLibrary.h"
|
||||
#include "Paper2D/Classes/PaperTileMapComponent.h"
|
||||
#include "Paper2D/Classes/PaperTileMap.h"
|
||||
#include "Paper2D/Classes/PaperTileLayer.h"
|
||||
#include "Engine/Engine.h"
|
||||
#include "UObject/ConstructorHelpers.h"
|
||||
|
||||
/* 相邻四格地形信息映射到TileSet的索引
|
||||
* 以左上、右上、左下、右下地形块存在为1,不存在为0, 从左到右构建一个4位二进制整数
|
||||
* 假设原始TileSet中,0号索引左上、右上、右下为空, 对应二进制整数为0x0010
|
||||
* 那么TileSet的这个索引与相邻数据对应关系就是[0] -> 2
|
||||
* 也就是DefaultNeighborDataToIdxMappings[2] = 0
|
||||
*/
|
||||
const static int DefaultNeighborDataToIdxMappings[16] = {
|
||||
12, 13, 0, 3, 8, 1, 14, 5, 15, 4, 11, 2, 9, 10, 7, 6
|
||||
};
|
||||
|
||||
APaperTerrainMapActor::APaperTerrainMapActor()
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = false;
|
||||
|
||||
// 创建根组件
|
||||
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
|
||||
|
||||
// 创建TileMap组件
|
||||
TileMapComponent = CreateDefaultSubobject<UPaperTileMapComponent>(TEXT("TileMapComponent"));
|
||||
TileMapComponent->SetupAttachment(RootComponent);
|
||||
}
|
||||
|
||||
void APaperTerrainMapActor::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
if (bAutoGenerateOnBeginPlay)
|
||||
{
|
||||
GenerateTerrainMap();
|
||||
}
|
||||
}
|
||||
|
||||
void APaperTerrainMapActor::OnConstruction(const FTransform& Transform)
|
||||
{
|
||||
Super::OnConstruction(Transform);
|
||||
// 初始化地形生成器
|
||||
InitializeGenerator();
|
||||
// 初始化TileMap
|
||||
InitializeTileMap();
|
||||
|
||||
if (bAutoGenerateOnConstruction)
|
||||
{
|
||||
GenerateTerrainMap();
|
||||
}
|
||||
}
|
||||
|
||||
void APaperTerrainMapActor::GenerateTerrainMap()
|
||||
{
|
||||
if (!TerrainGenerator)
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("TerrainGenerator is null!"));
|
||||
return;
|
||||
}
|
||||
if (!TerrainTileSetConfigs)
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("TerrainTileSetConfigs is null!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 生成地形数据
|
||||
GeneratedTerrainData = TerrainGenerator->GenerateMap(MapWidth, MapHeight);
|
||||
|
||||
// 应用到TileMap
|
||||
ApplyTerrainToTileMap(GeneratedTerrainData);
|
||||
|
||||
UE_LOG(LogTemp, Log, TEXT("Terrain map generated successfully! Size: %dx%d"), MapWidth, MapHeight);
|
||||
}
|
||||
|
||||
void APaperTerrainMapActor::ClearMap()
|
||||
{
|
||||
if (!TileMapComponent || !TileMapComponent->TileMap)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 清除所有Tile - 通过重新创建空的TileMap来实??
|
||||
if (TileMapComponent->TileMap)
|
||||
{
|
||||
UPaperTileMap* NewTileMap = NewObject<UPaperTileMap>(this);
|
||||
NewTileMap->MapWidth = MapWidth;
|
||||
NewTileMap->MapHeight = MapHeight;
|
||||
NewTileMap->TileWidth = TileSize;
|
||||
NewTileMap->TileHeight = TileSize;
|
||||
|
||||
// 添加一个空图层
|
||||
UPaperTileLayer* NewLayer = NewObject<UPaperTileLayer>(NewTileMap);
|
||||
NewLayer->LayerName = FText::FromString("TerrainLayer");
|
||||
NewTileMap->TileLayers.Add(NewLayer);
|
||||
|
||||
TileMapComponent->SetTileMap(NewTileMap);
|
||||
}
|
||||
|
||||
GeneratedTerrainData.Empty();
|
||||
UE_LOG(LogTemp, Log, TEXT("Map cleared!"));
|
||||
}
|
||||
|
||||
#if WITH_EDITOR
|
||||
void APaperTerrainMapActor::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
||||
{
|
||||
Super::PostEditChangeProperty(PropertyChangedEvent);
|
||||
|
||||
FName PropertyName = (PropertyChangedEvent.Property != nullptr)
|
||||
? PropertyChangedEvent.Property->GetFName()
|
||||
: NAME_None;
|
||||
|
||||
// 当地图尺寸或Tile大小改变时,重新初始化TileMap
|
||||
if (PropertyName == GET_MEMBER_NAME_CHECKED(APaperTerrainMapActor, MapWidth) ||
|
||||
PropertyName == GET_MEMBER_NAME_CHECKED(APaperTerrainMapActor, MapHeight) ||
|
||||
PropertyName == GET_MEMBER_NAME_CHECKED(APaperTerrainMapActor, TileSize) ||
|
||||
PropertyName == GET_MEMBER_NAME_CHECKED(APaperTerrainMapActor, TileSetDataAsset))
|
||||
|
||||
{
|
||||
InitializeTileMap();
|
||||
GenerateTerrainMap();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void APaperTerrainMapActor::InitializeTileMap()
|
||||
{
|
||||
if (!TileMapComponent) return;
|
||||
|
||||
if (TileSetDataAsset)
|
||||
{
|
||||
TerrainTileSetConfigs = &TileSetDataAsset.Get()->TerrainTileSetConfigs;
|
||||
}
|
||||
else
|
||||
{
|
||||
TerrainTileSetConfigs = nullptr;
|
||||
}
|
||||
|
||||
// 创建TileMap
|
||||
UPaperTileMap *TileMap = NewObject<UPaperTileMap>(this);
|
||||
|
||||
// 设置TileMap参数
|
||||
TileMap->MapWidth = MapWidth;
|
||||
TileMap->MapHeight = MapHeight;
|
||||
TileMap->TileWidth = TileSize;
|
||||
TileMap->TileHeight = TileSize;
|
||||
|
||||
// 创建四层layer
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
UPaperTileLayer* NewLayer = NewObject<UPaperTileLayer>(TileMap);
|
||||
NewLayer->LayerName = FText::FromString(
|
||||
FString::Format(TEXT("TerrainLayer{0}"), {FString::FromInt(i)})
|
||||
);
|
||||
NewLayer->ResizeMap(MapWidth, MapHeight);
|
||||
TileMap->TileLayers.Add(NewLayer);
|
||||
}
|
||||
|
||||
TileMapComponent->SetTileMap(TileMap);
|
||||
UE_LOG(LogTemp, Log, TEXT("TileMap initialized: %dx%d, TileSize: %d"), MapWidth, MapHeight, TileSize);
|
||||
}
|
||||
|
||||
void APaperTerrainMapActor::InitializeGenerator()
|
||||
{
|
||||
// 创建地形生成器
|
||||
if (GeneratorClass.Get())
|
||||
{
|
||||
TerrainGenerator = NewObject<UTerrainGeneratorBase>(this, GeneratorClass.Get());
|
||||
UTerrainGeneratorBlueprintLibrary::SetupExampleTerrainConfig(TerrainGenerator);
|
||||
}
|
||||
else
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("APaperTerrainMapActor::APaperTerrainMapActor, GeneratorClass is nullptr"));
|
||||
}
|
||||
}
|
||||
|
||||
void APaperTerrainMapActor::ApplyTerrainToTileMap(const TArray<FGameplayTag>& TerrainData) const
|
||||
{
|
||||
if (!TileMapComponent || !TileMapComponent->TileMap || TerrainData.Num() != MapWidth * MapHeight)
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("Cannot apply terrain data to TileMap!"));
|
||||
return;
|
||||
}
|
||||
if (TileMapComponent->TileMap->TileLayers.Num() == 0)
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("No tile layers in TileMap!"));
|
||||
return;
|
||||
}
|
||||
|
||||
FGameplayTag TerrainTags[4];
|
||||
const int32 LimitedWidth = MapWidth - 1;
|
||||
const int32 LimitedHeight = MapHeight - 1;
|
||||
|
||||
for (int32 Y = 0; Y < LimitedHeight; Y++)
|
||||
{
|
||||
for (int32 X = 0; X < LimitedWidth; X++)
|
||||
{
|
||||
TerrainTags[0] = TerrainData[Y * MapWidth + X];
|
||||
TerrainTags[1] = TerrainData[Y * MapWidth + X + 1];
|
||||
TerrainTags[2] = TerrainData[(Y + 1) * MapWidth + X];
|
||||
TerrainTags[3] = TerrainData[(Y + 1) * MapWidth + X + 1];
|
||||
DrawTile(X, Y, TerrainTags);
|
||||
}
|
||||
}
|
||||
UE_LOG(LogTemp, Log, TEXT("Terrain data applied to TileMap!"));
|
||||
}
|
||||
|
||||
static inline int32 GetNeighborInfo(const FGameplayTag& TargetTag, FGameplayTag TerrainTags[4])
|
||||
{
|
||||
int32 NeighborInfo = 0;
|
||||
NeighborInfo += (TargetTag == TerrainTags[0] ? 1 : 0) << 3;
|
||||
NeighborInfo += (TargetTag == TerrainTags[1] ? 1 : 0) << 2;
|
||||
NeighborInfo += (TargetTag == TerrainTags[2] ? 1 : 0) << 1;
|
||||
NeighborInfo += (TargetTag == TerrainTags[3] ? 1 : 0);
|
||||
return NeighborInfo;
|
||||
}
|
||||
|
||||
static inline void GetSortedLayerDrawingInfo(FGameplayTag **LayerTerrainTags, int32 *LayerNeighborInfo, FGameplayTag TerrainTags[4])
|
||||
{
|
||||
// 返回0-3层每层应该画哪种地形格子,以及这个格子的哪种形状,可能需要排序
|
||||
LayerTerrainTags[0] = &TerrainTags[0];
|
||||
LayerTerrainTags[1] = &TerrainTags[1];
|
||||
LayerTerrainTags[2] = &TerrainTags[2];
|
||||
LayerTerrainTags[3] = &TerrainTags[3];
|
||||
LayerNeighborInfo[0] = GetNeighborInfo(TerrainTags[0], TerrainTags);
|
||||
LayerNeighborInfo[1] = GetNeighborInfo(TerrainTags[1], TerrainTags);
|
||||
LayerNeighborInfo[2] = GetNeighborInfo(TerrainTags[2], TerrainTags);
|
||||
LayerNeighborInfo[3] = GetNeighborInfo(TerrainTags[3], TerrainTags);
|
||||
}
|
||||
|
||||
void APaperTerrainMapActor::DrawTile(const int32 X, const int32 Y, FGameplayTag TerrainTags[4])const
|
||||
{
|
||||
int32 LayerNeighborInfo[4];
|
||||
FGameplayTag *LayerTerrainTags[4];
|
||||
UPaperTileMap* TileMap = TileMapComponent->TileMap;
|
||||
GetSortedLayerDrawingInfo(LayerTerrainTags, LayerNeighborInfo, TerrainTags);
|
||||
|
||||
for (int32 Index = 0; Index < 4; ++Index)
|
||||
{
|
||||
int32 TileIndex = 0;
|
||||
FPaperTileInfo TileInfo;
|
||||
|
||||
const FTerrainTileSetConfig *TileSetConfig = TerrainTileSetConfigs->Find(*LayerTerrainTags[Index]);
|
||||
if (!TileSetConfig)
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("APaperTerrainMapActor::DrawTile TileSetConfig not found: %s"), *LayerTerrainTags[Index]->GetTagName().ToString());
|
||||
continue;
|
||||
}
|
||||
const int32 NeighborInfo = LayerNeighborInfo[Index];
|
||||
if (TileSetConfig->bNeedOverrideMappings)
|
||||
{
|
||||
if (NeighborInfo < TileSetConfig->NeighborDataToIdxMappings.Num())
|
||||
{
|
||||
TileIndex = TileSetConfig->NeighborDataToIdxMappings[NeighborInfo];
|
||||
}
|
||||
else
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("APaperTerrainMapActor::DrawTile Neighbor Data not find: %s, %d"),
|
||||
*LayerTerrainTags[Index]->GetTagName().ToString(), NeighborInfo
|
||||
)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TileIndex = DefaultNeighborDataToIdxMappings[NeighborInfo];
|
||||
}
|
||||
UPaperTileLayer* TerrainLayer = TileMap->TileLayers[Index];
|
||||
TileInfo.TileSet = TileSetConfig->TileSet;
|
||||
TileInfo.PackedTileIndex = TileIndex;
|
||||
TerrainLayer->SetCell(X, Y, TileInfo);
|
||||
}
|
||||
}
|
||||
@ -10,7 +10,6 @@
|
||||
#include "Role/BusyRoleMovement.h"
|
||||
#include "Role/RoleAnimation.h"
|
||||
#include "BusyGamePlayLibrary.h"
|
||||
#include "Gas/BusyAbilitySystemComponent.h"
|
||||
#include "Components/InventoryComponent.h"
|
||||
#include "Core/PW_AbilitySystemComponent.h"
|
||||
#include "EnhancedInputComponent.h"
|
||||
@ -71,7 +70,7 @@ void ABusyRole::SetRole(const FName& Name){
|
||||
RoleName = Name;
|
||||
RoleConfig = *Row;
|
||||
|
||||
// <20><><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <20><><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
if (RoleAttribute) {
|
||||
RoleAttribute->InitHealth(Row->Health);
|
||||
RoleAttribute->InitHunger(Row->Hunger);
|
||||
@ -79,7 +78,7 @@ void ABusyRole::SetRole(const FName& Name){
|
||||
RoleAttribute->RegisterCustomAttribute();
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ü<EFBFBD><C3BC><EFBFBD>
|
||||
// <20><><EFBFBD>ü<EFBFBD><C3BC><EFBFBD>
|
||||
for (UClass* AbilityClass : Row->DefaultAbilities) {
|
||||
if (AbilityClass) {
|
||||
RoleAbility->GiveAbility(FGameplayAbilitySpec(AbilityClass));
|
||||
|
||||
@ -33,7 +33,7 @@ public:
|
||||
static UClass* GetGameUIClass(const FString& ClassName);
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
static UWorld* K2_GetWorld(UObject* obj);
|
||||
static UWorld* K2_GetWorld(const UObject* obj);
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
static bool GetLevelBaseConfig(const FName& RowName, FBusyLevelBaseConfig& RowData);
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "AbilitySystemComponent.h"
|
||||
#include "BusyAbilitySystemComponent.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class BUSYRABBIT_API UBusyAbilitySystemComponent : public UAbilitySystemComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
};
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "LuaPawn.h"
|
||||
#include "Level/Actor/Components/BusyPawnMovement.h"
|
||||
#include "Level/Actor/Components/BusyAbilitySystemComponent.h"
|
||||
#include "BusyPawnBase.generated.h"
|
||||
|
||||
|
||||
@ -8,6 +9,7 @@ class USphereComponent;
|
||||
class USpineBoneFollowerComponent;
|
||||
class USpineSkeletonRendererComponent;
|
||||
class USpineSkeletonAnimationComponent;
|
||||
class UBusyPawnMovementComponent;
|
||||
|
||||
|
||||
UCLASS()
|
||||
@ -22,7 +24,7 @@ public:
|
||||
virtual void UpdateMoveDirection_Implementation(const FVector2D& InDirection) override;
|
||||
|
||||
virtual float GetSpeed_Implementation()const override;
|
||||
|
||||
|
||||
protected:
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
TObjectPtr<USceneComponent> RootScene; //场景根组件
|
||||
@ -44,7 +46,13 @@ protected:
|
||||
TObjectPtr<USpineSkeletonAnimationComponent> SpineAnimationComponent;
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-----------------------------GAS相关--------------------------------*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly)
|
||||
TObjectPtr<UBusyAbilitySystemComponent> AbilitySystemComponent;
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
public:
|
||||
/*-------------------------------移动组件------------------------------*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly)
|
||||
TObjectPtr<UBusyPawnMovement> MovementComponent;
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "slua.h"
|
||||
#include "AbilitySystemComponent.h"
|
||||
#include "BusyAbilitySystemComponent.generated.h"
|
||||
|
||||
|
||||
UCLASS()
|
||||
class UBusyAbilitySystemComponent : public UAbilitySystemComponent, public ILuaOverriderInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
virtual FString GetLuaFilePath_Implementation() const override;
|
||||
|
||||
|
||||
protected:
|
||||
FString LuaFilePath;
|
||||
};
|
||||
@ -37,9 +37,6 @@ public:
|
||||
FVector2D GetMoveDirection()const;
|
||||
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)override;
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly)
|
||||
float MoveSpeed = 400;
|
||||
|
||||
protected:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly)
|
||||
|
||||
@ -16,6 +16,12 @@ public:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
|
||||
public: // RPC相关
|
||||
UFUNCTION(Server, Reliable)
|
||||
void SetRoleMoveTo(const FVector2D& Location);
|
||||
void SetRoleMoveTo_Implementation(const FVector2D& Location);
|
||||
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, Category = "Controller")
|
||||
bool GetCursorPosition(FVector2D& Position) const;
|
||||
@ -24,7 +30,7 @@ public:
|
||||
void GetCursorHitResult(TArray<AActor*>& Results) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Controller")
|
||||
void GetControlledRole() const;
|
||||
ABusyPlayerRole* GetControlledRole() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Controller")
|
||||
void SwitchControlledRole(ABusyPlayerRole* Target);
|
||||
@ -38,4 +44,7 @@ public: // 输入相关
|
||||
UPROPERTY(EditDefaultsOnly, Category = "Input")
|
||||
TObjectPtr<class UInputAction> TouchAction;
|
||||
|
||||
|
||||
UFUNCTION()
|
||||
void OnTouch(const FInputActionValue& Value);
|
||||
};
|
||||
|
||||
@ -14,27 +14,47 @@ class ALevelPlayerState : public ALuaPlayerState
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
||||
|
||||
public: // 给蓝图初始化的接口
|
||||
UFUNCTION(BlueprintCallable)
|
||||
AActor* CreateRoleRoster(class APlayerController* PlayerController);
|
||||
|
||||
|
||||
|
||||
public:
|
||||
public: // 给蓝图的Get接口
|
||||
UFUNCTION(BlueprintCallable)
|
||||
ABusyPlayerRole* GetControlledRole() const;
|
||||
|
||||
|
||||
|
||||
public: // 给蓝图的Set接口
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetRoleRoster(const TArray<ABusyPlayerRole*>& Roster);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
virtual FVector2D GetSpawnLocation()const;
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere)
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly)
|
||||
TArray<TSubclassOf<ABusyPlayerRole>> RoleClasses;
|
||||
|
||||
protected:
|
||||
UPROPERTY()
|
||||
UPROPERTY(Replicated, BlueprintReadOnly)
|
||||
int ControlledRoleIndex = -1;
|
||||
|
||||
|
||||
UPROPERTY()
|
||||
TArray<ABusyPlayerRole*> Roles;
|
||||
UPROPERTY(Replicated, BlueprintReadOnly)
|
||||
TArray<ABusyPlayerRole*> RoleRoster;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,97 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "Generator/TerrainGeneratorBase.h"
|
||||
#include "Map/TerrainLayerComponent.h"
|
||||
#include "PaperTerrainMapActor.generated.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
UCLASS(Blueprintable, BlueprintType)
|
||||
class BUSYRABBIT_API APaperTerrainMapActor : public AActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
APaperTerrainMapActor();
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
virtual void OnConstruction(const FTransform& Transform) override;
|
||||
|
||||
public:
|
||||
// 生成地图(可在蓝图中调用)
|
||||
UFUNCTION(BlueprintCallable, Category = "Terrain Map")
|
||||
void GenerateTerrainMap();
|
||||
|
||||
// 清除当前地图
|
||||
UFUNCTION(BlueprintCallable, Category = "Terrain Map")
|
||||
void ClearMap();
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
#endif
|
||||
|
||||
|
||||
protected: // 生成器相关
|
||||
// 地形生成器类
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "Terrain Map")
|
||||
TSubclassOf<class UTerrainGeneratorBase> GeneratorClass;
|
||||
|
||||
// 地形生成器实例
|
||||
UPROPERTY()
|
||||
TObjectPtr<class UTerrainGeneratorBase> TerrainGenerator;
|
||||
|
||||
// 生成的地形数据
|
||||
TArray<FGameplayTag> GeneratedTerrainData;
|
||||
|
||||
|
||||
protected: // 地图配置相关
|
||||
// 地图宽度
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Map Settings", meta = (ClampMin = "1", ClampMax = "1024"))
|
||||
int32 MapWidth = 16;
|
||||
|
||||
// 地图高度
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Map Settings", meta = (ClampMin = "1", ClampMax = "1024"))
|
||||
int32 MapHeight = 16;
|
||||
|
||||
// 瓦片大小(像素)
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Map Settings", meta = (ClampMin = "1"))
|
||||
int32 TileSize = 16;
|
||||
|
||||
protected: // 瓦片相关
|
||||
TMap<FGameplayTag, FTerrainTileSetConfig> *TerrainTileSetConfigs;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Map Settings", DisplayName="瓦片设置")
|
||||
TObjectPtr<UTerrainDoubleGridDataAsset> TileSetDataAsset;
|
||||
|
||||
|
||||
protected:
|
||||
// Paper2D瓦片地图组件
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
TObjectPtr<class UPaperTileMapComponent> TileMapComponent;
|
||||
|
||||
// 是否在构造时自动生成地图
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Map Settings")
|
||||
bool bAutoGenerateOnConstruction = true;
|
||||
|
||||
// 是否在开始时自动生成地图
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Map Settings")
|
||||
bool bAutoGenerateOnBeginPlay = true;
|
||||
private:
|
||||
// 初始化TileMap组件
|
||||
void InitializeTileMap();
|
||||
|
||||
void InitializeGenerator();
|
||||
|
||||
// 应用地形数据到TileMap
|
||||
void ApplyTerrainToTileMap(const TArray<FGameplayTag>& TerrainData)const;
|
||||
|
||||
void DrawTile(const int32 X, const int32 Y, FGameplayTag TerrainTags[4])const;
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user