PikaHUDBase.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/HUD.h"
#include "PikaMainInterface.h"
#include "PikaUIData.h"
#include "PikaGodStonePlayerController.h"
#include "PikaHUDBase.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API APikaHUDBase : public AHUD
{
GENERATED_BODY()
public:
APikaHUDBase();
virtual void BeginPlay() override;
//该函数类似Tick函数,会被连续调用
virtual void DrawHUD() override;
FORCEINLINE APikaGodStonePlayerController* PikaGetPC();
//UI数据
UPikaUIData * PikaUIDataInstance;
private:
//主界面指针
UPikaMainInterface * PikaMainInterfacePre;
};PikaHUDBase.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaHUDBase.h"
#include "ConstructorHelpers.h"
APikaHUDBase::APikaHUDBase()
{
//加载主界面蓝图
TSubclassOf<UPikaUIData> MyUIData = UPikaUIData::StaticClass();
if (GetWorld())
{
PikaUIDataInstance = NewObject<UPikaUIData>(GetWorld(), MyUIData);
static ConstructorHelpers::FClassFinder<UPikaMainInterface> PikaMainInterfaceInstance(TEXT("/Game/HUD/GameUI/PikaMainInterfaceBP"));
TSubclassOf<UPikaMainInterface> PikaInterfaceTsubclass = PikaMainInterfaceInstance.Class;
if (PikaInterfaceTsubclass && PikaUIDataInstance)
{
PikaMainInterfacePre = CreateWidget<UPikaMainInterface>(GetWorld(), PikaInterfaceTsubclass);
PikaMainInterfacePre->PikaUIDataPtr = PikaUIDataInstance;
PikaMainInterfacePre->AddToViewport();
}
}
}
void APikaHUDBase::BeginPlay()
{
Super::BeginPlay();
}
//该函数类似Tick函数,会被连续调用
void APikaHUDBase::DrawHUD()
{
if (PikaGetPC() && PikaGetPC()->PikaGlobalConfigPrePlayerCon && PikaGetPC()->PikaGameResourcePtr)
{
//绘制我们的地图
if (PikaGetPC()->PikaGetCurrentLevelMiniMap() && Canvas && PikaGetPC()->PikaGameResourcePtr->PikaLevelMiniMap.IsValidIndex(PikaGetPC()->PikaGlobalConfigPrePlayerCon->PikaGameLevelManangenment.PikaCurrentLevel))
{
//********************************************************************************************
int32 PikaCurrentLevel = PikaGetPC()->PikaGlobalConfigPrePlayerCon->PikaGameLevelManangenment.PikaCurrentLevel;
//贴图占我们的720分辨率的百分比
float PikaView_RatioY = PikaGetPC()->PikaGameResourcePtr->PikaLevelMiniMap[PikaCurrentLevel].PikaMiniMapSizeY / 720.f;
float PikaView_WHRatio = PikaGetPC()->PikaGameResourcePtr->PikaLevelMiniMap[PikaCurrentLevel].PikaMiniMapSizeY / PikaGetPC()->PikaGameResourcePtr->PikaLevelMiniMap[PikaCurrentLevel].PikaMiniMapSizeX;
//我们的视野离边界的距离
float PikaView_RatioIntervalY = PikaGetPC()->PikaGameResourcePtr->PikaLevelMiniMap[PikaCurrentLevel].PikaMiniMapSizeYInterval / 720.f;
float PikaView_IntervalWHRatio = PikaGetPC()->PikaGameResourcePtr->PikaLevelMiniMap[PikaCurrentLevel].PikaMiniMapSizeYInterval / PikaGetPC()->PikaGameResourcePtr->PikaLevelMiniMap[PikaCurrentLevel].PikaMiniMapSizeXInterval;
//当前的贴图大小
float PikaView_CurrentHeight = PikaView_RatioY * Canvas->SizeY;
float PikaView_CurrentWidth = PikaView_CurrentHeight / PikaView_WHRatio;
//当前的贴图与外边框的距离
float PikaView_CurrentIntervalHeight = PikaView_RatioIntervalY * Canvas->SizeY;
float PikaView_CurrentIntervalWidth = PikaView_CurrentIntervalHeight / PikaView_IntervalWHRatio;
//获取绘制地图的x,y坐标
float PikaView_MiniMapSizeX = Canvas->SizeX - (PikaView_CurrentWidth + PikaView_CurrentIntervalWidth);
float PikaView_MiniMapSizeY = Canvas->SizeY - (PikaView_CurrentHeight + PikaView_CurrentIntervalHeight);
//绘制地图
DrawTexture(PikaGetPC()->PikaGetCurrentLevelMiniMap(), PikaView_MiniMapSizeX, PikaView_MiniMapSizeY, PikaView_CurrentWidth, PikaView_CurrentHeight, 0, 0, 1, 1);
//********************************************************************************************
//绘制玩家的位置坐标
if (PikaGetPC()->PikaGlobalConfigPrePlayerCon)
{
//移除死亡的,不绘制
for (int32 i = 0; i < PikaGetPC()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterSpawnID.Num(); i++)
{
if (!PikaGetPC()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterActive[i])
PikaGetPC()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaRemoveIt(i);
}
for (int32 i = 0; i < PikaGetPC()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterSpawnID.Num(); i++)
{
//所有角色的世界位置
FVector PikaCharacter_Pos = PikaGetPC()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterLocation[i];
//获取该角色相对与我们的M(X,Y)的坐标的位置
FVector PikaVecLocation = (-1 * (PikaGetPC()->PikaGetMapMarkPointRotator())).RotateVector(PikaCharacter_Pos - PikaGetPC()->PikaGetMapMarkPointLocation());
//求出在真实场景内玩家在小地图上的距离
float PikaMiniMap_SizeX = (PikaVecLocation.X / PikaGetPC()->PikaGameResourcePtr->PikaLevelMiniMap[PikaCurrentLevel].PikaMapSizeX) * PikaView_CurrentWidth;
float PikaMiniMap_SizeY = (PikaVecLocation.Y / PikaGetPC()->PikaGameResourcePtr->PikaLevelMiniMap[PikaCurrentLevel].PikaMapSizeY) * PikaView_CurrentHeight;
//求出角色在我们地图上的坐标
float PikaChar_PosMiniMapX = PikaView_MiniMapSizeX + PikaMiniMap_SizeX;
float PikaChar_PosMiniMapY = PikaView_MiniMapSizeY + PikaMiniMap_SizeY;
//绘制点在我们的小地图上
if (PikaGetPC()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterTeam[i])
Canvas->K2_DrawLine(FVector2D(PikaChar_PosMiniMapX, PikaChar_PosMiniMapY), FVector2D(PikaChar_PosMiniMapX + 1, PikaChar_PosMiniMapY + 1), 6, FLinearColor::Blue);
else
Canvas->K2_DrawLine(FVector2D(PikaChar_PosMiniMapX, PikaChar_PosMiniMapY), FVector2D(PikaChar_PosMiniMapX + 1, PikaChar_PosMiniMapY + 1), 6, FLinearColor::Red);
}
//绘制相机框
if (PikaGetPC()->PikaGameResourcePtr->PikaNewCameraBoard && PikaGetPC()->GetPawn())
{
//获取地图比值
FVector2D PikaCharacter_Pos = PikaGetPC()->PikaGameResourcePtr->PikaPlayerLocConverMiniMapCoord(PikaCurrentLevel, PikaGetPC()->PikaGetMapMarkPoint(), PikaGetPC()->GetPawn());
float PikaMiniMap_SizeX = FMath::Abs(PikaCharacter_Pos.X* PikaView_CurrentWidth);
float PikaMiniMap_SizeY = FMath::Abs(PikaCharacter_Pos.Y* PikaView_CurrentHeight);
//求出角色在我们地图上的坐标
float PikaChar_PosMiniMapX = PikaView_MiniMapSizeX + PikaMiniMap_SizeX;
float PikaChar_PosMiniMapY = PikaView_MiniMapSizeY + PikaMiniMap_SizeY;
//摄像机尺寸
float PikaCamraBoardX = ((PikaGetPC()->PikaGameResourcePtr->PikaNewCameraBoardSize.X / PikaGetPC()->PikaGameResourcePtr->PikaLevelMiniMap[PikaCurrentLevel].PikaMapSizeX)* PikaView_CurrentWidth)*PikaGetPC()->PikaGlobalConfigPrePlayerCon->PikaMouseZoom;
float PikaCamraBoardY = ((PikaGetPC()->PikaGameResourcePtr->PikaNewCameraBoardSize.Y / PikaGetPC()->PikaGameResourcePtr->PikaLevelMiniMap[PikaCurrentLevel].PikaMapSizeY)* PikaView_CurrentHeight)*PikaGetPC()->PikaGlobalConfigPrePlayerCon->PikaMouseZoom;
DrawTexture(PikaGetPC()->PikaGameResourcePtr->PikaNewCameraBoard, PikaChar_PosMiniMapX - PikaCamraBoardX, PikaChar_PosMiniMapY - PikaCamraBoardY / 2, PikaCamraBoardX, PikaCamraBoardY, 0, 0, 1, 1);
}
}
}
}
}
FORCEINLINE APikaGodStonePlayerController* APikaHUDBase::PikaGetPC()
{
return PlayerOwner != NULL ? ((APikaGodStonePlayerController*)PlayerOwner) : NULL;
}PikaMainInterface.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "PikaUI_Inventory.h"
#include "SizeBox.h"
#include "PikaUITowerInfo.h"
#include "PikaUIGameCount.h"
#include "PikaUIGameMenu.h"
#include "PikaGameErrorHint.h"
#include "WidgetSwitcher.h"
#include "PikaUIReadAndWrite.h"
#include "PikaUIHallGameSetting.h"
#include "PikaUIGameWarning.h"
#include "PikaMainInterface.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FEventPikaLog, FString, MyString);
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaMainInterface : public UPikaUIWidgetBase
{
GENERATED_BODY()
//用来载入PikaUI_Inventory的蓝图类
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
TSubclassOf<UPikaUI_Inventory> PikaInventoryClass;
//用来载入UPikaUITowerInfo的蓝图类
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
TSubclassOf<UPikaUITowerInfo> PikaUITowerInfoClass;
//用来载入UPikaUIGameCount的蓝图类
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
TSubclassOf<UPikaUIGameCount> PikaUIGameCountClass;
//用来载入UPikaUIGameMenu的蓝图类
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
TSubclassOf<UPikaUIGameMenu> PikaUIGameMenuClass;
//用来载入UPikaGameErrorHint的蓝图类
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
TSubclassOf<UPikaGameErrorHint> PikaGameErrorHintClass;
//用来载入UPikaUIReadAndWrite的蓝图类
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
TSubclassOf<UPikaUIReadAndWrite> PikaReadAndWriteClass;
//用来载入UPikaUIHallGameSetting的蓝图类
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
TSubclassOf<UPikaUIHallGameSetting> PikaHallGameSettingsClass;
//用来载入UPikaUIGameWarning的蓝图类
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
TSubclassOf<UPikaUIGameWarning> PikaGameWarningClass;
//BoxSize相关的名字
//////////////////////////////////////////////////////////////////////////
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaAttributeInfoArrayName;
//物品栏集合的名字,由蓝图传入
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaInventoryArrayName;
//物品栏道具的信息,由蓝图传入
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaCharacterInfoArrayName;
//游戏规则和游戏计时,由蓝图传入
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaUIGameCountArrayName;
//游戏内部简易菜单,由蓝图传入
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaUIGameMenuArrayName;
//错误提示,由蓝图传入
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaGameErrorHintArrayName;
//打开游戏菜单
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaGameOpenMenuName;
//设置和存储菜单
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaBoxSaveGameArrayName;
//警告框
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaBoxGameWarningArrayName;
public:
virtual void AddToViewport(int32 ZOrder = 0) override;
//每一帧的屏幕信息
FGeometry ScreenGeometry;
//打印的代理
FEventPikaLog PikaLog;
//负责打印GameLOG
virtual void PikaLogPrintf(FString MyString) override;
virtual void PikaDrawUIToScreen() override;
//Tick
virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;
//敲击
virtual void PikaOnClickedWidget(UWidget* MyWidget)override;
//屏蔽操作
void PikaShieldedInteractiveOperation(bool InVisibility);
//存档与游戏设置切换
void PikaSetBoxListDisplayOrder(PikaBoxListType::Type BoxListType);
PikaBoxListType::Type PikaGetBoxListDisplayOrder() const;
virtual void PikaSetWarningWindowsState(bool IsVisibles, float StateTime = 0, FString MyWidget = "", TEnumAsByte<PikaEButtonSureType::Type> MyButtonSureType = PikaEButtonSureType::BST_None) override;
////////////////////////////////////内联/////////////////////////////////////
FORCEINLINE USizeBox* PikaGetCharacterAttribute() const { return PikaAttributeInfoArray; }
FORCEINLINE UPikaUITowerInfo* PikaGetUITowerInfo() const { return PikaUITowerInfoPtr; }
FORCEINLINE UWidgetSwitcher* PikaGetBoxSaveGameArray()const { return PikaBoxSaveGameArray; }
FORCEINLINE UPikaUIReadAndWrite* PikaGetReadAndWrite() const { return PikaReadAndWrite; }
FORCEINLINE UPikaUIGameWarning* PikaGetGameWarning() const { return PikaGameWarningPtr; }
private:
//UPikaUI_Inventory类的指针
UPikaUI_Inventory * PikaUIInventoryPtr;
//UPikaUITowerInfo类的指针,对应PikaAttributeInfoArray
UPikaUITowerInfo * PikaUITowerInfoPtr;
//作为临时角色数据显示
FPikaCharacterInformationWidget* PikaTempCharacterInformationWidget;
//游戏规则和游戏计时
UPikaUIGameCount* PikaUIGameCountPtr;
//游戏内部简易菜单
UPikaUIGameMenu* PikaUIGameMenuPtr;
//错误提示
UPikaGameErrorHint* PikaGameErrorHintPtr;
//保存和读取界面
UPikaUIReadAndWrite* PikaReadAndWrite;
//游戏设置
UPikaUIHallGameSetting* PikaHallGameSettings;
//提示界面
UPikaUIGameWarning* PikaGameWarningPtr;
//容器相关
USizeBox * PikaInventorySlotArrayBox;
USizeBox * PikaCharacterInfoArray;
USizeBox* PikaAttributeInfoArray;
USizeBox* PikaGameCountArray;
USizeBox* PikaGameErrorHintArray;
USizeBox* PikaGameMenuArray;
UButton* PikaGameOpenMenu;
UWidgetSwitcher* PikaBoxSaveGameArray;
USizeBox* PikaBoxGameWarninArray;
//存储我们的控件的上级
TArray<UWidget*> PikaBoxSizeArray;
protected:
//NativeOnDragDetected激活后,如果将图标从一个物品栏拖拽到另外一个物品栏则会触发该事件
//接收拖拽信息,InOperation为空时,该函数不会被激活
virtual bool NativeOnDrop(const FGeometry& InGeometry, const FDragDropEvent& InDragDropEvent, UDragDropOperation* InOperation) override;
};PikaMainInterface.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaMainInterface.h"
#include "Engine/Engine.h"
#include "Public/PikaDragDropOperation.h"
void UPikaMainInterface::AddToViewport(int32 ZOrder /*= 0*/)
{
Super::AddToViewport(ZOrder);
PikaInventorySlotArrayBox = Cast<USizeBox>(PikaqiuGetBlueprintWidget(PikaInventoryArrayName));
PikaCharacterInfoArray = Cast<USizeBox>(PikaqiuGetBlueprintWidget(PikaCharacterInfoArrayName));
PikaGameCountArray = Cast<USizeBox>(PikaqiuGetBlueprintWidget(PikaUIGameCountArrayName));
PikaGameErrorHintArray = Cast<USizeBox>(PikaqiuGetBlueprintWidget(PikaGameErrorHintArrayName));
PikaGameMenuArray = Cast<USizeBox>(PikaqiuGetBlueprintWidget(PikaUIGameMenuArrayName));
PikaGameOpenMenu = PikaGetButtonFromBlueprint(PikaGameOpenMenuName);
PikaBoxSaveGameArray = Cast<UWidgetSwitcher>(PikaqiuGetBlueprintWidget(PikaBoxSaveGameArrayName));
PikaBoxGameWarninArray = Cast<USizeBox>(GetWidgetFromName(PikaBoxGameWarningArrayName));
//在基础UI里添加控件
if (GetWorld())
{
//添加Inventory
if (PikaInventoryClass && PikaInventorySlotArrayBox)
{
PikaUIInventoryPtr = CreateWidget<UPikaUI_Inventory>(GetWorld(), PikaInventoryClass);
PikaUIInventoryPtr->PikaUIDataPtr = PikaUIDataPtr;
//添加进去
PikaAddSizeBox(PikaInventorySlotArrayBox, PikaUIInventoryPtr);
PikaUIInventoryPtr->PikaSetMainInterface(this);
PikaUIInventoryPtr->PikaDrawUIToScreen();
}
//添加PikaUITowerInfo控件
if (PikaUITowerInfoClass && PikaCharacterInfoArray)
{
PikaUITowerInfoPtr = CreateWidget<UPikaUITowerInfo>(GetWorld(), PikaUITowerInfoClass);
PikaUITowerInfoPtr->PikaUIDataPtr = PikaUIDataPtr;
//添加进去
PikaAddSizeBox(PikaCharacterInfoArray, PikaUITowerInfoPtr);
PikaUITowerInfoPtr->PikaDrawUIToScreen();
//默认状态下隐藏
PikaUITowerInfoPtr->SetVisibility(ESlateVisibility::Hidden);
}
//添加UPikaUIGameCount
if (PikaUIGameCountClass && PikaGameCountArray)
{
PikaUIGameCountPtr = CreateWidget<UPikaUIGameCount>(GetWorld(), PikaUIGameCountClass);
PikaUIGameCountPtr->PikaUIDataPtr = PikaUIDataPtr;
//添加进去
PikaAddSizeBox(PikaGameCountArray, PikaUIGameCountPtr);
PikaUIGameCountPtr->PikaSetMainInterface(this);
PikaUIGameCountPtr->PikaDrawUIToScreen();
}
//添加UPikaUIGameMenu
if (PikaUIGameMenuClass && PikaGameMenuArray)
{
PikaUIGameMenuPtr = CreateWidget<UPikaUIGameMenu>(GetWorld(), PikaUIGameMenuClass);
PikaUIGameMenuPtr->PikaUIDataPtr = PikaUIDataPtr;
//添加进去
PikaAddSizeBox(PikaGameMenuArray, PikaUIGameMenuPtr);
PikaUIGameMenuPtr->PikaSetMainInterface(this);
PikaUIGameMenuPtr->PikaDrawUIToScreen();
//默认状态下隐藏
PikaUIGameMenuPtr->SetVisibility(ESlateVisibility::Hidden);
}
//添加UPikaGameErrorHint
if (PikaGameErrorHintClass && PikaGameErrorHintArray)
{
PikaGameErrorHintPtr = CreateWidget<UPikaGameErrorHint>(GetWorld(), PikaGameErrorHintClass);
PikaGameErrorHintPtr->PikaUIDataPtr = PikaUIDataPtr;
//添加进去
PikaAddSizeBox(PikaGameErrorHintArray, PikaGameErrorHintPtr);
PikaGameErrorHintPtr->PikaSetMainInterface(this);
PikaGameErrorHintPtr->PikaDrawUIToScreen();
}
//叠加界面
if (PikaBoxSaveGameArray)
{
//隐藏自己
PikaBoxSaveGameArray->SetVisibility(ESlateVisibility::Hidden);
//添加我们的游戏存储界面
if (PikaReadAndWriteClass)
{
PikaReadAndWrite = CreateWidget<UPikaUIReadAndWrite>(GetWorld(), PikaReadAndWriteClass);
check(PikaReadAndWrite);
PikaReadAndWrite->PikaUIDataPtr = PikaUIDataPtr;
PikaBoxSaveGameArray->AddChild(PikaReadAndWrite);
PikaReadAndWrite->PikaDrawUIToScreen();
if (PikaUIGameMenuPtr)
PikaReadAndWrite->PikaSetGameMenu(PikaUIGameMenuPtr);
PikaReadAndWrite->PikaSetButtonText(PikaReadAndWrite->Pika_WText[0]);
PikaReadAndWrite->PikaSetNewButtonType(PikaETDButtonType::SaveGame);
}
//添加设置界面
if (PikaHallGameSettingsClass)
{
PikaHallGameSettings = CreateWidget<UPikaUIHallGameSetting>(GetWorld(), PikaHallGameSettingsClass);
check(PikaHallGameSettings);
PikaHallGameSettings->PikaUIDataPtr = PikaUIDataPtr;
PikaBoxSaveGameArray->AddChild(PikaHallGameSettings);
PikaHallGameSettings->PikaDrawUIToScreen();
if (PikaUIGameMenuPtr)
PikaHallGameSettings->PikaSetGameMenu(PikaUIGameMenuPtr);
}
}
//加载游戏警告
if (PikaGameWarningClass && PikaBoxGameWarninArray)
{
//隐藏自己
PikaBoxGameWarninArray->SetVisibility(ESlateVisibility::Hidden);
PikaGameWarningPtr = CreateWidget<UPikaUIGameWarning>(GetWorld(), PikaGameWarningClass);
check(PikaGameWarningPtr);
PikaGameWarningPtr->PikaUIDataPtr = PikaUIDataPtr;
//添加进去
PikaAddSizeBox(PikaBoxGameWarninArray, PikaGameWarningPtr);
PikaGameWarningPtr->PikaSetMainInterface(this);
PikaGameWarningPtr->PikaDrawUIToScreen();
//隐藏
//SetWarningWindowsState(false, 0.5f);
}
}
//添加到数组,用在暂停游戏时,屏蔽掉所有不能和鼠标互动的组件
if (PikaInventorySlotArrayBox)
PikaBoxSizeArray.Add(PikaInventorySlotArrayBox);
if (PikaGameOpenMenu)
PikaBoxSizeArray.Add(PikaGameOpenMenu);
if (PikaCharacterInfoArray)
PikaBoxSizeArray.Add(PikaCharacterInfoArray);
if (PikaGameCountArray)
PikaBoxSizeArray.Add(PikaGameCountArray);
if (PikaGameErrorHintArray)
PikaBoxSizeArray.Add(PikaGameErrorHintArray);
}
void UPikaMainInterface::PikaLogPrintf(FString MyString)
{
PikaLog.Broadcast(MyString);
}
void UPikaMainInterface::PikaDrawUIToScreen()
{
///////////////////////////////////控件///////////////////////////////////////
//InventorySlotArray = Cast<USizeBox>(GetWidgetFromName(InventorySlotArrayName));
//WidgetInformationArray = Cast<USizeBox>(GetWidgetFromName(WidgetInformationArrayName));
//GameMenuArray = Cast<USizeBox>(GetWidgetFromName(GameMenuName));
//GamePromptErrorArray = Cast<USizeBox>(GetWidgetFromName(GamePromptErrorName));
//GameCountArray = Cast<USizeBox>(GetBlueprintWidget(GameCountName));
//BoxSaveGameArray = Cast<UWidgetSwitcher>(GetBlueprintWidget(BoxSaveGameArrayName));
//BoxGameWarninArray = Cast<USizeBox>(GetWidgetFromName(BoxGameWarningArrayName));
//BoxCharacterList = Cast<USizeBox>(GetWidgetFromName(BoxCharacterButtonName));
//BoxKeyList = Cast<USizeBox>(GetBlueprintWidget(BoxKeyListName));
//ConditionsArray = Cast<USizeBox>(GetWidgetFromName(ConditionsArrayName));
PikaAttributeInfoArray = Cast<USizeBox>(GetWidgetFromName(PikaAttributeInfoArrayName));
//APointOnScreen = Cast<UImage>(GetBlueprintWidget(APointOnScreenName));
//////////////////////////////////////////////////////////////////////////
}
void UPikaMainInterface::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
Super::NativeTick(MyGeometry, InDeltaTime);
//获取角色数据并在界面上显示
if (PikaUIInventoryPtr && PikaUITowerInfoPtr)
{
if (PikaUIInventoryPtr->PikaGetNewInventorySlot() && PikaUIInventoryPtr->PikaGetNewInventorySlot()->PikaBuildingTowerStruct.PikaIsActive())
{
//只要是我们的CharacterInformationWidget的值发生改变,才会显示改变的值
if (!PikaTempCharacterInformationWidget || !(&PikaUIInventoryPtr->PikaGetNewInventorySlot()->PikaBuildingTowerStruct.PikaCharacterInformationWidget == PikaTempCharacterInformationWidget))
{
PikaUITowerInfoPtr->PikaCharacterInformationWidget = &PikaUIInventoryPtr->PikaGetNewInventorySlot()->PikaBuildingTowerStruct.PikaCharacterInformationWidget;
//作为临时判断的界面信息
PikaTempCharacterInformationWidget = &PikaUIInventoryPtr->PikaGetNewInventorySlot()->PikaBuildingTowerStruct.PikaCharacterInformationWidget;
//更新界面显示
PikaUITowerInfoPtr->PikaUpdateCharacterInformation();
}
}
}
}
//onclick事件是通过父类UPikaUIWidgetBase里的PikaGetButtonFromBlueprint方法绑定的
void UPikaMainInterface::PikaOnClickedWidget(UWidget* MyWidget)
{
if (MyWidget == PikaGameOpenMenu)
{
if (PikaUIGameMenuPtr && PikaGetPlayerController())
{
PikaUIGameMenuPtr->SetVisibility(ESlateVisibility::Visible);
PikaShieldedInteractiveOperation(false);
//设置全局时间
if (PikaGetGameInstance())
{
//设置全局时间的增量为0,默认值为0
PikaGetGameInstance()->PikaSetGlobalGameTime();
}
}
}
}
void UPikaMainInterface::PikaShieldedInteractiveOperation(bool InVisibility)
{
for (UWidget* ElementWidger : PikaBoxSizeArray)
{
ElementWidger->SetIsEnabled(InVisibility);
}
//锁住CD更新或继续CD更新
if (PikaUIInventoryPtr)
PikaUIInventoryPtr->PikaLockSlotCD(!InVisibility);
//暂停游戏或继续游戏
PikaGetPlayerController()->SetPause(!InVisibility);
}
void UPikaMainInterface::PikaSetBoxListDisplayOrder(PikaBoxListType::Type BoxListType)
{
if (PikaBoxSaveGameArray)
PikaBoxSaveGameArray->SetActiveWidgetIndex(BoxListType);
}
PikaBoxListType::Type UPikaMainInterface::PikaGetBoxListDisplayOrder() const
{
if (PikaBoxSaveGameArray)
return (PikaBoxListType::Type)PikaBoxSaveGameArray->GetActiveWidgetIndex();
return (PikaBoxListType::Type)INDEX_NONE;
}
void UPikaMainInterface::PikaSetWarningWindowsState(bool IsVisibles, float StateTime /*= 0*/, FString MyWidget /*= ""*/, TEnumAsByte<PikaEButtonSureType::Type> MyButtonSureType /*= PikaEButtonSureType::BST_None*/)
{
if (IsVisibles)
{
//显示警告框
PikaGameWarningPtr->PikaSetText(MyWidget);
PikaBoxGameWarninArray->SetVisibility(ESlateVisibility::Visible);
}
else
{
PikaBoxGameWarninArray->SetVisibility(ESlateVisibility::Hidden);
}
}
bool UPikaMainInterface::NativeOnDrop(const FGeometry& InGeometry, const FDragDropEvent& InDragDropEvent, UDragDropOperation* InOperation)
{
Super::NativeOnDrop(InGeometry, InDragDropEvent, InOperation);
bool PikaIsDrop = false;
return PikaIsDrop;
}PikaMonster.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaCharacterBase.h"
#include "PikaBulletBase.h"
#include "PikaMonster.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API APikaMonster : public APikaCharacterBase
{
GENERATED_BODY()
public:
//怪物的攻击逻辑
virtual void PikaAttackTarget(AActor * Target) override;
//接收对方的伤害
virtual float PikaGetDefenceDamage(AActor * OtherActor);
//子弹
APikaBulletBase * PikaMyBullet;
//怪物死亡函数
virtual void PikaDestoryCharacter(float DelayTime = 0) override;
virtual void BeginPlay() override;
};PikaMonster.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaMonster.h"
#include "Kismet/GameplayStatics.h"
#include "Public/PikaMonsterAIController.h"
//怪物的攻击逻辑,攻击目标Target由行为树传递过来
void APikaMonster::PikaAttackTarget(AActor * Target)
{
Super::PikaAttackTarget(Target);
if (PikaCharacterBullet && GetWorld() && GetSpawnPoint())
{
APikaCharacterBase * PikaEnemyTower = Cast<APikaCharacterBase>(Target);
FVector PikaBulletLocation = GetSpawnPoint()->GetComponentLocation();
//FRotator PikaBuletRotator = GetSpawnPoint()->GetComponentRotation();
//销毁上一次的子弹
/*if (PikaMyBullet)
{
PikaMyBullet->Destroy(true);
PikaMyBullet = NULL;
}*/
PikaMyBullet = GetWorld()->SpawnActor<APikaBulletBase>(PikaCharacterBullet, PikaBulletLocation, FRotationMatrix::MakeFromX(PikaEnemyTower->GetHomingPoint()->GetComponentLocation() - PikaBulletLocation).Rotator());
if (PikaMyBullet)
{
//将自己赋值到子弹的施法者里
PikaMyBullet->PikaSetCasterCharacter(this);
//跟踪子弹
if (PikaMyBullet->PikaBulletTypeBP == PikaBulletType::PikaBULLET_Track)
{
APikaCharacterBase * PikaMyTarget = (APikaCharacterBase*)Target;
if (PikaMyTarget)
{
//跟踪加速度大小
PikaMyBullet->GetProjectleMovment()->HomingAccelerationMagnitude = 4000.f;
//跟踪组件
PikaMyBullet->GetProjectleMovment()->HomingTargetComponent = PikaMyTarget->GetHomingPoint();
//绑定伤害特效
/*if (PikaMyBullet->PikaDamageParticle)
{
UGameplayStatics::SpawnEmitterAttached(PikaMyBullet->PikaDamageParticle, PikaMyTarget->GetHomingPoint());
}*/
}
return;
}
//直线飞行子弹
if (PikaMyBullet->PikaBulletTypeBP == PikaBulletType::PikaBULLET_Line)
{
return;
}
//范围攻击型子弹
if (PikaMyBullet->PikaBulletTypeBP == PikaBulletType::PikaBULLET_Range)
{
return;
}
//闪电型攻击
if (PikaMyBullet->PikaBulletTypeBP == PikaBulletType::PikaBULLET_Chain)
{
return;
}
}
}
}
float APikaMonster::PikaGetDefenceDamage(AActor * OtherActor)
{
return 0;
}
void APikaMonster::PikaDestoryCharacter(float DelayTime)
{
//上传死亡的数据
if (PikaGetPlayerController())
PikaGetPlayerController()->PikaGlobalConfigPre->PikaGameData.PikaKillSoldierNumber++;
Super::PikaDestoryCharacter(DelayTime);
APikaMonsterAIController * PikaMonAICon = Cast<APikaMonsterAIController>(Controller);
//告诉行为树角色已死亡
if (PikaMonAICon)
{
PikaMonAICon->PikaSetCharacterDeathInfoSendBehaviorTree(true);
}
}
void APikaMonster::BeginPlay()
{
Super::BeginPlay();
//将塔的Team设置为true,初始化时为false
if (PikaCharDataPre)
PikaCharDataPre->PikaCharBaseData.PikaTeam = false;
}PikaMonsterAIController.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "AIController.h"
#include "BehaviorTree/BehaviorTree.h"
#include "Public/PikaTowers.h"
#include "PikaMonsterAIController.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API APikaMonsterAIController : public AAIController
{
GENERATED_BODY()
//创建行为树指针
UPROPERTY(EditDefaultsOnly , Category = "PikaBehaviorTree")
UBehaviorTree * PikaMonsterBeahaviorTreePre;
UPROPERTY(EditDefaultsOnly, Category = "PikaBehaviorTree")
FName PikaDeathName;
public:
virtual void BeginPlay() override;
//寻找目标
AActor * PikaFindTarget();
//获取随机点
FVector PikaGetRandomLoaction();
//将角色的死亡信息传递到行为树
void PikaSetCharacterDeathInfoSendBehaviorTree(bool BoolDeath);
APikaTowers* PikaGetRecentlyTowers(TArray<APikaTowers*>MyTowersArr);
};PikaMonsterAIController.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaMonsterAIController.h"
#include "Public/PikaCharacterBase.h"
#include "EngineUtils.h"
#include "AI/Navigation/NavigationSystem.h"
#include "BehaviorTree/BlackboardComponent.h"
void APikaMonsterAIController::BeginPlay()
{
Super::BeginPlay();
//执行行为树
if (PikaMonsterBeahaviorTreePre)
{
RunBehaviorTree(PikaMonsterBeahaviorTreePre);
}
//初始化死亡状态
PikaSetCharacterDeathInfoSendBehaviorTree(false);
}
//寻找目标
AActor * APikaMonsterAIController::PikaFindTarget()
{
if (!GetWorld() || !GetPawn()) { return NULL; }
//存储主塔
TArray<APikaTowers*> PikaTargetMainTarray;
//存储需要攻击的目标
TArray<APikaTowers*> PikaTargetTarray;
APikaCharacterBase * PikaPawn = Cast<APikaCharacterBase>(GetPawn());
//获取整个场景中APikaCharacterBase类的全部实例
if (PikaPawn)
{
for (TActorIterator<APikaTowers>it(GetWorld() , APikaTowers::StaticClass()); it; ++it)
{
APikaTowers * PikaTheCharacter = *it;
if (PikaTheCharacter && PikaTheCharacter->PikaIsActive())
{
if (PikaTheCharacter->PikaGetTowersType() == EPikaTowersType::PikaTOWERS_MainTowers)
{
PikaTargetMainTarray.Add(PikaTheCharacter);
}
else if (PikaTheCharacter->PikaGetTowersType() == EPikaTowersType::PikaTOWERS_Towers)
{
PikaTargetTarray.Add(PikaTheCharacter);
}
}
}
}
//寻找离自己最近的主塔和普通塔,有主塔优先返回主塔为目标塔
APikaTowers* PikaMainTowers = PikaGetRecentlyTowers(PikaTargetMainTarray);
APikaTowers* PikaNormalTowers = PikaGetRecentlyTowers(PikaTargetTarray);
if (PikaMainTowers)
{
return PikaMainTowers;
}
else if (PikaNormalTowers)
{
return PikaNormalTowers;
}
return NULL;
}
//获取随机点
FVector APikaMonsterAIController::PikaGetRandomLoaction()
{
FVector PikaRandomPoint = FVector::ZeroVector;
if (GetWorld())
{
//第四个参数表示在多大范围内进行随机
UNavigationSystem::K2_GetRandomPointInNavigableRadius(GetWorld() , GetPawn()->GetActorLocation() , PikaRandomPoint , 2000.f);
}
return PikaRandomPoint;
}
//将角色的死亡信息传递到行为树
void APikaMonsterAIController::PikaSetCharacterDeathInfoSendBehaviorTree(bool BoolDeath)
{
UBlackboardComponent * PikaMyBlackBoard = GetBlackboardComponent();
if (PikaMyBlackBoard)
{
PikaMyBlackBoard->SetValueAsBool(PikaDeathName, BoolDeath);
}
}
APikaTowers* APikaMonsterAIController::PikaGetRecentlyTowers(TArray<APikaTowers*>MyTowersArr)
{
//寻找离自己最近的敌对目标
if (MyTowersArr.Num() > 0)
{
float PikaTowerTargetDistance = 999999;
int PikaTowerID = -2;
//获取自己的位置
FVector PikaMyLocation = GetPawn()->GetActorLocation();
for (int32 i = 0; i < MyTowersArr.Num(); i++)
{
APikaTowers * PikaTowerChar = MyTowersArr[i];
if (PikaTowerChar)
{
FVector PikaTowerLocation = PikaTowerChar->GetActorLocation();
//距离
FVector TempVector = PikaTowerLocation - PikaMyLocation;
float PikaTowerAndMonsterDistance = TempVector.Size();
if (PikaTowerAndMonsterDistance < PikaTowerTargetDistance)
{
//获取容器中最近的那个
PikaTowerID = i;
//和下一个塔的位置做比较,寻找最近的那个
PikaTowerTargetDistance = PikaTowerAndMonsterDistance;
}
}
}
//找到的离自己最近的塔
if (PikaTowerID > -1)
{
return MyTowersArr[PikaTowerID];
}
}
return NULL;
}PikaMonsterBTServiceFindTarget.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "BehaviorTree/BTService.h"
#include "PikaCharacterBase.h"
#include "PikaMonsterBTServiceFindTarget.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaMonsterBTServiceFindTarget : public UBTService
{
GENERATED_BODY()
APikaCharacterBase * PikaTargetTower;
//是否终止循环
bool PikaIsStop;
public:
virtual void InitializeFromAsset(UBehaviorTree & Asset) override;
/** update next tick interval
* this function should be considered as const (don't modify state of object) if node is not instanced! */
virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
//下面的两个结构体会通过行为树的selector里选择和黑板对应的变量
//tower
UPROPERTY(EditAnywhere, Category = "PikaBlackBoard")
struct FBlackboardKeySelector PikaBlackBoardKeyTarget;
//tower离Monster之间的距离
UPROPERTY(EditAnywhere, Category = "PikaBlackBoard")
struct FBlackboardKeySelector PikaBlackBoardKeyDistance;
public:
/** Notify called after GameplayTask finishes initialization (not active yet) */
virtual void OnGameplayTaskInitialized(UGameplayTask& Task) {}
/** Notify called after GameplayTask changes state to Active (initial activation or resuming) */
virtual void OnGameplayTaskActivated(UGameplayTask& Task) {}
/** Notify called after GameplayTask changes state from Active (finishing or pausing) */
virtual void OnGameplayTaskDeactivated(UGameplayTask& Task) {}
};PikaMonsterBTServiceFindTarget.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "PikaMonsterBTServiceFindTarget.h"
#include "BehaviorTree/BehaviorTreeComponent.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "Public/PikaMonsterAIController.h"
void UPikaMonsterBTServiceFindTarget::InitializeFromAsset(UBehaviorTree & Asset)
{
Super::InitializeFromAsset(Asset);
PikaIsStop = false;
}
void UPikaMonsterBTServiceFindTarget::TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds)
{
Super::TickNode(OwnerComp , NodeMemory , DeltaSeconds);
UBehaviorTreeComponent & PikaBehaveiorTree = OwnerComp;
APikaMonsterAIController * PikaMonsAIController = Cast<APikaMonsterAIController>(PikaBehaveiorTree.GetOwner());
UBlackboardComponent * PikaBlackBoard = OwnerComp.GetBlackboardComponent();
if (!PikaBlackBoard) { return; }
if (PikaMonsAIController)
{
//目标塔为空时
if (!PikaTargetTower)
{
//寻找离自己最近的目标塔
PikaTargetTower = Cast<APikaCharacterBase>(PikaMonsAIController->PikaFindTarget());
//存储目标塔到黑板里
//PikaBlackBoard->SetValueAsObject(PikaBlackBoardKeyTarget.SelectedKeyName, PikaTargetTower);
}
else
{
//目标塔死亡后,重新寻找目标
if (PikaTargetTower->PikaCharDataPre->PikaCharBaseData.PikaDeath)
{
//PikaIsStop = false;
PikaTargetTower = NULL;
}
}
//存储目标塔到黑板里
PikaBlackBoard->SetValueAsObject(PikaBlackBoardKeyTarget.SelectedKeyName, PikaTargetTower);
//实时获取距离
if (PikaTargetTower)
{
//AI自己的位置
FVector PikaLocation = PikaMonsAIController->GetPawn()->GetActorLocation();
FVector PikaDsitance = PikaLocation - PikaTargetTower->GetActorLocation();
PikaBlackBoard->SetValueAsFloat(PikaBlackBoardKeyDistance.SelectedKeyName, PikaDsitance.Size());
}
}
}PikaToolRangeOfCharacter.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/SphereComponent.h"
#include "Components/TimelineComponent.h"
#include "PikaToolRangeOfCharacter.generated.h"
UCLASS()
class PIKAGODSTONE_API APikaToolRangeOfCharacter : public AActor
{
GENERATED_BODY()
//碰撞盒子
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBulletBase", meta = (AllowPrivateAccess = "true"))
class USphereComponent * PikaBoxDamage;
public:
// Sets default values for this actor's properties
APikaToolRangeOfCharacter();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
//碰撞
UFUNCTION()
void PikaBeginOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);
void PikaPrint(FString PikaStr);
//范围攻击,该曲线由蓝图载入
UPROPERTY(EditDefaultsOnly, Category = "PikaBullet")
UCurveFloat * PikaCurveFloat;
UPROPERTY()
FTimeline PikaRangeAttackTimeLine;
//范围攻击球体的半径
UPROPERTY(EditDefaultsOnly, Category = "PikaBullet")
float PikaBoxDamageTargetRadius;
UFUNCTION()
void PikaTimeLineRangeAttack(float PikaValue);
UFUNCTION()
void PikaTimeLineFinished();
//发起者(怪物死亡后,将自身的经验添加到离自己最近的塔上)
UPROPERTY()
AActor * PikaCastCharacter;
//将检测到的敌人加入到容器
TArray<AActor*> PikaCharacterArray;
};PikaToolRangeOfCharacter.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaToolRangeOfCharacter.h"
#include "Engine/Engine.h"
#include "Public/PikaCharacterBase.h"
// Sets default values
APikaToolRangeOfCharacter::APikaToolRangeOfCharacter()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
PikaBoxDamage = CreateDefaultSubobject<USphereComponent>(TEXT("PikaBoxDamage"));
PikaBoxDamage->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
}
// Called when the game starts or when spawned
void APikaToolRangeOfCharacter::BeginPlay()
{
Super::BeginPlay();
//碰撞绑定
if (PikaBoxDamage)
{
PikaBoxDamage->OnComponentBeginOverlap.AddUniqueDynamic(this, &APikaToolRangeOfCharacter::PikaBeginOverlapping);
}
if (GetWorld())
{
//曲线存在,通过代理绑定处理函数
if (PikaCurveFloat)
{
FOnTimelineFloat PikaTimeLineDelegate;
FOnTimelineEvent PikaFinishedEvent;
PikaFinishedEvent.BindUFunction(this, FName("PikaTimeLineFinished"));
PikaTimeLineDelegate.BindUFunction(this, FName("PikaTimeLineRangeAttack"));
//添加曲线
PikaRangeAttackTimeLine.AddInterpFloat(PikaCurveFloat, PikaTimeLineDelegate);
//设置停止循环
PikaRangeAttackTimeLine.SetLooping(false);
//开始播放
PikaRangeAttackTimeLine.PlayFromStart();
//TimeLine结束时触发的事件
PikaRangeAttackTimeLine.SetTimelineFinishedFunc(PikaFinishedEvent);
}
}
}
// Called every frame
void APikaToolRangeOfCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (PikaCurveFloat)
{
PikaRangeAttackTimeLine.TickTimeline(DeltaTime);
}
}
void APikaToolRangeOfCharacter::PikaBeginOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
if (!OtherActor || !PikaCastCharacter)
{
return;
}
APikaCharacterBase * PikaTargetActor = Cast<APikaCharacterBase>(OtherActor);
APikaCharacterBase * PikaCasterActor = Cast<APikaCharacterBase>(PikaCastCharacter);
if (PikaTargetActor && PikaCasterActor)
{
if (PikaTargetActor->PikaIsActive() && (PikaTargetActor->PikaGetTeam() == PikaCasterActor->PikaGetTeam()))
{
PikaCharacterArray.AddUnique(PikaTargetActor);
}
}
}
void APikaToolRangeOfCharacter::PikaPrint(FString PikaStr)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 6.f, FColor::Red, PikaStr);
}
}
void APikaToolRangeOfCharacter::PikaTimeLineRangeAttack(float PikaValue)
{
float PikaBoxDamageCurentRadius = FMath::Lerp(PikaBoxDamage->GetScaledSphereRadius(), PikaBoxDamageTargetRadius, PikaValue);
PikaBoxDamage->SetSphereRadius(PikaBoxDamageCurentRadius);
}
void APikaToolRangeOfCharacter::PikaTimeLineFinished()
{
APikaCharacterBase * PikaCasterActor = Cast<APikaCharacterBase>(PikaCastCharacter);
if (PikaCasterActor)
{
PikaCasterActor->PikaUpdateLevelCharacterArray(PikaCharacterArray);
}
Destroy(true);
}PikaTowerAIController.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "AIController.h"
#include "PikaTowerAIController.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API APikaTowerAIController : public AAIController
{
GENERATED_BODY()
};PikaTowerAIController.cpp
// Fill out your copyright notice in the Description page of Project Settings. #include "Public/PikaTowerAIController.h"
PikaTowerDoll.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/StaticMeshComponent.h"
#include "Components/SphereComponent.h"
#include "Materials/MaterialInstanceDynamic.h"
#include "PikaTowerDoll.generated.h"
class APikaGodStonePlayerController;
//记录空间信息
USTRUCT()
struct FPikaComponentSpaceInfo
{
GENERATED_BODY()
public:
UPROPERTY()
TArray<FVector> PikaComponentSize;
UPROPERTY()
TArray<FVector> PikaComponentLocation;
UPROPERTY()
TArray<FRotator> PikaComponentRotation;
FPikaComponentSpaceInfo()
{
PikaComponentSize.Empty();
PikaComponentLocation.Empty();
PikaComponentRotation.Empty();
}
FPikaComponentSpaceInfo& operator=(const FPikaComponentSpaceInfo& MyPikaComponentSpaceInfo)
{
PikaComponentSize = MyPikaComponentSpaceInfo.PikaComponentSize;
PikaComponentLocation = MyPikaComponentSpaceInfo.PikaComponentLocation;
PikaComponentRotation = MyPikaComponentSpaceInfo.PikaComponentRotation;
return *this;
}
//判断该序列号是不是在该容器内有效
bool PikaIsValuable(int32 ID)
{
return (PikaComponentLocation.IsValidIndex(ID) && PikaComponentSize.IsValidIndex(ID) && PikaComponentRotation.IsValidIndex(ID)) ? true : false;
}
//获取FComponentSpaceInformation最大的数量
//获取PikaComponentLocation.Num()、PikaComponentSize.Num()、PikaComponentLocation.Num()里的最大值
int32 PikaGetMax()
{
return(PikaComponentLocation.Num() >= PikaComponentSize.Num() ? PikaComponentLocation.Num() : PikaComponentSize.Num()) >= PikaComponentRotation.Num() ? (PikaComponentLocation.Num() >= PikaComponentSize.Num() ? PikaComponentLocation.Num() : PikaComponentSize.Num()) : PikaComponentRotation.Num();
}
};
UCLASS()
class PIKAGODSTONE_API APikaTowerDoll : public AActor
{
GENERATED_BODY()
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBaseAttrubte", meta = (AllowPrivateAccess = "true"))
class USceneComponent * PikaHomingPoint;
//运行建造范围检测
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBaseAttrubte", meta = (AllowPrivateAccess = "true"))
class USphereComponent * PikaAllowBuildRange;
//StaticMeshComponent组件集
TArray<UStaticMeshComponent*> PikaMeshComponentArray;
//StaticMeshComponent基础材质集
TArray<UMaterialInstanceDynamic*> PikaTowerDollAllMatrial;
//指向Doll材质的指针
UMaterialInterface* PikaTowerDollMaterial;
//本地的游戏控制
APikaGodStonePlayerController* PikaLocalPlayerController;
public:
// Sets default values for this actor's properties
APikaTowerDoll();
//将mesh添加到我们的MeshComponents中
void PikaSetMeshAddToMeshComponet(TArray<UStaticMesh*> MyMesh , FPikaComponentSpaceInfo& MyPikaComponentSpaceInfo);
void PikaSetMeshColor(bool PermitConstruction);
virtual void Destroyed() override;
void PikaSetController(APikaGodStonePlayerController* OurPlayerController) { PikaLocalPlayerController = OurPlayerController; }
//测试打印函数
void PikaPrint(FString PikaStr);
//碰撞
UFUNCTION()
void PikaDollAllowBuildBeginOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);
UFUNCTION()
void PikaDollAllowBuildEndOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex);
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
APikaGodStonePlayerController* PikaGetTowerDefencePlayerController() { return PikaLocalPlayerController; }
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
private:
//初始化MeshComponent数量
void PikaSetMeshComponentSize(int32 ComponentNumber , FPikaComponentSpaceInfo& MyPikaComponentSpaceInfo);
};PikaTowerDoll.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaTowerDoll.h"
#include "ConstructorHelpers.h"
#include "Components/BoxComponent.h"
// Sets default values
APikaTowerDoll::APikaTowerDoll()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
static ConstructorHelpers::FObjectFinder<UMaterialInterface> PikaMyMaterial = (TEXT("/Game/TowerAI/TowerDollMat/MAT_TowersDoll"));
PikaTowerDollMaterial = PikaMyMaterial.Object;
PikaHomingPoint = CreateDefaultSubobject<USceneComponent>(TEXT("PikaTowerDollHominPoint"));
PikaAllowBuildRange = CreateDefaultSubobject<USphereComponent>(TEXT("PikaTowerAllowBuildRange"));
if (PikaHomingPoint && PikaAllowBuildRange)
{
RootComponent = PikaHomingPoint;
PikaAllowBuildRange->AttachToComponent(PikaHomingPoint, FAttachmentTransformRules::KeepRelativeTransform);
//设置通道类型,名字为DefaultEngine.ini文件里通道的Name="PikaAllowBuild"
PikaAllowBuildRange->SetCollisionProfileName("PikaAllowBuild");
PikaAllowBuildRange->SetSphereRadius(250.0f);
PikaAllowBuildRange->SetHiddenInGame(true);
}
}
//获取Mesh的数量
void APikaTowerDoll::PikaSetMeshComponentSize(int32 ComponentNumber , FPikaComponentSpaceInfo& MyPikaComponentSpaceInfo)
{
if (PikaHomingPoint)
{
for (int32 i = 0; i < ComponentNumber; i++)
{
FString PikaStaticMeshComponentName = "Mesh_" + FString::FromInt(i);
UStaticMeshComponent* PikaMyMeshComponent = NewObject<UStaticMeshComponent>(this , *PikaStaticMeshComponentName);
if (PikaMyMeshComponent && MyPikaComponentSpaceInfo.PikaIsValuable(i))
{
PikaMyMeshComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
PikaMyMeshComponent->SetRelativeLocation(MyPikaComponentSpaceInfo.PikaComponentLocation[i]);
PikaMyMeshComponent->SetRelativeRotation(MyPikaComponentSpaceInfo.PikaComponentRotation[i]);
PikaMyMeshComponent->SetRelativeScale3D(MyPikaComponentSpaceInfo.PikaComponentSize[i]);
PikaMyMeshComponent->AttachToComponent(PikaHomingPoint, FAttachmentTransformRules::KeepRelativeTransform);
PikaMeshComponentArray.Add(PikaMyMeshComponent);
//注册组件
PikaMyMeshComponent->RegisterComponent();
}
}
}
}
void APikaTowerDoll::PikaSetMeshAddToMeshComponet(TArray<UStaticMesh*> MyMesh , FPikaComponentSpaceInfo& MyPikaComponentSpaceInfo)
{
PikaSetMeshComponentSize(MyMesh.Num() , MyPikaComponentSpaceInfo);
int32 i = 0;
TArray<UMaterialInterface*> PikaTempMaterialInterfaceArray;
if (PikaTowerDollMaterial)
{
for (UStaticMesh* SimMesh : MyMesh)
{
if(PikaMeshComponentArray[i])
PikaMeshComponentArray[i]->SetStaticMesh(SimMesh);
//替换成我们自己的材质
for (int32 MatIndex = 0 ; MatIndex < PikaMeshComponentArray[i]->GetNumMaterials() ; MatIndex++)
{
PikaMeshComponentArray[i]->SetMaterial(MatIndex , PikaTowerDollMaterial);
}
//获取所有材质
for (int32 MeshIndex = 0 ; MeshIndex < PikaMeshComponentArray[i]->GetMaterials().Num(); MeshIndex++)
{
UMaterialInstanceDynamic* PikaMID = PikaMeshComponentArray[i]->CreateAndSetMaterialInstanceDynamic(MeshIndex);
if (PikaMID)
PikaTowerDollAllMatrial.Add(PikaMID);
}
i++;
}
}
}
void APikaTowerDoll::PikaSetMeshColor(bool PermitConstruction)
{
if (PermitConstruction)
{
for (UMaterialInstanceDynamic* PikaMyDynamicMat : PikaTowerDollAllMatrial)
{
FString test1 = PikaMyDynamicMat->GetName();
if (PikaMyDynamicMat->GetName() != "None" && PikaMyDynamicMat->GetName() != "Invalid")
//显示绿色,ColorStatus为TowerAI下MAT_TowersDoll材质里,节点参数化后的变量名
PikaMyDynamicMat->SetScalarParameterValue("ColorStatus" , 0);
}
}
else
{
for (UMaterialInstanceDynamic* PikaMyDynamicMat : PikaTowerDollAllMatrial)
{
if (PikaMyDynamicMat->GetName() != "None" && PikaMyDynamicMat->GetName() != "Invalid")
//显示红色,ColorStatus为TowerAI下MAT_TowersDoll材质里,节点参数化后的变量名
PikaMyDynamicMat->SetScalarParameterValue("ColorStatus", 1);
}
}
}
void APikaTowerDoll::Destroyed()
{
for (UStaticMeshComponent* MyStaticMeshComponent : PikaMeshComponentArray)
{
if (MyStaticMeshComponent)
MyStaticMeshComponent->DestroyComponent(true);
MyStaticMeshComponent = NULL;
}
if (PikaTowerDollMaterial)
PikaTowerDollMaterial->ConditionalBeginDestroy();
PikaTowerDollMaterial = NULL;
PikaAllowBuildRange->DestroyComponent(true);
Super::Destroyed();
}
void APikaTowerDoll::PikaPrint(FString PikaStr)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 6.f, FColor::Red, PikaStr);
}
}
void APikaTowerDoll::PikaDollAllowBuildBeginOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
if (OtherComp->IsA(UBoxComponent::StaticClass()) && PikaGetTowerDefencePlayerController())
{
if (OtherComp->GetCollisionObjectType() == ECollisionChannel::ECC_GameTraceChannel6)
{
PikaSetMeshColor(false);
PikaGetTowerDefencePlayerController()->PikaSetAllowBuillingTowers(false);
}
}
}
void APikaTowerDoll::PikaDollAllowBuildEndOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex)
{
if (OtherComp->IsA(UBoxComponent::StaticClass()) && PikaGetTowerDefencePlayerController())
{
if (OtherComp->GetCollisionObjectType() == ECollisionChannel::ECC_GameTraceChannel6)
{
PikaSetMeshColor(true);
PikaGetTowerDefencePlayerController()->PikaSetAllowBuillingTowers(true);
}
}
}
// Called when the game starts or when spawned
void APikaTowerDoll::BeginPlay()
{
Super::BeginPlay();
if (PikaAllowBuildRange)
{
PikaAllowBuildRange->OnComponentBeginOverlap.AddUniqueDynamic(this, &APikaTowerDoll::PikaDollAllowBuildBeginOverlapping);
PikaAllowBuildRange->OnComponentEndOverlap.AddUniqueDynamic(this, &APikaTowerDoll::PikaDollAllowBuildEndOverlapping);
}
}
// Called every frame
void APikaTowerDoll::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}PikaTowerIcon.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "Public/PikaUI_InventorySlot.h"
#include "PikaTowerIcon.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaTowerIcon : public UPikaUIWidgetBase
{
GENERATED_BODY()
//控件实例的名字
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaTowerImageName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaTowerCDImageName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaTowerPrepareBuildingNumTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaTowerCompletionNumTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaTowerCDValueTextName;
//CD材质的名字,该值为CD材质里参数化的变量ControllerCD
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaCDMatName;
public:
void PikaInitTowreIcon(UTexture2D* TowresIcon);
//相当于BeginPlay,用于解决BeginPlay执行时,有些资源可能还没加载完成的问题
//需要手动调用
virtual void PikaDrawUIToScreen() override;
//每一个物品栏对应的单个数据
FPikaBulidingTowres PikaBuildingTowerStructIcon;
//打印测试
void PikaPrint(FString piksStr);
private:
//控件实例
UImage* PikaTowerImage;
UImage* PikaTowerCDImage;
UTextBlock* PikaTowerPrepareBuildingNumText;
UTextBlock* PikaTowerCompletionNumText;
UTextBlock* PikaTowerCDValueText;
//显示字体和CD
void PikaDisplayNumber(UTextBlock* MyTextNumberBlock, int32 MyTextNumber);
};PikaTowerIcon.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaTowerIcon.h"
void UPikaTowerIcon::PikaInitTowreIcon(UTexture2D* TowresIcon)
{
if (PikaTowerImage && TowresIcon)
{
PikaTowerImage->SetBrushFromTexture(TowresIcon);
PikaTowerImage->SetVisibility(ESlateVisibility::Visible);
}
}
void UPikaTowerIcon::PikaDrawUIToScreen()
{
PikaTowerImage = Cast<UImage>(PikaqiuGetBlueprintWidget(PikaTowerImageName));
PikaTowerCDImage = Cast<UImage>(PikaqiuGetBlueprintWidget(PikaTowerCDImageName));
PikaTowerPrepareBuildingNumText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaTowerPrepareBuildingNumTextName));
PikaTowerCompletionNumText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaTowerCompletionNumTextName));
PikaTowerCDValueText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaTowerCDValueTextName));
//获取动态材质实例
if (PikaTowerCDImage)
{
UMaterialInstanceDynamic* PikaCDMaterialDynamic = PikaTowerCDImage->GetDynamicMaterial();
if (PikaCDMaterialDynamic)
PikaCDMaterialDynamic->SetScalarParameterValue(PikaCDMatName, PikaBuildingTowerStructIcon.PikaGetTowerConstructionTimePercentage());
}
//填充PikaTowerImage
PikaInitTowreIcon(PikaBuildingTowerStructIcon.PikaTexture);
//填充PikaTowerPrepareBuildingNumText
if (PikaTowerPrepareBuildingNumText)
PikaDisplayNumber(PikaTowerPrepareBuildingNumText , PikaBuildingTowerStructIcon.PikaTowerPerpareBuildingNumber);
//填充PikaTowerCompletionNumText
if (PikaTowerCompletionNumText)
PikaDisplayNumber(PikaTowerCompletionNumText, PikaBuildingTowerStructIcon.PikaTowerConstructionNumber);
//填充PikaTowerPrepareBuildingNumText
if (PikaTowerCDValueText)
PikaDisplayNumber(PikaTowerCDValueText, PikaBuildingTowerStructIcon.PikaCurrentConstructionTowerCD);
}
void UPikaTowerIcon::PikaPrint(FString piksStr)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 6.0f, FColor::Red, piksStr);
}
}
void UPikaTowerIcon::PikaDisplayNumber(UTextBlock* MyTextNumberBlock, int32 MyTextNumber)
{
//物品栏上有道显示文本,没有道具则不显示文本
if (MyTextNumber < 1 || !PikaBuildingTowerStructIcon.PikaIsActive())
{
MyTextNumberBlock->SetVisibility(ESlateVisibility::Hidden);
}
else
{
//格式输出里,%02d表示输出格式为00,%03d的输出格式为000
MyTextNumberBlock->SetText(FText::FromString(FString::Printf(TEXT("%02d"), MyTextNumber)));
MyTextNumberBlock->SetVisibility(ESlateVisibility::Visible);
}
}PikaTowers.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaCharacterBase.h"
#include "PikaBulletBase.h"
#include "Components/SphereComponent.h"
#include "PikaTowers.generated.h"
//塔类型
UENUM()
namespace EPikaTowersType
{
enum Type
{
PikaTOWERS_Towers,
PikaTOWERS_MainTowers,
PikaTOWERS_Max
};
}
/**
*
*/
UCLASS()
class PIKAGODSTONE_API APikaTowers : public APikaCharacterBase
{
GENERATED_BODY()
//Box组件,用于设置产生碰撞的Box
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBaseAttack" , meta = (AllowPrivateAccess = "true"))
class UBoxComponent * PikaBoxCollision;
//Box组件,用于允许建设的设置
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBaseAttack", meta = (AllowPrivateAccess = "true"))
class UBoxComponent * PikaAllowBuildBox;
//怪物数组
UPROPERTY()
TArray<APikaMonster*> PikaTarrayMonster;
//塔类型
UPROPERTY(EditDefaultsOnly, Category = "PikaTowerType")
TEnumAsByte<EPikaTowersType::Type> PikaTowersType;
//攻击范围
UPROPERTY(EditDefaultsOnly, Category = "PikaTowerType")
float PikaAattakRange;
//被动技能范围
UPROPERTY(EditDefaultsOnly, Category = "PikaTowerType")
float PikaPassiveSkillRange;
public:
APikaTowers();
virtual void BeginPlay() override;
virtual void Tick(float DeltaTime) override;
//塔攻击逻辑
virtual void PikaAttackTarget(AActor * Target) override;
/******************攻击前摇start*********************/
//攻击前摇时间
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PikaAttackFront")
float PikaAttackFrontDelayTimeBP;
//攻击前摇时间句柄
UPROPERTY()
FTimerHandle PikaAttackFrontDelayTimeHandle;
void PikaAttackType();
/******************攻击前摇end**********************/
//塔的持续性攻击,由定时器来模拟Tick
//virtual void PikaAttackTick() override;
//攻击时间句柄
FTimerHandle PikaAttackHandle;
//链击的时间句柄
FTimerHandle PikaChainHandle;
float PikaChainSave;
//是否停止攻击检测
bool PikaStopAttackCheck;
//子弹
APikaBulletBase * PikaMyBullet;
//闪电攻击时,获取敌人的位置
bool PikaCheckAttackTick;
//闪电攻击时,目标位置纠正
virtual void PiakGetParticlePostionCheckAttackTick();
APikaCharacterBase * PikaGetTargetActor();
//碰撞
UFUNCTION()
void PikaBeginOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);
UFUNCTION()
void PikaEndOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex);
//碰撞
UFUNCTION()
void PikaAllowBuildBeginOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);
UFUNCTION()
void PikaAllowBuildEndOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex);
//防止碰撞多次触发
AActor * PikaLastActor;
//链击伤害
void PikaChainDamage();
//塔死亡函数
virtual void PikaDestoryCharacter(float DelayTime = 0) override;
//获取塔类型
FORCEINLINE EPikaTowersType::Type PikaGetTowersType() { return PikaTowersType; }
/**********和范围相关Start**********/
//获取攻击范围内的敌人
void PikaBTServiceGetTarget();
//获取范围内的同伴
TArray<APikaTowers*> PikaBTServiceGetCompanion();
/**********和范围相关End**********/
/**********角色TickStart**********/
//攻击检测
virtual void PikaAttackTick() override;
//被动技能
//void PikaPassiveSkill(float DeltaTime);
/**********角色TickEnd**********/
//当前的时间
float PikaTimeSet;
//当前攻击记时
float PikaCurrentAttackCountTime;
};PikaTowers.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaTowers.h"
#include "Public/PikaMonster.h"
#include "Kismet/GameplayStatics.h"
#include "RotationMatrix.h"
#include "EngineUtils.h"
APikaTowers::APikaTowers()
{
PikaBoxCollision = CreateDefaultSubobject<UBoxComponent>(TEXT("PikaBoxCollision"));
PikaAllowBuildBox = CreateDefaultSubobject<UBoxComponent>(TEXT("PikaAllowBuildBox"));
if (PikaBoxCollision && PikaAllowBuildBox)
{
PikaBoxCollision->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
PikaAllowBuildBox->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
PikaAllowBuildBox->SetCollisionProfileName("PikaAllowBuild");
}
//是否停止攻击检测
PikaStopAttackCheck = false;
PikaMyBullet = NULL;
PikaCheckAttackTick = false;
//怪物数组初始化
PikaTarrayMonster.Empty();
PikaLastActor = nullptr;
PikaChainSave = 0;
//塔的攻击范围
PikaAattakRange = 820;
//被动技能范围
PikaPassiveSkillRange = 1000.f;
PikaTimeSet = 0;
PikaAttackFrontDelayTimeBP = 0.1f;
}
void APikaTowers::BeginPlay()
{
Super::BeginPlay();
//将塔的Team设置为true,初始化时为false
if(PikaCharDataPre)
PikaCharDataPre->PikaCharBaseData.PikaTeam = true;
}
void APikaTowers::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (PikaEnemyTarget && PikaMyBullet && PikaMyBullet->PikaBulletTypeBP == PikaBulletType::PikaBULLET_Chain)
{
//子弹攻击的目标
//PikaMyBullet->GetParticleMesh()->SetBeamTargetPoint(0, PikaEnemyTarget->GetActorLocation(), 0);
APikaCharacterBase * PikaMyTarget = (APikaCharacterBase*)PikaEnemyTarget;
if (PikaMyTarget)
{
PikaMyBullet->GetParticleMesh()->SetBeamTargetPoint(0 , PikaMyTarget->GetHomingPoint()->GetComponentLocation() , 0);
}
}
//开始检测范围内周围敌人
if (PikaGetPlayerController() && PikaGetPlayerController()->PikaGlobalConfigPre)
{
if (PikaTimeSet <= PikaGetPlayerController()->PikaGlobalConfigPre->PikaTowersData.PikaTimeInterval)
{
PikaTimeSet += DeltaTime;
}
else
{
PikaTimeSet = 0;
//获取攻击范围内的敌人
PikaBTServiceGetTarget();
}
}
if (PikaCharDataPre)
{
//开始攻击
if (PikaCharDataPre->PikaCharBaseData.PikaAttackSpeed != 0)
{
PikaCurrentAttackCountTime += DeltaTime;
//攻击间隔
float PikaCurrentAttackIntervalTime = 1 / PikaCharDataPre->PikaCharBaseData.PikaAttackSpeed;
//当前攻击时间如果大于攻击间隔,则开始攻击,并清空当前攻击时间
if (PikaCurrentAttackCountTime >= PikaCurrentAttackIntervalTime)
{
PikaCurrentAttackCountTime = 0;
PikaAttackTick();
}
}
/*//开始被动技能
if (CurrentPassiveTime <= PASSIVE_SKILL_MAX_TIME)
{
CurrentPassiveTime += DeltaTime;
}
else
{
PassiveSkill(CurrentPassiveTime);
CurrentPassiveTime = 0.f;
}*/
}
}
void APikaTowers::PikaAttackTarget(AActor * Target)
{
Super::PikaAttackTarget(Target);
//攻击动画
PikaCharacterMontage_Play(PikaCharacterAttackSkillMontage);
//攻击前摇
if (GetWorld())
GetWorld()->GetTimerManager().SetTimer(PikaAttackFrontDelayTimeHandle , this , &APikaTowers::PikaAttackType , PikaAttackFrontDelayTimeBP);
}
void APikaTowers::PikaAttackType()
{
if (PikaAttackFrontDelayTimeHandle.IsValid())
GetWorld()->GetTimerManager().ClearTimer(PikaAttackFrontDelayTimeHandle);
APikaCharacterBase * PikaEnemyTargetBase = (APikaCharacterBase *)PikaEnemyTarget;
if (PikaCharacterBullet && GetWorld() && GetSpawnPoint() && PikaIsActive())
{
FVector PikaBulletLocation = GetSpawnPoint()->GetComponentLocation();
//FRotator PikaBuletRotator = GetSpawnPoint()->GetComponentRotation();
//销毁上一次的子弹
/*if (PikaMyBullet)
{
PikaMyBullet->Destroy(true);
PikaMyBullet = NULL;
}*/
PikaMyBullet = GetWorld()->SpawnActor<APikaBulletBase>(PikaCharacterBullet, PikaBulletLocation, FRotationMatrix::MakeFromX(PikaEnemyTargetBase->GetHomingPoint()->GetComponentLocation() - PikaBulletLocation).Rotator());
if (PikaMyBullet)
{
//将自己赋值到子弹的施法者里
PikaMyBullet->PikaSetCasterCharacter(this);
//跟踪子弹
if (PikaMyBullet->PikaBulletTypeBP == PikaBulletType::PikaBULLET_Track)
{
APikaCharacterBase * PikaMyTarget = (APikaCharacterBase*)PikaEnemyTarget;
if (PikaMyTarget)
{
//跟踪加速度大小
PikaMyBullet->GetProjectleMovment()->HomingAccelerationMagnitude = 4000.f;
//跟踪组件
PikaMyBullet->GetProjectleMovment()->HomingTargetComponent = PikaMyTarget->GetHomingPoint();
//绑定伤害特效
/*if (PikaMyBullet->PikaDamageParticle)
{
UGameplayStatics::SpawnEmitterAttached(PikaMyBullet->PikaDamageParticle, PikaMyTarget->GetHomingPoint());
}*/
}
return;
}
//直线飞行子弹
if (PikaMyBullet->PikaBulletTypeBP == PikaBulletType::PikaBULLET_Line)
{
return;
}
//范围攻击型子弹
if (PikaMyBullet->PikaBulletTypeBP == PikaBulletType::PikaBULLET_Range)
{
//设置范围攻击的转向为0向量
//PikaMyBullet->SetActorRotation(FRotator::ZeroRotator);
if (PikaMyBullet->GetParticleMesh())
{
PikaMyBullet->GetParticleMesh()->SetWorldRotation(FRotator::ZeroRotator);
}
return;
}
//闪电型攻击
if (PikaMyBullet->PikaBulletTypeBP == PikaBulletType::PikaBULLET_Chain)
{
//SetBeamSourcePoint函数里,第一个参数为粒子系统发射器的index,第三个参数为源index
if (PikaMyBullet->GetParticleMesh())
{
//设置闪电攻击的初始点,目标点写在Tick里
PikaMyBullet->GetParticleMesh()->SetBeamSourcePoint(0, PikaBulletLocation, 0);
//绑定伤害特效
if (PikaMyBullet->PikaDamageParticle && PikaEnemyTargetBase)
{
UGameplayStatics::SpawnEmitterAttached(PikaMyBullet->PikaDamageParticle, PikaEnemyTargetBase->GetHomingPoint());
//0.01表示即时执行该函数,如果换成1/攻击速度,特效上会有延迟
//持续费血
GetWorld()->GetTimerManager().SetTimer(PikaChainHandle, this, &APikaTowers::PikaChainDamage, 0.01, true);
}
}
return;
}
}
}
}
//连续攻击
/*void APikaTowers::PikaAttackTick()
{
Super::PikaAttackTick();
if (PikaAttackHandle.IsValid())
{
//清除时间句柄
GetWorld()->GetTimerManager().ClearTimer(PikaAttackHandle);
//关闭Tick里的检测
PikaCheckAttackTick = false;
}
//自身如果已经死亡,则返回空
if (!PikaIsActive()) { return; }
//诊断攻击的目标是否死亡
if (PikaEnemyTarget)
{
APikaCharacterBase * PikaIsDeathTarget = (APikaCharacterBase*)PikaEnemyTarget;
if (PikaIsDeathTarget && PikaIsDeathTarget->PikaCharDataPre->PikaCharBaseData.PikaDeath)
{
//目标已死亡,移除死亡目标,并获取新的目标
PikaTarrayMonster.Remove(PikaIsDeathTarget);
PikaEnemyTarget = PikaGetTargetActor();
}
}
//是否停止检测攻击
//if (PikaStopAttackCheck) { return; }
//没有敌对目标时停止检测
if (!PikaEnemyTarget)
{
//正在攻击的目标为null,但目标数组里还有值时,重新获取新的攻击目标
if (PikaTarrayMonster.Num() > 0)
{
PikaEnemyTarget = PikaGetTargetActor();
}
else
{
return;
}
}
if (PikaEnemyTarget)
{
//有敌对目标,进行攻击
PikaCheckAttackTick = true;
PikaAttackTarget(PikaEnemyTarget);
}
if (GetWorld())
{
float PikaAttackSpeedTime = 1 / (PikaCharDataPre->PikaCharBaseData.PikaAttackSpeed);
GetWorld()->GetTimerManager().SetTimer(PikaAttackHandle, this, &APikaTowers::PikaAttackTick, PikaAttackSpeedTime, true);
}
}*/
void APikaTowers::PiakGetParticlePostionCheckAttackTick()
{
}
APikaCharacterBase * APikaTowers::PikaGetTargetActor()
{
if (PikaTarrayMonster.Num() > 0)
{
if (1 == PikaTarrayMonster.Num())
{
return PikaTarrayMonster[0];
}
else
{
//返回多个目标中离自己最近的目标
int32 PikaMonsterIndex = -1;
FVector PikaMyLocation = GetActorLocation();
float PikaMyDistance = 999999999999;
for (int32 i=0 ; i< PikaTarrayMonster.Num(); i++)
{
FVector PikaMonsterLocation = PikaTarrayMonster[i]->GetActorLocation();
FVector PikaTempDistance = PikaMonsterLocation - PikaMyLocation;
if (PikaTempDistance.Size() < PikaMyDistance)
{
PikaMyDistance = PikaTempDistance.Size();
PikaMonsterIndex = i;
}
}
if (PikaMonsterIndex < 0)
{
return NULL;
}
else
{
return PikaTarrayMonster[PikaMonsterIndex];
}
}
}
return NULL;
}
void APikaTowers::PikaBeginOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
/*if (PikaLastActor == OtherActor)
{
PikaLastActor = nullptr;
return;
}*/
//触发碰撞事件的对象是否为APikaMonster类的实例
/*if (OtherActor->IsA(APikaMonster::StaticClass()))
{
APikaCharacterBase * PikaTempActor = (APikaCharacterBase*)OtherActor;
//添加入侵攻击范围内的敌对目标
if (PikaTempActor)
{
if (PikaTempActor->PikaIsActive())
{
PikaTarrayMonster.AddUnique(PikaTempActor);
}
//进入攻击范围的目标,每增加一个就进行一次查找当前离自己最近目标的逻辑
//诊断攻击的目标是否死亡
if (PikaEnemyTarget)
{
APikaCharacterBase * PikaIsDeathTarget = (APikaCharacterBase*)PikaEnemyTarget;
if (PikaIsDeathTarget && PikaIsDeathTarget->PikaCharDataPre->PikaCharBaseData.PikaDeath)
{
//目标已死亡,移除死亡目标,并获取新的目标
PikaTarrayMonster.Remove(PikaIsDeathTarget);
PikaEnemyTarget = PikaGetTargetActor();
}
}
else
{
PikaEnemyTarget = PikaGetTargetActor();
}
//PikaLastActor = OtherActor;
PikaAttackTick();
}
}*/
}
void APikaTowers::PikaEndOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex)
{
/*if (OtherActor->IsA(APikaMonster::StaticClass()))
{
APikaCharacterBase * PikaTempActor = Cast<APikaCharacterBase>(OtherActor);
//移除入侵攻击范围内的敌对目标
if (PikaTempActor)
{
PikaTarrayMonster.Remove(PikaTempActor);
//当前的攻击目标离开了攻击范围时,将当前攻击目标的值置为NULL
if (PikaEnemyTarget == PikaTempActor)
{
PikaEnemyTarget = NULL;
}
}
}*/
}
void APikaTowers::PikaAllowBuildBeginOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
}
void APikaTowers::PikaAllowBuildEndOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex)
{
}
void APikaTowers::PikaChainDamage()
{
if (!GetWorld()) { return; }
if (PikaChainHandle.IsValid())
{
GetWorld()->GetTimerManager().ClearTimer(PikaChainHandle);
}
float PikaTempFloat = (1 / PikaCharDataPre->PikaCharBaseData.PikaAttackSpeed) * 0.2;
//PikaChainSave += (PikaTempFloat + 0.1);
//攻击修正
PikaChainSave += ((1 / PikaCharDataPre->PikaCharBaseData.PikaAttackSpeed)*0.2 + 0.1*(1 / PikaCharDataPre->PikaCharBaseData.PikaAttackSpeed) / (1 / PikaCharDataPre->PikaCharBaseData.PikaAttackSpeedMin));
if (PikaEnemyTarget)
{
APikaCharacterBase * EnemyTarget = Cast<APikaCharacterBase>(PikaEnemyTarget);
if (EnemyTarget)
{
//0.2表示将伤害分割成5次,1 / PikaCharDataPre->PikaCharBaseData.PikaAttackSpeed*0.2
EnemyTarget->PikaGetCharacterState(EnemyTarget->PikaGetDefenceDamage(this) * 0.2);
EnemyTarget->PikaUpdateUMGHealth();
}
}
if (PikaChainSave < (1 / PikaCharDataPre->PikaCharBaseData.PikaAttackSpeed))
{
GetWorld()->GetTimerManager().SetTimer(PikaChainHandle, this, &APikaTowers::PikaChainDamage, PikaTempFloat, 1);
}
else
{
PikaChainSave = 0;
}
}
void APikaTowers::PikaDestoryCharacter(float DelayTime)
{
//上传死亡的数据
if (PikaGetPlayerController())
PikaGetPlayerController()->PikaGlobalConfigPre->PikaGameData.PikaTowersDeathNumber++;
Super::PikaDestoryCharacter(DelayTime);
}
//获取攻击范围内的敌人
void APikaTowers::PikaBTServiceGetTarget()
{
PikaTarrayMonster.Empty();
//获取我们全场景的ARuleOfTheCharacter的Actor
for (TActorIterator<APikaMonster>it(GetWorld(), APikaMonster::StaticClass()); it; ++it)
{
APikaMonster* PikaTheCharacter = *it;
if (PikaTheCharacter)
{
if (PikaTheCharacter->PikaIsActive())
{
FVector PikaTDistance = PikaTheCharacter->GetActorLocation() - GetActorLocation();
if (PikaTDistance.Size() <= PikaAattakRange)
PikaTarrayMonster.AddUnique(PikaTheCharacter);
}
}
}
}
//获取范围内的同伴
TArray<APikaTowers*> APikaTowers::PikaBTServiceGetCompanion()
{
TArray<APikaTowers*> PikaTArrayATowers;
//获取我们全场景的ARuleOfTheCharacter的Actor
for (TActorIterator<APikaTowers>it(GetWorld(), APikaTowers::StaticClass()); it; ++it)
{
APikaTowers* PikaTheCharacter = *it;
if (PikaTheCharacter && PikaTheCharacter != this)
{
if (PikaTheCharacter->PikaIsActive())
{
FVector PikaTDistance = PikaTheCharacter->GetActorLocation() - GetActorLocation();
if (PikaTDistance.Size() <= PikaPassiveSkillRange)
PikaTArrayATowers.Add(PikaTheCharacter);
}
}
}
return PikaTArrayATowers;
}
//攻击检测
void APikaTowers::PikaAttackTick()
{
Super::PikaAttackTick();
//关闭检测
PikaCheckAttackTick = false;
//自己是否死亡
if (!PikaIsActive())
{
return;
}
//检测玩家设定的目标敌人
if (PikaGetPlayerController() && PikaGetPlayerController()->PikaGetTargetMonster())
{
for (APikaMonster* PikaTargetMonsters : PikaTarrayMonster)
{
if (PikaTargetMonsters->PikaIsActive())
{
if (PikaGetPlayerController()->PikaGetTargetMonster() == PikaTargetMonsters)
{
PikaEnemyTarget = PikaGetPlayerController()->PikaGetTargetMonster();
break;
}
}
else if (PikaTargetMonsters == PikaEnemyTarget)
{
PikaEnemyTarget = nullptr;
}
}
}
//检查怪物是否死亡
if (PikaEnemyTarget)
{
//判断该角色是否在范围内
if ((PikaEnemyTarget->GetActorLocation() - GetActorLocation()).Size() > PikaAattakRange)
{
//重新确定目标
PikaEnemyTarget = PikaGetTargetActor();
}
else
{
APikaMonster* PikaEnemyTargetPtr = Cast<APikaMonster>(PikaEnemyTarget);
if (PikaEnemyTargetPtr)
{
if (!PikaEnemyTargetPtr->PikaIsActive())
{
//移除目标死亡的怪物
PikaTarrayMonster.Remove(PikaEnemyTargetPtr);
//重新搜索怪物
PikaEnemyTarget = PikaGetTargetActor();
}
}
}
}
else
{
//重新获取目标
PikaEnemyTarget = PikaGetTargetActor();
}
//有没有目标
if (PikaEnemyTarget)
{
//攻击目标
PikaAttackTarget(PikaEnemyTarget);
}
}PikaUI_InformationWeight.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "TextBlock.h"
#include "PikaUI_InformationWeight.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUI_InformationWeight : public UPikaUIWidgetBase
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaHealthTextBlockName;
public:
//调用去初始化我们的UI
virtual void PikaDrawUIToScreen() override;
void PikaDrawSubtractionHealthInformation(float DamageValue, float DamagePercentage);
void PikaDrawGoldformation(int32 GlodValue, float DamagePercentage);
void PikaDrawAddHealthInformation(float AddHealthValue, float DamagePercentage);
private:
UTextBlock* PikaHealthTextBlock;
};PikaUI_InformationWeight.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUI_InformationWeight.h"
void UPikaUI_InformationWeight::PikaDrawUIToScreen()
{
PikaHealthTextBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaHealthTextBlockName));
}
void UPikaUI_InformationWeight::PikaDrawSubtractionHealthInformation(float DamageValue, float DamagePercentage)
{
int32 PikaMaxFontSize = 50;
int32 PikaMinFontSize = 16;
int32 PikaCurrentFontSize = PikaMinFontSize + (PikaMaxFontSize - PikaMinFontSize) * DamagePercentage;
if (PikaHealthTextBlock && DamageValue != 0)
{
PikaHealthTextBlock->SetText(FText::FromString(FString::Printf(TEXT("-%0.f"), DamageValue)));
PikaHealthTextBlock->Font.Size = PikaCurrentFontSize;
//设置颜色为红色
PikaHealthTextBlock->SetColorAndOpacity(FSlateColor(FLinearColor::Red));
}
}
void UPikaUI_InformationWeight::PikaDrawGoldformation(int32 GlodValue, float DamagePercentage)
{
int32 PikaMaxFontSize = 50;
int32 PikaMinFontSize = 16;
int32 PikaCurrentFontSize = PikaMinFontSize + (PikaMaxFontSize - PikaMinFontSize) * DamagePercentage;
if (PikaHealthTextBlock)
{
PikaHealthTextBlock->SetText(FText::FromString(FString::Printf(TEXT("+%d"), GlodValue)));
PikaHealthTextBlock->Font.Size = PikaCurrentFontSize;
//设置颜色为黄色
PikaHealthTextBlock->SetColorAndOpacity(FSlateColor(FLinearColor::Yellow));
}
}
void UPikaUI_InformationWeight::PikaDrawAddHealthInformation(float AddHealthValue, float DamagePercentage)
{
int32 PikaMaxFontSize = 50;
int32 PikaMinFontSize = 16;
int32 PikaCurrentFontSize = PikaMinFontSize + (PikaMaxFontSize - PikaMinFontSize) * DamagePercentage;
if (PikaHealthTextBlock && AddHealthValue != 0)
{
PikaHealthTextBlock->SetText(FText::FromString(FString::Printf(TEXT("+%0.f"), AddHealthValue)));
PikaHealthTextBlock->Font.Size = PikaCurrentFontSize;
//设置颜色为绿色
PikaHealthTextBlock->SetColorAndOpacity(FSlateColor(FLinearColor::Green));
}
}PikaUI_Inventory.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "PikaUI_InventorySlot.h"
#include "UniformGridPanel.h"
#include "UniformGridSlot.h"
#include "PikaUI_Inventory.generated.h"
class UPikaMainInterface;
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUI_Inventory : public UPikaUIWidgetBase
{
GENERATED_BODY()
//用来载入PikaUI_InventorySlot的蓝图类
UPROPERTY(EditDefaultsOnly , Category = "PikaUI")
TSubclassOf<UPikaUI_InventorySlot> PikaInventorySlotClass;
//从蓝图中获取soltArray的名字
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaSoltArrayInventoryName;
public:
virtual void PikaDrawUIToScreen() override;
void PikaLayoutInventorySlot(int32 PikaColumn , int32 PikaRow);
/*********************************响应控制Start***************************************/
//绑定我们的鼠标中键响应
//以下两个函数是通过代理绑定的,需要加UFUNCTIO()
UFUNCTION()
void PikaSpawnTowerDollPressed(APikaGodStonePlayerController* MyPlayerController);
UFUNCTION()
void PikaSpawnTowerDollReleased(APikaGodStonePlayerController* MyPlayerController);
/*********************************响应控制End***************************************/
/*********************************临时InventorySlot变量Start***************************************/
UPikaUI_InventorySlot* GetTempInventorySlot()const;
void PikaSetTempInventorySlot(UPikaUI_InventorySlot* NewInventorySlot);
//将InventorySlot置空
void PikaCancelTempInventorySlot();
//获取PikaTempInventorySlot
UPikaUI_InventorySlot* PikaGetNewInventorySlot()const { return PikaTempInventorySlot; }
/*********************************临时InventorySlot变量End***************************************/
//打印测试
void PikaPrint(FString piksStr);
//负责打印GameLOG
virtual void PikaLogPrintf(FString MyString)override;
UPikaMainInterface* PikaGetMainInterface() const { return PikaMainInterfacePtr; }
void PikaSetMainInterface(UPikaMainInterface* NewWidget) {PikaMainInterfacePtr = NewWidget;}
//锁CD
void PikaLockSlotCD(bool IsLock);
private:
UUniformGridPanel * PikaSlotArrayInventory;
TArray<UPikaUI_InventorySlot*> PikaInventorySlotArray;
UPikaUI_InventorySlot* PikaTempInventorySlot;
UPikaMainInterface* PikaMainInterfacePtr;
};PikaUI_Inventory.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUI_Inventory.h"
#include "Public/PikaCharacterBase.h"
#include "Engine/Engine.h"
void UPikaUI_Inventory::PikaDrawUIToScreen()
{
if (!GetWorld())
{
return;
}
PikaSlotArrayInventory = Cast<UUniformGridPanel>(PikaqiuGetBlueprintWidget(PikaSoltArrayInventoryName));
//布局界面
if (PikaUIDataPtr)
{
PikaLayoutInventorySlot(PikaUIDataPtr->PikaInventoryColumn , PikaUIDataPtr->PikaInventoryRow);
}
//绑定我们的鼠标中建响应
if (PikaGetPlayerController())
{
PikaGetPlayerController()->PikaEventMouseMiddlePressed.AddDynamic(this , &UPikaUI_Inventory::PikaSpawnTowerDollPressed);
PikaGetPlayerController()->PikaEventFMouseMiddleReleased.AddDynamic(this, &UPikaUI_Inventory::PikaSpawnTowerDollReleased);
}
}
void UPikaUI_Inventory::PikaLayoutInventorySlot(int32 PikaColumn, int32 PikaRow)
{
if (PikaInventorySlotClass && PikaSlotArrayInventory)
{
for (int32 MyRow = 0 ; MyRow < PikaRow; MyRow++)
{
for (int32 MyColumn=0 ; MyColumn< PikaColumn; MyColumn++)
{
UPikaUI_InventorySlot * PikaSlotWidget = CreateWidget<UPikaUI_InventorySlot>(GetWorld() , PikaInventorySlotClass);
if(PikaSlotWidget)
{
//需要将我们的UMG添加进去
UUniformGridSlot * PikaGridSlot = PikaSlotArrayInventory->AddChildToUniformGrid(PikaSlotWidget);
if (PikaGridSlot)
{
PikaGridSlot->SetColumn(MyColumn);
PikaGridSlot->SetRow(MyRow);
PikaGridSlot->SetHorizontalAlignment(EHorizontalAlignment::HAlign_Fill);
PikaGridSlot->SetVerticalAlignment(EVerticalAlignment::VAlign_Fill);
}
PikaSlotWidget->PikaDrawUIToScreen();
//设置父类
PikaSlotWidget->PikaSetParentClass(this);
//添加到容器内
PikaInventorySlotArray.Add(PikaSlotWidget);
}
}
}
if (PikaGetPlayerController())
{
TArray<UTexture2D*> PikaMyTextureArray = PikaGetPlayerController()->PikaGetTowerIocn();
//塔的建造CD
TArray<float> PikaMyTowerCD = PikaGetPlayerController()->PikaGetBuildCD();
//建造塔所需的金币
TArray<int32> PikaMyGoldArray = PikaGetPlayerController()->PikaGetTowerComsumeGold();
//信息的注册
TArray<FName> PikaTowersNameArray = PikaGetPlayerController()->PikaGetTowersName();
TArray<FText> PikaTowersIntroductionArray = PikaGetPlayerController()->PikaGetTowersIntroduction();
TArray<float> PikaTowersAttackArray = PikaGetPlayerController()->PikaGetTowerData(EPikaCharacterInfoDataTableType::DATA_PikaCharacterAttack);
TArray<float> PikaTowersArmorArray = PikaGetPlayerController()->PikaGetTowerData(EPikaCharacterInfoDataTableType::DATA_PikaCharacterArm);
TArray<float> PikaTowersAttackSpeedArray = PikaGetPlayerController()->PikaGetTowerData(EPikaCharacterInfoDataTableType::DATA_PikaCharacterAttackSpeed);
TArray<float> PikaTowersHealthArray = PikaGetPlayerController()->PikaGetTowerData(EPikaCharacterInfoDataTableType::DATA_PikaCharacterHealth);
int32 i = 0;
for (UTexture2D* MyTexture: PikaMyTextureArray)
{
if (PikaInventorySlotArray.IsValidIndex(i) && PikaMyTowerCD.IsValidIndex(i) && PikaMyGoldArray.IsValidIndex(i)
&& PikaTowersNameArray.IsValidIndex(i) && PikaTowersArmorArray.IsValidIndex(i) && PikaTowersAttackArray.IsValidIndex(i)
&& PikaTowersAttackSpeedArray.IsValidIndex(i) && PikaTowersHealthArray.IsValidIndex(i) && PikaTowersIntroductionArray.IsValidIndex(i))
{
//备份
PikaInventorySlotArray[i]->PikaBuildingTowerStruct.PikaTexture = MyTexture;
//激活
PikaInventorySlotArray[i]->PikaBuildingTowerStruct.PikaSetActive(true);
//初始化物品栏图片
PikaInventorySlotArray[i]->PikaInitTowerIcon();
//初始化塔的建造时间
PikaInventorySlotArray[i]->PikaBuildingTowerStruct.PikaMaxConstructionTowerCD = PikaMyTowerCD[i];
//消费金币更新
//PikaInventorySlotArray[i]->PikaBuildingTowerStruct.PikaNeedGold = PikaMyGoldArray[i];
//注册信息
PikaInventorySlotArray[i]->PikaBuildingTowerStruct.PikaCharacterInformationWidget.PikaCharacterName = PikaTowersNameArray[i];
PikaInventorySlotArray[i]->PikaBuildingTowerStruct.PikaCharacterInformationWidget.PikaCharacterArmor = PikaTowersArmorArray[i];
PikaInventorySlotArray[i]->PikaBuildingTowerStruct.PikaCharacterInformationWidget.PikaCharacterAttack = PikaTowersAttackArray[i];
PikaInventorySlotArray[i]->PikaBuildingTowerStruct.PikaCharacterInformationWidget.PikaCharacterAttackSpeed = PikaTowersAttackSpeedArray[i];
PikaInventorySlotArray[i]->PikaBuildingTowerStruct.PikaCharacterInformationWidget.PikaCharacterHealth = PikaTowersHealthArray[i];
PikaInventorySlotArray[i]->PikaBuildingTowerStruct.PikaCharacterInformationWidget.PikaComsumeGlod = PikaMyGoldArray[i];
PikaInventorySlotArray[i]->PikaBuildingTowerStruct.PikaCharacterInformationWidget.PikaCharacterIntroduction = PikaTowersIntroductionArray[i];
//为读写存档做准备
if (1)
{
//注册,保存建造的数量信息
PikaGetSaveGameData()->PikaTowerConstructionNumber.Add(0);
PikaGetSaveGameData()->PikaTowerPrepareBuildingNumber.Add(0);
}
else
{
}
}
i++;
}
}
}
}
void UPikaUI_Inventory::PikaSpawnTowerDollPressed(APikaGodStonePlayerController* MyPlayerController)
{
if (MyPlayerController && PikaTempInventorySlot && PikaTempInventorySlot->PikaBuildingTowerStruct.PikaIsActive() && PikaTempInventorySlot->PikaGetTowersIcon())
{
if (PikaTempInventorySlot->PikaBuildingTowerStruct.PikaTowerConstructionNumber >= 1)
{
//通过图标寻找对应塔的序列位置
int32 PikaTowersIndex = MyPlayerController->PikaGetTowerIocn().Find(PikaTempInventorySlot->PikaGetTowersIcon()->PikaqiuGetTexture2D());
APikaTowerDoll* PikaTowersDoll = MyPlayerController->PikaSpawnTowerDoll(PikaTowersIndex);
}
else
PikaLogPrintf("At least one tower to complete!");
}
}
void UPikaUI_Inventory::PikaSpawnTowerDollReleased(APikaGodStonePlayerController* MyPlayerController)
{
if (MyPlayerController && MyPlayerController->PikaGetTowersDoll() && MyPlayerController->PikaGetAllowBuillingTowers())
{
if (MyPlayerController->PikaGetTowersDoll()->GetActorLocation() != FVector::ZeroVector)
{
//通过图标寻找对应塔的序列位置
int32 PikaTowersIndex = MyPlayerController->PikaGetTowerIocn().Find(PikaTempInventorySlot->PikaGetTowersIcon()->PikaqiuGetTexture2D());
APikaCharacterBase* PikaTowersMesh = Cast<APikaCharacterBase>(MyPlayerController->PikaSpawnTowers(PikaTowersIndex, 1));
if (PikaTowersMesh)
{
PikaTowersMesh->SetActorLocation(MyPlayerController->PikaGetTowersDoll()->GetActorLocation());
PikaTowersMesh->SetActorRotation(MyPlayerController->PikaGetTowersDoll()->GetActorRotation());
//减去建造数量
PikaTempInventorySlot->PikaBuildingTowerStruct.PikaTowerConstructionNumber--;
//上传到我们的存储
PikaTempInventorySlot->PikaUpdateTowerCompletionNumText(PikaTempInventorySlot->PikaBuildingTowerStruct.PikaTowerConstructionNumber);
//上传我们的位置信息数据
if (MyPlayerController->PikaGlobalConfigPrePlayerCon)
{
int32 PikaCharacterIndex = MyPlayerController->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaGetCurrentCharacterSpawnIDIndex(PikaTowersMesh->PikaGetCharacterSpawnID());
if (MyPlayerController->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaIsActive(PikaCharacterIndex))
{
MyPlayerController->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterLocation[PikaCharacterIndex] = PikaTowersMesh->GetActorLocation();
MyPlayerController->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterRotator[PikaCharacterIndex] = PikaTowersMesh->GetActorRotation();
}
}
PikaLogPrintf("Tower Success");
}
}
else
PikaLogPrintf("Prohibition of construction in the region!");
//销毁
PikaCancelTempInventorySlot();
MyPlayerController->PikaDestoryTowerDoll();
}
else
{
PikaLogPrintf("UPikaUI_Inventory::PikaSpawnTowerDollReleased Error");
PikaCancelTempInventorySlot();
MyPlayerController->PikaDestoryTowerDoll();
}
}
UPikaUI_InventorySlot* UPikaUI_Inventory::GetTempInventorySlot() const
{
return PikaTempInventorySlot;
}
void UPikaUI_Inventory::PikaSetTempInventorySlot(UPikaUI_InventorySlot* NewInventorySlot)
{
PikaTempInventorySlot = NewInventorySlot;
}
void UPikaUI_Inventory::PikaCancelTempInventorySlot()
{
if (PikaTempInventorySlot)
PikaTempInventorySlot = NULL;
}
void UPikaUI_Inventory::PikaPrint(FString piksStr)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Red, piksStr);
}
}
void UPikaUI_Inventory::PikaLogPrintf(FString MyString)
{
if (PikaGetMainInterface())
PikaGetMainInterface()->PikaLogPrintf(MyString);
}
void UPikaUI_Inventory::PikaLockSlotCD(bool IsLock)
{
for (UPikaUI_InventorySlot* InventorySlot_E : PikaInventorySlotArray)
{
if (IsLock)
InventorySlot_E->PikaCDLock();
else
InventorySlot_E->PikaUnCDLock();
}
}PikaUI_InventorySlot.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "Image.h"
#include "TextBlock.h"
#include "Widget.h"
#include "PikaUI_InventorySlot.generated.h"
//前向声明
class UPikaUI_Inventory;
USTRUCT()
struct FPikaBulidingTowres
{
GENERATED_BODY()
//需要消费的金币
int32 PikaNeedGold;
//准备阶段塔的建造数量
int32 PikaTowerPerpareBuildingNumber;
//塔已经建造的数量
int32 PikaTowerConstructionNumber;
//当前塔最大建造CD
float PikaMaxConstructionTowerCD;
//当前建造中塔的CD
float PikaCurrentConstructionTowerCD;
//是否更新塔的CD
bool PikaIsUpdateTowerCD;
//作为图片指针
UTexture2D* PikaTexture;
//是否拖拽图标
bool PikaIsDragIco;
//锁
bool PikaIsLockCD;
FPikaBulidingTowres()
{
PikaInitBuildingTower();
}
~FPikaBulidingTowres()
{
if (PikaTexture)
PikaTexture = NULL;
}
//获取当前建造时间与最大建造时间的百分比
float PikaGetTowerConstructionTimePercentage() { return PikaMaxConstructionTowerCD ? PikaCurrentConstructionTowerCD / PikaMaxConstructionTowerCD : 0 ; }
//重置CD
void PikaSetCurrentCD() { PikaCurrentConstructionTowerCD = PikaMaxConstructionTowerCD; }
//设置激活状态
void PikaSetActive(bool DeathInformation) { PikaIsSlotActive = DeathInformation; }
//判断物品栏是否激活
bool PikaIsActive() const { return PikaIsSlotActive; }
//存储角色信息
FPikaCharacterInformationWidget PikaCharacterInformationWidget;
//重载操作符
FPikaBulidingTowres& operator = (const FPikaBulidingTowres& StructBuildingTower)
{
PikaNeedGold = StructBuildingTower.PikaNeedGold;
PikaTowerPerpareBuildingNumber = StructBuildingTower.PikaTowerPerpareBuildingNumber;
PikaTowerConstructionNumber = StructBuildingTower.PikaTowerConstructionNumber;
PikaMaxConstructionTowerCD = StructBuildingTower.PikaMaxConstructionTowerCD;
PikaCurrentConstructionTowerCD = StructBuildingTower.PikaCurrentConstructionTowerCD;
PikaIsUpdateTowerCD = StructBuildingTower.PikaIsUpdateTowerCD;
PikaSetActive(StructBuildingTower.PikaIsActive());
PikaTexture = StructBuildingTower.PikaTexture;
PikaCharacterInformationWidget = StructBuildingTower.PikaCharacterInformationWidget;
return *this;
}
//初始化结构体
void PikaInitBuildingTower()
{
PikaNeedGold = 0;
PikaTowerPerpareBuildingNumber = 0;
PikaTowerConstructionNumber = 0;
PikaMaxConstructionTowerCD = 0;
PikaCurrentConstructionTowerCD = 0;
PikaIsUpdateTowerCD = false;
PikaIsSlotActive = false;
PikaTexture = nullptr;
PikaIsDragIco = false;
PikaIsLockCD = false;
//初始化我们的显示信息
PikaCharacterInformationWidget.PikaClearCharacterInformationWidget();
}
private:
//判断本结构体是不是使用中
bool PikaIsSlotActive;
};
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUI_InventorySlot : public UPikaUIWidgetBase
{
GENERATED_BODY()
//控件实例的名字
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaTowerImageName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaTowerCDImageName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaTowerPrepareBuildingNumTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaTowerCompletionNumTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaTowerCDValueTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaInventorySlotButtonName;
//CD材质的名字,该值为CD材质里参数化的变量ControllerCD
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaCDMatName;
//物品栏上是否有道具
/*UPROPERTY()
bool PikaIsExistItem;*/
//CD材质
UPROPERTY()
UMaterialInstanceDynamic* PikaCDMaterialDynamic;
public:
UPikaUI_InventorySlot();
void PikaInitTowerIcon();
//相当于BeginPlay,用于解决BeginPlay执行时,有些资源可能还没加载完成的问题
//需要手动调用
virtual void PikaDrawUIToScreen() override;
virtual void PikaOnClickedWidget(UWidget* PikaWidget) override;
//NativeTick函数里会调用蓝图里的Tick
virtual void NativeTick(const FGeometry& MyGeometry , float InDeltaTime) override;
//每一个物品栏对应的单个数据
FPikaBulidingTowres PikaBuildingTowerStruct;
//初始化,还原物品栏没有道具时的状态
void PikaInitInventorySlot();
//用当前的物品栏数据,刷新物品栏的状态,如图标、CD等
void PikaUpdateInventorySlotData();
//重新设置父类
void PikaSetParentClass(UPikaUI_Inventory* MyParentClass);
//打印测试
void PikaPrint(FString piksStr);
UImage* PikaGetTowersIcon() { return PikaTowerImage; }
//更新物品栏上的文本
void PikaUpdateTowerCompletionNumText(int32 TowerImageIndex);
//负责打印GameLOG
virtual void PikaLogPrintf(FString MyString)override;
FORCEINLINE void PikaCDLock() { PikaBuildingTowerStruct.PikaIsLockCD = true; }
FORCEINLINE void PikaUnCDLock() { PikaBuildingTowerStruct.PikaIsLockCD = false; }
private:
//控件实例
UImage* PikaTowerImage;
UImage* PikaTowerCDImage;
UTextBlock* PikaTowerPrepareBuildingNumText;
UTextBlock* PikaTowerCompletionNumText;
UTextBlock* PikaTowerCDValueText;
UButton* PikaInventorySlotButton;
UPikaUI_Inventory* PikaInventoryPtr;
//显示字体和CD
void PikaDisplayNumber(UTextBlock* MyTextNumberBlock , int32 MyTextNumber);
//更新物品栏上的文本
void PikaUpdateTowerPrepareBuildingNumText(int32 TowerImageIndex);
void PikaUpdateTowerCDValueText(float MyTowerCDValueText);
//绘制CD,CDParameter的取值范围为0-1
void PikaUpdateTowerCDImage(float CDParameter);
//构造塔的CD
void PikaUpdateTowerCD(float InDeltaTime);
//注册图标
void PikaRegisterTowreIcon(UTexture2D* TowresIcon);
protected:
/*开启Slate和SlateCore模块后start*/
virtual FReply NativeOnMouseButtonDown(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent) override;
//NativeOnMouseButtonDown里增加的拖拽事件的响应函数
virtual void NativeOnDragDetected(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent, UDragDropOperation*& OutOperation) override;
//NativeOnDragDetected激活后,如果将图标从一个物品栏拖拽到另外一个物品栏则会触发该事件
//接收拖拽信息,InOperation为空时,该函数不会被激活
virtual bool NativeOnDrop(const FGeometry& InGeometry, const FDragDropEvent& InDragDropEvent, UDragDropOperation* InOperation) override;
//鼠标移动到物品栏时触发,前提条件是在没有按鼠标上任何键位时移动进入的,如拖拽时不会触发该函数
virtual void NativeOnMouseEnter(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent) override;
//鼠标离开到物品栏时触发,前提条件是在没有按鼠标上任何键位时移动进入的,如拖拽时不会触发该函数
virtual void NativeOnMouseLeave(const FPointerEvent& InMouseEvent) override;
/*开启Slate和SlateCore模块后end*/
};PikaUI_InventorySlot.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUI_InventorySlot.h"
#include "Engine/Engine.h"
#include "Components/Image.h"
#include "Public/PikaTowerIcon.h"
#include "Public/PikaDragDropOperation.h"
UPikaUI_InventorySlot::UPikaUI_InventorySlot()
{
//PikaIsExistItem = false;
}
void UPikaUI_InventorySlot::PikaRegisterTowreIcon(UTexture2D* TowresIcon)
{
if (PikaTowerImage)
{
if (TowresIcon)
{
PikaTowerImage->SetBrushFromTexture(TowresIcon);
PikaTowerImage->SetVisibility(ESlateVisibility::Visible);
}
else
{
PikaTowerImage->SetBrushFromTexture(TowresIcon);
PikaTowerImage->SetVisibility(ESlateVisibility::Hidden);
}
}
}
void UPikaUI_InventorySlot::PikaUpdateInventorySlotData()
{
//还原图标
PikaInitTowerIcon();
//还原CD材质
PikaUpdateTowerCDImage(PikaBuildingTowerStruct.PikaCurrentConstructionTowerCD);
//还原准备建造的塔
PikaUpdateTowerPrepareBuildingNumText(PikaBuildingTowerStruct.PikaTowerPerpareBuildingNumber);
//还原已经完成的塔
PikaUpdateTowerCompletionNumText(PikaBuildingTowerStruct.PikaTowerConstructionNumber);
//还原CD显示
PikaUpdateTowerCDValueText(PikaBuildingTowerStruct.PikaGetTowerConstructionTimePercentage());
}
void UPikaUI_InventorySlot::PikaSetParentClass(UPikaUI_Inventory* MyParentClass)
{
PikaInventoryPtr = MyParentClass;
}
void UPikaUI_InventorySlot::PikaInitTowerIcon()
{
PikaRegisterTowreIcon(PikaBuildingTowerStruct.PikaTexture);
}
void UPikaUI_InventorySlot::PikaDrawUIToScreen()
{
PikaTowerImage = Cast<UImage>(PikaqiuGetBlueprintWidget(PikaTowerImageName));
PikaTowerCDImage = Cast<UImage>(PikaqiuGetBlueprintWidget(PikaTowerCDImageName));
PikaTowerPrepareBuildingNumText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaTowerPrepareBuildingNumTextName));
PikaTowerCompletionNumText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaTowerCompletionNumTextName));
PikaTowerCDValueText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaTowerCDValueTextName));
/*
* Button的获取方式是UButton * UPikaUIWidgetBase::PikaGetButtonFromBlueprint(FName BlueprintWidgetName) const
* 而除Button之外的为UWidget* UUserWidget::PikaqiuGetBlueprintWidget(FName PikaBlueprintWidgetName) const
*/
PikaInventorySlotButton = PikaGetButtonFromBlueprint(PikaInventorySlotButtonName);
//获取动态材质实例
if (PikaTowerCDImage)
PikaCDMaterialDynamic = PikaTowerCDImage->GetDynamicMaterial();
//材质绘制CD旋转
PikaUpdateTowerCDImage(0);
}
void UPikaUI_InventorySlot::PikaOnClickedWidget(UWidget* PikaWidget)
{
if (PikaWidget == PikaInventorySlotButton)
{
if (PikaGetSaveGameData() && PikaBuildingTowerStruct.PikaIsActive() && PikaTowerImage->PikaqiuGetTexture2D())
{
if (PikaGetSaveGameData()->PikaGetGlobalGold() >= PikaBuildingTowerStruct.PikaNeedGold)
{
//获取图片对应的序列号
int32 PikaTowerImageIndex = PikaGetPlayerController()->PikaGetTowerIocn().Find(PikaTowerImage->PikaqiuGetTexture2D());
//消费金币
PikaGetSaveGameData()->PikaConsumeGlobalGold(PikaBuildingTowerStruct.PikaNeedGold);
//记录我们的塔
PikaBuildingTowerStruct.PikaTowerPerpareBuildingNumber++;
//更新到界面并且上传到存储
PikaUpdateTowerPrepareBuildingNumText(PikaTowerImageIndex);
//赋值CD
if (PikaBuildingTowerStruct.PikaCurrentConstructionTowerCD <= 0)
{
PikaBuildingTowerStruct.PikaSetCurrentCD();
}
}
else
{
PikaLogPrintf("Insufficient glod");
}
}
}
}
void UPikaUI_InventorySlot::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
Super::NativeTick(MyGeometry , InDeltaTime);
//构造塔的CD
if (!PikaBuildingTowerStruct.PikaIsLockCD)
{
if (!PikaBuildingTowerStruct.PikaIsDragIco)
PikaUpdateTowerCD(InDeltaTime);
}
}
void UPikaUI_InventorySlot::PikaUpdateTowerPrepareBuildingNumText(int32 TowerImageIndex)
{
if (PikaTowerPrepareBuildingNumText)
{
//显示到界面
PikaDisplayNumber(PikaTowerPrepareBuildingNumText , PikaBuildingTowerStruct.PikaTowerPerpareBuildingNumber);
//上传数据到存储类
if (PikaGetSaveGameData()->PikaTowerPrepareBuildingNumber.IsValidIndex(TowerImageIndex))
PikaGetSaveGameData()->PikaTowerPrepareBuildingNumber[TowerImageIndex] = PikaBuildingTowerStruct.PikaTowerPerpareBuildingNumber;
}
}
void UPikaUI_InventorySlot::PikaUpdateTowerCompletionNumText(int32 TowerImageIndex)
{
if (PikaTowerCompletionNumText)
{
//显示到界面
PikaDisplayNumber(PikaTowerCompletionNumText, PikaBuildingTowerStruct.PikaTowerConstructionNumber);
//上传数据到存储类
if (PikaGetSaveGameData()->PikaTowerConstructionNumber.IsValidIndex(TowerImageIndex))
PikaGetSaveGameData()->PikaTowerConstructionNumber[TowerImageIndex] = PikaBuildingTowerStruct.PikaCurrentConstructionTowerCD;
}
}
void UPikaUI_InventorySlot::PikaLogPrintf(FString MyString)
{
PikaInventoryPtr->PikaLogPrintf(MyString);
}
void UPikaUI_InventorySlot::PikaUpdateTowerCDValueText(float MyTowerCDValueText)
{
if (PikaTowerCDValueText)
{
PikaDisplayNumber(PikaTowerCDValueText, MyTowerCDValueText);
}
}
//绘制CD,CDParameter的取值范围为0-1
void UPikaUI_InventorySlot::PikaUpdateTowerCDImage(float CDParameter)
{
if (PikaCDMaterialDynamic)
{
PikaCDMaterialDynamic->SetScalarParameterValue(PikaCDMatName, CDParameter);
}
}
/**************************构建CD**************************/
void UPikaUI_InventorySlot::PikaUpdateTowerCD(float InDeltaTime)
{
//当前CD是否小于0
if (PikaBuildingTowerStruct.PikaCurrentConstructionTowerCD > 0)
{
//绘制旋转的材质CD
PikaUpdateTowerCDImage(PikaBuildingTowerStruct.PikaGetTowerConstructionTimePercentage());
//绘制数字CD显示
PikaUpdateTowerCDValueText(PikaBuildingTowerStruct.PikaCurrentConstructionTowerCD);
//用来呼叫完成事件
PikaBuildingTowerStruct.PikaIsUpdateTowerCD = true;
//数字变化
PikaBuildingTowerStruct.PikaCurrentConstructionTowerCD -= InDeltaTime;
return;
}
//等价于CD转完后呼叫一个完成事件
if (PikaBuildingTowerStruct.PikaIsUpdateTowerCD)
{
PikaBuildingTowerStruct.PikaIsUpdateTowerCD = false;
//PikaTowerImage->Brush.GetResourceObject()可以返回图片资源
if (PikaTowerImage && PikaTowerImage->PikaqiuGetTexture2D())
{
//获取图片对应的序列号
int32 PikaTowerImageIndex = PikaGetPlayerController()->PikaGetTowerIocn().Find(PikaTowerImage->PikaqiuGetTexture2D());
//准备构建的塔
PikaBuildingTowerStruct.PikaTowerPerpareBuildingNumber--;
//建造完成的塔
PikaBuildingTowerStruct.PikaTowerConstructionNumber++;
PikaUpdateTowerPrepareBuildingNumText(PikaTowerImageIndex);
PikaUpdateTowerCompletionNumText(PikaTowerImageIndex);
//让我们的建造会一直根据我们的输入而建造
if (PikaBuildingTowerStruct.PikaTowerPerpareBuildingNumber > 0)
PikaBuildingTowerStruct.PikaSetCurrentCD();
//打印塔建造完成的信息
//获取游戏路径
FString gameDir = FPaths::ProjectDir();
FString path = gameDir + "111.txt";
FString string;
TArray<FString> stringArray;
FFileHelper::LoadFileToString(string, *path);
string.ParseIntoArray(stringArray, TEXT(","), false);
if(stringArray.IsValidIndex(0) && stringArray.IsValidIndex(1) && stringArray.IsValidIndex(2))
PikaLogPrintf(stringArray[0] + stringArray[1] + stringArray[2]);
//PikaLogPrintf(PikaBuildingTowerStruct.PikaCharacterInformationWidget.PikaCharacterName.ToString() + string);
//PikaLogPrintf(FString::Printf(TEXT("%s:%i has been done and %i 's in perparation for constriction!") , *PikaBuildingTowerStruct.PikaCharacterInformationWidget.PikaCharacterName.ToString() , PikaBuildingTowerStruct.PikaTowerConstructionNumber ,PikaBuildingTowerStruct.PikaTowerPerpareBuildingNumber));
}
}
}
FReply UPikaUI_InventorySlot::NativeOnMouseButtonDown(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
{
Super::NativeOnMouseButtonDown(InGeometry, InMouseEvent);
//InMouseEvent.IsTouchEvent()为触摸屏的判断
if (InMouseEvent.GetEffectingButton() == EKeys::RightMouseButton || InMouseEvent.IsTouchEvent())
{
//FReply::Handled()表示按键响应已经被处理
FReply PikaReply = FReply::Handled();
TSharedPtr<SWidget> PikaSlateWidgetDrag = GetCachedWidget();
if (PikaSlateWidgetDrag.IsValid())
{
//PikaReply.DetectDrag()检测到拖拽后会触发一个UUserWidget类里的NativeOnDragDetected事件
PikaReply.DetectDrag(PikaSlateWidgetDrag.ToSharedRef() , EKeys::RightMouseButton);
return PikaReply;
}
}
//FReply::Unhandled()表示按键响应未被处理
return FReply::Unhandled();
}
//NativeOnMouseButtonDown里增加的拖拽事件的响应函数
void UPikaUI_InventorySlot::NativeOnDragDetected(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent, UDragDropOperation*& OutOperation)
{
if (PikaBuildingTowerStruct.PikaIsActive() && GetWorld())
{
TSubclassOf<UPikaTowerIcon> PikaIcoDragDrop = LoadClass<UPikaTowerIcon>(NULL , TEXT("WidgetBlueprint'/Game/HUD/GameUI/PikaTowerIconBP.PikaTowerIconBP_C'"));
if (PikaIcoDragDrop)
{
UPikaTowerIcon* PikaCharactersIcoDragDrop = CreateWidget<UPikaTowerIcon>(GetWorld() , PikaIcoDragDrop);
if (PikaCharactersIcoDragDrop)
{
//生成图标
UPikaDragDropOperation* PikaTowerDragOperation = nullptr;
TSubclassOf<UPikaDragDropOperation> PikaTowerDragOperationClass = UPikaDragDropOperation::StaticClass();
if (PikaTowerDragOperationClass)
{
PikaTowerDragOperation = NewObject<UPikaDragDropOperation>(GetTransientPackage() , PikaTowerDragOperationClass);
}
else
{
PikaTowerDragOperation = NewObject<UPikaDragDropOperation>();
}
if (PikaTowerDragOperation)
PikaTowerDragOperation->SetFlags(RF_StrongRefOnFrame);//设置标识
//注册图标显示信息
PikaTowerDragOperation->PikaInventorySlot = this;
PikaCharactersIcoDragDrop->PikaBuildingTowerStructIcon = PikaBuildingTowerStruct;
PikaTowerDragOperation->DefaultDragVisual = PikaCharactersIcoDragDrop;
OutOperation = PikaTowerDragOperation;
//初始化我们的值(显示图标信息)
PikaCharactersIcoDragDrop->PikaDrawUIToScreen();
//处于拖拽状态中,停止所有CD
PikaBuildingTowerStruct.PikaIsDragIco = true;
}
}
}
Super::NativeOnDragDetected(InGeometry, InMouseEvent, OutOperation);
}
//NativeOnDragDetected激活后,拖拽完成时,如果将图标从一个物品栏拖拽到另外一个物品栏时,则会触发该事件
//接收拖拽信息,InOperation为空时,该函数不会被激活
bool UPikaUI_InventorySlot::NativeOnDrop(const FGeometry& InGeometry, const FDragDropEvent& InDragDropEvent, UDragDropOperation* InOperation)
{
this;
Super::NativeOnDrop(InGeometry, InDragDropEvent, InOperation);
bool PikaIsDrop = false;
UPikaDragDropOperation* PikaDragDropOperation = Cast<UPikaDragDropOperation>(InOperation);
if (PikaDragDropOperation)
{
//PikaMyInventorySlot为拖拽前的物品栏,类本身为拖拽的目标物品栏
UPikaUI_InventorySlot* PikaMyInventorySlot = Cast<UPikaUI_InventorySlot>(PikaDragDropOperation->PikaInventorySlot);
if (PikaMyInventorySlot)
{
PikaMyInventorySlot->PikaBuildingTowerStruct.PikaIsDragIco = false;
PikaBuildingTowerStruct.PikaIsDragIco = false;
if (PikaBuildingTowerStruct.PikaIsActive())
{
//拖拽的目标物品栏处于激活状态,做物品栏交换操作
FPikaBulidingTowres PikaTempBulidTower;
PikaTempBulidTower = PikaBuildingTowerStruct;
PikaBuildingTowerStruct = PikaMyInventorySlot->PikaBuildingTowerStruct;
PikaMyInventorySlot->PikaBuildingTowerStruct = PikaTempBulidTower;
//更新数据显示
PikaMyInventorySlot->PikaUpdateInventorySlotData();
PikaUpdateInventorySlotData();
}
else
{
//拖拽的目标物品栏处于未激活状态,做物品栏移动操作
PikaBuildingTowerStruct = PikaMyInventorySlot->PikaBuildingTowerStruct;
//物品栏还原没有道具时的状态
PikaMyInventorySlot->PikaInitInventorySlot();
PikaUpdateInventorySlotData();
}
PikaIsDrop = true;
}
PikaIsDrop = false;
}
else
PikaIsDrop = false;
//销毁,引擎会自动释放,下面的释放代码可以不写
/*if (InOperation)
{
if (InOperation->DefaultDragVisual)
InOperation->DefaultDragVisual->RemoveFromParent();
InOperation->DefaultDragVisual = NULL;
InOperation->ConditionalBeginDestroy();
}*/
return PikaIsDrop;
}
void UPikaUI_InventorySlot::NativeOnMouseEnter(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
{
if (PikaInventoryPtr)
{
PikaInventoryPtr->PikaSetTempInventorySlot(this);
//显示塔信息
if (PikaInventoryPtr->PikaGetMainInterface() && PikaBuildingTowerStruct.PikaIsActive())
{
if (PikaInventoryPtr->PikaGetMainInterface()->PikaGetUITowerInfo())
PikaInventoryPtr->PikaGetMainInterface()->PikaGetUITowerInfo()->SetVisibility(ESlateVisibility::Visible);
}
}
}
void UPikaUI_InventorySlot::NativeOnMouseLeave(const FPointerEvent& InMouseEvent)
{
if (PikaInventoryPtr)
{
//PikaInventoryPtr->PikaCancelTempInventorySlot();
//隐藏塔信息
if (PikaInventoryPtr->PikaGetMainInterface())
{
if (PikaInventoryPtr->PikaGetMainInterface()->PikaGetUITowerInfo())
PikaInventoryPtr->PikaGetMainInterface()->PikaGetUITowerInfo()->SetVisibility(ESlateVisibility::Hidden);
}
}
}
void UPikaUI_InventorySlot::PikaInitInventorySlot()
{
//初始化结构体
PikaBuildingTowerStruct.PikaInitBuildingTower();
PikaUpdateInventorySlotData();
}
void UPikaUI_InventorySlot::PikaPrint(FString piksStr)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 6.0f, FColor::Red, piksStr);
}
}
//显示字体和CD
void UPikaUI_InventorySlot::PikaDisplayNumber(UTextBlock* MyTextNumberBlock, int32 MyTextNumber)
{
//物品栏上有道显示文本,没有道具则不显示文本
if (MyTextNumber < 1 || !PikaBuildingTowerStruct.PikaIsActive())
{
MyTextNumberBlock->SetVisibility(ESlateVisibility::Hidden);
}
else
{
//格式输出里,%02d表示输出格式为00,%03d的输出格式为000
MyTextNumberBlock->SetText(FText::FromString(FString::Printf(TEXT("%02d") , MyTextNumber)));
MyTextNumberBlock->SetVisibility(ESlateVisibility::Visible);
}
}PikaUICharacterAttribute.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "PikaCharacterData.h"
#include "TextBlock.h"
#include "ProgressBar.h"
#include "MultiLineEditableTextBox.h"
#include "Image.h"
#include "PikaMainInterface.h"
#include "PikaUICharacterAttribute.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUICharacterAttribute : public UPikaUIWidgetBase
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaCharacterNameBlockName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaComsumeGlodBlockName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaCharacterLevelName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaCharacterHealthBlockName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaCharacterAttackBlockName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaCharacterArmorBlockName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaCharacterAttackSpeedBlockName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaCharacterEmpiricalValueBlockName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaCharacterEmpiricalValueBarName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaIntroductionName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaTowersIcoName;
//角色的信息数据
UPikaCharacterData* PikaCharacterDataPtr;
public:
//作为初始化实例
virtual void NativePreConstruct()override;
virtual void PikaDrawUIToScreen() override;
//设置我们的数据
void PikaSetGameCharacterData(UPikaCharacterData* NewCharacterData) { PikaCharacterDataPtr = NewCharacterData; }
//只要角色值变动就会更新
void PikaUpdateCharacterInformation();
//角色升级后更新
void PikaUpdateLevelCharacterElement();
void PikaUpdataAll();
//游戏初始化进行更新(只更新一次)
void PikaUpdatecharacterElement();
void PikaSetMianScreen(UPikaMainInterface* NewMianScreen) { PikaMianScreen = NewMianScreen; }
private:
UTextBlock* PikaCharacterNameBlock;
UTextBlock* PikaComsumeGlodBlock;
UTextBlock* PikaCharacterLevelBlock;
UTextBlock* PikaCharacterHealthBlock;
UTextBlock* PikaCharacterAttackBlock;
UTextBlock* PikaCharacterArmorBlock;
UTextBlock* PikaCharacterAttackSpeedBlock;
UTextBlock* PikaCharacterEmpiricalValueBlock;
UProgressBar* PikaCharacterEmpiricalValueBar;
UMultiLineEditableTextBox* PikaIntroduction;
UImage* PikaTowersIco;
UPikaMainInterface* PikaMianScreen;
protected:
virtual void NativeOnMouseLeave(const FPointerEvent& InMouseEvent)override;
};PikaUICharacterAttribute.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUICharacterAttribute.h"
void UPikaUICharacterAttribute::NativePreConstruct()
{
Super::NativePreConstruct();
if (!PikaCharacterNameBlock)
PikaCharacterNameBlock = Cast<UTextBlock>(GetWidgetFromName(PikaCharacterNameBlockName));
if (!PikaComsumeGlodBlock)
PikaComsumeGlodBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaComsumeGlodBlockName));
if (!PikaCharacterLevelBlock)
PikaCharacterLevelBlock = Cast<UTextBlock>(GetWidgetFromName(PikaCharacterLevelName));
if (!PikaCharacterHealthBlock)
PikaCharacterHealthBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterHealthBlockName));
if (!PikaCharacterAttackBlock)
PikaCharacterAttackBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterAttackBlockName));
if (!PikaCharacterArmorBlock)
PikaCharacterArmorBlock = Cast<UTextBlock>(GetWidgetFromName(PikaCharacterArmorBlockName));
if (!PikaCharacterAttackSpeedBlock)
PikaCharacterAttackSpeedBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterAttackSpeedBlockName));
if (!PikaCharacterEmpiricalValueBlock)
PikaCharacterEmpiricalValueBlock = Cast<UTextBlock>(GetWidgetFromName(PikaCharacterEmpiricalValueBlockName));
if (!PikaCharacterEmpiricalValueBar)
PikaCharacterEmpiricalValueBar = Cast<UProgressBar>(PikaqiuGetBlueprintWidget(PikaCharacterEmpiricalValueBarName));
if (!PikaIntroduction)
PikaIntroduction = Cast<UMultiLineEditableTextBox>(GetWidgetFromName(PikaIntroductionName));
if (!PikaTowersIco)
PikaTowersIco = Cast<UImage>(PikaqiuGetBlueprintWidget(PikaTowersIcoName));
}
void UPikaUICharacterAttribute::PikaDrawUIToScreen()
{
if (!PikaCharacterNameBlock)
PikaCharacterNameBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterNameBlockName));
if (!PikaComsumeGlodBlock)
PikaComsumeGlodBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaComsumeGlodBlockName));
if (!PikaCharacterLevelBlock)
PikaCharacterLevelBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterLevelName));
if (!PikaCharacterHealthBlock)
PikaCharacterHealthBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterHealthBlockName));
if (!PikaCharacterAttackBlock)
PikaCharacterAttackBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterAttackBlockName));
if (!PikaCharacterArmorBlock)
PikaCharacterArmorBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterArmorBlockName));
if (!PikaCharacterAttackSpeedBlock)
PikaCharacterAttackSpeedBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterAttackSpeedBlockName));
if (!PikaCharacterEmpiricalValueBlock)
PikaCharacterEmpiricalValueBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterEmpiricalValueBlockName));
if (!PikaCharacterEmpiricalValueBar)
PikaCharacterEmpiricalValueBar = Cast<UProgressBar>(PikaqiuGetBlueprintWidget(PikaCharacterEmpiricalValueBarName));
if (!PikaIntroduction)
PikaIntroduction = Cast<UMultiLineEditableTextBox>(PikaqiuGetBlueprintWidget(PikaIntroductionName));
if (!PikaTowersIco)
PikaTowersIco = Cast<UImage>(PikaqiuGetBlueprintWidget(PikaTowersIcoName));
}
//只要角色值变动就会更新
void UPikaUICharacterAttribute::PikaUpdateCharacterInformation()
{
if (PikaCharacterDataPtr)
{
//生命值
if (PikaCharacterHealthBlock)
PikaCharacterHealthBlock->SetText(FText::FromString(FString::Printf(TEXT("%0.f / %0.f"), PikaCharacterDataPtr->PikaCharBaseData.PikaMaxHealth, PikaCharacterDataPtr->PikaCharBaseData.PikaCurrentHealth)));
//经验数值
if (PikaCharacterEmpiricalValueBlock)
PikaCharacterEmpiricalValueBlock->SetText(FText::FromString(FString::Printf(TEXT("%0.f / %0.f"), PikaCharacterDataPtr->PikaCharBaseData.PikaMaxExperienceValue, PikaCharacterDataPtr->PikaCharBaseData.PikaCurrentExperienceValue)));
//经验值百分百Bar
if (PikaCharacterEmpiricalValueBar)
PikaCharacterEmpiricalValueBar->SetPercent(PikaCharacterDataPtr->PikaCharBaseData.PikaGetEmpircalValuePercentage());
}
}
//角色升级后更新
void UPikaUICharacterAttribute::PikaUpdateLevelCharacterElement()
{
if (PikaCharacterDataPtr)
{
//攻击力
if (PikaCharacterAttackBlock)
PikaCharacterAttackBlock->SetText(FText::AsNumber(PikaCharacterDataPtr->PikaCharBaseData.PikaPhysicalAttack));
//防御力
if (PikaCharacterArmorBlock)
PikaCharacterArmorBlock->SetText(FText::AsNumber(PikaCharacterDataPtr->PikaCharBaseData.PikaArmor));
//攻击速度
if (PikaCharacterAttackSpeedBlock)
PikaCharacterAttackSpeedBlock->SetText(FText::AsNumber(PikaCharacterDataPtr->PikaCharBaseData.PikaAttackSpeed));
//等级
if (PikaCharacterLevelBlock)
PikaCharacterLevelBlock->SetText(FText::FromString(FString::Printf(TEXT("Lv- %02d"), PikaCharacterDataPtr->PikaCharBaseData.PikaCharacterLevel)));
//生命值
if (PikaCharacterHealthBlock)
PikaCharacterHealthBlock->SetText(FText::FromString(FString::Printf(TEXT("%0.f / %0.f"), PikaCharacterDataPtr->PikaCharBaseData.PikaMaxHealth, PikaCharacterDataPtr->PikaCharBaseData.PikaCurrentHealth)));
//经验数值
if (PikaCharacterEmpiricalValueBlock)
PikaCharacterEmpiricalValueBlock->SetText(FText::FromString(FString::Printf(TEXT("%0.f / %0.f"), PikaCharacterDataPtr->PikaCharBaseData.PikaMaxExperienceValue, PikaCharacterDataPtr->PikaCharBaseData.PikaCurrentExperienceValue)));
//经验值百分百Bar
if (PikaCharacterEmpiricalValueBar)
PikaCharacterEmpiricalValueBar->SetPercent(PikaCharacterDataPtr->PikaCharBaseData.PikaGetEmpircalValuePercentage());
}
}
void UPikaUICharacterAttribute::PikaUpdataAll()
{
this->PikaUpdatecharacterElement();
this->PikaUpdateCharacterInformation();
this->PikaUpdateLevelCharacterElement();
}
//游戏初始化进行更新(只更新一次)
void UPikaUICharacterAttribute::PikaUpdatecharacterElement()
{
if (PikaGetPlayerController() && PikaCharacterDataPtr)
{
//更新名字
if (PikaCharacterNameBlock)
PikaCharacterNameBlock->SetText(FText::FromName(PikaCharacterDataPtr->PikaCharBaseData.PikaCharacterName));
//花费
if (PikaComsumeGlodBlock)
PikaComsumeGlodBlock->SetText(FText::AsNumber(PikaCharacterDataPtr->PikaCharBaseData.PikaComsumeGold));
if (PikaCharacterDataPtr->PikaCharBaseData.PikaTeam)
{
int32 PikaIndexTowerName = PikaGetPlayerController()->PikaGetTowersName().Find(PikaCharacterDataPtr->PikaCharBaseData.PikaCharacterName);
if (PikaIndexTowerName >= 0 && PikaIndexTowerName < PikaGetPlayerController()->PikaGetTowersIntroduction().Num())
{
if (PikaTowersIco)
PikaTowersIco->SetBrushFromTexture(PikaGetPlayerController()->PikaGetTowerIocn()[PikaIndexTowerName]);
if (PikaIntroduction)
PikaIntroduction->SetText(PikaGetPlayerController()->PikaGetTowersIntroduction()[PikaIndexTowerName]);
}
}
else
{
int32 PikaIndexMonsterName = PikaGetPlayerController()->PikaGetMonsterName().Find(PikaCharacterDataPtr->PikaCharBaseData.PikaCharacterName);
if (PikaIndexMonsterName >= 0 && PikaIndexMonsterName < PikaGetPlayerController()->PikaGetMonsterName().Num())
{
if (PikaTowersIco)
PikaTowersIco->SetBrushFromTexture(PikaGetPlayerController()->PikaGetMonsterIocn()[PikaIndexMonsterName]);
if (PikaIntroduction)
PikaIntroduction->SetText(PikaGetPlayerController()->PikaGetMonsterIntroduction()[PikaIndexMonsterName]);
}
}
}
}
void UPikaUICharacterAttribute::NativeOnMouseLeave(const FPointerEvent& InMouseEvent)
{
//将自己隐藏
if (PikaMianScreen && PikaMianScreen->PikaGetCharacterAttribute() && PikaMianScreen->PikaGetCharacterAttribute()->GetVisibility() != ESlateVisibility::Hidden)
{
PikaMianScreen->PikaGetCharacterAttribute()->SetVisibility(ESlateVisibility::Hidden);
}
}PikaUIData.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "PikaUIData.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUIData : public UObject
{
GENERATED_BODY()
public:
//物品栏的格子数
int32 PikaInventoryColumn, PikaInventoryRow;
float PikaLogDisplayTime;
UPikaUIData();
};PikaUIData.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUIData.h"
UPikaUIData::UPikaUIData()
{
PikaInventoryColumn = 3;
PikaInventoryRow = 6;
PikaLogDisplayTime = 2.f;
}PikaUIGameCount.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "ProgressBar.h"
#include "TextBlock.h"
#include "PikaUIGameCount.generated.h"
class UPikaMainInterface;
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUIGameCount : public UPikaUIWidgetBase
{
GENERATED_BODY()
//控件示例的名字
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaGameGlobName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaTowersDeathNumberName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaGameCountName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaGameLevelScheduleName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaGameLevelScheduleSginName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaKillSoldierName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FString PikaBaseIamgeFadeInName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FString PikaBaseIamgeFadeOutName;
public:
//调用去初始化我们的UI
virtual void PikaDrawUIToScreen() override;
//void PikaPlayIamgeAnimationState(bool IsBegin);
//负责打印GameLOG
virtual void PikaLogPrintf(FString MyString) override;
void PikaUpdateInformation();
//更新数字显示 25/5
void PikaUpdateMonsterMaximum(int32 MaxValue, int32 Surplus);
//获取时间格式
FString PikaGetCurrentCount(float NewTimeCount);
//Tick
virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;
UPikaMainInterface* PikaGetMianScreen()const { return PikaMainInterface; }
void PikaSetMainInterface(UPikaMainInterface* NewWidget) { PikaMainInterface = NewWidget; }
private:
UTextBlock* PikaGameGlob;
UTextBlock* PikaTowersDeathNumber;
UTextBlock* PikaGameCount;
UTextBlock* PikaKillSoldier;
UTextBlock* PikaGameLevelScheduleTexrSgin;
UProgressBar* PikaGameLevelSchedule;
UPikaMainInterface* PikaMainInterface;
//动画
//UWidgetAnimation* PikaBaseIamgeFadeIn;
//UWidgetAnimation* PikaBaseIamgeFadeOut;
protected:
//virtual void NativeOnMouseEnter(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent);
//virtual void NativeOnMouseLeave(const FPointerEvent& InMouseEvent);
};PikaUIGameCount.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUIGameCount.h"
void UPikaUIGameCount::PikaDrawUIToScreen()
{
PikaGameGlob = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaGameGlobName));
PikaTowersDeathNumber = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaTowersDeathNumberName));
PikaGameLevelScheduleTexrSgin = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaGameLevelScheduleSginName));
PikaGameCount = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaGameCountName));
PikaKillSoldier = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaKillSoldierName));
PikaGameLevelSchedule = Cast<UProgressBar>(PikaqiuGetBlueprintWidget(PikaGameLevelScheduleName));
//PikaBaseIamgeFadeIn = GetNameWidgetAnimation(PikaBaseIamgeFadeInName);
//PikaBaseIamgeFadeOut = GetNameWidgetAnimation(PikaBaseIamgeFadeOutName);
}
void UPikaUIGameCount::PikaLogPrintf(FString MyString)
{
if (PikaMainInterface)
PikaMainInterface->PikaLogPrintf(MyString);
}
void UPikaUIGameCount::PikaUpdateInformation()
{
if (PikaGetPlayerController() && PikaGetPlayerController()->PikaGlobalConfigPre)
{
//显示游戏的倒计时
if (PikaGameCount)
PikaGameCount->SetText(FText::FromString(PikaGetCurrentCount(PikaGetPlayerController()->PikaGlobalConfigPre->PikaGameData.PikaGameCount)));
//显示金币
if (PikaGameGlob)
PikaGameGlob->SetText(FText::AsNumber(PikaGetSaveGameData()->PikaGetGlobalGold()));
//显示塔死亡
if (PikaTowersDeathNumber)
PikaTowersDeathNumber->SetText(FText::AsNumber(PikaGetPlayerController()->PikaGlobalConfigPre->PikaGameData.PikaTowersDeathNumber));
//显示击杀小兵信息
if (PikaKillSoldier)
PikaKillSoldier->SetText(FText::AsNumber(PikaGetPlayerController()->PikaGlobalConfigPre->PikaGameData.PikaKillSoldierNumber));
//显示关卡进度
if (PikaGameLevelSchedule)
PikaGameLevelSchedule->SetPercent(PikaGetPlayerController()->PikaGlobalConfigPre->PikaGameData.PikaGetLevelPercentage());
//关卡信号标记
PikaUpdateMonsterMaximum(PikaGetPlayerController()->PikaGlobalConfigPre->PikaGameLevelManangenment.PikaMaxStagesAreMonsters, PikaGetPlayerController()->PikaGlobalConfigPre->PikaGameLevelManangenment.PikaCurrentStagesAreMonsters);
}
}
void UPikaUIGameCount::PikaUpdateMonsterMaximum(int32 MaxValue, int32 Surplus)
{
//调整系数
Surplus += 1;
if (Surplus > MaxValue)
Surplus = MaxValue;
//显示当前波段
if (PikaGameLevelScheduleTexrSgin)
PikaGameLevelScheduleTexrSgin->SetText(FText(FText::FromString(FString::Printf(TEXT("%2d / %2d"), MaxValue, Surplus))));
}
//获取时间格式
FString UPikaUIGameCount::PikaGetCurrentCount(float NewTimeCount)
{
const int32 NewOurTime = FMath::Max(0, FMath::TruncToInt(NewTimeCount));
const int32 NewMinrutes = NewOurTime / 60;
const int32 NewSeconds = NewOurTime % 60;
return FString::Printf(TEXT("%02d:%02d"), NewMinrutes, NewSeconds);
}
void UPikaUIGameCount::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
Super::NativeTick(MyGeometry, InDeltaTime);
//更新我们的显示数据
PikaUpdateInformation();
}PikaUIGameMenu.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "PikaUIGameMenu.generated.h"
class UPikaMainInterface;
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUIGameMenu : public UPikaUIWidgetBase
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = UI)
FString PikaGameBeginAnimationName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FString PikaGameEndAnimationName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaReturnGameButtonName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaSaveGameButtonName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaGameSettingButtonName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaGameQuitButtonName;
public:
UPikaUIGameMenu();
virtual void PikaDrawUIToScreen() override;
//负责打印GameLOG
virtual void PikaLogPrintf(FString MyString)override;
//敲击
virtual void PikaOnClickedWidget(UWidget* MyWidget)override;
virtual void PikaSetWarningWindowsState(bool IsVisibles, float StateTime = 0, FString MyWidget = "", TEnumAsByte<PikaEButtonSureType::Type> MyButtonSureType = PikaEButtonSureType::BST_None) override;
UPikaMainInterface* PikaGetMainInterface()const { return PikaMainInterface; }
void PikaSetMainInterface(UPikaMainInterface* NewWidget) { PikaMainInterface = NewWidget; }
/////////////////////////////////动画相关/////////////////////////////////////////
void PikaGameMenuFadeInAndFadeOut(bool IsOut);
private:
UButton* PikaReturnGameButton;
UButton* PikaSaveGameButton;
UButton* PikaGameSettingButtonButton;
UButton* PikaGameQuitButtonButton;
UPikaMainInterface* PikaMainInterface;
//动画相关
UWidgetAnimation* PikaGameBeginAnimation;
UWidgetAnimation* PikaGameEndAnimation;
};PikaUIGameMenu.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUIGameMenu.h"
UPikaUIGameMenu::UPikaUIGameMenu()
{
}
void UPikaUIGameMenu::PikaDrawUIToScreen()
{
PikaReturnGameButton = PikaGetButtonFromBlueprint(PikaReturnGameButtonName);
PikaSaveGameButton = PikaGetButtonFromBlueprint(PikaSaveGameButtonName);
PikaGameSettingButtonButton = PikaGetButtonFromBlueprint(PikaGameSettingButtonName);
PikaGameQuitButtonButton = PikaGetButtonFromBlueprint(PikaGameQuitButtonName);
//PikaGameBeginAnimation = GetNameWidgetAnimation(GameBeginAnimationName);
//PikaGameEndAnimation = GetNameWidgetAnimation(GameEndAnimationName);
}
void UPikaUIGameMenu::PikaLogPrintf(FString MyString)
{
if (PikaMainInterface)
PikaMainInterface->PikaLogPrintf(MyString);
}
//onclick事件是通过父类UPikaUIWidgetBase里的PikaGetButtonFromBlueprint方法绑定的
void UPikaUIGameMenu::PikaOnClickedWidget(UWidget* MyWidget)
{
if (MyWidget == PikaReturnGameButton)
{
SetVisibility(ESlateVisibility::Hidden);
//开始淡出
if (PikaMainInterface && PikaGetPlayerController())
{
PikaMainInterface->PikaShieldedInteractiveOperation(true);
//PikaMainInterface->GameMenuFadeInAndFadeOut(false);
//设置全局时间
if (PikaGetGameInstance())
{
//设置全局时间的增量为1
PikaGetGameInstance()->PikaSetGlobalGameTime(PIKA_STANDARD_VALUE);
}
}
}
if (MyWidget == PikaSaveGameButton)
{
if (PikaMainInterface)
{
//打开存储列表
PikaMainInterface->PikaSetBoxListDisplayOrder(PikaBoxListType::BOXLIST_SaveList);
PikaMainInterface->PikaGetBoxSaveGameArray()->SetVisibility(ESlateVisibility::Visible);
//PikaMainInterface->ClickedMenuFadeInAndFadeOut(true);
}
}
if (MyWidget == PikaGameSettingButtonButton)
{
/*if (PikaMainInterface)
{
//打开设置列表列表
PikaMainInterface->SetBoxListDisplayOrder(EBoxListType::BOXLIST_GameSettings);
PikaMainInterface->ClickedMenuFadeInAndFadeOut(true);
}*/
}
if (MyWidget == PikaGameQuitButtonButton)
{
/*//打开提示菜单
SetWarningWindowsState(true, 0, FString::Printf(TEXT("Return to the menu, unsaved data will be lost. do you want to exit?")), EButtonSureType::BST_QuitMeun);
//设置面板状态
if (PikaMainInterface)
PikaMainInterface->SetWindowsState(true);*/
}
}
void UPikaUIGameMenu::PikaSetWarningWindowsState(bool IsVisibles, float StateTime /*= 0*/, FString MyWidget /*= ""*/, TEnumAsByte<PikaEButtonSureType::Type> MyButtonSureType /*= PikaEButtonSureType::BST_None*/)
{
if (PikaMainInterface)
{
PikaMainInterface->PikaSetWarningWindowsState(IsVisibles, StateTime, MyWidget, MyButtonSureType);
}
}
void UPikaUIGameMenu::PikaGameMenuFadeInAndFadeOut(bool IsOut)
{
/*if (IsOut)
{
if (PikaGameBeginAnimation)
PlayAnimation(PikaGameBeginAnimation);
}
else
{
if (PikaGameEndAnimation)
PlayAnimation(PikaGameEndAnimation);
}*/
}PikaUIGameWarning.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "MultiLineEditableTextBox.h"
#include "PikaUIGameWarning.generated.h"
class UPikaMainInterface;
class UPikaUIMainHall;
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUIGameWarning : public UPikaUIWidgetBase
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaSureButtonName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaCancelButtonName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaEditableTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FString PikaOpenContorllerColorName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FString PikaCloseContorllerColorName;
public:
UPikaUIGameWarning();
//存储游戏的编号
int32 PikaCurrentGameArchiveNumber;
//调用去初始化我们的UI
virtual void PikaDrawUIToScreen()override;
virtual void PikaOnClickedWidget(UWidget* MyWidget) override;
//设置字体显示
void PikaSetText(FString FSInformation);
//设置MianScreen
void PikaSetMainInterface(UPikaMainInterface* NewMianScreen);
//设置MainHall
void PikaSetMainHall(UPikaUIMainHall* NewMainHall);
//virtual void PikaSetWarningWindowsState(bool IsVisibles, float StateTime = 0, FString MyWidget = "", TEnumAsByte<PikaEButtonSureType::Type> MyButtonSureType = PikaEButtonSureType::BST_None)override;
//取消显示
void PikaCancelWarningDisplay();
///////////////////////////////动画///////////////////////////////////////////
//void GameWarningFadeInAndFadeOut(bool IsVisibles, float StateTime = 0, FString MyWidget = "", TEnumAsByte<EButtonSureType::Type> MyButtonSureType = EButtonSureType::BST_None);
//动画完成播放后执行该函数
//virtual void OnAnimationFinished_Implementation(const UWidgetAnimation* Animation) override;
//动画开始播放后执行该函数
//virtual void OnAnimationStarted_Implementation(const UWidgetAnimation* Animation) override;
private:
//界面
UPikaMainInterface* PikaMianInterfacePtr;
UPikaUIMainHall* PikaMainHallPtr;
//按键
UButton* PikaSureButton;
UButton* PikaCancelButton;
UMultiLineEditableTextBox* PikaEditableText;
//动画相关
UWidgetAnimation* PikaOpenContorllerColor;
UWidgetAnimation* PikaCloseContorllerColor;
};PikaUIGameWarning.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUIGameWarning.h"
UPikaUIGameWarning::UPikaUIGameWarning()
{
PikaCurrentGameArchiveNumber = INDEX_NONE;
}
void UPikaUIGameWarning::PikaDrawUIToScreen()
{
PikaSureButton = PikaGetButtonFromBlueprint(PikaSureButtonName);
PikaCancelButton = PikaGetButtonFromBlueprint(PikaCancelButtonName);
PikaEditableText = Cast<UMultiLineEditableTextBox>(GetWidgetFromName(PikaEditableTextName));
/*//动画
OpenContorllerColor = GetNameWidgetAnimation(OpenContorllerColorName);
CloseContorllerColor = GetNameWidgetAnimation(CloseContorllerColorName);
//默认关闭
if (CloseContorllerColor)
PlayAnimation(CloseContorllerColor, 0.5);*/
}
void UPikaUIGameWarning::PikaOnClickedWidget(UWidget* MyWidget)
{
if (MyWidget == PikaSureButton)
{
/*//覆盖之发生在游戏中,不发生在大厅内
if (PikaGameButtonSureType == PikaEButtonSureType::BST_CoverSave)
{
if (PikaMianInterfacePtr &&
PikaMianInterfacePtr->GetReadAndWrite() &&
GetTowerDefencePlayerController() &&
GetTowerDefencePlayerController()->Confo)
{
//覆盖存档
MianScreen->GetReadAndWrite()->SaveArchiveSlot(true);
}
}*/
//游戏删除
if (PikaGameButtonSureType == PikaEButtonSureType::BST_DeleteSave)
{
if (PikaCurrentGameArchiveNumber != INDEX_NONE)
{
//游戏场景内
if (PikaMianInterfacePtr && PikaMianInterfacePtr->PikaGetReadAndWrite())
{
//还原显示设置
PikaMianInterfacePtr->PikaGetReadAndWrite()->PikaClearNumberSave(PikaCurrentGameArchiveNumber);
//隐藏自己
PikaMianInterfacePtr->PikaSetWarningWindowsState(false);
if (PikaGetGameInstance())
{
bool DeleData = PikaGetGameInstance()->PikaDeleteGameData(PikaCurrentGameArchiveNumber);
if (DeleData)
{
PIKA_LOG("Delete Successfully");
}
else
{
PIKA_LOG("Delete Failure");
}
}
}
//大厅内
if (PikaMainHallPtr && PikaMainHallPtr->PikaGetReadAndWrite())
{
//清除显示并且还原
PikaMainHallPtr->PikaGetReadAndWrite()->PikaClearNumberSave(PikaCurrentGameArchiveNumber);
//隐藏自己
PikaMainHallPtr->PikaSetWarningWindowsState(false);
if (PikaGetGameInstance())
{
bool PikaDeleData = PikaGetGameInstance()->PikaDeleteGameData(PikaCurrentGameArchiveNumber);
if (PikaDeleData)
{
PIKA_LOG("Delete Successfully");
}
else
{
PIKA_LOG("Delete Failure");
}
}
}
}
else
{
PIKA_LOG("CurrentGameArchiveNumber == INDEX_NONE");
}
}
/*//返回主菜单
if (GameButtonSureType == EButtonSureType::BST_QuitMeun)
{
//通知游戏菜单播放动画
MianScreen->SetGameButtonSureType(EButtonSureType::BST_QuitMeun);
MianScreen->MainUMGFadeInAndFadeOut(false, EAnimationState::BST_QuitMeun);
}*/
/*//退出游戏
if (GameButtonSureType == EButtonSureType::BST_QuitGame)
{
////考虑不同的场景所以使用这种办法
if (MainHall)
{
MainHall->MainUMGFadeInAndFadeOut(false, EAnimationState::EA_GameQuit);
}
//播放离游戏开动画 //只能在菜单界面播放
if (GetTowerDefenceHallGameMode())
{
GetTowerDefenceHallGameMode()->PlayCurrentCameraAnimation(ECameraArray::Camera_Leave, EMatineeArray::Matinee_Max, TD_CAMARE_BLENDTIME + 2);
}
}*/
}
if (MyWidget == PikaCancelButton)
{
//取消
//隐藏自己
if(PikaMianInterfacePtr)
PikaMianInterfacePtr->PikaSetWarningWindowsState(false);
//隐藏自己
if(PikaMainHallPtr)
{
PikaMainHallPtr->PikaSetWarningWindowsState(false);
PikaMainHallPtr->PikaWindowsFadeInAndFadeOut(false);
}
}
}
void UPikaUIGameWarning::PikaSetText(FString FSInformation)
{
//更新显示字体
if (PikaEditableText)
PikaEditableText->SetText(FText::FromString(FSInformation));
}
void UPikaUIGameWarning::PikaSetMainInterface(UPikaMainInterface* NewMianScreen)
{
PikaMianInterfacePtr = NewMianScreen;
}
void UPikaUIGameWarning::PikaSetMainHall(UPikaUIMainHall* NewMainHall)
{
PikaMainHallPtr = NewMainHall;
}
void UPikaUIGameWarning::PikaCancelWarningDisplay()
{
}PikaUIHallGameSetting.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "PikaGameSettingsAudio.h"
#include "PikaGameSettingsGameSettings.h"
#include "PikaGameSettingsOtherSettings.h"
#include "PikaGameSettingsVideo.h"
#include "CheckBox.h"
#include "WidgetSwitcher.h"
#include "PikaUIGameMenu.h"
#include "PikaUIHallGameSetting.generated.h"
class UPikaUIMainHall;
UENUM()
namespace PikaGameSettingsType
{
enum Type
{
GAMESETTINGS_Sound,
GAMESTETTINGS_Graphics,
GAMESTETTINGS_Game,
GAMESTETTINGS_Other,
GAMESETTINGS_Max
};
}
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUIHallGameSetting : public UPikaUIWidgetBase
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaSoundSettingBoxName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaGraphicsSettingsBoxName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaGameSettingsBoxName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaOtherGameSettingsBoxName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaSaveBarButtonName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaReturnMenuButtonName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaSettingsListWitcherName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
TSubclassOf<UPikaGameSettingsAudio> PikaGameSettingsAudioClass;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
TSubclassOf<UPikaGameSettingsGameSettings> PikaGameSettingsGameSettingsClass;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
TSubclassOf<UPikaGameSettingsOtherSettings> PikaGameSettingsOtherSettingsClass;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
TSubclassOf<UPikaGameSettingsVideo> PikaGameSettingsVideoClass;
public:
UPikaUIHallGameSetting();
//调用去初始化我们的UI
virtual void PikaDrawUIToScreen()override;
//返回和存储设置按钮
virtual void PikaOnClickedWidget(UWidget* MyWidget)override;
virtual void PikaClickedCheckBox(UWidget* MyWidget, bool ClickedWidget)override;
void PikaShowOneCheckBox(PikaGameSettingsType::Type GameSettingsType);
void PikaSetMainHall(UPikaUIMainHall* NewWidget) { PikaMainHall = NewWidget; }
void PikaSetGameMenu(UPikaUIGameMenu* NewWidget) { PikaMyGameMenu = NewWidget; }
FORCEINLINE UPikaUIMainHall* PikaGetMainHall()const { return PikaMainHall; }
protected:
void PikaSaveGameSettings();
void PikaLoadGameSettings();
private:
UCheckBox* PikaSoundSettingBox;
UCheckBox* PikaGraphicsSettingsBox;
UCheckBox* PikaGameSettingsBox;
UCheckBox* PikaOtherGameSettingsBox;
UButton* PikaSaveBarButton;
UButton* PikaReturnMenuButton;
//设置选项列表
UWidgetSwitcher* PikaSettingsListWitcher;
UPikaUIMainHall* PikaMainHall;
UPikaUIGameMenu* PikaMyGameMenu;
UPikaGameSettingsAudio* PikaGameSettingsAudio;
UPikaGameSettingsGameSettings* PikaGameSettingsGameSettings;
UPikaGameSettingsOtherSettings* PikaGameSettingsOtherSettings;
UPikaGameSettingsVideo* PikaGameSettingsVideo;
TArray<UCheckBox*> PikaCheckBoxArray;
};PikaUIHallGameSetting.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUIHallGameSetting.h"
#include "Public/PikaGameUserSettings.h"
#include "Public/PikaWorldSettings.h"
UPikaUIHallGameSetting::UPikaUIHallGameSetting()
{
}
void UPikaUIHallGameSetting::PikaDrawUIToScreen()
{
PikaSettingsListWitcher = Cast<UWidgetSwitcher>(GetWidgetFromName(PikaSettingsListWitcherName));
PikaSoundSettingBox = PikaGetCheckBoxFormBlueprint(PikaSoundSettingBoxName);
PikaGraphicsSettingsBox = PikaGetCheckBoxFormBlueprint(PikaGraphicsSettingsBoxName);
PikaGameSettingsBox = PikaGetCheckBoxFormBlueprint(PikaGameSettingsBoxName);
PikaOtherGameSettingsBox = PikaGetCheckBoxFormBlueprint(PikaOtherGameSettingsBoxName);
PikaReturnMenuButton = PikaGetButtonFromBlueprint(PikaReturnMenuButtonName);
PikaSaveBarButton = PikaGetButtonFromBlueprint(PikaSaveBarButtonName);
if (PikaSettingsListWitcher && GetWorld())
{
//添加Audio
if (PikaGameSettingsAudioClass)
{
PikaGameSettingsAudio = CreateWidget<UPikaGameSettingsAudio>(GetWorld(), PikaGameSettingsAudioClass);
if (PikaGameSettingsAudio)
{
PikaSettingsListWitcher->AddChild(PikaGameSettingsAudio);
PikaGameSettingsAudio->PikaDrawUIToScreen();
PikaGameSettingsAudio->PikaSetHallGameSettings(this);
}
}
//添加图像设置
if (PikaGameSettingsVideoClass)
{
//添加图像设置
PikaGameSettingsVideo = CreateWidget<UPikaGameSettingsVideo>(GetWorld(), PikaGameSettingsVideoClass);
if (PikaGameSettingsVideo)
{
PikaSettingsListWitcher->AddChild(PikaGameSettingsVideo);
PikaGameSettingsVideo->PikaDrawUIToScreen();
PikaGameSettingsVideo->PikaSetHallGameSettings(this);
}
}
//添加游戏设置
if (PikaGameSettingsGameSettingsClass)
{
//添加游戏设置
PikaGameSettingsGameSettings = CreateWidget<UPikaGameSettingsGameSettings>(GetWorld(), PikaGameSettingsGameSettingsClass);
if (PikaGameSettingsGameSettings)
{
PikaSettingsListWitcher->AddChild(PikaGameSettingsGameSettings);
PikaGameSettingsGameSettings->PikaDrawUIToScreen();
PikaGameSettingsGameSettings->PikaSetHallGameSettings(this);
}
}
//添加其他设置
if (PikaGameSettingsOtherSettingsClass)
{
//添加其他设置
PikaGameSettingsOtherSettings = CreateWidget<UPikaGameSettingsOtherSettings>(GetWorld(), PikaGameSettingsOtherSettingsClass);
if (PikaGameSettingsOtherSettings)
{
PikaSettingsListWitcher->AddChild(PikaGameSettingsOtherSettings);
PikaGameSettingsOtherSettings->PikaDrawUIToScreen();
PikaGameSettingsOtherSettings->PikaSetHallGameSettings(this);
}
}
}
//添加我们的敲击盒子和绑定它
if (PikaSoundSettingBox)
PikaCheckBoxArray.Add(PikaSoundSettingBox);
if (PikaGraphicsSettingsBox)
PikaCheckBoxArray.Add(PikaGraphicsSettingsBox);
if (PikaGameSettingsBox)
PikaCheckBoxArray.Add(PikaGameSettingsBox);
if (PikaOtherGameSettingsBox)
PikaCheckBoxArray.Add(PikaOtherGameSettingsBox);
//读取本地的配置
PikaLoadGameSettings();
}
//返回和存储设置按钮
void UPikaUIHallGameSetting::PikaOnClickedWidget(UWidget* MyWidget)
{
if (MyWidget == PikaSaveBarButton)
{
PikaSaveGameSettings();
}
if (MyWidget == PikaReturnMenuButton)
{
if (PikaGetMainHall() && PikaGetMainHall()->PikaGetBoxList())
//PikaGetMainHall()->PikaGetBoxList()->ClearChildren();
PikaGetMainHall()->PikaGetBoxList()->SetVisibility(ESlateVisibility::Hidden);
}
}
void UPikaUIHallGameSetting::PikaClickedCheckBox(UWidget* MyWidget, bool ClickedWidget)
{
if (MyWidget == PikaSoundSettingBox)
{
if (PikaSettingsListWitcher)
{
PikaSettingsListWitcher->SetActiveWidgetIndex(PikaGameSettingsType::GAMESETTINGS_Sound);
PikaShowOneCheckBox(PikaGameSettingsType::GAMESETTINGS_Sound);
}
}
if (MyWidget == PikaGraphicsSettingsBox)
{
if (PikaSettingsListWitcher)
{
PikaSettingsListWitcher->SetActiveWidgetIndex(PikaGameSettingsType::GAMESTETTINGS_Graphics);
PikaShowOneCheckBox(PikaGameSettingsType::GAMESTETTINGS_Graphics);
}
}
if (MyWidget == PikaGameSettingsBox)
{
if (PikaSettingsListWitcher)
{
PikaSettingsListWitcher->SetActiveWidgetIndex(PikaGameSettingsType::GAMESTETTINGS_Game);
PikaShowOneCheckBox(PikaGameSettingsType::GAMESTETTINGS_Game);
}
}
if (MyWidget == PikaOtherGameSettingsBox)
{
if (PikaSettingsListWitcher)
{
PikaSettingsListWitcher->SetActiveWidgetIndex(PikaGameSettingsType::GAMESTETTINGS_Other);
PikaShowOneCheckBox(PikaGameSettingsType::GAMESTETTINGS_Other);
}
}
}
void UPikaUIHallGameSetting::PikaShowOneCheckBox(PikaGameSettingsType::Type GameSettingsType)
{
for (int32 i = 0; i < PikaGameSettingsType::GAMESETTINGS_Max; i++)
{
if (i != GameSettingsType && PikaCheckBoxArray.IsValidIndex(i))
PikaCheckBoxArray[i]->SetCheckedState(ECheckBoxState::Checked);
else
PikaCheckBoxArray[i]->SetCheckedState(ECheckBoxState::Unchecked);
}
}
void UPikaUIHallGameSetting::PikaSaveGameSettings()
{
if (UPikaGameUserSettings::PikaGetGameUserSettings())
{
//音乐存储
if (PikaGameSettingsAudio)
{
if (PikaGameSettingsAudio->PikaGetSoundControllSlider())
UPikaGameUserSettings::PikaGetGameUserSettings()->PikaqiuTotalSoundControl = PikaGameSettingsAudio->PikaGetSoundControllSlider()->GetValue();
if (PikaGameSettingsAudio->PikaGetMusicSlider())
UPikaGameUserSettings::PikaGetGameUserSettings()->PikaBackgroundSoundControl = PikaGameSettingsAudio->PikaGetMusicSlider()->GetValue();
if (PikaGameSettingsAudio->PikaGetSoundEffectSlider())
UPikaGameUserSettings::PikaGetGameUserSettings()->PikaEffectsSoundControl = PikaGameSettingsAudio->PikaGetSoundEffectSlider()->GetValue();
if (PikaGameSettingsAudio->PikaGetAudioSlider())
UPikaGameUserSettings::PikaGetGameUserSettings()->PikaqiuButtonSoundControl = PikaGameSettingsAudio->PikaGetAudioSlider()->GetValue();
}
if (PikaGameSettingsVideo)
{
//保存分辨率
if (PikaGameSettingsVideo->PikaGetResolutionBoxString())
{
FString PikaResolution_H;
FString PikaResolution_W;
FString PikaResolutionString = PikaGameSettingsVideo->PikaGetResolutionBoxString()->GetSelectedOption();
PikaResolutionString.Split(TEXT("x"), &PikaResolution_W, &PikaResolution_H);
FIntPoint PikaResolutionInt;
PikaResolutionInt.X = FCString::Atoi(*PikaResolution_W);
PikaResolutionInt.Y = FCString::Atoi(*PikaResolution_H);
UPikaGameUserSettings::PikaGetGameUserSettings()->SetScreenResolution(PikaResolutionInt);
}
/*//语言
if (GameSettingsVideo->GetLanguageString())
{
FString LanguageTmp = GameSettingsVideo->GetLanguageString()->GetSelectedOption();
UTowerDefenceGameUserSettings::GetTowerDefenceGameUserSettings()->SetCuurrLanguage(LanguageTmp);
}*/
//设置屏幕模式
if (PikaGameSettingsVideo->PikaGetFullScreenCheckBox() && PikaGameSettingsVideo->PikaGetWindowScreenCheckBox())
{
if (PikaGameSettingsVideo->PikaGetFullScreenCheckBox()->IsChecked())
{
if (!PikaGameSettingsVideo->PikaGetWindowScreenCheckBox()->IsChecked())
{
UPikaGameUserSettings::PikaGetGameUserSettings()->SetFullscreenMode(EWindowMode::WindowedFullscreen);
}
}
else if (PikaGameSettingsVideo->PikaGetWindowScreenCheckBox()->IsChecked())
{
UPikaGameUserSettings::PikaGetGameUserSettings()->SetFullscreenMode(EWindowMode::Windowed);
}
}
//默认级别
int32 PikaScalabilityQualityLevel = 5.0f;
//贴图质量
if (PikaGameSettingsVideo->PikaGetTextureQualitySlider())
{
float PikaCurrentValue = PikaGameSettingsVideo->PikaGetTextureQualitySlider()->GetValue();
int32 PikaCurrentQualityLevel = PikaCurrentValue * PikaScalabilityQualityLevel;
UPikaGameUserSettings::PikaGetGameUserSettings()->ScalabilityQuality.TextureQuality = PikaCurrentQualityLevel;
}
//阴影质量
if (PikaGameSettingsVideo->PikaGetShadowQualitySlider())
{
float PikaCurrentValue = PikaGameSettingsVideo->PikaGetShadowQualitySlider()->GetValue();
int32 PikaCurrentQualityLevel = PikaCurrentValue * PikaScalabilityQualityLevel;
UPikaGameUserSettings::PikaGetGameUserSettings()->ScalabilityQuality.ShadowQuality = PikaCurrentQualityLevel;
}
//锯齿质量
if (PikaGameSettingsVideo->PikaGetAntiAliasingSlider())
{
float PikaCurrentValue = PikaGameSettingsVideo->PikaGetAntiAliasingSlider()->GetValue();
int32 PikaCurrentQualityLevel = PikaCurrentValue * PikaScalabilityQualityLevel;
UPikaGameUserSettings::PikaGetGameUserSettings()->ScalabilityQuality.AntiAliasingQuality = PikaCurrentQualityLevel;
}
//后期质量
if (PikaGameSettingsVideo->PikaGetPostProcessingSlider())
{
float PikaCurrentValue = PikaGameSettingsVideo->PikaGetPostProcessingSlider()->GetValue();
int32 PikaCurrentQualityLevel = PikaCurrentValue * PikaScalabilityQualityLevel;
UPikaGameUserSettings::PikaGetGameUserSettings()->ScalabilityQuality.PostProcessQuality = PikaCurrentQualityLevel;
}
//特效质量
if (PikaGameSettingsVideo->PikaGetEffectsSlider())
{
float PikaCurrentValue = PikaGameSettingsVideo->PikaGetEffectsSlider()->GetValue();
int32 PikaCurrentQualityLevel = PikaCurrentValue * PikaScalabilityQualityLevel;
UPikaGameUserSettings::PikaGetGameUserSettings()->ScalabilityQuality.EffectsQuality = PikaCurrentQualityLevel;
}
//Foliage质量
if (PikaGameSettingsVideo->PikaGetFoliageSlider())
{
float PikaCurrentValue = PikaGameSettingsVideo->PikaGetFoliageSlider()->GetValue();
int32 PikaCurrentQualityLevel = PikaCurrentValue * PikaScalabilityQualityLevel;
UPikaGameUserSettings::PikaGetGameUserSettings()->ScalabilityQuality.FoliageQuality = PikaCurrentQualityLevel;
}
//视距离质量
if (PikaGameSettingsVideo->PikaGetViewDistanceSlider())
{
float PikaCurrentValue = PikaGameSettingsVideo->PikaGetViewDistanceSlider()->GetValue();
int32 PikaCurrentQualityLevel = PikaCurrentValue * PikaScalabilityQualityLevel;
UPikaGameUserSettings::PikaGetGameUserSettings()->ScalabilityQuality.ViewDistanceQuality = PikaCurrentQualityLevel;
}
//摄像机FOV设置
if (PikaGameSettingsVideo->PikaGetFOVSlider())
{
//载入摄像机FOV
if (GetWorld() && GetWorld()->GetWorldSettings())
{
APikaWorldSettings* PikaWorldSettings = Cast<APikaWorldSettings>(GetWorld()->GetWorldSettings());
if (PikaWorldSettings && PikaWorldSettings->PikaCurrentLevel != INDEX_NONE)
{
if (PikaGetPlayerController() && PikaGetPlayerController()->PikaGetTowreCamera())
{
float PikaCurrentFOV = PikaGameSettingsVideo->PikaGetFOVSlider()->GetValue() * PIKA_FOVMAX_VALUE + 40;
if (PikaCurrentFOV >= 40 && PikaCurrentFOV <= 240)
{
//大厅里设置该值会崩
//PikaGetPlayerController()->PikaGetTowreCamera()->PikaSetCameraFOV(PikaCurrentFOV);
UPikaGameUserSettings::PikaGetGameUserSettings()->PikaCameraFOV = PikaCurrentFOV;
}
}
}
}
}
//总级别控制,
/*总级别控制这项一定要放到所有其它设置的最后面,否则读取不到值*/
if (PikaGameSettingsVideo->PikaGetOverallScalabilityLevelSlider())
{
float PikaCurrentValue = PikaGameSettingsVideo->PikaGetOverallScalabilityLevelSlider()->GetValue();
int32 PikaCurrentQualityLevel = PikaCurrentValue * PikaScalabilityQualityLevel;
if (PikaCurrentQualityLevel != UPikaGameUserSettings::PikaGetGameUserSettings()->GetOverallScalabilityLevel())
{
UPikaGameUserSettings::PikaGetGameUserSettings()->SetOverallScalabilityLevel(PikaCurrentQualityLevel);
}
}
}
UPikaGameUserSettings::PikaGetGameUserSettings()->ApplySettings(true);
}
}
void UPikaUIHallGameSetting::PikaLoadGameSettings()
{
if ((UPikaGameUserSettings::PikaGetGameUserSettings()))
{
//读取配置
UPikaGameUserSettings::PikaGetGameUserSettings()->LoadSettings();
//读取音乐配置
if (PikaGameSettingsAudio)
{
if (PikaGameSettingsAudio->PikaGetSoundControllSlider())
PikaGameSettingsAudio->PikaGetSoundControllSlider()->SetValue(UPikaGameUserSettings::PikaGetGameUserSettings()->PikaqiuTotalSoundControl);
if (PikaGameSettingsAudio->PikaGetMusicSlider())
PikaGameSettingsAudio->PikaGetMusicSlider()->SetValue(UPikaGameUserSettings::PikaGetGameUserSettings()->PikaBackgroundSoundControl);
if (PikaGameSettingsAudio->PikaGetSoundEffectSlider())
PikaGameSettingsAudio->PikaGetSoundEffectSlider()->SetValue(UPikaGameUserSettings::PikaGetGameUserSettings()->PikaEffectsSoundControl);
if (PikaGameSettingsAudio->PikaGetAudioSlider())
PikaGameSettingsAudio->PikaGetAudioSlider()->SetValue(UPikaGameUserSettings::PikaGetGameUserSettings()->PikaqiuButtonSoundControl);
//更新属性
PikaGameSettingsAudio->PikaUpdateAttibe();
}
//关于显示设置
if (PikaGameSettingsVideo)
{
//载入分辨率
if (PikaGameSettingsVideo->PikaGetResolutionBoxString())
{
FIntPoint PikaResolutionPoint = UPikaGameUserSettings::PikaGetGameUserSettings()->GetScreenResolution();
FString PikaResolutionString = FString::Printf(TEXT("%ix%i"), PikaResolutionPoint.X, PikaResolutionPoint.Y);
PikaGameSettingsVideo->PikaGetResolutionBoxString()->SetSelectedOption(PikaResolutionString);
}
/*//本地语言
if (GameSettingsVideo->GetLanguageString())
{
FString LanguageString = UTowerDefenceGameUserSettings::GetTowerDefenceGameUserSettings()->GetCurrentLanguageType();
GameSettingsVideo->GetLanguageString()->SetSelectedOption(LanguageString);
}*/
//载入窗口模式
if (PikaGameSettingsVideo->PikaGetFullScreenCheckBox() && PikaGameSettingsVideo->PikaGetWindowScreenCheckBox())
{
EWindowMode::Type PikaWindowMode = UPikaGameUserSettings::PikaGetGameUserSettings()->GetLastConfirmedFullscreenMode();
switch (PikaWindowMode)
{
case EWindowMode::Fullscreen:
PikaGameSettingsVideo->PikaGetFullScreenCheckBox()->SetCheckedState(ECheckBoxState::Checked);
PikaGameSettingsVideo->PikaGetWindowScreenCheckBox()->SetCheckedState(ECheckBoxState::Unchecked);
break;
case EWindowMode::Windowed:
PikaGameSettingsVideo->PikaGetFullScreenCheckBox()->SetCheckedState(ECheckBoxState::Unchecked);
PikaGameSettingsVideo->PikaGetWindowScreenCheckBox()->SetCheckedState(ECheckBoxState::Checked);
break;
case EWindowMode::NumWindowModes:
break;
case EWindowMode::WindowedFullscreen:
PikaGameSettingsVideo->PikaGetFullScreenCheckBox()->SetCheckedState(ECheckBoxState::Unchecked);
PikaGameSettingsVideo->PikaGetWindowScreenCheckBox()->SetCheckedState(ECheckBoxState::Checked);
break;
}
}
//默认级别
float PikaScalabilityQualityLevel = 5.0f;
//贴图质量
if (PikaGameSettingsVideo->PikaGetTextureQualitySlider())
{
float PikaTextureQualityLevel = UPikaGameUserSettings::PikaGetGameUserSettings()->ScalabilityQuality.TextureQuality;
PikaGameSettingsVideo->PikaGetTextureQualitySlider()->SetValue(PikaTextureQualityLevel / PikaScalabilityQualityLevel);
}
//阴影质量
if (PikaGameSettingsVideo->PikaGetShadowQualitySlider())
{
float PikaShadowQualityLevel = UPikaGameUserSettings::PikaGetGameUserSettings()->ScalabilityQuality.ShadowQuality;
PikaGameSettingsVideo->PikaGetShadowQualitySlider()->SetValue(PikaShadowQualityLevel / PikaScalabilityQualityLevel);
}
//锯齿质量
if (PikaGameSettingsVideo->PikaGetAntiAliasingSlider())
{
float PikaAntiAliasingQuality = UPikaGameUserSettings::PikaGetGameUserSettings()->ScalabilityQuality.AntiAliasingQuality;
PikaGameSettingsVideo->PikaGetAntiAliasingSlider()->SetValue(PikaAntiAliasingQuality / PikaScalabilityQualityLevel);
}
//后期质量
if (PikaGameSettingsVideo->PikaGetPostProcessingSlider())
{
float PikaCurrentQualityLevel = UPikaGameUserSettings::PikaGetGameUserSettings()->ScalabilityQuality.PostProcessQuality;
PikaGameSettingsVideo->PikaGetPostProcessingSlider()->SetValue(PikaCurrentQualityLevel / PikaScalabilityQualityLevel);
}
//特效质量
if (PikaGameSettingsVideo->PikaGetEffectsSlider())
{
float PikaCurrentQualityLevel = UPikaGameUserSettings::PikaGetGameUserSettings()->ScalabilityQuality.EffectsQuality;
PikaGameSettingsVideo->PikaGetEffectsSlider()->SetValue(PikaCurrentQualityLevel / PikaScalabilityQualityLevel);
}
//Foliage质量
if (PikaGameSettingsVideo->PikaGetFoliageSlider())
{
float PikaCurrentQualityLevel = UPikaGameUserSettings::PikaGetGameUserSettings()->ScalabilityQuality.FoliageQuality;
PikaGameSettingsVideo->PikaGetFoliageSlider()->SetValue(PikaCurrentQualityLevel / PikaScalabilityQualityLevel);
}
//视距离质量
if (PikaGameSettingsVideo->PikaGetViewDistanceSlider())
{
float PikaCurrentViewDistanceQuality = UPikaGameUserSettings::PikaGetGameUserSettings()->ScalabilityQuality.ViewDistanceQuality;
PikaGameSettingsVideo->PikaGetViewDistanceSlider()->SetValue(PikaCurrentViewDistanceQuality / PikaScalabilityQualityLevel);
}
//摄像机FOV设置
if (PikaGameSettingsVideo->PikaGetFOVSlider())
{
//能够滑块
PikaGameSettingsVideo->PikaGetFOVSlider()->SetIsEnabled(true);
//载入摄像机FOV
if (GetWorld() && GetWorld()->GetWorldSettings())
{
APikaWorldSettings* PikaWorldSettings = Cast<APikaWorldSettings>(GetWorld()->GetWorldSettings());
if (PikaWorldSettings && PikaWorldSettings->PikaCurrentLevel != INDEX_NONE)
{
if (PikaGetPlayerController() && PikaGetPlayerController()->PikaGetTowreCamera())
{
PikaGetPlayerController()->PikaGetTowreCamera()->PikaSetCameraFOV(UPikaGameUserSettings::PikaGetGameUserSettings()->PikaCameraFOV);
}
}
else
{
PikaGameSettingsVideo->PikaGetFOVSlider()->SetIsEnabled(false);
}
}
//显示FOV
//FOV 40 - 240 ,取中间数
//FOVMAX_VALUE
float PikaCurrentFOV = UPikaGameUserSettings::PikaGetGameUserSettings()->PikaCameraFOV - 40;
if (PikaCurrentFOV >= 0 && PikaCurrentFOV <= 200)
{
PikaGameSettingsVideo->PikaGetFOVSlider()->SetValue(PikaCurrentFOV / PIKA_FOVMAX_VALUE);
}
}
//全局质量
if (PikaGameSettingsVideo->PikaGetOverallScalabilityLevelSlider())
{
float PikaCurrentQualityLevel = UPikaGameUserSettings::PikaGetGameUserSettings()->GetOverallScalabilityLevel();
if (PikaCurrentQualityLevel < 0)
PikaCurrentQualityLevel = 0;
PikaGameSettingsVideo->PikaGetOverallScalabilityLevelSlider()->SetValue(PikaCurrentQualityLevel / PikaScalabilityQualityLevel);
}
//更新显示
PikaGameSettingsVideo->PikaUpdateAttibe();
}
/*//游戏的设置
if (GameSettingsGameSettings)
{
//读取鼠标设置
if (GameSettingsGameSettings->GetMouseSpeedSlider())
GameSettingsGameSettings->GetMouseSpeedSlider()->SetValue((UTowerDefenceGameUserSettings::GetTowerDefenceGameUserSettings()->MouseSpeed / 500));
//读取模型角度设置
if (GameSettingsGameSettings->GetAngleOfRotationSlider())
GameSettingsGameSettings->GetAngleOfRotationSlider()->SetValue(UTowerDefenceGameUserSettings::GetTowerDefenceGameUserSettings()->AngleOfRotation / 180);
GameSettingsGameSettings->UpdateAttibe();
}
//其他设置(该设置,不会在本地进行存储,只为了显示,只读不可修改)
if (GameSettingsOtherSettings && GameUIData)
{
//物品栏
if (GameSettingsOtherSettings->GetInventoryColumSlider())
GameSettingsOtherSettings->GetInventoryColumSlider()->SetValue(GameUIData->InventoryColumn / 10);
//物品栏
if (GameSettingsOtherSettings->GetInventoryRowSlider())
GameSettingsOtherSettings->GetInventoryRowSlider()->SetValue(GameUIData->InventoryRow / 10);
//Log持续时间
if (GameSettingsOtherSettings->GetLogContinueTimeSlider())
GameSettingsOtherSettings->GetLogContinueTimeSlider()->SetValue(GameUIData->LogDisplayTime / 10);
GameSettingsOtherSettings->UpdateAttibe();
}*/
}
}PikaUIHallKey.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "PikaUIHallKey.generated.h"
class UPikaUIMainHall;
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUIHallKey : public UPikaUIWidgetBase
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaNewWarButtonName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaHistoryButtonName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaMySettingsButtonName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaTutorialWebsiteButtonName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaAuthorButtonName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaQuitGameButtonName;
//当前摄像机序列
uint8 PikaCurrentCameraType;
public:
UPikaUIHallKey();
//调用去初始化我们的UI
virtual void PikaDrawUIToScreen()override;
virtual void PikaOnClickedWidget(UWidget* MyWidget) override;
//播放音效
virtual void PikaOnHoveredWidget(UWidget* CurrentButton) override;
virtual void PikaOnUnHoveredWidget() override;
UPikaUIMainHall* PikaGetMainHall()const { return PikaMainHall; }
//关闭Button Hov
//void PikaCloseButtonHov();
void PikaSetMainHall(UPikaUIMainHall* NewWidget) { PikaMainHall = NewWidget; }
//virtual void SetWarningWindowsState(bool IsVisibles, float StateTime = 0, FString MyWidget = "", TEnumAsByte<EButtonSureType::Type> MyButtonSureType = EButtonSureType::BST_None) override;
private:
UButton* PikaNewWarButton;
UButton* PikaHistoryButton;
UButton* PikaMySettingsButton;
UButton* PikaTutorialWebsiteButton;
UButton* PikaAuthorButton;
UButton* PikaQuitGameButton;
UPikaUIMainHall* PikaMainHall;
TArray<UButton*> PikaButtonArray;
};PikaUIHallKey.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUIHallKey.h"
#include "WidgetSwitcher.h"
#include "Kismet/GameplayStatics.h"
#include "WidgetAnimation.h"
UPikaUIHallKey::UPikaUIHallKey()
{
PikaCurrentCameraType = INDEX_NONE;
}
void UPikaUIHallKey::PikaDrawUIToScreen()
{
PikaNewWarButton = PikaGetButtonFromBlueprint(PikaNewWarButtonName);
PikaHistoryButton = PikaGetButtonFromBlueprint(PikaHistoryButtonName);
PikaMySettingsButton = PikaGetButtonFromBlueprint(PikaMySettingsButtonName);
PikaTutorialWebsiteButton = PikaGetButtonFromBlueprint(PikaTutorialWebsiteButtonName);
PikaQuitGameButton = PikaGetButtonFromBlueprint(PikaQuitGameButtonName);
PikaAuthorButton = PikaGetButtonFromBlueprint(PikaAuthorButtonName);
//记录按键
if (PikaNewWarButton)
PikaButtonArray.Add(PikaNewWarButton);
if (PikaHistoryButton)
PikaButtonArray.Add(PikaHistoryButton);
if (PikaMySettingsButton)
PikaButtonArray.Add(PikaMySettingsButton);
if (PikaTutorialWebsiteButton)
PikaButtonArray.Add(PikaTutorialWebsiteButton);
if (PikaQuitGameButton)
PikaButtonArray.Add(PikaQuitGameButton);
if (PikaAuthorButton)
PikaButtonArray.Add(PikaAuthorButton);
}
void UPikaUIHallKey::PikaOnClickedWidget(UWidget* MyWidget)
{
//新游戏
if (MyWidget == PikaNewWarButton)
{
//打开新关卡
if (GetWorld())
UGameplayStatics::OpenLevel(GetWorld(), "PikaGodStone_Level_Main_01");
/*if (GetMainHall())
{
//提示游戏开始关卡
GetMainHall()->MainUMGFadeInAndFadeOut(false, EAnimationState::EA_GameStart);
}
//播放开始游戏动画
if (GetTowerDefenceHallGameMode())
{
GetTowerDefenceHallGameMode()->PlayCurrentCameraAnimation(ECameraArray::Camera_IntoGame, EMatineeArray::Matinee_Max, TD_CAMARE_BLENDTIME + 1);
}
//设置不可敲击
SetVisibility(ESlateVisibility::HitTestInvisible);
//关闭其他按键
CloseButtonHov();*/
}
//游戏存储
if (MyWidget == PikaHistoryButton)
{
if (PikaGetMainHall() && PikaGetMainHall()->PikaGetBoxList())
{
if (PikaGetMainHall()->PikaGetBoxList()->GetVisibility() == ESlateVisibility::Visible)
{
if (PikaGetMainHall()->PikaGetBoxListDisplayOrder() != PikaBoxListType::BOXLIST_SaveList)
{
//设置显示界面类型
PikaGetMainHall()->PikaSetBoxListDisplayOrder(PikaBoxListType::BOXLIST_SaveList);
}
//隐藏和显示界面
PikaGetMainHall()->PikaClickedMenuFadeInAndFadeOut(false , PikaqiuEAnimationState::BST_QuitMeun);
}
else
{
PikaGetMainHall()->PikaGetBoxList()->SetVisibility(ESlateVisibility::Visible);
//隐藏和显示界面
PikaGetMainHall()->PikaClickedMenuFadeInAndFadeOut(true);
//设置显示界面类型
PikaGetMainHall()->PikaSetBoxListDisplayOrder(PikaBoxListType::BOXLIST_SaveList);
}
}
}
//游戏设置
if (MyWidget == PikaMySettingsButton)
{
if (PikaGetMainHall() && PikaGetMainHall()->PikaGetBoxList())
{
//关闭网站
//if (!GetMainHall()->IsWeb())
//GetMainHall()->CloseWeb();
if (PikaGetMainHall()->PikaGetBoxList()->GetVisibility() == ESlateVisibility::Visible)
{
if (PikaGetMainHall()->PikaGetBoxListDisplayOrder() == PikaBoxListType::BOXLIST_GameSettings)
{
//设置显示界面类型
PikaGetMainHall()->PikaSetBoxListDisplayOrder(PikaBoxListType::BOXLIST_GameSettings);
}
//隐藏和显示界面
PikaGetMainHall()->PikaClickedMenuFadeInAndFadeOut(false, PikaqiuEAnimationState::BST_QuitMeun);
}
else
{
PikaGetMainHall()->PikaGetBoxList()->SetVisibility(ESlateVisibility::Visible);
//隐藏和显示界面
PikaGetMainHall()->PikaClickedMenuFadeInAndFadeOut(true);
//设置显示界面类型
PikaGetMainHall()->PikaSetBoxListDisplayOrder(PikaBoxListType::BOXLIST_GameSettings);
}
}
}
//教程网站
if (MyWidget == PikaTutorialWebsiteButton)
{
if (PikaGetMainHall() && PikaGetMainHall()->PikaGetBoxList())
{
PikaGetMainHall()->PikaGetBoxList()->SetVisibility(ESlateVisibility::Hidden);
//隐藏和显示界面
/*if (GetMainHall()->GetBoxList()->GetVisibility() == ESlateVisibility::Visible)
GetMainHall()->ClickedMenuFadeInAndFadeOut(false);
if (GetMainHall()->IsWeb())
{
//打开网站
GetMainHall()->OpenWeb();
}
else
{
//关闭网站
GetMainHall()->CloseWeb();
}*/
}
}
//游戏秘境
if (MyWidget == PikaAuthorButton)
{
/*if (GetMainHall() && GetMainHall()->GetBoxList())
{
//关闭网站
if (!GetMainHall()->IsWeb())
GetMainHall()->CloseWeb();
if (GetMainHall()->GetBoxList()->GetVisibility() == ESlateVisibility::Visible)
{
//隐藏和显示界面
GetMainHall()->ClickedMenuFadeInAndFadeOut(false);
}
//提示游戏开始关卡
GetMainHall()->MainUMGFadeInAndFadeOut(false, EAnimationState::EA_SteamGameStart);
//播放开始游戏动画
if (GetTowerDefenceHallGameMode())
{
GetTowerDefenceHallGameMode()->PlayCurrentCameraAnimation(ECameraArray::Camera_IntoGame, EMatineeArray::Matinee_Max, TD_CAMARE_BLENDTIME + 1);
}
//关闭其他按键
CloseButtonHov();
}*/
}
//游戏退出
if (MyWidget == PikaQuitGameButton)
{
if (PikaGetPlayerController())
PikaGetPlayerController()->ConsoleCommand(FString(TEXT("exit")));
/*if (MainHall)
{
if (TD_WText.IsValidIndex(0))
{
SetWarningWindowsState(true, 0, TD_WText[0].ToString(), EButtonSureType::BST_QuitGame);
}
}*/
}
}
void UPikaUIHallKey::PikaOnHoveredWidget(UWidget* CurrentButton)
{
//播放声音
if (PikaGetPlayerController() && PikaGetPlayerController()->PikaGameResourcePtr)
{
PikaGetPlayerController()->PikaPlaySoundAtVetor(PikaGetPlayerController()->PikaGameResourcePtr->PikaHoverSound, FVector::ZeroVector, PikaETowerDefenceSoundType::SOUND_KEY_SOUND);
}
}
void UPikaUIHallKey::PikaOnUnHoveredWidget()
{
//播放声音
if (PikaGetPlayerController() && PikaGetPlayerController()->PikaGameResourcePtr)
{
PikaGetPlayerController()->PikaPlaySoundAtVetor(PikaGetPlayerController()->PikaGameResourcePtr->PikaUnHoverSound, FVector::ZeroVector, PikaETowerDefenceSoundType::SOUND_KEY_SOUND);
}
}PikaUIHealthShow.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "TextBlock.h"
#include "ProgressBar.h"
#include "PikaCharacterData.h"
#include "PikaUIHealthShow.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUIHealthShow : public UPikaUIWidgetBase
{
GENERATED_BODY()
//血条栏
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaHealthValueBarName;
//角色名称和等级
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaCharacterNameAndLVName;
//角色的信息数据
UPikaCharacterData* PikaCharacterDataPtr;
public:
UPikaUIHealthShow();
virtual void PikaDrawUIToScreen() override;
//只要角色值变动机会更新
void PikaUpdateCharacterInformation();
//设置我们的数据
void PikaSetGameCharacterData(UPikaCharacterData* NewCharacterData) { PikaCharacterDataPtr = NewCharacterData; }
private:
UTextBlock* PikaCharacterNameAndLV;
UProgressBar* PikaHealthValueBar;
};PikaUIHealthShow.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUIHealthShow.h"
UPikaUIHealthShow::UPikaUIHealthShow()
{
}
void UPikaUIHealthShow::PikaDrawUIToScreen()
{
if (!PikaCharacterNameAndLV)
PikaCharacterNameAndLV = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterNameAndLVName));
if (!PikaHealthValueBar)
PikaHealthValueBar = Cast<UProgressBar>(PikaqiuGetBlueprintWidget(PikaHealthValueBarName));
}
void UPikaUIHealthShow::PikaUpdateCharacterInformation()
{
if (PikaCharacterDataPtr)
{
if (PikaCharacterNameAndLV)
PikaCharacterNameAndLV->SetText(FText::FromString(FString::Printf(TEXT("Lv - %i %s"), PikaCharacterDataPtr->PikaCharBaseData.PikaCharacterLevel, *PikaCharacterDataPtr->PikaCharBaseData.PikaCharacterName.ToString())));
if (PikaHealthValueBar)
PikaHealthValueBar->SetPercent(PikaCharacterDataPtr->PikaCharBaseData.PikaGetHealthValuePercentage());
}
}PikaUILoading.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "PikaUILoading.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUILoading : public UPikaUIWidgetBase
{
GENERATED_BODY()
};PikaUILoading.cpp
// Fill out your copyright notice in the Description page of Project Settings. #include "Public/PikaUILoading.h"
PikaUIMainHall.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "PikaUIWebBrowser.h"
#include "PikaUIGameWarning.h"
#include "PikaUIHallGameSetting.h"
#include "PikaUIReadAndWrite.h"
#include "PikaUIHallKey.h"
#include "PikaGameErrorHint.h"
#include "WidgetSwitcher.h"
#include "WidgetAnimation.h"
#include "PikaUIMainHall.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FEventPikaHallLog, FString, MyString);
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUIMainHall : public UPikaUIWidgetBase
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = "PikaAnimation")
FString PikaSaveSettingAnimationBeginName;
UPROPERTY(EditDefaultsOnly, Category = "PikaAnimation")
FString PikaSaveSettingAnimationEndName;
UPROPERTY(EditDefaultsOnly, Category = "PikaAnimation")
FString PikaMaskAnimationBeginName;
UPROPERTY(EditDefaultsOnly, Category = "PikaAnimation")
FString PikaMaskAnimationEndName;
UPROPERTY(EditDefaultsOnly, Category = "PikaAnimation")
FString PikaGradualChangeAnimationBeginName;
UPROPERTY(EditDefaultsOnly, Category = "PikaAnimation")
FString PikaGradualChangeAnimationEndName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaBoxKeyHallListName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaBoxWindowListName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaBoxWarningListName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaBoxListName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaBoxWebName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaMoveToLogName;
UPROPERTY(EditDefaultsOnly, Category = UI)
TSubclassOf<UPikaGameErrorHint> PikaGamePromptErrorClass;
UPROPERTY(EditDefaultsOnly, Category = UI)
TSubclassOf<UPikaUIHallKey> PikaHallKeyClass;
UPROPERTY(EditDefaultsOnly, Category = UI)
TSubclassOf<UPikaUIReadAndWrite> PikaReadAndWriteClass;
UPROPERTY(EditDefaultsOnly, Category = UI)
TSubclassOf<UPikaUIHallGameSetting> PikaHallGameSettingsClass;
UPROPERTY(EditDefaultsOnly, Category = UI)
TSubclassOf<UPikaUIGameWarning> PikaGameWarningClass;
UPROPERTY(EditDefaultsOnly, Category = UI)
TSubclassOf<UPikaUIWebBrowser> PikaWebBrowserClass;
public:
FGeometry PikaHallGeometry;
UPikaUIMainHall();
FEventPikaHallLog PikaHallLog;
//调用去初始化我们的UI
virtual void PikaDrawUIToScreen() override;
//virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime)override;
//负责打印GameLOG
//virtual void PikaLogPrintf(FString MyString) override;
//移除相应设置
virtual void RemoveFromViewport()override;
/*void SetMoveToLogPostion(FVector2D NewPostion);*/
//提示窗口显示
virtual void PikaSetWarningWindowsState(bool IsVisibles, float StateTime = 0, FString MyWidget = "", TEnumAsByte<PikaEButtonSureType::Type> MyButtonSureType = PikaEButtonSureType::BST_None) override;
//存档与游戏设置切换
void PikaSetBoxListDisplayOrder(PikaBoxListType::Type BoxListType);
PikaBoxListType::Type PikaGetBoxListDisplayOrder() const;
/*********************Web***********************/
//void PikaSetWebListState(bool IsWebState);
//打开网站
//void PikaOpenWeb();
//关闭网站
//void PikaCloseWeb();
//是不是网站
//bool PikaIsWeb();
FORCEINLINE UWidgetSwitcher* PikaGetBoxList() const { return PikaBoxList; }
FORCEINLINE UPikaUIReadAndWrite* PikaGetReadAndWrite() const { return PikaReadAndWritePtr; }
FORCEINLINE UPikaUIHallGameSetting* PikaGetHallGameSettings()const { return PikaHallGameSettingsPtr; }
FORCEINLINE UPikaUIGameWarning* PikaGetGameWarning() const { return PikaGameWarningPtr; }
FORCEINLINE UPikaUIWebBrowser* PikaGetCurrentWebBrowser() const { return PikaCurrentWebBrowserPtr; }
public:
/***********************动画相关**************************/
void PikaInitAnimation();
//主UMG淡入淡出
void PikaMainUMGFadeInAndFadeOut(bool IsOut, PikaqiuEAnimationState NewAnimationState = PikaqiuEAnimationState::EA_Empty);
//敲击动画淡入淡出
void PikaClickedMenuFadeInAndFadeOut(bool IsOut, PikaqiuEAnimationState NewAnimationState = PikaqiuEAnimationState::EA_Empty);
//窗口状态
/*void PikaSetWindowsState(bool IsState);
//获取淡入淡出列表设置
FORCEINLINE UWidgetAnimation* PikaGetBeginAndEndSaveAndSettingUMGFadeInAndFadeOut(bool IsBeign = true) const { return IsBeign ? GameSaveSettingsBeginAnimation : GameSaveSettingsEndAnimation; }*/
//窗口淡入淡出
void PikaWindowsFadeInAndFadeOut(bool IsVisibles, float StateTime = 0, FString MyWidget = "", TEnumAsByte<PikaEButtonSureType::Type> MyButtonSureType = PikaEButtonSureType::BST_None);
private:
//动画完成播放后执行该函数
virtual void OnAnimationFinished_Implementation(const UWidgetAnimation* Animation) override;
//动画开始播放后执行该函数
virtual void OnAnimationStarted_Implementation(const UWidgetAnimation* Animation) override;
private:
//控件相关
USizeBox* PikaBoxKeyHallList;
USizeBox* PikaBoxWebList;
USizeBox* PikaBoxWarningList;
USizeBox* PikaBoxWindowList;
UWidgetSwitcher* PikaBoxList;
//UMG类相关
UPikaUIHallGameSetting* PikaHallGameSettingsPtr;
UPikaUIReadAndWrite* PikaReadAndWritePtr;
UPikaUIHallKey* PikaHallKeyPtr;
UPikaGameErrorHint* PikaGamePromptErrorPtr;
UPikaUIGameWarning* PikaGameWarningPtr;
UPikaUIWebBrowser* PikaCurrentWebBrowserPtr;
//UUI_MoveToLog* MoveToLogPtr;
//动画相关
UWidgetAnimation* PikaSaveSettingAnimationBegin;
UWidgetAnimation* PikaSaveSettingAnimationEnd;
UWidgetAnimation* PikaMaskAnimationBegin;
UWidgetAnimation* PikaMaskAnimationEnd;
UWidgetAnimation* PikaGradualChangeAnimationBegin;
UWidgetAnimation* PikaGradualChangeAnimationEnd;
};PikaUIMainHall.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUIMainHall.h"
UPikaUIMainHall::UPikaUIMainHall()
{
}
void UPikaUIMainHall::PikaDrawUIToScreen()
{
//UE控件相关
PikaBoxKeyHallList = Cast<USizeBox>(PikaqiuGetBlueprintWidget(PikaBoxKeyHallListName));
PikaBoxList = Cast<UWidgetSwitcher>(GetWidgetFromName(PikaBoxListName));
PikaBoxWarningList = Cast<USizeBox>(PikaqiuGetBlueprintWidget(PikaBoxWarningListName));
PikaBoxWindowList = Cast<USizeBox>(GetWidgetFromName(PikaBoxWindowListName));
PikaBoxWebList = Cast<USizeBox>(PikaqiuGetBlueprintWidget(PikaBoxWebName));
//PikaMoveToLog = Cast<UUI_MoveToLog>(GetWidgetFromName(MoveToLogName));
//动画相关
PikaSaveSettingAnimationBegin = PikaqiuGetNameWidgetAnimation(PikaSaveSettingAnimationBeginName);
PikaSaveSettingAnimationEnd = PikaqiuGetNameWidgetAnimation(PikaSaveSettingAnimationEndName);
PikaMaskAnimationBegin = PikaqiuGetNameWidgetAnimation(PikaMaskAnimationBeginName);
PikaMaskAnimationEnd = PikaqiuGetNameWidgetAnimation(PikaMaskAnimationEndName);
PikaGradualChangeAnimationBegin = PikaqiuGetNameWidgetAnimation(PikaGradualChangeAnimationBeginName);
PikaGradualChangeAnimationEnd = PikaqiuGetNameWidgetAnimation(PikaGradualChangeAnimationEndName);
//////////////////////////////////////////////////////////////////////////
if (GetWorld())
{
//添加我们的打印
if (PikaGamePromptErrorClass && PikaBoxWindowList)
{
PikaGamePromptErrorPtr = CreateWidget<UPikaGameErrorHint>(GetWorld(), PikaGamePromptErrorClass);
check(PikaGamePromptErrorPtr);
PikaGamePromptErrorPtr->PikaUIDataPtr = PikaUIDataPtr;
//将PikaGamePromptErrorPtr添加到size Box里
PikaAddSizeBox(PikaBoxWindowList, PikaGamePromptErrorPtr);
PikaGamePromptErrorPtr->PikaSetMainHall(this);
PikaGamePromptErrorPtr->PikaDrawUIToScreen();
}
//添加我们的HallKey
if (PikaHallKeyClass && PikaBoxKeyHallList)
{
PikaHallKeyPtr = CreateWidget<UPikaUIHallKey>(GetWorld(), PikaHallKeyClass);
check(PikaHallKeyPtr);
PikaHallKeyPtr->PikaUIDataPtr = PikaUIDataPtr;
//将PikaHallKeyPtr添加到WidgetSwitcher类的实例PikaBoxList里
PikaAddSizeBox(PikaBoxKeyHallList, PikaHallKeyPtr);
PikaHallKeyPtr->PikaSetMainHall(this);
PikaHallKeyPtr->PikaDrawUIToScreen();
}
//添加Box列表
if (PikaBoxList)
{
//隐藏自己
PikaBoxList->SetVisibility(ESlateVisibility::Hidden);
//获取存储
if (PikaReadAndWriteClass)
{
PikaReadAndWritePtr = CreateWidget<UPikaUIReadAndWrite>(GetWorld(), PikaReadAndWriteClass);
check(PikaReadAndWritePtr);
PikaReadAndWritePtr->PikaUIDataPtr = PikaUIDataPtr;
//将PikaReadAndWritePtr添加到WidgetSwitcher类的实例PikaBoxList里
PikaBoxList->AddChild(PikaReadAndWritePtr);
PikaReadAndWritePtr->PikaSetMainHall(this);
PikaReadAndWritePtr->PikaDrawUIToScreen();
//ReadAndWrite->SetButtonText(TD_WText[0], TD_WText[1]);
PikaReadAndWritePtr->PikaSetNewButtonType(PikaETDButtonType::LoadingGame);
}
//游戏设置
if (PikaHallGameSettingsClass)
{
PikaHallGameSettingsPtr = CreateWidget<UPikaUIHallGameSetting>(GetWorld(), PikaHallGameSettingsClass);
check(PikaHallGameSettingsPtr);
PikaHallGameSettingsPtr->PikaUIDataPtr = PikaUIDataPtr;
//将PikaHallGameSettingsPtr添加到WidgetSwitcher里
PikaBoxList->AddChild(PikaHallGameSettingsPtr);
PikaHallGameSettingsPtr->PikaSetMainHall(this);
PikaHallGameSettingsPtr->PikaDrawUIToScreen();
}
}
//游戏提示
if (PikaGameWarningClass, PikaBoxWarningList)
{
//隐藏自己
PikaBoxWarningList->SetVisibility(ESlateVisibility::Hidden);
PikaGameWarningPtr = CreateWidget<UPikaUIGameWarning>(GetWorld(), PikaGameWarningClass);
check(PikaGameWarningPtr);
PikaGameWarningPtr->PikaUIDataPtr = PikaUIDataPtr;
//将PikaGameWarningPtr添加到WidgetSwitcher类的实例PikaBoxList里
PikaAddSizeBox(PikaBoxWarningList, PikaGameWarningPtr);
PikaGameWarningPtr->PikaSetMainHall(this);
PikaGameWarningPtr->PikaDrawUIToScreen();
}
/*//添加网络web浏览功能
if (WebBrowserClass, BoxWebList)
{
CurrentWebBrowser = CreateWidget<UUI_WebBrowser>(GetWorld(), WebBrowserClass);
check(CurrentWebBrowser);
CurrentWebBrowser->GameUIData = GameUIData;
//添加进去
AddUSizeBox(BoxWebList, CurrentWebBrowser);
CurrentWebBrowser->SetMainHall(this);
CurrentWebBrowser->DrawUIToSrceen();
BoxWebList->SetVisibility(ESlateVisibility::Hidden);
}
if (MoveToLog)
{
MoveToLog->SetMianHall(this);
}*/
}
//初始化动画
PikaInitAnimation();
}
void UPikaUIMainHall::RemoveFromViewport()
{
//UMG类相关
if (PikaHallGameSettingsPtr)
PikaHallGameSettingsPtr->RemoveFromViewport();
PikaHallGameSettingsPtr = NULL;
if (PikaReadAndWritePtr)
PikaReadAndWritePtr->RemoveFromViewport();
PikaReadAndWritePtr = NULL;
if (PikaHallKeyPtr)
PikaHallKeyPtr->RemoveFromViewport();
PikaHallKeyPtr = NULL;
if (PikaGamePromptErrorPtr)
PikaGamePromptErrorPtr->RemoveFromViewport();
PikaGamePromptErrorPtr = NULL;
if (PikaGameWarningPtr)
PikaGameWarningPtr->RemoveFromViewport();
PikaGameWarningPtr = NULL;
if (PikaCurrentWebBrowserPtr)
PikaCurrentWebBrowserPtr->RemoveFromViewport();
PikaCurrentWebBrowserPtr = NULL;
Super::RemoveFromViewport();
}
void UPikaUIMainHall::PikaSetWarningWindowsState(bool IsVisibles, float StateTime /*= 0*/, FString MyWidget /*= ""*/, TEnumAsByte<PikaEButtonSureType::Type> MyButtonSureType /*= PikaEButtonSureType::BST_None*/)
{
if (IsVisibles)
{
//显示警告框
PikaGameWarningPtr->PikaSetText(MyWidget);
PikaBoxWarningList->SetVisibility(ESlateVisibility::Visible);
}
else
{
PikaBoxWarningList->SetVisibility(ESlateVisibility::Hidden);
}
}
void UPikaUIMainHall::PikaSetBoxListDisplayOrder(PikaBoxListType::Type BoxListType)
{
if (PikaBoxList)
PikaBoxList->SetActiveWidgetIndex(BoxListType);
}
PikaBoxListType::Type UPikaUIMainHall::PikaGetBoxListDisplayOrder() const
{
if (PikaBoxList)
return (PikaBoxListType::Type)PikaBoxList->GetActiveWidgetIndex();
return (PikaBoxListType::Type)INDEX_NONE;
}
void UPikaUIMainHall::PikaInitAnimation()
{
PikaMainUMGFadeInAndFadeOut(true);
if (PikaBoxWindowList)
PikaBoxWindowList->SetVisibility(ESlateVisibility::Hidden);
if (PikaBoxList)
PikaBoxList->SetVisibility(ESlateVisibility::Hidden);
}
void UPikaUIMainHall::PikaMainUMGFadeInAndFadeOut(bool IsOut, PikaqiuEAnimationState NewAnimationState /*= PikaqiuEAnimationState::EA_Empty*/)
{
if (IsOut)
{
if (PikaGradualChangeAnimationBegin)
{
PlayAnimation(PikaGradualChangeAnimationBegin);
PikaGradualChangeAnimationBegin->PikaqiuSetAnimationState(NewAnimationState);
}
}
else
{
if (PikaGradualChangeAnimationEnd)
{
PlayAnimation(PikaGradualChangeAnimationEnd);
PikaGradualChangeAnimationEnd->PikaqiuSetAnimationState(NewAnimationState);
}
}
}
void UPikaUIMainHall::PikaClickedMenuFadeInAndFadeOut(bool IsOut, PikaqiuEAnimationState NewAnimationState /*= EAnimationState::EA_Empty*/)
{
if (IsOut)
{
if (PikaSaveSettingAnimationBegin)
{
//设置动画状态
if (NewAnimationState != PikaqiuEAnimationState::EA_Empty)
PikaSaveSettingAnimationBegin->PikaqiuSetAnimationState(NewAnimationState);
//开始动画开始
PlayAnimation(PikaSaveSettingAnimationBegin);
}
}
else
{
if (PikaSaveSettingAnimationEnd)
{
//设置动画状态
if (NewAnimationState != PikaqiuEAnimationState::EA_Empty)
PikaSaveSettingAnimationEnd->PikaqiuSetAnimationState(NewAnimationState);
//开始动画结束
PlayAnimation(PikaSaveSettingAnimationEnd);
}
}
}
void UPikaUIMainHall::PikaWindowsFadeInAndFadeOut(bool IsVisibles, float StateTime /*= 0*/, FString MyWidget /*= ""*/, TEnumAsByte<PikaEButtonSureType::Type> MyButtonSureType /*= EButtonSureType::BST_None*/)
{
if (IsVisibles)
{
if (PikaMaskAnimationBegin)
PlayAnimation(PikaMaskAnimationBegin);
}
else
{
if (PikaMaskAnimationEnd)
PlayAnimation(PikaMaskAnimationEnd);
}
}
void UPikaUIMainHall::OnAnimationFinished_Implementation(const UWidgetAnimation* Animation)
{
if (PikaSaveSettingAnimationEnd == Animation)
{
//PikaSaveSettingAnimationEnd动画播放完成
if (Animation->PikaqiuGetAnimationState() == PikaqiuEAnimationState::BST_QuitMeun)
{
PikaGetBoxList()->SetVisibility(ESlateVisibility::Hidden);
}
}
}
void UPikaUIMainHall::OnAnimationStarted_Implementation(const UWidgetAnimation* Animation)
{
}PikaUIReadAndWrite.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "PikaUISaveLoadBar.h"
#include "ScrollBox.h"
#include "PikaUIGameMenu.h"
#include "TextBlock.h"
#include "PikaUIReadAndWrite.generated.h"
class UPikaUIMainHall;
class UPikaUIGameMenu;
namespace PikaEClickedSaveType
{
enum Type
{
CST_UnClicked,
CST_HasStruck,
CST_Max
};
}
enum class PikaETDButtonType : uint8
{
LoadingGame,
SaveGame,
Max
};
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUIReadAndWrite : public UPikaUIWidgetBase
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaLoadingListTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaReturnListTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaReturnListButtonName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaLoadingGameButtonName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaSaveListButtonName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
TSubclassOf<UPikaUISaveLoadBar> PikaSaveLoadBarClass;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FText PikaCoverText;
//准备读取该进度
uint8 PikaIsLoading : 1;
//当前类型
PikaETDButtonType PikaButtonType;
public:
//存储界面上,按钮是显示存储还是载入
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
TArray<FText> Pika_WText;
UPikaUIReadAndWrite();
//checkBox存储类型,表示是否产生了checkBox的点击事件
TEnumAsByte<PikaEClickedSaveType::Type> PikaClickedSaveType;
//当前游戏存储区域Bar号码 (SaveBarNumber)
int32 PikaCurrentSaveGameBoxNumber;
//存储游戏的编号
int32 PikaCurrentGameArchiveNumber;
//调用去初始化我们的UI
virtual void PikaDrawUIToScreen()override;
virtual void PikaSetWarningWindowsState(bool IsVisibles, float StateTime = 0, FString MyWidget = "", TEnumAsByte<PikaEButtonSureType::Type> MyButtonSureType = PikaEButtonSureType::BST_None) override;
//设置显示字体
void PikaSetButtonText(FText Text_A);
void PikaReadArchive();
//负责打印GameLOG
virtual void PikaLogPrintf(FString MyString) override;
virtual void PikaOnClickedWidget(UWidget* MyWidget) override;
//存储游戏,参数为存储内容时是覆盖操作还是新建操作
void PikaSaveArchiveSlot(bool IsCopy);
FORCEINLINE UPikaUIMainHall* PikaGetMainHall()const { return PikaMainHall; }
FORCEINLINE UPikaUIGameMenu* PikaGetGameMenu()const { return PikaUIGameMenu; }
void PikaSetMainHall(UPikaUIMainHall* NewWidget) { PikaMainHall = NewWidget; }
void PikaSetGameMenu(UPikaUIGameMenu* NewWidget) { PikaUIGameMenu = NewWidget; }
//checkBox显示
void PikaShowOneClickButton(int32 NumberBIndex);
void PikaShowOneClickButton();
//设置按键类型
void PikaSetNewButtonType(PikaETDButtonType NewButtonType) { PikaButtonType = NewButtonType; }
//清除第几号存储
void PikaClearNumberSave(int32 CurrentDelectNumber = INDEX_NONE);
private:
UPikaUIMainHall* PikaMainHall;
UButton* PikaReturnListButton;
UButton* PikaLoadingGameButton;
UTextBlock* PikaReturnListText;
UTextBlock* PikaLoadingListText;
UScrollBox* PikaSaveListButton;
TArray<UPikaUISaveLoadBar*> PikaSaveLoadBarArrayEnter;
UPikaUIGameMenu* PikaUIGameMenu;
};PikaUIReadAndWrite.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUIReadAndWrite.h"
UPikaUIReadAndWrite::UPikaUIReadAndWrite()
{
PikaCurrentGameArchiveNumber = INDEX_NONE;
PikaCurrentSaveGameBoxNumber = INDEX_NONE;
PikaIsLoading = false;
PikaButtonType = PikaETDButtonType::Max;
PikaClickedSaveType = PikaEClickedSaveType::CST_UnClicked;
}
void UPikaUIReadAndWrite::PikaDrawUIToScreen()
{
PikaReturnListButton = PikaGetButtonFromBlueprint(PikaReturnListButtonName);
PikaLoadingGameButton = PikaGetButtonFromBlueprint(PikaLoadingGameButtonName);
PikaSaveListButton = Cast<UScrollBox>(PikaqiuGetBlueprintWidget(PikaSaveListButtonName));
PikaReturnListText = Cast<UTextBlock>(GetWidgetFromName(PikaReturnListTextName));
PikaLoadingListText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaLoadingListTextName));
//读取存档
PikaReadArchive();
}
void UPikaUIReadAndWrite::PikaSetWarningWindowsState(bool IsVisibles, float StateTime /*= 0*/, FString MyWidget /*= ""*/, TEnumAsByte<PikaEButtonSureType::Type> MyButtonSureType /*= PikaEButtonSureType::BST_None*/)
{
if (PikaMainHall)
{
PikaMainHall->PikaSetWarningWindowsState(IsVisibles, StateTime, MyWidget, MyButtonSureType);
}
if (PikaUIGameMenu)
{
PikaUIGameMenu->PikaSetWarningWindowsState(IsVisibles, StateTime, MyWidget, MyButtonSureType);
}
}
void UPikaUIReadAndWrite::PikaSetButtonText(FText Text_A)
{
if (PikaLoadingListText)
PikaLoadingListText->SetText(Text_A);
}
void UPikaUIReadAndWrite::PikaReadArchive()
{
if (PikaGetGameInstance() && GetWorld())
{
//创建20可以存档的区域
if (PikaSaveLoadBarClass)
{
//注册
for (int32 i = 0; i < Pika_SAVE_SaveBarNumber; i++)
{
UPikaUISaveLoadBar* PikaSlotBar = CreateWidget<UPikaUISaveLoadBar>(GetWorld(), PikaSaveLoadBarClass);
if (PikaSlotBar)
{
//初始化绘制信息
PikaSlotBar->PikaDrawUIToScreen();
//显示默认的存储的信息
PikaSlotBar->PikaClearSaveGameSlot();
//传递自己
PikaSlotBar->PikaSetReadAndWrite(this);
//存储游戏序列
PikaSlotBar->PikaSaveGameBoxNumber = i;
//添加如容器
PikaSaveLoadBarArrayEnter.Add(PikaSlotBar);
//添加到列表
if (PikaSaveListButton)
{
PikaSaveListButton->AddChild(PikaSlotBar);
}
else
{
PIKA_LOG(FString::Printf(TEXT("SaveListButton == NULL ,Failed to create %i storage"), i));
}
}
else
{
PIKA_LOG(FString::Printf(TEXT("Failed to create %i storage"), i));
}
}
}
//游戏开始读取我们的存档
if (PIKA_ISSAVE_SLOT(PIKA_SAVE_SLOT_NAME, 0))
{
//读取游戏存档在本地,并且验证存档
UPikaGameSaveData* PikaGameSaveData = PikaGetGameInstance()->PikaVerificationSaveData();
//获取存档信息
if (PikaGameSaveData)
{
int32 PikaCurrentIndex = 0;
//用读取的本地存档还原bar里的数据
for (int32 PikaCurrentSaveValue : PikaGameSaveData->PikaReadGameData.PikaSaveGameBoxNumberArray)
{
if (PikaCurrentSaveValue != INDEX_NONE)
{
if (PikaSaveLoadBarArrayEnter.IsValidIndex(PikaCurrentIndex))
{
PikaSaveLoadBarArrayEnter[PikaCurrentIndex]->PikaSetSaveGameText(PikaCurrentSaveValue, FText::FromString(PikaGameSaveData->PikaReadGameData.PikaSaveDataText[PikaCurrentSaveValue]));
}
else
{
PIKA_LOG(FString::Printf(TEXT("Nothingness %i"), PikaCurrentIndex));
}
}
PikaCurrentIndex++;
}
}
else
{
PIKA_LOG("GameSaveData read failed!!");
}
}
else
{
PIKA_LOG("There is no stored data!!");
}
}
else
{
PIKA_LOG("Not obtained TowerDefenceGameInstance!!");
}
}
void UPikaUIReadAndWrite::PikaLogPrintf(FString MyString)
{
}
//通过PikaGetButtonFromBlueprint获取的Button,在本类的基类UPikaUIWidgetBase里绑定
void UPikaUIReadAndWrite::PikaOnClickedWidget(UWidget* MyWidget)
{
if (MyWidget == PikaLoadingGameButton)
{
check(PikaLoadingListText);
//必须是敲击状态
if (PikaClickedSaveType == PikaEClickedSaveType::CST_HasStruck)
{
//是读取界面
if (PikaButtonType == PikaETDButtonType::LoadingGame)
{
if (PikaGetGameInstance())
{
//检查当选中的PikaUISaveLoadBar里,是否能读取成功
PikaIsLoading = PikaGetGameInstance()->PikaIsLoadingGameData(PikaCurrentGameArchiveNumber);
if (PikaIsLoading)
{
//存档读取成功
PIKA_LOG("Loading Successfully");
//激活关闭菜单功能
if (PikaGetMainHall() && PikaGetMainHall()->PikaGetBoxList())
{
//GetMainHall()->ClickedMenuFadeInAndFadeOut(false, EAnimationState::EA_ReadyLoading);
//设置界面不可敲击
PikaGetMainHall()->SetVisibility(ESlateVisibility::HitTestInvisible);
}
/*//播放开始游戏动画
if (GetTowerDefenceHallGameMode())
{
GetTowerDefenceHallGameMode()->PlayCurrentCameraAnimation(ECameraArray::Camera_IntoGame, EMatineeArray::Matinee_Max, TD_CAMARE_BLENDTIME + 1);
}*/
//存储读档序列
PikaGetGameInstance()->PikaTmpArchive = PikaCurrentGameArchiveNumber;
if (GetWorld())
UGameplayStatics::OpenLevel(GetWorld(), "PikaGodStone_Level_Main_01");
}
else
{
PIKA_LOG("Loading Failure");
}
}
else
{
PIKA_LOG("GetTowerDefenceGameInstance() = NULL!");
}
}//是存储界面
else if (PikaButtonType == PikaETDButtonType::SaveGame)
{
if (PikaGetPlayerController() && PikaGetGameInstance())
{
//游戏存储
if (PikaCurrentGameArchiveNumber == INDEX_NONE)//存储到一个空的存储条里面
{
PikaSaveArchiveSlot(false);
}
else//需要覆盖一个存档,这个时候会跳出一个弹窗,确定是否要覆盖
{
PikaSaveArchiveSlot(true);
/*//打开在大厅
if (GetMainHall() && GetMainHall()->GetGameWarning())
{
//弹窗状态设置为显示
SetWarningWindowsState(true, 0, FString::Printf(TEXT("%s # %i?"), *CoverText.ToString(), CurrentGameArchiveNumber), EButtonSureType::BST_CoverSave);
}
//打开在游戏
if (GetGameMenu() && GetGameMenu()->GetMianScreen() && GetGameMenu()->GetMianScreen()->GetGameWarning())
{
SetWarningWindowsState(true, 0, FString::Printf(TEXT("%s # %i?"), *CoverText.ToString(), CurrentGameArchiveNumber), EButtonSureType::BST_CoverSave);
}*/
}
}
else
{
PIKA_LOG("GetTowerDefencePlayerController() = NULL!");
}
}
}
}
if (MyWidget == PikaReturnListButton)
{
//取消
//隐藏自己
if (PikaUIGameMenu)
PikaUIGameMenu->PikaGetMainInterface()->PikaGetBoxSaveGameArray()->SetVisibility(ESlateVisibility::Hidden);;
//隐藏自己
if (PikaMainHall)
PikaMainHall->PikaGetBoxList()->SetVisibility(ESlateVisibility::Hidden);;
/*if (TDButtonType == ETDButtonType::LoadingGame)
{
if (GetMainHall() && GetMainHall()->GetBoxList())
{
GetMainHall()->ClickedMenuFadeInAndFadeOut(false);
}
}
else if (TDButtonType == ETDButtonType::SaveGame)
{
if (GetGameMenu() && GetGameMenu()->GetMianScreen())
{
GetGameMenu()->GetMianScreen()->ClickedMenuFadeInAndFadeOut(false);
}
}*/
}
}
//存储游戏,参数为存储内容时是覆盖操作还是新建操作
void UPikaUIReadAndWrite::PikaSaveArchiveSlot(bool IsCopy)
{
//标记存档序列
if (PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon)
PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon->PikaSaveCount++;
if (IsCopy)
{
//覆盖,指定要覆盖的存档
//PikaCurrentSaveGameBoxNumber的值为点击了某个存档bar类PikaUISaveLoadBar后,在PikaUISaveLoadBar类里设置的
//------------------------------------
//在已有的存档上进行覆盖存档时,由PikaUIReadAndWrite::PikaReadArchive读取的本地存档,
//并将PikaCurrentGameArchiveNumber的值保存在PikaUISaveLoadBar里的PikaGameArchiveNumber属性里
//点击某个PikaUISaveLoadBar类的按钮后,
//通过读取PikaUISaveLoadBar类里的PikaGameArchiveNumber属性就能得到PikaCurrentGameArchiveNumber的值
bool PikaIsSave = PikaGetPlayerController()->PikaSaveGameData(PikaFSaveSlotDataChannel(PikaCurrentSaveGameBoxNumber, PikaCurrentGameArchiveNumber));
if (PikaIsSave)
{
//更新显示日期
//上面的PikaSaveGameData成功时,新的日期已经存档,此处再次读取存档,用来更新界面
FText PikaNewText = PikaGetPlayerController()->PikaGetSaveInformation(PikaCurrentGameArchiveNumber);
if (PikaCurrentSaveGameBoxNumber >= 0 && PikaCurrentSaveGameBoxNumber < PikaSaveLoadBarArrayEnter.Num())
{
PikaSaveLoadBarArrayEnter[PikaCurrentSaveGameBoxNumber]->PikaSetSaveGameText(PikaCurrentGameArchiveNumber, PikaNewText);
PikaSaveLoadBarArrayEnter[PikaCurrentSaveGameBoxNumber]->PikaUpdateClickState();
}
PIKA_LOG("Save Successfully");
}
else
{
PIKA_LOG("Save Failure");
}
}
else//新建
{
//PikaGetCurrentSaveArchiveNumber:获取当前存档的编号
int32 PikaCurrenMaxArchiveNumber = PikaGetGameInstance()->PikaGetCurrentSaveArchiveNumber();
if (PikaCurrenMaxArchiveNumber == INDEX_NONE)
{
PIKA_LOG(" GetTowerDefenceGameInstance()->GetCurrentSaveArchiveNumber() = INDEX_NONE,Is error!!");
return;
}
//将最新的存档数PikaCurrenMaxArchiveNumber作为下一个存档的一个序列号角标
//PikaCurrentSaveGameBoxNumber的值为点击了某个存档bar类PikaUISaveLoadBar后,在PikaUISaveLoadBar类里设置的
bool PikaIsSave = PikaGetPlayerController()->PikaSaveGameData(PikaFSaveSlotDataChannel(PikaCurrentSaveGameBoxNumber, PikaCurrenMaxArchiveNumber));
if (PikaIsSave)
{
//更新显示日期
FText PikaNewTDText = PikaGetPlayerController()->PikaGetSaveInformation(PikaCurrenMaxArchiveNumber);
if (PikaCurrentSaveGameBoxNumber >= 0 && PikaCurrentSaveGameBoxNumber < PikaSaveLoadBarArrayEnter.Num())
{
PikaSaveLoadBarArrayEnter[PikaCurrentSaveGameBoxNumber]->PikaSetSaveGameText(PikaCurrenMaxArchiveNumber, PikaNewTDText);
PikaSaveLoadBarArrayEnter[PikaCurrentSaveGameBoxNumber]->PikaUpdateClickState();
}
PIKA_LOG("Save Successfully");
}
else
{
PIKA_LOG("Save Failure");
}
}
}
//checkBox显示
void UPikaUIReadAndWrite::PikaShowOneClickButton(int32 NumberBIndex)
{
for (int32 i = 0; i < PikaSaveLoadBarArrayEnter.Num(); i++)
{
if (PikaSaveLoadBarArrayEnter[i]->PikaSaveGameBoxNumber == NumberBIndex)
PikaSaveLoadBarArrayEnter[i]->PikaShowOneCheckBox(true);
else
PikaSaveLoadBarArrayEnter[i]->PikaShowOneCheckBox(false);
}
}
//checkBox显示
void UPikaUIReadAndWrite::PikaShowOneClickButton()
{
for (int32 i = 0; i < PikaSaveLoadBarArrayEnter.Num(); i++)
{
if (PikaSaveLoadBarArrayEnter.IsValidIndex(i))
{
PikaSaveLoadBarArrayEnter[i]->PikaShowOneCheckBox(false);
}
}
}
//还原
void UPikaUIReadAndWrite::PikaClearNumberSave(int32 CurrentDelectNumber /*= INDEX_NONE*/)
{
for (int32 i = 0; i < PikaSaveLoadBarArrayEnter.Num(); i++)
{
if (PikaSaveLoadBarArrayEnter.IsValidIndex(i))
{
if (PikaSaveLoadBarArrayEnter[i]->PikaGameArchiveNumber == CurrentDelectNumber)
{
//还原数据显示
PikaSaveLoadBarArrayEnter[i]->PikaClearSaveGameSlot();
break;
}
}
}
PikaCurrentSaveGameBoxNumber = INDEX_NONE;
PikaCurrentGameArchiveNumber = INDEX_NONE;
PikaClickedSaveType = PikaEClickedSaveType::CST_UnClicked;
PikaShowOneClickButton();
}PikaUISaveLoadBar.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "TextBlock.h"
#include "CheckBox.h"
#include "Button.h"
#include "PikaUISaveLoadBar.generated.h"
class UPikaUIReadAndWrite;
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUISaveLoadBar : public UPikaUIWidgetBase
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaGameTextBlockName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaClickedBoxButtonName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaSaveGameDataBlockName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaDeleteMyDataButtonName;
//删除存档时,警告框上显示的文件
//确定删除该存档吗,皮卡~~~
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FText PikadeleteText;
//无存档时的默认显示文本
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FText PikaDefaultNoDataText;
public:
//游戏bar序列,在PikaUIReadAndWrite::PikaReadArchive里循环生成本类时,将循环的index存入该值
int32 PikaSaveGameBoxNumber;
//游戏存储后,本存档存档编号,默认值为-1
int32 PikaGameArchiveNumber;
UPikaUISaveLoadBar();
//调用去初始化我们的UI
virtual void PikaDrawUIToScreen() override;
//负责打印GameLOG
virtual void PikaLogPrintf(FString MyString) override;
UFUNCTION()
virtual void PikaClickedCheckBox(UWidget* MyWidget, bool ClickedWidget);
void PikaShowOneCheckBox(bool ClickedWidget);
void PikaUpdateClickState();
virtual void PikaSetWarningWindowsState(bool IsVisibles, float StateTime = 0, FString MyWidget = "", TEnumAsByte<PikaEButtonSureType::Type> MyButtonSureType = PikaEButtonSureType::BST_None) override;
virtual void PikaOnClickedWidget(UWidget* MyWidget) override;
//设置字体数据信息显示
void PikaSetSaveGameText(int32 IndexSaveData, FText MySaveText);
//清除游戏存储显示节点
void PikaClearSaveGameSlot();
void PikaSetReadAndWrite(UPikaUIReadAndWrite* NewReadAndWrite) { PikaReadAndWrite = NewReadAndWrite; }
private:
UTextBlock* PikaGameTextBlock;
UTextBlock* PikaSaveGameDataBlock;
UButton* PikaDeleteMyDataButton;
UCheckBox* PikaClickedBoxButton;
UPikaUIReadAndWrite* PikaReadAndWrite;
};PikaUISaveLoadBar.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUISaveLoadBar.h"
UPikaUISaveLoadBar::UPikaUISaveLoadBar()
{
PikaGameArchiveNumber = -1;
PikaSaveGameBoxNumber = -1;
}
void UPikaUISaveLoadBar::PikaDrawUIToScreen()
{
PikaGameTextBlock = Cast<UTextBlock>(GetWidgetFromName(PikaGameTextBlockName));
PikaSaveGameDataBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaSaveGameDataBlockName));
PikaDeleteMyDataButton = PikaGetButtonFromBlueprint(PikaDeleteMyDataButtonName);
PikaClickedBoxButton = Cast<UCheckBox>(PikaqiuGetBlueprintWidget(PikaClickedBoxButtonName));
//绑定按键
if (PikaClickedBoxButton)
PikaClickedBoxButton->PikaqiuOnCheckStateChanged.AddDynamic(this, &UPikaUISaveLoadBar::PikaClickedCheckBox);
}
void UPikaUISaveLoadBar::PikaLogPrintf(FString MyString)
{
}
void UPikaUISaveLoadBar::PikaClickedCheckBox(UWidget* MyWidget, bool ClickedWidget)
{
if (MyWidget == PikaClickedBoxButton)
{
if (PikaReadAndWrite)
{
//显示当前游戏敲击显示
//PikaSaveGameBoxNumber的值为PikaUIReadAndWrite类循环加载本类里时用循环的index设置的
PikaReadAndWrite->PikaShowOneClickButton(PikaSaveGameBoxNumber);
//设置当前存储游戏的载体数字
PikaUpdateClickState();
//打印选择第几个存储
PIKA_LOG(FString::Printf(TEXT("Select archive # %i"), PikaGameArchiveNumber));
}
}
}
void UPikaUISaveLoadBar::PikaShowOneCheckBox(bool ClickedWidget)
{
if (PikaClickedBoxButton)
{
if (ClickedWidget)
PikaClickedBoxButton->SetCheckedState(ECheckBoxState::Checked);
else
PikaClickedBoxButton->SetCheckedState(ECheckBoxState::Unchecked);
}
}
void UPikaUISaveLoadBar::PikaUpdateClickState()
{
if (PikaReadAndWrite)
{
PikaReadAndWrite->PikaCurrentSaveGameBoxNumber = PikaSaveGameBoxNumber;
//游戏存储后,本存档存档编号,默认值为-1
//PikaGameArchiveNumber该值由PikaUIReadAndWrite类调用PikaDrawUIToScreen函数进行加载时,
//由PikaUIReadAndWrite::PikaReadArchive函数调用本类里的PikaSetSaveGameText函数进行设置
//PikaUIReadAndWrite::PikaSaveArchiveSlot的新建逻辑时,PikaGameArchiveNumber为-1
PikaReadAndWrite->PikaCurrentGameArchiveNumber = PikaGameArchiveNumber;
PikaReadAndWrite->PikaClickedSaveType = PikaEClickedSaveType::CST_HasStruck;
}
}
void UPikaUISaveLoadBar::PikaSetWarningWindowsState(bool IsVisibles, float StateTime /*= 0*/, FString MyWidget /*= ""*/, TEnumAsByte<PikaEButtonSureType::Type> MyButtonSureType /*= PikaEButtonSureType::BST_None*/)
{
if (PikaReadAndWrite)
{
PikaReadAndWrite->PikaSetWarningWindowsState(IsVisibles, StateTime, MyWidget, MyButtonSureType);
}
}
void UPikaUISaveLoadBar::PikaOnClickedWidget(UWidget* MyWidget)
{
if (MyWidget == PikaDeleteMyDataButton)
{
if (PikaGameArchiveNumber != INDEX_NONE)
{
//游戏大厅
if (PikaReadAndWrite &&
PikaReadAndWrite->PikaGetMainHall() &&
PikaReadAndWrite->PikaGetMainHall()->PikaGetGameWarning())
{
//弹窗状态设置为显示
PikaSetWarningWindowsState(true, 0, FString::Printf(TEXT("%s %i"), *PikadeleteText.ToString(), PikaGameArchiveNumber), PikaEButtonSureType::BST_DeleteSave);
//设置是哪个控件
PikaReadAndWrite->PikaGetMainHall()->PikaGetGameWarning()->PikaCurrentGameArchiveNumber = PikaGameArchiveNumber;
PikaReadAndWrite->PikaGetMainHall()->PikaGetGameWarning()->PikaSetGameButtonSureType(PikaEButtonSureType::BST_DeleteSave);
//播放背景模糊动画
PikaReadAndWrite->PikaGetMainHall()->PikaWindowsFadeInAndFadeOut(true);
}
//游戏
if (PikaReadAndWrite &&
PikaReadAndWrite->PikaGetGameMenu() &&
PikaReadAndWrite->PikaGetGameMenu()->PikaGetMainInterface() &&
PikaReadAndWrite->PikaGetGameMenu()->PikaGetMainInterface()->PikaGetGameWarning())
{
//弹窗状态设置为显示
PikaSetWarningWindowsState(true, 0, FString::Printf(TEXT("%s %i"), *PikadeleteText.ToString(), PikaGameArchiveNumber), PikaEButtonSureType::BST_DeleteSave);
//设置是哪个控件
PikaReadAndWrite->PikaGetGameMenu()->PikaGetMainInterface()->PikaGetGameWarning()->PikaCurrentGameArchiveNumber = PikaGameArchiveNumber;
PikaReadAndWrite->PikaGetGameMenu()->PikaGetMainInterface()->PikaGetGameWarning()->PikaSetGameButtonSureType(PikaEButtonSureType::BST_DeleteSave);
}
}
else
{
PIKA_LOG("No archive");
}
}
}
//设置字体数据信息显示
void UPikaUISaveLoadBar::PikaSetSaveGameText(int32 IndexSaveData, FText MySaveText)
{
//赋值我们的存档序列
PikaGameArchiveNumber = IndexSaveData;
//第几个存档
if (PikaGameTextBlock)
PikaGameTextBlock->SetText(FText::FromString(FString::Printf(TEXT("Storage number %i"), IndexSaveData)));
//存档日期
if (PikaSaveGameDataBlock)
PikaSaveGameDataBlock->SetText(MySaveText);
}
void UPikaUISaveLoadBar::PikaClearSaveGameSlot()
{
if(!(PikaDefaultNoDataText.IsEmpty()))
PikaSetSaveGameText(INDEX_NONE, PikaDefaultNoDataText);
}PikaUITowerInfo.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "TextBlock.h"
#include "MultiLineEditableTextBox.h"
#include "PikaUITowerInfo.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUITowerInfo : public UPikaUIWidgetBase
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaCharacterNameBlockName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaComsumeGlodBlockName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaCharacterHealthBlockName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaCharacterAttackBlockName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaCharacterArmorBlockName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaCharacterAttackSpeedBlockName;
UPROPERTY(EditDefaultsOnly, Category = UI)
FName PikaIntroductionName;
public:
FPikaCharacterInformationWidget* PikaCharacterInformationWidget;
//作为初始化实例
virtual void PikaDrawUIToScreen() override;
//只要角色值变动机会更新
void PikaUpdateCharacterInformation();
private:
UTextBlock* PikaCharacterNameBlock;
UTextBlock* PikaComsumeGlodBlock;
UTextBlock* PikaCharacterHealthBlock;
UTextBlock* PikaCharacterAttackBlock;
UTextBlock* PikaCharacterArmorBlock;
UTextBlock* PikaCharacterAttackSpeedBlock;
UMultiLineEditableTextBox* PikaIntroduction;
protected:
//virtual void NativeOnMouseLeave(const FPointerEvent& InMouseEvent)override;
};PikaUITowerInfo.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUITowerInfo.h"
void UPikaUITowerInfo::PikaDrawUIToScreen()
{
if (!PikaCharacterNameBlock)
PikaCharacterNameBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterNameBlockName));
if (!PikaComsumeGlodBlock)
PikaComsumeGlodBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaComsumeGlodBlockName));
if (!PikaCharacterHealthBlock)
PikaCharacterHealthBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterHealthBlockName));
if (!PikaCharacterAttackBlock)
PikaCharacterAttackBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterAttackBlockName));
if (!PikaCharacterArmorBlock)
PikaCharacterArmorBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterArmorBlockName));
if (!PikaCharacterAttackSpeedBlock)
PikaCharacterAttackSpeedBlock = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaCharacterAttackSpeedBlockName));
if (!PikaIntroduction)
PikaIntroduction = Cast<UMultiLineEditableTextBox>(PikaqiuGetBlueprintWidget(PikaIntroductionName));
}
void UPikaUITowerInfo::PikaUpdateCharacterInformation()
{
if (PikaCharacterInformationWidget)
{
if (PikaCharacterNameBlock)
PikaCharacterNameBlock->SetText(FText::FromName(PikaCharacterInformationWidget->PikaCharacterName));
if (PikaComsumeGlodBlock)
PikaComsumeGlodBlock->SetText(FText::AsNumber(PikaCharacterInformationWidget->PikaComsumeGlod));
if (PikaCharacterHealthBlock)
PikaCharacterHealthBlock->SetText(FText::AsNumber(PikaCharacterInformationWidget->PikaCharacterHealth));
if (PikaCharacterAttackBlock)
PikaCharacterAttackBlock->SetText(FText::AsNumber(PikaCharacterInformationWidget->PikaCharacterAttack));
if (PikaCharacterArmorBlock)
PikaCharacterArmorBlock->SetText(FText::AsNumber(PikaCharacterInformationWidget->PikaCharacterArmor));
if (PikaCharacterAttackSpeedBlock)
PikaCharacterAttackSpeedBlock->SetText(FText::AsNumber(PikaCharacterInformationWidget->PikaCharacterAttackSpeed));
if (PikaIntroduction)
PikaIntroduction->SetText(PikaCharacterInformationWidget->PikaCharacterIntroduction);
}
}PikaUIWebBrowser.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "PikaUIWebBrowser.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUIWebBrowser : public UPikaUIWidgetBase
{
GENERATED_BODY()
};PikaUIWebBrowser.cpp
// Fill out your copyright notice in the Description page of Project Settings. #include "Public/PikaUIWebBrowser.h"
PikaUIWidgetBase.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Button.h"
#include "PikaUIData.h"
#include "SizeBox.h"
#include "Public/PikaGodStonePlayerController.h"
#include "PikaGameSaveData.h"
#include "Slider.h"
#include "ComboBoxString.h"
#include "CheckBox.h"
#include "PikaUIWidgetBase.generated.h"
//日志打印
#define PikaLOG(Cen) PikaLogPrintf(Cen)
UENUM()
namespace PikaEButtonSureType
{
enum Type
{
BST_None,
BST_DeleteSave, //删除游戏存储
BST_CoverSave, //覆盖游戏存储
BST_QuitMeun, //退到主菜单
BST_QuitGame,
BST_MAX
};
}
//面板Box类型
namespace PikaBoxListType
{
//枚举的定义顺序对应于UPikaUIMainHall::PikaDrawUIToScreen里添加到PikaBoxList的顺序
enum Type
{
BOXLIST_SaveList,//对应PikaBoxList里第一个被添加进去的控件
BOXLIST_GameSettings,//对应PikaBoxList里第二个被添加进去的控件
BOXLIST_Max,
};
}
//作为角色的基础信息现实
USTRUCT()
struct FPikaCharacterInformationWidget
{
GENERATED_BODY()
//角色名字
FName PikaCharacterName;
//金币消费
int32 PikaComsumeGlod;
//生命值
float PikaCharacterHealth;
//攻击力
float PikaCharacterAttack;
//防御力
float PikaCharacterArmor;
//攻击速度
float PikaCharacterAttackSpeed;
//角色简介
FText PikaCharacterIntroduction;
FPikaCharacterInformationWidget() :
PikaComsumeGlod(0),
PikaCharacterHealth(0),
PikaCharacterAttack(0),
PikaCharacterArmor(0),
PikaCharacterAttackSpeed(0),
PikaCharacterIntroduction(FText::FromString("NoData")),
PikaCharacterName(FName(*FString("None")))
{}
//重载等号操作符
FORCEINLINE FPikaCharacterInformationWidget& operator=(const FPikaCharacterInformationWidget& CharacterInformationWidget)
{
PikaComsumeGlod = CharacterInformationWidget.PikaComsumeGlod;
PikaCharacterHealth = CharacterInformationWidget.PikaCharacterHealth;
PikaCharacterAttack = CharacterInformationWidget.PikaCharacterAttack;
PikaCharacterArmor = CharacterInformationWidget.PikaCharacterArmor;
PikaCharacterAttackSpeed = CharacterInformationWidget.PikaCharacterAttackSpeed;
PikaCharacterName = CharacterInformationWidget.PikaCharacterName;
PikaCharacterIntroduction = CharacterInformationWidget.PikaCharacterIntroduction;
return *this;
}
FORCEINLINE bool operator==(const FPikaCharacterInformationWidget& NewCharacterInformation)
{
return (PikaComsumeGlod == NewCharacterInformation.PikaComsumeGlod &&
PikaCharacterHealth == NewCharacterInformation.PikaCharacterHealth &&
PikaCharacterAttack == NewCharacterInformation.PikaCharacterAttack &&
PikaCharacterArmor == NewCharacterInformation.PikaCharacterArmor &&
PikaCharacterAttackSpeed == NewCharacterInformation.PikaCharacterAttackSpeed &&
PikaCharacterName == NewCharacterInformation.PikaCharacterName);
}
//还原出厂设置
void PikaClearCharacterInformationWidget()
{
PikaComsumeGlod = 0;
PikaCharacterHealth = 0;
PikaCharacterAttack = 0;
PikaCharacterArmor = 0;
PikaCharacterAttackSpeed = 0;
PikaCharacterName = FName(*FString("None"));
PikaCharacterIntroduction = FText::FromString("NoData");
}
};
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaUIWidgetBase : public UUserWidget
{
GENERATED_BODY()
public:
//存储弹窗类型
UPROPERTY()
TEnumAsByte<PikaEButtonSureType::Type> PikaGameButtonSureType;
//设置弹窗类型
//ButtonSureType: 弹窗类型
void PikaSetGameButtonSureType(TEnumAsByte<PikaEButtonSureType::Type> MewButtonSureType);
//UIData的指针
UPikaUIData * PikaUIDataPtr;
//直接获取Button
UButton * PikaGetButtonFromBlueprint(FName BlueprintWidgetName) const;
UButton * PikaGetButtonFromBlueprint(FString BlueprintWidgetName) const;
USlider* PikaGetSliderFormBlueprint(FString BlueprintWidgetName) const;
USlider* PikaGetSliderFormBlueprint(FName BlueprintWidgetName) const;
UFUNCTION()
virtual void PikaChangedValue(float Val) {}
virtual void PikaUpdateAttibe() {}
UComboBoxString* PikaGetComboBoxStringFormBlueprint(FName BlueprintWidgetName) const;
UComboBoxString* PikaGetComboBoxStringFormBlueprint(FString BlueprintWidgetName) const;
UCheckBox* PikaGetCheckBoxFormBlueprint(FName BlueprintWidgetName) const;
UCheckBox* PikaGetCheckBoxFormBlueprint(FString BlueprintWidgetName) const;
UFUNCTION()
virtual void PikaSelectionChangedBySelf(UWidget* MyWidget, FString SelectedItem, ESelectInfo::Type SelectionType) {}
//调用后去初始化自已的UI,需要手动调用
//相当于BeginPlay,用于解决BeginPlay执行时,有些资源可能还没加载完成的问题
//继承自本类的UI类里,会在主界面类里手动调用本函数
virtual void PikaDrawUIToScreen() {}
//负责打印GameLOG
virtual void PikaLogPrintf(FString MyString) {}
void PikaAddSizeBox(USizeBox* TargetWidget , UWidget* BaseWidget);
//获取PlayerController
APikaGodStonePlayerController* PikaGetPlayerController();
//获取PlayerState
APikaGodStonePlayerState* PikaGetPlayerState();
//获取GameInstance
UPikaGodStoneGameInstance* PikaGetGameInstance();
//获取SaveGameData
FPikaGodStoneSaveGameData* PikaGetSaveGameData();
///////////////////////////////Button///////////////////////////////////////////
UFUNCTION()
virtual void PikaOnClickedWidget(UWidget* MyWidget) {}
UFUNCTION()
virtual void PikaOnHoveredWidget(UWidget* CurrentButton) {}
UFUNCTION()
virtual void PikaOnUnHoveredWidget() {}
UFUNCTION()
virtual void PikaClickedCheckBox(UWidget* MyWidget, bool ClickedWidget) {}
virtual void PikaSetWarningWindowsState(bool IsVisibles, float StateTime = 0, FString MyWidget = "", TEnumAsByte<PikaEButtonSureType::Type> MyButtonSureType = PikaEButtonSureType::BST_None) {}
};PikaUIWidgetBase.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaUIWidgetBase.h"
void UPikaUIWidgetBase::PikaSetGameButtonSureType(TEnumAsByte<PikaEButtonSureType::Type> MewButtonSureType)
{
PikaGameButtonSureType = MewButtonSureType;
}
UButton * UPikaUIWidgetBase::PikaGetButtonFromBlueprint(FName BlueprintWidgetName) const
{
/*
* 修改了引擎后,除了Button,所有widget都可以用Cast进行强转
*/
UButton * PikaMyButton = Cast<UButton>(PikaqiuGetBlueprintWidget(BlueprintWidgetName));
if (PikaMyButton)
{
PikaMyButton->PikaqiuClickedWidget.AddDynamic(this , &UPikaUIWidgetBase::PikaOnClickedWidget);
PikaMyButton->PikaqiuHoverWidget.AddDynamic(this, &UPikaUIWidgetBase::PikaOnHoveredWidget);
PikaMyButton->OnUnhovered.AddDynamic(this, &UPikaUIWidgetBase::PikaOnUnHoveredWidget);
}
return PikaMyButton;
}
UButton * UPikaUIWidgetBase::PikaGetButtonFromBlueprint(FString BlueprintWidgetName) const
{
UButton * PikaMyButton = Cast<UButton>(PikaqiuGetBlueprintWidget(BlueprintWidgetName));
if (PikaMyButton)
{
PikaMyButton->PikaqiuClickedWidget.AddDynamic(this, &UPikaUIWidgetBase::PikaOnClickedWidget);
PikaMyButton->PikaqiuHoverWidget.AddDynamic(this, &UPikaUIWidgetBase::PikaOnHoveredWidget);
PikaMyButton->OnUnhovered.AddDynamic(this, &UPikaUIWidgetBase::PikaOnUnHoveredWidget);
}
return PikaMyButton;
}
USlider* UPikaUIWidgetBase::PikaGetSliderFormBlueprint(FString BlueprintWidgetName) const
{
USlider* TmpSlider = Cast<USlider>(PikaqiuGetBlueprintWidget(BlueprintWidgetName));
if (TmpSlider)
{
TmpSlider->OnValueChanged.AddDynamic(this, &UPikaUIWidgetBase::PikaChangedValue);
}
return TmpSlider;
}
USlider* UPikaUIWidgetBase::PikaGetSliderFormBlueprint(FName BlueprintWidgetName) const
{
USlider* TmpSlider = Cast<USlider>(PikaqiuGetBlueprintWidget(BlueprintWidgetName));
if (TmpSlider)
{
TmpSlider->OnValueChanged.AddDynamic(this, &UPikaUIWidgetBase::PikaChangedValue);
}
return TmpSlider;
}
UComboBoxString* UPikaUIWidgetBase::PikaGetComboBoxStringFormBlueprint(FName BlueprintWidgetName) const
{
UComboBoxString* PikaComboBoxString = Cast<UComboBoxString>(PikaqiuGetBlueprintWidget(BlueprintWidgetName));
if (PikaComboBoxString)
{
PikaComboBoxString->PikaqiuOnSelectionChangedBySelf.AddDynamic(this, &UPikaUIWidgetBase::PikaSelectionChangedBySelf);
}
return PikaComboBoxString;
}
UComboBoxString* UPikaUIWidgetBase::PikaGetComboBoxStringFormBlueprint(FString BlueprintWidgetName) const
{
UComboBoxString* PikaComboBoxString = Cast<UComboBoxString>(PikaqiuGetBlueprintWidget(BlueprintWidgetName));
if (PikaComboBoxString)
{
PikaComboBoxString->PikaqiuOnSelectionChangedBySelf.AddDynamic(this, &UPikaUIWidgetBase::PikaSelectionChangedBySelf);
}
return PikaComboBoxString;
}
UCheckBox* UPikaUIWidgetBase::PikaGetCheckBoxFormBlueprint(FName BlueprintWidgetName) const
{
UCheckBox* PikaCheckBoxWidget = Cast<UCheckBox>(PikaqiuGetBlueprintWidget(BlueprintWidgetName));
if (PikaCheckBoxWidget)
{
PikaCheckBoxWidget->PikaqiuOnCheckStateChanged.AddDynamic(this, &UPikaUIWidgetBase::PikaClickedCheckBox);
}
return PikaCheckBoxWidget;
}
UCheckBox* UPikaUIWidgetBase::PikaGetCheckBoxFormBlueprint(FString BlueprintWidgetName) const
{
UCheckBox* PikaCheckBoxWidget = Cast<UCheckBox>(PikaqiuGetBlueprintWidget(BlueprintWidgetName));
if (PikaCheckBoxWidget)
{
PikaCheckBoxWidget->PikaqiuOnCheckStateChanged.AddDynamic(this, &UPikaUIWidgetBase::PikaClickedCheckBox);
}
return PikaCheckBoxWidget;
}
void UPikaUIWidgetBase::PikaAddSizeBox(USizeBox* TargetWidget, UWidget* BaseWidget)
{
if (TargetWidget && BaseWidget)
{
TargetWidget->AddChild(BaseWidget);
}
}
APikaGodStonePlayerController* UPikaUIWidgetBase::PikaGetPlayerController()
{
return GetWorld() ? ((APikaGodStonePlayerController*)GetWorld()->GetFirstPlayerController()) : NULL;
}
APikaGodStonePlayerState* UPikaUIWidgetBase::PikaGetPlayerState()
{
return PikaGetPlayerController() ? PikaGetPlayerController()->PikaGetTowerPlayerState() : NULL ;
}
UPikaGodStoneGameInstance* UPikaUIWidgetBase::PikaGetGameInstance()
{
return PikaGetPlayerState() ? PikaGetPlayerState()->PikaGetGameInstance() : NULL;
}
/*FPikaGodStoneSaveGameData* UPikaUIWidgetBase::PikaGetSaveGameData()
{
return (PikaGetGameInstance() && PikaGetGameInstance()->PikaGetGameSaveData()) ? &(PikaGetGameInstance()->PikaGetGameSaveData()->PikaGodStongSaveData) : NULL;
}*/
FPikaGodStoneSaveGameData* UPikaUIWidgetBase::PikaGetSaveGameData()
{
return PikaGetPlayerController() != nullptr ? (PikaGetPlayerController()->PikaGlobalConfigPre ? &PikaGetPlayerController()->PikaGlobalConfigPre->PikaGameData : nullptr) : nullptr;
}PikaWorldSettings.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/WorldSettings.h"
#include "PikaWorldSettings.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API APikaWorldSettings : public AWorldSettings
{
GENERATED_BODY()
public:
APikaWorldSettings();
//当前关卡的序列ID
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "PikaBaseSettings", meta = (DisplayName = "Level Number"))
int32 PikaCurrentLevel;
};PikaWorldSettings.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaWorldSettings.h"
//PikaGameUserSettings属于ini配置类,该构造函数只会在代码编译时以及启动游戏时分别调用一次,在运行中不会再次执行
APikaWorldSettings::APikaWorldSettings()
{
PikaCurrentLevel = 1;
}11
22