联机版实现,先备份
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