PikaGodStoneMacroLib.h
#pragma once
#include "Kismet/GameplayStatics.h"
#pragma region SaveSlot
//关于我们自己的游戏储存
#define PIKA_CREATESAVE_SLOT( MyParameter) UGameplayStatics::CreateSaveGameObject(MyParameter)
#define PIKA_SAVE_SLOT( MyParameter1,MyParameter2,MyParameter3) UGameplayStatics::SaveGameToSlot(MyParameter1,MyParameter2,MyParameter3)
#define PIKA_ISSAVE_SLOT( MyParameter1, MyParameter2) UGameplayStatics::DoesSaveGameExist( MyParameter1, MyParameter2)
#define PIKA_LOADGAME_SLOT( MyParameter1, MyParameter2) UGameplayStatics::LoadGameFromSlot(MyParameter1, MyParameter2)
#define PIKA_DELETEGAME_SLOT( MyParameter1, MyParameter2) UGameplayStatics::DeleteGameInSlot(MyParameter1, MyParameter2)
#pragma endregion SaveSlot
//我们游戏存储的名字
#define PIKA_SAVE_SLOT_NAME "PikaSaveSlot"
#define PIKA_SAVE_GAME_NAME "PikaSaveGame"
//默认填充字体
#define PIKA_SAVE_PIKA "Pikaqiu"
//FOV间隔值
#define PIKA_FOVMAX_VALUE (200.0f)
#define Pika_Debug 1 //方便我们测试游戏
//定义UE4打印屏幕
#if Pika_Debug
#define PIKA_UE_PRINT(MyString) if(GEngine) { GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, MyString); }
#else
#define PIKA_UE_PRINT(MyString)
#endif
// 0
#define PIKA_ZERO (0)
#define PIKA_STANDARD_VALUE 1
//关于存储内容设定
#define Pika_SAVE_SaveBarNumber 20 //默认的条数量
//获取场景内所有Actor
#define PikaGETALLACTOR(MyParameter1,MyParameter2,MyParameter3) UGameplayStatics::GetAllActorsOfClass(MyParameter1,MyParameter2,MyParameter3)
//日志打印
#define PIKA_LOG(Cen) PikaLogPrintf(Cen)
//播放声音
#define PIKA_SPAWN_SOUND_LOCATION(MyParameter1,MyParameter2,MyParameter3,MyParameter4,MyParameter5,MyParameter6,MyParameter7,MyParameter8) UGameplayStatics::PlaySoundAtLocation(MyParameter1,MyParameter2,MyParameter3,MyParameter4,MyParameter5,MyParameter6,MyParameter7,MyParameter8)
#pragma region PikaSaveDataChannel
//作为一个单数据通道使用
struct PikaFSaveSlotDataChannel
{
//存储游戏的区域
//------------------------------------
//PikaUIReadAndWrite循环创建PikaUISaveLoadBar时,
//将循环的index存入PikaUISaveLoadBar类里的PikaSaveGameBoxNumber
//点击某个PikaUISaveLoadBar类的按钮后,
//通过读取PikaUISaveLoadBar类里的PikaSaveGameBoxNumber属性就能得到PikaCurrentSaveGameBoxNumber的值
int32 PikaCurrentSaveGameBoxNumber;
//存储游戏的编号
//------------------------------------
//在空的存档上新建存档时,在PikaUIReadAndWrite::PikaSaveArchiveSlot的新建逻辑里,
//通过PikaGetGameInstance()->PikaGetCurrentSaveArchiveNumber获取已有存档的数量,
//并用该数量来进行设置PikaCurrentGameArchiveNumber
//------------------------------------
//在已有的存档上进行覆盖存档时,由PikaUIReadAndWrite::PikaReadArchive读取的本地存档,
//并将PikaCurrentGameArchiveNumber的值保存在PikaUISaveLoadBar里的PikaGameArchiveNumber属性里
//点击某个PikaUISaveLoadBar类的按钮后,
//通过读取PikaUISaveLoadBar类里的PikaGameArchiveNumber属性就能得到PikaCurrentGameArchiveNumber的值
int32 PikaCurrentGameArchiveNumber;
//构造赋值
PikaFSaveSlotDataChannel(int32 SaveGameBoxNumber)
{
PikaCurrentSaveGameBoxNumber = SaveGameBoxNumber;
PikaCurrentGameArchiveNumber = INDEX_NONE;
}
PikaFSaveSlotDataChannel(int32 SaveGameBoxNumber, int32 GameArchiveNumber)
{
PikaCurrentSaveGameBoxNumber = SaveGameBoxNumber;
PikaCurrentGameArchiveNumber = GameArchiveNumber;
}
};
#pragma endregion PikaSaveDataChannelPikaGodStone.Build.cs
// Fill out your copyright notice in the Description page of Project Settings.
using UnrealBuildTool;
public class PikaGodStone : ModuleRules
{
public PikaGodStone(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" , "UMG" , "MoviePlayer" });
PrivateDependencyModuleNames.AddRange(new string[] { });
// Uncomment if you are using Slate UI
PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
}
}PikaGodStone.h
// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "PikaGodStoneMacroLib.h"
PikaGodStone.cpp
// Fill out your copyright notice in the Description page of Project Settings. #include "PikaGodStone.h" #include "Modules/ModuleManager.h" IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, PikaGodStone, "PikaGodStone" );
PikaGodStoneGameModeBase.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "PikaGodStoneGameModeBase.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API APikaGodStoneGameModeBase : public AGameModeBase
{
GENERATED_BODY()
public:
APikaGodStoneGameModeBase();
virtual void BeginPlay()override;
};PikaGodStoneGameModeBase.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "PikaGodStoneGameModeBase.h"
#include "Public/PikaGodStoneGameStateBase.h"
#include "Public/PikaGodStonePlayerController.h"
#include "Public/PikaGodStoneCamera.h"
#include "Public/PikaGodStonePlayerState.h"
#include "Public/PikaHUDBase.h"
#include "Public/PikaGameUserSettings.h"
APikaGodStoneGameModeBase::APikaGodStoneGameModeBase()
{
//加载GameState
GameStateClass = APikaGodStoneGameStateBase::StaticClass();
//加载Controller
PlayerControllerClass = APikaGodStonePlayerController::StaticClass();
//加载ContorllerPawn
DefaultPawnClass = APikaGodStoneCamera::StaticClass();
//加载PlayerState
PlayerStateClass = APikaGodStonePlayerState::StaticClass();
//加载HUD
HUDClass = APikaHUDBase::StaticClass();
}
void APikaGodStoneGameModeBase::BeginPlay()
{
Super::BeginPlay();
//设置PikaGameUserSettings的UWorld
if (UPikaGameUserSettings::PikaGetGameUserSettings())
{
UPikaGameUserSettings::PikaGetGameUserSettings()->PikaSetretrieveWorldContext(GetWorld());
}
}PikaAITargetPoint.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/TargetPoint.h"
#include "PikaAITargetPoint.generated.h"
/**
*
*/
UCLASS(Blueprintable)
class PIKAGODSTONE_API APikaAITargetPoint : public ATargetPoint
{
GENERATED_BODY()
//生成怪物时的特效
UPROPERTY(EditDefaultsOnly, Category = "PikaTargetPoint")
TArray<UParticleSystem*> PikaSPawnCharacterParticleArray;
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PikaTargetPoint")
bool PikaTeam;
protected:
virtual void BeginPlay() override;
public:
APikaAITargetPoint();
FORCEINLINE bool PikaGetTeam() { return PikaTeam; }
};PikaAITargetPoint.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaAITargetPoint.h"
#include "Kismet/GameplayStatics.h"
void APikaAITargetPoint::BeginPlay()
{
Super::BeginPlay();
if (GetWorld())
{
if (!PikaTeam)
{
//特效的总数
int32 PikaIndex_ParNumber = PikaSPawnCharacterParticleArray.Num();
//特效的随机数
int32 PikaRandomIndex = FMath::RandRange(0, PikaIndex_ParNumber - 1);
//特效生成
if (PikaSPawnCharacterParticleArray.IsValidIndex(PikaRandomIndex))
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), PikaSPawnCharacterParticleArray[PikaRandomIndex], GetActorLocation(), GetActorRotation());
}
}
}
APikaAITargetPoint::APikaAITargetPoint()
{
PikaTeam = false;
}PikaAllowBuildTrigger.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/BoxComponent.h"
#include "PikaAllowBuildTrigger.generated.h"
UCLASS()
class PIKAGODSTONE_API APikaAllowBuildTrigger : public AActor
{
GENERATED_BODY()
//碰撞组件
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBox", meta = (AllowPrivateAccess = "true"))
UBoxComponent * PikaBox;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBox", meta = (AllowPrivateAccess = "true"))
USceneComponent * PikaRoot;
public:
// Sets default values for this actor's properties
APikaAllowBuildTrigger();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};PikaAllowBuildTrigger.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaAllowBuildTrigger.h"
// Sets default values
APikaAllowBuildTrigger::APikaAllowBuildTrigger()
{
// 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;
PikaBox = CreateDefaultSubobject<UBoxComponent>(TEXT("PikaBox"));
PikaRoot = CreateDefaultSubobject<USceneComponent>(TEXT("PikaRoot"));
RootComponent = PikaRoot;
//绑定
PikaBox->SetupAttachment(PikaRoot);
PikaBox->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
}
// Called when the game starts or when spawned
void APikaAllowBuildTrigger::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void APikaAllowBuildTrigger::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}PikaAttackInterface.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaAttackInterface.generated.h"
// This class does not need to be modified.
UINTERFACE(MinimalAPI)
class UPikaAttackInterface : public UInterface
{
GENERATED_BODY()
};
/**
*
*/
class PIKAGODSTONE_API IPikaAttackInterface
{
GENERATED_BODY()
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
//攻击
virtual void PikaAttackTarget(AActor * Target) {}
//持续性攻击接口
virtual void PikaAttackTick() {}
//接受对方的伤害
//virtual float PikaGetDefenceDamage(AActor * OtherActor);
//同伴升级的值传递
virtual void PikaUpdateLevelCharacterArray(TArray<AActor*> MyActor) {};
};PikaAttackInterface.cpp
// Fill out your copyright notice in the Description page of Project Settings. #include "Public/PikaAttackInterface.h" // Add default functionality here for any IPikaAttackInterface functions that are not pure virtual.
PikaBTTask_RandomWalk.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "BehaviorTree/Tasks/BTTask_BlackboardBase.h"
#include "PikaBTTask_RandomWalk.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaBTTask_RandomWalk : public UBTTask_BlackboardBase
{
GENERATED_BODY()
public:
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
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) {}
};PikaBTTask_RandomWalk.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "PikaBTTask_RandomWalk.h"
#include "Public/PikaMonsterAIController.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "BehaviorTree/Blackboard/BlackboardKeyType_Vector.h"
EBTNodeResult::Type UPikaBTTask_RandomWalk::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
Super::ExecuteTask(OwnerComp , NodeMemory);
APikaMonsterAIController * PikaMyAIController = Cast<APikaMonsterAIController>(OwnerComp.GetOwner());
UBlackboardComponent * PikaMyBlackBoard = (UBlackboardComponent *)OwnerComp.GetBlackboardComponent();
if (PikaMyAIController == NULL)
{
return EBTNodeResult::Failed;
}
else
{
//获取随机点
FVector PikaRandomPoint = PikaMyAIController->PikaGetRandomLoaction();
//将随机点传出去
if (BlackboardKey.SelectedKeyType == UBlackboardKeyType_Vector::StaticClass())
{
//BlackboardKey.SelectedKeyName表示在行为树的蓝图中,手动选择的变量
PikaMyBlackBoard->SetValueAsVector(BlackboardKey.SelectedKeyName , PikaRandomPoint);
}
return EBTNodeResult::Succeeded;
}
return EBTNodeResult::Failed;
}PikaBTTaskAttackTarget.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "BehaviorTree/BTTaskNode.h"
#include "PikaBTTaskAttackTarget.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaBTTaskAttackTarget : public UBTTaskNode
{
GENERATED_BODY()
public:
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
virtual void InitializeFromAsset(UBehaviorTree & Asset) override;
//加载敌对目标
UPROPERTY(EditAnywhere, Category = "PikaBlackboard")
struct FBlackboardKeySelector PikaBlackboardActor;
//敌对目标在行为树的黑板中的变量名,在蓝图中设置
UPROPERTY(EditAnywhere, Category = "PikaBlackboard")
FName PikaActorKeyName;
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) {}
};PikaBTTaskAttackTarget.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "PikaBTTaskAttackTarget.h"
#include "Public/PikaMonsterAIController.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "BehaviorTree/Blackboard/BlackboardKeyType_Object.h"
#include "Public/PikaCharacterBase.h"
//PikaBlackboardActor调用前需要先初始化
EBTNodeResult::Type UPikaBTTaskAttackTarget::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
Super::ExecuteTask(OwnerComp, NodeMemory);
APikaMonsterAIController * PikaMyAIController = Cast<APikaMonsterAIController>(OwnerComp.GetOwner());
UBlackboardComponent * PikaMyBlackBoard = (UBlackboardComponent *)OwnerComp.GetBlackboardComponent();
if (PikaMyAIController == NULL)
{
return EBTNodeResult::Failed;
}
else
{
if (PikaBlackboardActor.SelectedKeyType == UBlackboardKeyType_Object::StaticClass())
{
UObject * PikaTowerObject = PikaMyBlackBoard->GetValueAsObject(PikaActorKeyName);
if (PikaTowerObject)
{
AActor * PikaTargetTower = (AActor *)PikaTowerObject;
APikaCharacterBase * PikaMyPawn = Cast<APikaCharacterBase>(PikaMyAIController->GetPawn());
if (PikaTargetTower && PikaMyPawn)
{
PikaMyPawn->PikaAttackTarget(PikaTargetTower);
return EBTNodeResult::Succeeded;
}
}
}
}
return EBTNodeResult::Failed;
}
//初始化PikaBlackboardActor
void UPikaBTTaskAttackTarget::InitializeFromAsset(UBehaviorTree & Asset)
{
Super::InitializeFromAsset(Asset);
UBlackboardData * PikaBlackboardAsset = GetBlackboardAsset();
if (PikaBlackboardAsset)
{
PikaBlackboardActor.ResolveSelectedKey(*PikaBlackboardAsset);
}
else
{
UE_LOG(LogBehaviorTree, Warning, TEXT("Pika Can'Initialize task:%s"), *GetName());
}
}PikaBTTaskMoveToTarget.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "BehaviorTree/BTTaskNode.h"
#include "PikaBTTaskMoveToTarget.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaBTTaskMoveToTarget : public UBTTaskNode
{
GENERATED_BODY()
public:
UPikaBTTaskMoveToTarget();
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
virtual void InitializeFromAsset(UBehaviorTree & Asset) override;
//加载敌对目标
UPROPERTY(EditAnywhere, Category = "PikaBlackboard")
struct FBlackboardKeySelector PikaBlackboardActor;
//接触半径
UPROPERTY(EditAnywhere, Category = "PikaBlackboard")
float PikaAcceptanceRadius;
//敌对目标在行为树的黑板中的变量名,在蓝图中设置
UPROPERTY(EditAnywhere, Category = "PikaBlackboard")
FName PikaActorKeyName;
//打印测试
void PikaPrint(FString piksStr);
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) {}
};PikaBTTaskMoveToTarget.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "PikaBTTaskMoveToTarget.h"
#include "Public/PikaMonsterAIController.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "BehaviorTree/Blackboard/BlackboardKeyType_Object.h"
UPikaBTTaskMoveToTarget::UPikaBTTaskMoveToTarget()
{
PikaAcceptanceRadius = 800.f;
}
//PikaBlackboardActor调用前需要先初始化
EBTNodeResult::Type UPikaBTTaskMoveToTarget::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
Super::ExecuteTask(OwnerComp, NodeMemory);
APikaMonsterAIController * PikaMyAIController = Cast<APikaMonsterAIController>(OwnerComp.GetOwner());
UBlackboardComponent * PikaMyBlackBoard = (UBlackboardComponent *)OwnerComp.GetBlackboardComponent();
if (PikaMyAIController == NULL)
{
return EBTNodeResult::Failed;
}
else
{
if (PikaBlackboardActor.SelectedKeyType == UBlackboardKeyType_Object::StaticClass())
{
UObject * PikaTowerObject = PikaMyBlackBoard->GetValueAsObject(PikaActorKeyName);
if (PikaTowerObject)
{
AActor * PikaTargetTower = (AActor *)PikaTowerObject;
if (PikaTargetTower)
{
//PikaPrint("PikaMove");
/*FVector PikaTest = PikaTargetTower->GetActorLocation();
PikaPrint(FString::SanitizeFloat(PikaTest.X));
PikaPrint("x");
PikaPrint(FString::SanitizeFloat(PikaTest.Y));
PikaPrint("y");
PikaPrint(FString::SanitizeFloat(PikaTest.Z));
PikaPrint("z");*/
PikaMyAIController->MoveToLocation(PikaTargetTower->GetActorLocation() , PikaAcceptanceRadius);
return EBTNodeResult::Succeeded;
}
}
}
}
return EBTNodeResult::Failed;
}
//初始化PikaBlackboardActor
void UPikaBTTaskMoveToTarget::InitializeFromAsset(UBehaviorTree & Asset)
{
Super::InitializeFromAsset(Asset);
UBlackboardData * PikaBlackboardAsset = GetBlackboardAsset();
if (PikaBlackboardAsset)
{
PikaBlackboardActor.ResolveSelectedKey(*PikaBlackboardAsset);
}
else
{
UE_LOG(LogBehaviorTree, Warning, TEXT("Pika Can'Initialize task:%s"), *GetName());
}
}
void UPikaBTTaskMoveToTarget::PikaPrint(FString piksStr)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 6.0f, FColor::Red, piksStr);
}
}PikaBulletBase.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Particles/ParticleSystemComponent.h"
#include "Components/BoxComponent.h"
#include "GameFramework/ProjectileMovementComponent.h"
#include "Components/SphereComponent.h"
#include "Components/TimelineComponent.h"
#include "PikaBulletBase.generated.h"
class APikaGodStonePlayerController;
UENUM()
namespace PikaBulletType
{
enum Type
{
PikaBULLET_Track,//跟踪子弹
PikaBULLET_Line,//直线飞行子弹
PikaBULLET_Range,//范围攻击型子弹
PikaBULLET_Chain,//闪电型攻击
PikaBULLET_MAX
};
}
UCLASS()
class PIKAGODSTONE_API APikaBulletBase : public AActor
{
GENERATED_BODY()
//载入显示的粒子(子弹飞行中特效)
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBulletBase", meta = (AllowPrivateAccess = "true"))
class UParticleSystemComponent * PikaParticleMesh;
//碰撞盒子
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBulletBase", meta = (AllowPrivateAccess = "true"))
//class UBoxComponent * PikaBoxDamage;
class USphereComponent * PikaBoxDamage;
//根组件
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBulletBase", meta = (AllowPrivateAccess = "true"))
class USceneComponent * PikaRootBullet;
//具有移动属性的组件
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBulletBase", meta = (AllowPrivateAccess = "true"))
class UProjectileMovementComponent * PikaProjectileMovement;
//子弹的施法者
AActor * PikaCasterCharacter;
UPROPERTY(EditDefaultsOnly, Category = "PikaBullet")
TSubclassOf<AActor> PikaDamageValueActor;
//开火的声音
UPROPERTY(EditDefaultsOnly, Category = "PikaBullet")
TArray <USoundBase*> PikaOpenFireSound;
public:
// Sets default values for this actor's properties
APikaBulletBase();
//蓝图中可以设置的子弹类型
UPROPERTY(EditDefaultsOnly, Category = "PikaBullet")
TEnumAsByte<PikaBulletType::Type> PikaBulletTypeBP;
//蓝图中设置的子弹伤害特效
UPROPERTY(EditDefaultsOnly, Category = "PikaBullet")
UParticleSystem * PikaDamageParticle;
//蓝图中设置的子弹开火特效
UPROPERTY(EditDefaultsOnly, Category = "PikaBullet")
UParticleSystem * PikaOpenFireParticle;
//定时销毁子弹
float PikaDestoryTime;
FTimerHandle PikaDestoryBulletTimeHandle;
void PikaDestoryBullet();
//范围攻击,该曲线由蓝图载入
UPROPERTY(EditDefaultsOnly, Category = "PikaBullet")
UCurveFloat * PikaCurveFloat;
UPROPERTY()
FTimeline PikaRangeAttackTimeLine;
UFUNCTION()
void PikaTimeLineRangeAttack(float PikaValue);
//范围攻击球体的半径
UPROPERTY(EditDefaultsOnly, Category = "PikaBullet")
float PikaBoxDamageTargetRadius;
//攻击特效
UPROPERTY(EditDefaultsOnly, Category = "PikaBullet")
UParticleSystem * PikaRangeAttackType;
UPROPERTY()
TArray<ACharacter*> PikaTargetRangeArr;
UFUNCTION()
void PikaTimeLineFinished();
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);
//获取子弹的粒子特效
FORCEINLINE UParticleSystemComponent * GetParticleMesh() {return PikaParticleMesh;}
//具有移动跟踪属性的子弹
FORCEINLINE UProjectileMovementComponent * GetProjectleMovment() { return PikaProjectileMovement; }
//设置子弹的发射者
void PikaSetCasterCharacter(AActor * MyCharacter) { PikaCasterCharacter = MyCharacter; }
FORCEINLINE class APikaGodStonePlayerController* PikaGetPlayerController();
};PikaBulletBase.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaBulletBase.h"
#include "Public/PikaTowers.h"
#include "Kismet/GameplayStatics.h"
#include "Public/PikaDamageValueText.h"
// Sets default values
APikaBulletBase::APikaBulletBase()
{
// 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;
PikaParticleMesh = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("PikaBulletParticleMesh"));
//PikaBoxDamage = CreateDefaultSubobject<UBoxComponent>(TEXT("PikaBoxDamage"));
PikaBoxDamage = CreateDefaultSubobject<USphereComponent>(TEXT("PikaBoxDamage"));
PikaRootBullet = CreateDefaultSubobject<USceneComponent>(TEXT("PikaRootBullet"));
PikaProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("PikaProjectileMovement"));
RootComponent = PikaRootBullet;
PikaBoxDamage->AttachToComponent(PikaRootBullet , FAttachmentTransformRules::KeepRelativeTransform);
PikaParticleMesh->AttachToComponent(PikaBoxDamage , FAttachmentTransformRules::KeepRelativeTransform);
//速度初始化
PikaProjectileMovement->InitialSpeed = 800.f;
PikaProjectileMovement->MaxSpeed = 2000.f;
PikaProjectileMovement->UpdatedComponent = PikaBoxDamage;
switch (PikaBulletTypeBP)
{
case PikaBulletType::PikaBULLET_Track://跟踪子弹
PikaProjectileMovement->bIsHomingProjectile = true;
PikaProjectileMovement->bRotationFollowsVelocity = true;
break;
case PikaBulletType::PikaBULLET_Line://直线飞行子弹
//取消重力模拟
PikaProjectileMovement->ProjectileGravityScale = 0.f;
PikaProjectileMovement->InitialSpeed = 1200.f;
break;
case PikaBulletType::PikaBULLET_Range://范围攻击型子弹
PikaProjectileMovement->InitialSpeed = 0;
break;
case PikaBulletType::PikaBULLET_Chain://闪电型攻击
//取消重力模拟
PikaProjectileMovement->ProjectileGravityScale = 0.f;
//初速度
PikaProjectileMovement->InitialSpeed = 0.f;
//取消碰撞
PikaBoxDamage->SetCollisionEnabled(ECollisionEnabled::NoCollision);
break;
default:
break;
}
//定时销毁子弹的时间
PikaDestoryTime = 6.5f;
}
void APikaBulletBase::PikaDestoryBullet()
{
if (PikaDestoryBulletTimeHandle.IsValid() && GetWorld())
{
GetWorld()->GetTimerManager().ClearTimer(PikaDestoryBulletTimeHandle);
Destroy(true);
}
}
void APikaBulletBase::PikaTimeLineRangeAttack(float PikaValue)
{
float PikaBoxDamageCurentRadius = FMath::Lerp(PikaBoxDamage->GetScaledSphereRadius() , PikaBoxDamageTargetRadius , PikaValue);
PikaBoxDamage->SetSphereRadius(PikaBoxDamageCurentRadius);
}
//TimeLine结束时触发的事件
void APikaBulletBase::PikaTimeLineFinished()
{
/*for (ACharacter * PikaMyCharacter:PikaTargetRangeArr)
{
APikaCharacterBase * PikaChar = Cast<APikaCharacterBase>(PikaMyCharacter);
APikaCharacterBase * PikaCasterActor = Cast<APikaCharacterBase>(PikaCasterCharacter);
if (PikaChar && PikaRangeAttackType && PikaCasterCharacter)
{
FVector PikaMyDistance = PikaChar->GetActorLocation() - PikaCasterActor->GetActorLocation();
if (PikaChar->PikaIsActive() && PikaMyDistance.Size()<1000)
{
//产生伤害,获取状态
PikaChar->PikaGetCharacterState(PikaChar->PikaGetDefenceDamage(PikaCasterActor));
//更新血条栏
PikaChar->PikaUpdateUMGHealth();
//攻击特效
UParticleSystemComponent * PikaParticleBullet = UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), PikaRangeAttackType, PikaCasterActor->GetSpawnPoint()->GetComponentLocation());
if (PikaParticleBullet)
{
PikaParticleBullet->SetBeamSourcePoint(0 , PikaCasterActor->GetHomingPoint()->GetComponentLocation(), 0);
PikaParticleBullet->SetBeamTargetPoint(0 , PikaChar->GetHomingPoint()->GetComponentLocation(), 0);
}
}
else
{
PikaTargetRangeArr.Remove(PikaChar);
}
}
}*/
}
// Called when the game starts or when spawned
void APikaBulletBase::BeginPlay()
{
Super::BeginPlay();
//碰撞绑定
if (PikaBoxDamage)
{
PikaBoxDamage->OnComponentBeginOverlap.AddUniqueDynamic(this, &APikaBulletBase::PikaBeginOverlapping);
}
if (GetWorld())
{
//开始执行销毁
GetWorld()->GetTimerManager().SetTimer(PikaDestoryBulletTimeHandle , this , &APikaBulletBase::PikaDestoryBullet , PikaDestoryTime);
//生成开火特效
if (PikaOpenFireParticle)
{
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), PikaOpenFireParticle, GetActorLocation());
}
//曲线存在,通过代理绑定处理函数
if (PikaCurveFloat && PikaBulletTypeBP == PikaBulletType::PikaBULLET_Range)
{
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);
}
}
//播放开火声音
if (PikaGetPlayerController())
PikaGetPlayerController()->PikaPlaySoundAtVetor(PikaOpenFireSound, GetActorLocation(), PikaETowerDefenceSoundType::SOUND_EFFECT_SOUND);
}
// Called every frame
void APikaBulletBase::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (PikaBulletTypeBP == PikaBulletType::PikaBULLET_Range)
{
PikaRangeAttackTimeLine.TickTimeline(DeltaTime);
}
}
/*
* OverlappedComponent:本类哪个组件触发的碰撞
* OtherActor:和本类触发碰撞的Actor
* OtherComp:和本类触发碰撞的Actor的组件
*/
void APikaBulletBase::PikaBeginOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
if (!PikaCasterCharacter)
{
return;
}
APikaCharacterBase * PikaEnemyCharacter = Cast<APikaCharacterBase>(OtherActor);
APikaCharacterBase * PikaCasterActor = Cast<APikaCharacterBase>(PikaCasterCharacter);
if (!OtherActor || !PikaEnemyCharacter || !PikaCasterActor)
{
return;
}
//判断是否为同一个队伍
if (PikaCasterActor->PikaCharDataPre->PikaCharBaseData.PikaTeam != PikaEnemyCharacter->PikaCharDataPre->PikaCharBaseData.PikaTeam)
{
if (PikaEnemyCharacter->PikaIsActive() && PikaBulletTypeBP != PikaBulletType::PikaBULLET_Chain && PikaDamageParticle && GetWorld())
{
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), PikaDamageParticle, SweepResult.Location);
PikaParticleMesh->SetActive(false);
PikaBoxDamage->SetCollisionEnabled(ECollisionEnabled::NoCollision);
/*if (PikaBulletTypeBP == PikaBulletType::PikaBULLET_Range)
{
PikaTargetRangeArr.AddUnique(PikaEnemyCharacter);
return;
}*/
//产生伤害,获取状态
float PikaDamageValue = PikaEnemyCharacter->PikaGetDefenceDamage(PikaCasterActor);
PikaEnemyCharacter->PikaGetCharacterState(PikaDamageValue);
//更新血条栏
PikaEnemyCharacter->PikaUpdateUMGHealth();
//停止移动组件
PikaProjectileMovement->StopMovementImmediately();
//被子弹打中后,损失的生命数值的显示
if (PikaDamageValue > 0 && PikaDamageValueActor)
{
APikaDamageValueText * PikaValueText = GetWorld()->SpawnActor<APikaDamageValueText>(PikaDamageValueActor, PikaEnemyCharacter->GetActorLocation(), FRotator::ZeroRotator);
if (PikaValueText)
PikaValueText->PikaDrawDamage(PikaDamageValue , 1.f);
}
}
}
}
void APikaBulletBase::PikaPrint(FString PikaStr)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 6.f, FColor::Red, PikaStr);
}
}
FORCEINLINE class APikaGodStonePlayerController* APikaBulletBase::PikaGetPlayerController()
{
return GetWorld() ? ((APikaGodStonePlayerController*)GetWorld()->GetFirstPlayerController()) : NULL;
}PikaCharacterBase.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "PikaCharacterData.h"
#include "WidgetComponent.h"
#include "PikaAttackInterface.h"
#include "PikaBulletBase.h"
#include "Components/ArrowComponent.h"
#include "PikaGameResource.h"
#include "Sound/SoundBase.h"
#include "PikaCharacterBase.generated.h"
class APikaGodStonePlayerController;
UCLASS()
class PIKAGODSTONE_API APikaCharacterBase : public ACharacter , public IPikaAttackInterface
{
GENERATED_BODY()
//跟踪点
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBaseAttribute", meta = (AllowPrivateAccess = "true"))
class USceneComponent * PikaHomingPoint;
//血条显示
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBaseAttribute", meta = (AllowPrivateAccess = "true"))
class UWidgetComponent * PikaShowUMG;
//属性显示
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBaseAttribute", meta = (AllowPrivateAccess = "true"))
class UWidgetComponent * PikaShowAttribute;
//开火点
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBaseAttribute", meta = (AllowPrivateAccess = "true"))
class UArrowComponent * PikaOpenFirePoint;
//载入显示的粒子(子弹飞行中特效)
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBulletBase", meta = (AllowPrivateAccess = "true"))
class UParticleSystemComponent * PikaParticleMesh;
//捕捉射线,用来显示角色信息
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBulletBase", meta = (AllowPrivateAccess = "true"))
class UBoxComponent * PikaTraceShowCharacterInfo;
//受到攻击的声音
UPROPERTY(EditDefaultsOnly, Category = "PikaBulletBase")
TArray<USoundBase*> PikaHitSound;
int32 PikaCharacterSpawnID;
public:
//实始化角色信息
void PikaInitCharacterInformation();
// Sets default values for this character's properties
APikaCharacterBase();
//创建一个指向角色数据类的指针
UPROPERTY()
UPikaCharacterData * PikaCharDataPre;
//加载子弹,该子弹实例从蓝图中手动指定
UPROPERTY(EditDefaultsOnly , Category = "PikaBullet")
TSubclassOf<APikaBulletBase> PikaCharacterBullet;
UPROPERTY(EditDefaultsOnly, Category = "PikaBullet")
TSubclassOf<AActor> PikaDeathRangeCharacter;
//攻击目标
UPROPERTY()
AActor * PikaEnemyTarget;
//角色死亡后,该范围内的敌人角色升级
UPROPERTY(EditDefaultsOnly, Category = "PikaBullet")
float PikaUpdateLevelRange;
/********蒙太奇start********/
//游戏开始蒙太奇
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "PikaMontage")
UAnimMontage* PikaGameBeignPlayMontage;
//攻击蒙太奇
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "PikaMontage")
TArray<UAnimMontage*> PikaCharacterAttackSkillMontage;
//死亡蒙太奇
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "PikaMontage")
TArray<UAnimMontage*> PikaCharacterDeathMontage;
//角色蒙太奇播放
void PikaCharacterMontage_Play(TArray<UAnimMontage*> CharacterMontageArray);
//开始播放动画
void PikaPlayAnimationForBegin(bool IsSaveCharater = false);
//蒙太奇开始播放通知蓝图
UFUNCTION(BlueprintImplementableEvent)
void PikaBlueprintMontageBegin(UAnimMontage* Montage);
//蒙太奇结束播放通知蓝图
UFUNCTION(BlueprintImplementableEvent)
void PikaBlueprintMontageEnd(UAnimMontage* Montage, bool bInterrupted);
//如果是读取文件则执行该函数
UFUNCTION(BlueprintImplementableEvent)
void PikaEventSaveGameEnd();
protected:
UFUNCTION()
void PikaMontageBegin(UAnimMontage* Montage);
UFUNCTION()
void PikaMontageEnd(UAnimMontage* Montage, bool bInterrupted);
/********蒙太奇end********/
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
//获取游戏的控制
FORCEINLINE APikaGodStonePlayerController* PikaGetPlayerController() { return GetWorld() ? ((APikaGodStonePlayerController*)GetWorld()->GetFirstPlayerController()) : NULL; }
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
void PikaPrint(FString PikaStr);
//获取当前等级
FORCEINLINE int32 PikaGetCharacterLevel()const { return PikaCharDataPre != NULL ? PikaCharDataPre->PikaCharBaseData.PikaCharacterLevel : INDEX_NONE; }
//获取开火点和跟踪点
FORCEINLINE UArrowComponent * GetSpawnPoint() {return PikaOpenFirePoint; }
FORCEINLINE USceneComponent * GetHomingPoint() { return PikaHomingPoint; }
//获取特效
FORCEINLINE UParticleSystemComponent * GetParticleMesh() { return PikaParticleMesh; }
//获取角色的生命百分比
float PikaGetHealthPercentage();
//接受对方的伤害
float PikaGetDefenceDamage(AActor * OtherActor);
//更新血条栏
void PikaUpdateUMGHealth();
//获取角色死亡状态
bool PikaGetCharacterState(float Damage);
//是否存活
UFUNCTION(BlueprintPure , Category = "PikaAnim")
bool PikaIsActive();
//是否死亡
UFUNCTION(BlueprintPure, Category = "PikaAnim")
bool PikaIsDeathBP();
//延时销毁时间句柄
FTimerHandle PikaDestoryActorHandle;
//销毁角色
virtual void PikaDestoryCharacter(float DelayTime = 0);
//延时销毁角色
void PikaDelayDestoryCharacter();
//队伍判断
bool PikaGetTeam();
//判断是不是一个队伍
bool PikaIsTeam();
//是否升级
void PikaIsUpdateLevel(float Exp);
//同伴升级的值传递
virtual void PikaUpdateLevelCharacterArray(TArray<AActor*> MyActor) override;
//是否显示角色信息
void PikaCharacterAttributeDisplay(bool IsDisplay);
//记录世界生成角色的ID
int32 PikaGetCharacterSpawnID() const { return PikaCharacterSpawnID; }
//记录世界生成角色的ID
void PikaSetCharacterSpawnID(int32 NewSpawnID) { PikaCharacterSpawnID = NewSpawnID; }
UPROPERTY()
UPikaGameResource* PikaTest2112;
};PikaCharacterBase.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaCharacterBase.h"
#include "Public/PikaUIHealthShow.h"
#include "Engine/Engine.h"
#include "Public/PikaToolRangeOfCharacter.h"
#include "Public/PikaUICharacterAttribute.h"
#include "EngineUtils.h"
void APikaCharacterBase::PikaInitCharacterInformation()
{
//更新角色信息
UUserWidget* PikaTest = PikaShowAttribute->GetUserWidgetObject();
if (PikaCharDataPre && PikaShowAttribute->GetUserWidgetObject())
{
UPikaUICharacterAttribute* PikaNewCharacterAttribute = Cast<UPikaUICharacterAttribute>(PikaShowAttribute->GetUserWidgetObject());
UPikaUIHealthShow * PikaHealthShow = Cast<UPikaUIHealthShow>(PikaShowUMG->GetUserWidgetObject());
//面板信息变化
if (PikaNewCharacterAttribute)
{
//注册
PikaNewCharacterAttribute->PikaSetGameCharacterData(PikaCharDataPre);
PikaNewCharacterAttribute->PikaDrawUIToScreen();
//更新面板
PikaNewCharacterAttribute->PikaUpdataAll();
}
//血条变化
if (PikaHealthShow)
{
PikaHealthShow->PikaSetGameCharacterData(PikaCharDataPre);
PikaHealthShow->PikaDrawUIToScreen();
PikaHealthShow->PikaUpdateCharacterInformation();
}
}
}
// Sets default values
APikaCharacterBase::APikaCharacterBase()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
PikaHomingPoint = CreateDefaultSubobject<USceneComponent>(TEXT("PikaHomingPoint"));
PikaShowUMG = CreateDefaultSubobject<UWidgetComponent>(TEXT("PikaShowUMG"));
PikaShowAttribute = CreateDefaultSubobject<UWidgetComponent>(TEXT("PikaShowAttribute"));
PikaOpenFirePoint = CreateDefaultSubobject<UArrowComponent>(TEXT("PikaOpenFirePoint"));
PikaParticleMesh = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("PikaParticleMesh"));
PikaTraceShowCharacterInfo = CreateDefaultSubobject<UBoxComponent>(TEXT("PikaTraceShowCharacterInfoComponent"));
//绑定
PikaOpenFirePoint->AttachToComponent(RootComponent , FAttachmentTransformRules::KeepRelativeTransform);
PikaShowAttribute->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
PikaShowUMG->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
PikaHomingPoint->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
PikaParticleMesh->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
PikaTraceShowCharacterInfo->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
//设置预设通道
PikaTraceShowCharacterInfo->SetCollisionProfileName("PikaScaning");
PikaTraceShowCharacterInfo->SetBoxExtent(FVector(50 , 50 , 100));
PikaCharacterSpawnID = -1;
PikaUpdateLevelRange = 1200.f;
}
void APikaCharacterBase::PikaCharacterMontage_Play(TArray<UAnimMontage*> CharacterMontageArray)
{
if (GetMesh() && GetMesh()->SkeletalMesh && GetMesh()->GetAnimInstance())
{
if (CharacterMontageArray.Num() > 0)
{
int32 PikaIndexM = FMath::RandRange(0, (CharacterMontageArray.Num() - 1));
GetMesh()->GetAnimInstance()->Montage_Play(CharacterMontageArray[PikaIndexM]);
}
}
}
void APikaCharacterBase::PikaPlayAnimationForBegin(bool IsSaveCharater /*= false*/)
{
//动画
if (GetMesh() && GetMesh()->SkeletalMesh && GetMesh()->GetAnimInstance())
{
//对蒙太奇进行记录绑定
GetMesh()->GetAnimInstance()->OnMontageStarted.AddDynamic(this, &APikaCharacterBase::PikaMontageBegin);
GetMesh()->GetAnimInstance()->OnMontageEnded.AddDynamic(this, &APikaCharacterBase::PikaMontageEnd);
//播放起始蒙太奇(如果该数据是存储中导入不需要执行起始蒙太奇)
if (!IsSaveCharater)
{
if (PikaGameBeignPlayMontage)
GetMesh()->GetAnimInstance()->Montage_Play(PikaGameBeignPlayMontage);
}
else
{
//执行蓝图内容
//EventSaveGameEnd();
}
}
}
void APikaCharacterBase::PikaMontageBegin(UAnimMontage* Montage)
{
PikaBlueprintMontageBegin(Montage);
}
void APikaCharacterBase::PikaMontageEnd(UAnimMontage* Montage, bool bInterrupted)
{
PikaBlueprintMontageEnd(Montage, bInterrupted);
}
// Called when the game starts or when spawned
void APikaCharacterBase::BeginPlay()
{
Super::BeginPlay();
//默认状态下隐藏角色信息
if(PikaShowAttribute && PikaShowAttribute->GetUserWidgetObject())
PikaShowAttribute->GetUserWidgetObject()->SetVisibility(ESlateVisibility::Hidden);
//生成角色需要生成一个默认的控制
if (!GetController())
{
SpawnDefaultController();
}
//为角色数据分配位置
TSubclassOf<UPikaCharacterData> PikaSubclassOfChartData = UPikaCharacterData::StaticClass();
if (GetWorld() && PikaSubclassOfChartData)
PikaCharDataPre = NewObject<UPikaCharacterData>(GetWorld(), PikaSubclassOfChartData);
}
// Called every frame
void APikaCharacterBase::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (!PikaGetPlayerController() && !PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon)
return;
//上传我们的数据,如果角色有速度变化时,更新角色在地图中的坐标
//GetVelocity().Size()表示速度变化的大小,没有移动时,该值为0
if (GetVelocity().Size())
{
int32 PikaCharacterIndex = PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaGetCurrentCharacterSpawnIDIndex(PikaCharacterSpawnID);
if (PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaIsActive(PikaCharacterIndex))
{
PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterLocation[PikaCharacterIndex] = GetActorLocation();
PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterRotator[PikaCharacterIndex] = GetActorRotation();
}
}
}
// Called to bind functionality to input
void APikaCharacterBase::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
void APikaCharacterBase::PikaPrint(FString PikaStr)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 6.0f, FColor::Red, PikaStr);
}
}
float APikaCharacterBase::PikaGetHealthPercentage()
{
return PikaCharDataPre != NULL ? PikaCharDataPre->PikaCharBaseData.PikaGetHealthValuePercentage() : 1 ;
}
float APikaCharacterBase::PikaGetDefenceDamage(AActor * OtherActor)
{
if (OtherActor)
{
APikaCharacterBase * PikaEnemy = (APikaCharacterBase *)OtherActor;
if (PikaEnemy)
{
return PikaEnemy->PikaCharDataPre->PikaCharBaseData.PikaPhysicalAttack / ((PikaEnemy->PikaCharDataPre->PikaCharBaseData.PikaArmor / 10) + 1);
}
}
return 0;
}
//更新血条栏
void APikaCharacterBase::PikaUpdateUMGHealth()
{
if (PikaShowUMG)
{
UPikaUIHealthShow * PikaHealthShow = Cast<UPikaUIHealthShow>(PikaShowUMG->GetUserWidgetObject());
UPikaUICharacterAttribute* PikaNewCharacterAttribute = Cast<UPikaUICharacterAttribute>(PikaShowAttribute->GetUserWidgetObject());
//更新血条显示
if (PikaHealthShow)
PikaHealthShow->PikaUpdateCharacterInformation();
//更新面板显示
if (PikaNewCharacterAttribute)
PikaNewCharacterAttribute->PikaUpdateCharacterInformation();
}
}
bool APikaCharacterBase::PikaGetCharacterState(float Damage)
{
//播放角色受伤的声音
if (PikaGetPlayerController())
PikaGetPlayerController()->PikaPlaySoundAtVetor(PikaHitSound, GetActorLocation(), PikaETowerDefenceSoundType::SOUND_EFFECT_SOUND);
//产生伤害
PikaCharDataPre->PikaCharBaseData.PikaCurrentHealth -= Damage;
if (PikaCharDataPre->PikaCharBaseData.PikaCurrentHealth > 0)
{
//上传我们血值信息
if (PikaGetPlayerController() && PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon)
{
int32 PikaCharacterIndex = PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaGetCurrentCharacterSpawnIDIndex(PikaCharacterSpawnID);
if (PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaIsActive(PikaCharacterIndex))
PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterCurrentHealth[PikaCharacterIndex] = PikaCharDataPre->PikaCharBaseData.PikaCurrentHealth;
}
return PikaCharDataPre->PikaCharBaseData.PikaDeath = false;
}
PikaCharDataPre->PikaCharBaseData.PikaDeath = true;
//角色死亡,销毁角色
PikaDestoryCharacter(2);
return true;
}
//是否存活
bool APikaCharacterBase::PikaIsActive()
{
if (PikaCharDataPre)
return !PikaCharDataPre->PikaCharBaseData.PikaDeath;
return true;
}
bool APikaCharacterBase::PikaIsDeathBP()
{
if (PikaCharDataPre)
return PikaCharDataPre->PikaCharBaseData.PikaDeath;
return false;
}
void APikaCharacterBase::PikaDestoryCharacter(float DelayTime)
{
if (GetWorld())
{
if (DelayTime > 0)
{
GetWorld()->GetTimerManager().SetTimer(PikaDestoryActorHandle , this , &APikaCharacterBase::PikaDelayDestoryCharacter , DelayTime);
}
else
{
GetWorld()->GetTimerManager().SetTimer(PikaDestoryActorHandle, this, &APikaCharacterBase::PikaDelayDestoryCharacter, 0.1f);
}
//该角色死亡后对角色范围内的非队友进行经验值增加
for (TActorIterator<APikaCharacterBase>it(GetWorld(), APikaCharacterBase::StaticClass()); it; ++it)
{
APikaCharacterBase* PikaNewATCharacter = *it;
if (PikaNewATCharacter && PikaNewATCharacter->PikaIsTeam() != PikaIsTeam())
{
if ((PikaNewATCharacter->GetActorLocation() - GetActorLocation()).Size() <= PikaUpdateLevelRange)
{
PikaNewATCharacter->PikaIsUpdateLevel(PikaCharDataPre->PikaCharBaseData.PikaAddExp);
}
}
}
/*if (PikaDeathRangeCharacter)
{
APikaToolRangeOfCharacter * PikaCompanion = GetWorld()->SpawnActor<APikaToolRangeOfCharacter>(PikaDeathRangeCharacter , GetActorLocation() , GetActorRotation());
}*/
if (PikaGetPlayerController())
{
//播放我们的死亡声音
//GetTowerDefencePlayerController()->PlaySoundAtVetor(DeathSound, GetActorLocation(), ETowerDefenceSoundType::SOUND_EFFECT_SOUND);
//上传我们的死亡信息
if (PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon)
{
int32 PikaCharacterIndex = PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaGetCurrentCharacterSpawnIDIndex(PikaCharacterSpawnID);
if (PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaIsActive(PikaCharacterIndex))
{
PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterActive[PikaCharacterIndex] = false;
PikaGetPlayerController()->PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterCurrentHealth[PikaCharacterIndex] = 0;
}
}
/*//通知Control添加奖励玩家金币
if (GameCharacterData)
{
if (!IsTeam())
{
//添加金币
GetTowerDefencePlayerController()->Confo->TDGameData.AddGlobalGold(GameCharacterData->CharacterDataBase.RewardGlod);
//显示增加金币数字
ATool_DamageValueText* MyValueText = GetWorld()->SpawnActor<ATool_DamageValueText>(DamageValueActor, GetActorLocation(), FRotator::ZeroRotator);
if (MyValueText)
MyValueText->DrawGold(GameCharacterData->CharacterDataBase.RewardGlod, .7f);
}
//条件是否成功
GetTowerDefencePlayerController()->GameCondition(ELevelCondition::ExceedingSpiritualForce);
//播放我们的金币声音
GetTowerDefencePlayerController()->PlaySoundAtVetor(GetTowerDefencePlayerController()->TDGameResources->GoldSound, GetActorLocation(), ETowerDefenceSoundType::SOUND_EFFECT_SOUND);
}*/
}
}
}
//延时销毁角色
void APikaCharacterBase::PikaDelayDestoryCharacter()
{
if (PikaDestoryActorHandle.IsValid() && GetWorld())
{
GetWorld()->GetTimerManager().ClearTimer(PikaDestoryActorHandle);
}
if (PikaCharDataPre)
{
PikaCharDataPre->ConditionalBeginDestroy();
PikaCharDataPre = NULL;
}
UPikaGameResource * PikaTest1 = PikaGetPlayerController()->PikaGameResourcePtr;
if (PikaGetPlayerController())
PikaGetPlayerController()->PikaClearTmpRuleOfTheCharacter();
Destroy(true);
}
bool APikaCharacterBase::PikaGetTeam()
{
return PikaCharDataPre->PikaCharBaseData.PikaTeam;
}
bool APikaCharacterBase::PikaIsTeam()
{
return PikaCharDataPre != NULL ? PikaCharDataPre->PikaCharBaseData.PikaTeam : false;
}
void APikaCharacterBase::PikaIsUpdateLevel(float Exp)
{
PikaCharDataPre->PikaCharBaseData.PikaCurrentExperienceValue += Exp;
if (PikaCharDataPre->PikaCharBaseData.PikaCurrentExperienceValue >= PikaCharDataPre->PikaCharBaseData.PikaMaxExperienceValue)
{
PikaCharDataPre->PikaCharBaseData.PikaUpdateLevel();
UPikaUICharacterAttribute* PikaNewCharacterAttribute = Cast<UPikaUICharacterAttribute>(PikaShowAttribute->GetUserWidgetObject());
// 更新面板
if (PikaNewCharacterAttribute)
PikaNewCharacterAttribute->PikaUpdateLevelCharacterElement();
}
}
void APikaCharacterBase::PikaUpdateLevelCharacterArray(TArray<AActor*> MyActor)
{
for (AActor* PikaOurActor : MyActor)
{
APikaCharacterBase * PikaTempCharacterBase = Cast<APikaCharacterBase>(PikaOurActor);
if (PikaTempCharacterBase)
{
PikaTempCharacterBase->PikaIsUpdateLevel(PikaCharDataPre->PikaCharBaseData.PikaAddExp);
}
}
}
void APikaCharacterBase::PikaCharacterAttributeDisplay(bool IsDisplay)
{
if (PikaShowAttribute && PikaShowAttribute->GetUserWidgetObject())
{
if (IsDisplay)
{
PikaShowAttribute->GetUserWidgetObject()->SetVisibility(ESlateVisibility::Visible);
}
else
{
PikaShowAttribute->GetUserWidgetObject()->SetVisibility(ESlateVisibility::Hidden);
}
}
}PikaCharacterData.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "PikaCharacterData.generated.h"
//角色基础数据结构体
USTRUCT()
struct FPikaCharacterDataAttribute
{
GENERATED_USTRUCT_BODY()
//角色名字
UPROPERTY()
FName PikaCharacterName;
//角色ID
UPROPERTY()
int32 PikaCharacterID;
//角色等级
UPROPERTY()
int32 PikaCharacterLevel;
//最大生命值
UPROPERTY()
float PikaMaxHealth;
//当前生命值
UPROPERTY()
float PikaCurrentHealth;
//死亡状态
UPROPERTY()
bool PikaDeath;
//角色组:True为友方,False为敌对方
UPROPERTY()
bool PikaTeam;
//物理攻击
UPROPERTY()
float PikaPhysicalAttack;
//护甲
UPROPERTY()
float PikaArmor;
//最大经验值
UPROPERTY()
float PikaMaxExperienceValue;
//当前经验值
UPROPERTY()
float PikaCurrentExperienceValue;
//攻击速度
UPROPERTY()
float PikaAttackSpeed;
//最小攻击速度
UPROPERTY()
float PikaAttackSpeedMin;
//建造时需要消耗的金币数
UPROPERTY()
float PikaComsumeGold;
//消灭时获得的金币数
UPROPERTY()
float PikaAddComsume;
//升级(每级加多少)
//添加生命值
UPROPERTY()
float PikaAddHealth;
//添加攻击力
UPROPERTY()
float PikaAddPhsicalAttack;
//添加护甲
UPROPERTY()
float PikaAddArmor;
//添加经验值
UPROPERTY()
float PikaAddExp;
//添加攻击速度
UPROPERTY()
float PikaAddAttackSpeed;
//添加金币
UPROPERTY()
float PikaAddGlod;
//奖励金币
UPROPERTY()
float PikaRewardGlod;
//属性初始化
FPikaCharacterDataAttribute();
//获取经验值百分比
float PikaGetEmpircalValuePercentage() const { return PikaMaxExperienceValue ? PikaCurrentExperienceValue / PikaMaxExperienceValue : 0; }
//生命值百分比
float PikaGetHealthValuePercentage() const { return PikaMaxHealth ? PikaCurrentHealth / PikaMaxHealth : 0; }
//角色注册后主动调用一次,用导入的csv数据进行初始化
void PikaInitCharacterAttrubute(float PikaMyMaxHealth , float PikaMyPhysicalAttack , float PikaMyAttackSpeed , float PikaMyMaxExperienceValue , float PikaMyArmor)
{
PikaMaxHealth = PikaMyMaxHealth;
PikaPhysicalAttack = PikaMyPhysicalAttack;
PikaAttackSpeed = PikaMyAttackSpeed;
PikaMaxExperienceValue = PikaMyMaxExperienceValue;
PikaArmor = PikaMyArmor;
PikaCurrentExperienceValue = 0;
PikaCurrentHealth = PikaMaxHealth;
PikaDeath = false;
//保存初始速度
PikaAttackSpeedMin = PikaAttackSpeed;
PikaCharacterLevel = 0;
}
//角色注册后主动调用一次
void PikaInitAddCharacterAttribute(float PikaMyAddHealth , float PikaMyAddPhsicalAttack , float PikaMyAddArmor , float PikaMyAddExp , float PikaMyAddAttackSpeed)
{
PikaAddHealth = PikaMyAddHealth;
PikaAddPhsicalAttack = PikaMyAddPhsicalAttack;
PikaAddArmor = PikaMyAddArmor;
PikaAddExp = PikaMyAddExp;
PikaAddAttackSpeed = PikaMyAddAttackSpeed;
}
//角色升级
void PikaUpdateLevel()
{
PikaCharacterLevel += 1;
PikaMaxHealth += (PikaCharacterLevel - 1)*PikaAddHealth;
PikaPhysicalAttack += (PikaCharacterLevel - 1)*PikaAddPhsicalAttack;
PikaAttackSpeed += (PikaCharacterLevel - 1)*PikaAddAttackSpeed;
//PikaMaxExperienceValue += (PikaCharacterLevel - 1)*PikaAddExp;
PikaArmor += (PikaCharacterLevel - 1)*PikaAddArmor;
PikaCurrentExperienceValue = 0;
PikaCurrentHealth = PikaMaxHealth;
UE_LOG(LogTemp, Log, TEXT("Pika:UpdateLevel Successfully!"));
return;
}
};
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaCharacterData : public UObject
{
GENERATED_BODY()
public:
FPikaCharacterDataAttribute PikaCharBaseData;
};PikaCharacterData.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaCharacterData.h"
FPikaCharacterDataAttribute::FPikaCharacterDataAttribute()
{
//角色名字
PikaCharacterName = "NoOne";
//角色ID
PikaCharacterID = 1;
//角色等级
PikaCharacterLevel = 1;
//最大生命值
PikaMaxHealth = 1000;
//当前生命值
PikaCurrentHealth = 1000;
//死亡状态
PikaDeath = false;
//角色组:True为友方,False为敌对方
PikaTeam = false;
//物理攻击
PikaPhysicalAttack = 100.f;
//护甲
PikaArmor = 10.f;
//最大经验值
PikaMaxExperienceValue = 6000.f;
//当前经验值
PikaCurrentExperienceValue = 0.f;
//增加经验值
PikaAddExp = 100.f;
//攻击速度
PikaAttackSpeed = PikaAttackSpeedMin = 0.66;
//建造时需要消耗的金币数
PikaComsumeGold = 100.f;
//消灭时获得的金币数
PikaAddComsume = 10.f;
}PikaCharacterInfoDataTable.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/DataTable.h"
#include "PikaCharacterInfoDataTable.generated.h"
UENUM()
namespace EPikaCharacterInfoDataTableType
{
enum Type
{
// 基础数据
DATA_PikaCharacterHealth,
DATA_PikaCharacterAttack,
DATA_PikaCharacterArm,
DATA_PikaCharacterEmpircalValue,
DATA_PikaCharacterAttackSpeed,
DATA_PikaCharacterComsumeGlod,
DATA_PikaCharacterConstructionTime,
//增加数据
DATA_PikaCharacterAddGlod,
DATA_PikaCharacterAddHealth,
DATA_PikaCharacterAddPhysicalAttack,
DATA_PikaCharacterAddArmor,
DATA_PikaCharacterAddEmpiricalValue,
DATA_PikaCharacterAddAttackSpeed,
DATA_PikaCharacterMax
};
}
/**
*
*/
USTRUCT(BlueprintType)
struct FPikaCharacterInfoDataTable : public FTableRowBase
{
GENERATED_BODY()
public:
//角色ID
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
int32 PikaCharacterID;
//角色图片
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
TAssetPtr<UTexture2D> PikaIcon;
//角色蓝图实例
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
TAssetSubclassOf<AActor> PikaCharacterBlueprintKey;
//基础属性
//最大生命值
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
float PikaMaxHealth;
//物理攻击
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
float PikaPhysicalAttack;
//护甲
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
float PikaArmor;
//最大经验值
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
float PikaMaxExperienceValue;
//攻击速度
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
float PikaAttackSpeed;
//建造时需要消耗的金币数
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
float PikaComsumeGold;
//建造时需要的时间
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
float PikaConstructionTime;
//角色简介
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
FText PikaComment;
//添加
//增加经验值
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
float PikaAddExperienceValue;
//消灭时获得的金币数
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
float PikaAddComsume;
//增加生命值
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
float PikaAddHealth;
//增加攻击力
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
float PikaAddPhysicalAttack;
//增加护甲
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
float PikaAddArmor;
//添加攻击速度
UPROPERTY(EditDefaultsOnly, Category = "PikaDataTable")
float PikaAddAttackSpeed;
FPikaCharacterInfoDataTable();
};PikaCharacterInfoDataTable.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaCharacterInfoDataTable.h"
FPikaCharacterInfoDataTable::FPikaCharacterInfoDataTable():
//角色ID
PikaCharacterID(1),
//最大生命值
PikaMaxHealth(1000),
//物理攻击
PikaPhysicalAttack(100.f),
//护甲
PikaArmor(10.f),
//最大经验值
PikaMaxExperienceValue(6000.f),
//增加经验值
PikaAddExperienceValue(100.f),
//攻击速度
PikaAttackSpeed(0.66),
//建造时需要消耗的金币数
PikaComsumeGold(100.f),
//消灭时获得的金币数
PikaAddComsume(10.f)
{
}PikaDamageValueText.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "WidgetComponent.h"
#include "Components/SceneComponent.h"
#include "Components/TimelineComponent.h"
#include "PikaDamageValueText.generated.h"
UCLASS()
class PIKAGODSTONE_API APikaDamageValueText : public AActor
{
GENERATED_BODY()
UPROPERTY(VisibleAnywhere , BlueprintReadOnly , Category="PikaDamage" , meta=(AllowPrivateAccess = "true"))
class UWidgetComponent * PikaDamageValueUMG;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaDamage", meta = (AllowPrivateAccess = "true"))
class USceneComponent * PikaRootPoint;
UPROPERTY(EditDefaultsOnly, Category = "PikaDamage")
float PikaTextHeight;
public:
// Sets default values for this actor's properties
APikaDamageValueText();
//绘制伤害
void PikaDrawDamage(float DamageValue, float DamagePercentage);
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// 范围攻击,该曲线由蓝图载入
UPROPERTY(EditDefaultsOnly, Category = "PikaBullet")
UCurveFloat * PikaCurveFloat;
UPROPERTY()
FTimeline PikaRangeAttackTimeLine;
//范围攻击球体的半径
UPROPERTY(EditDefaultsOnly, Category = "PikaBullet")
float PikaBoxDamageTargetRadius;
UFUNCTION()
void PikaTimeLineRangeAttack(float PikaValue);
UFUNCTION()
void PikaTimeLineFinished();
};PikaDamageValueText.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaDamageValueText.h"
#include "Public/PikaUI_InformationWeight.h"
// Sets default values
APikaDamageValueText::APikaDamageValueText()
{
// 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;
PikaDamageValueUMG = CreateDefaultSubobject<UWidgetComponent>(TEXT("PikaParticleMesh"));
PikaRootPoint = CreateDefaultSubobject<USceneComponent>(TEXT("PikaHomingPoint"));
RootComponent = PikaRootPoint;
PikaDamageValueUMG->AttachToComponent(PikaRootPoint, FAttachmentTransformRules::KeepRelativeTransform);
}
//绘制伤害
void APikaDamageValueText::PikaDrawDamage(float DamageValue, float DamagePercentage)
{
if (PikaDamageValueUMG && PikaDamageValueUMG->GetUserWidgetObject())
{
UPikaUI_InformationWeight* PikaMyInformationWidget = Cast<UPikaUI_InformationWeight>(PikaDamageValueUMG->GetUserWidgetObject());
if (PikaMyInformationWidget)
{
PikaMyInformationWidget->PikaDrawUIToScreen();
PikaMyInformationWidget->PikaDrawSubtractionHealthInformation(DamageValue, DamagePercentage);
}
}
}
// Called when the game starts or when spawned
void APikaDamageValueText::BeginPlay()
{
Super::BeginPlay();
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 APikaDamageValueText::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (PikaCurveFloat)
{
PikaRangeAttackTimeLine.TickTimeline(DeltaTime);
}
}
void APikaDamageValueText::PikaTimeLineRangeAttack(float PikaValue)
{
if (PikaDamageValueUMG && PikaTextHeight>0)
{
FVector PikaBoxDamageCurrentRadius = FMath::Lerp(FVector::ZeroVector , FVector(0 , 0 , PikaTextHeight) , PikaValue);
PikaDamageValueUMG->AddRelativeLocation(PikaBoxDamageCurrentRadius);
}
}
void APikaDamageValueText::PikaTimeLineFinished()
{
Destroy(true);
}PikaDisplaceTrigger.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/BoxComponent.h"
#include "PikaGodStoneCamera.h"
#include "PikaDisplaceTrigger.generated.h"
UCLASS()
class PIKAGODSTONE_API APikaDisplaceTrigger : public AActor
{
GENERATED_BODY()
//碰撞组件
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBox", meta = (AllowPrivateAccess = "true"))
UBoxComponent * PikaBox_1;
//根组件
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PikaBox", meta = (AllowPrivateAccess = "true"))
USceneComponent * PikaRoot;
//存储Camera的指针
UPROPERTY()
APikaGodStoneCamera * PikaCameraPawn;
public:
// Sets default values for this actor's properties
APikaDisplaceTrigger();
//蓝图中可以编辑的变量
UPROPERTY(EditAnywhere , BlueprintReadWrite , Category = "PikaUI")
float PikaAddDistance;
UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "PikaEventAddDistance"), Category = "PikaEvent")
void PikaAddDistanceCamera(AActor * OtherActor);
UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "PikaEventSubstractDistance"), Category = "PikaEvent")
void PikaSubstractDistanceCamera(AActor * OtherActor);
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);
UFUNCTION()
void PikaEndOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex);
//打印测试
UFUNCTION()
void PikaPrint(FString piksStr);
};PikaDisplaceTrigger.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaDisplaceTrigger.h"
// Sets default values
APikaDisplaceTrigger::APikaDisplaceTrigger()
{
// 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;
//创建碰撞组件
PikaBox_1 = CreateDefaultSubobject<UBoxComponent>(TEXT("PikaDisplacementTrigger_1"));
PikaRoot = CreateDefaultSubobject<USceneComponent>(TEXT("PikaRoot_1"));
RootComponent = PikaRoot;
//绑定
PikaBox_1->AttachToComponent(PikaRoot, FAttachmentTransformRules::KeepRelativeTransform);
}
// Called when the game starts or when spawned
void APikaDisplaceTrigger::BeginPlay()
{
Super::BeginPlay();
//绑定碰撞的事件
PikaBox_1->OnComponentBeginOverlap.AddUniqueDynamic(this, &APikaDisplaceTrigger::PikaBeginOverlapping);
PikaBox_1->OnComponentEndOverlap.AddUniqueDynamic(this, &APikaDisplaceTrigger::PikaEndOverlapping);
if (GetWorld())
{
//获取MainCamera的指针
PikaCameraPawn = Cast<APikaGodStoneCamera>(GetWorld()->GetFirstPlayerController()->GetPawn());
}
}
// Called every frame
void APikaDisplaceTrigger::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void APikaDisplaceTrigger::PikaBeginOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
PikaAddDistanceCamera(OtherActor);
}
void APikaDisplaceTrigger::PikaEndOverlapping(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex)
{
PikaSubstractDistanceCamera(OtherActor);
}
void APikaDisplaceTrigger::PikaPrint(FString piksStr)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 6.0f, FColor::Red, piksStr);
}
}PikaDragDropOperation.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/DragDropOperation.h"
#include "PikaUIWidgetBase.h"
#include "PikaDragDropOperation.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaDragDropOperation : public UDragDropOperation
{
GENERATED_BODY()
public:
//PikaUI_InventorySlot类的指针
UPROPERTY()
UPikaUIWidgetBase* PikaInventorySlot;
};PikaDragDropOperation.cpp
// Fill out your copyright notice in the Description page of Project Settings. #include "Public/PikaDragDropOperation.h"
PikaGameErrorHint.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 "PikaGameErrorHint.generated.h"
class UPikaMainInterface;
class UPikaUIMainHall;
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaGameErrorHint : public UPikaUIWidgetBase
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaGameLogName;
public:
UPikaGameErrorHint();
float PikaLogDisplayTime;
bool PikaCheckTime;
//相当于BeginPlay,用于解决BeginPlay执行时,有些资源可能还没加载完成的问题
virtual void PikaDrawUIToScreen() override;
//负责打印GameLOG
UFUNCTION()
virtual void PikaLogPrintf(FString MyString) override;
//NativeTick函数里会调用蓝图里的Tick
virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;
UPikaMainInterface* PikaGetMainInterface() const { return PikaMainInterface; }
void PikaSetMainInterface(UPikaMainInterface* NewWidget) { PikaMainInterface = NewWidget; }
UPikaUIMainHall* PikaGetMainHall() const { return PikaMainHall; }
void PikaSetMainHall(UPikaUIMainHall* NewWidget) { PikaMainHall = NewWidget; }
private:
UPikaMainInterface* PikaMainInterface;
UPikaUIMainHall* PikaMainHall;
UTextBlock* PikaGameLog;
};PikaGameErrorHint.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGameErrorHint.h"
UPikaGameErrorHint::UPikaGameErrorHint()
{
PikaLogDisplayTime = 0.f;
PikaCheckTime = false;
}
void UPikaGameErrorHint::PikaDrawUIToScreen()
{
PikaGameLog = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaGameLogName));
if (PikaGetMainInterface())
PikaGetMainInterface()->PikaLog.AddDynamic(this , &UPikaGameErrorHint::PikaLogPrintf);
if (PikaGameLog)
PikaGameLog->SetVisibility(ESlateVisibility::Hidden);
}
void UPikaGameErrorHint::PikaLogPrintf(FString MyString)
{
if (PikaGameLog)
{
PikaGameLog->SetText(FText::FromString(MyString));
PikaGameLog->SetVisibility(ESlateVisibility::Visible);
}
if (PikaUIDataPtr)
PikaLogDisplayTime = PikaUIDataPtr->PikaLogDisplayTime;
}
void UPikaGameErrorHint::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
Super::NativeTick(MyGeometry , InDeltaTime);
if (PikaLogDisplayTime > 0)
{
PikaLogDisplayTime -= InDeltaTime;
PikaCheckTime = true;
return;
}
if (PikaCheckTime && PikaGameLog)
{
PikaCheckTime = false;
PikaGameLog->SetVisibility(ESlateVisibility::Hidden);
}
}PikaGameManager.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/CheatManager.h"
#include "Public/PikaGodStonePlayerController.h"
#include "Public/PikaGodStonePlayerState.h"
#include "Public/PikaGodStoneCamera.h"
#include "PikaGameManager.generated.h"
/**
*
*/
UCLASS(Within = PikaGodStonePlayerController)
class PIKAGODSTONE_API UPikaGameManager : public UCheatManager
{
GENERATED_BODY()
public:
UFUNCTION(exec)
void PikaLogPrint();
//添加一个塔
UFUNCTION(exec)
void PikaAddTowers(int32 TowerID , int32 TowerLevel , int32 TowerCount);
APikaGodStonePlayerController * PikaGetPC();
APikaGodStonePlayerState * PikaGetTowersPlayerState();
APikaGodStoneCamera * PikaGetTowerCamera();
};PikaGameManager.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGameManager.h"
void UPikaGameManager::PikaLogPrint()
{
FString PiksStr = "pikapika";
float PikaFloat = 0.22;
int32 PikaInt = 123;
UE_LOG(LogTemp , Log , TEXT("PikaOK"));
UE_LOG(LogTemp , Warning , TEXT("%s , %f , %i") , *PiksStr , PikaFloat , PikaInt);
UE_LOG(LogTemp, Error, TEXT("%s , %f , %i"), *PiksStr, PikaFloat, PikaInt);
}
//添加一个塔
void UPikaGameManager::PikaAddTowers(int32 TowerID, int32 TowerLevel, int32 TowerCount)
{
if (!(TowerCount >= 1))
{
UE_LOG(LogTemp , Warning ,TEXT("%i < 1") , TowerCount);
return;
}
for (int32 i=0 ; i<TowerCount ; i++)
{
PikaGetPC()->PikaSpawnTowers(TowerID , TowerLevel);
}
}
APikaGodStonePlayerController * UPikaGameManager::PikaGetPC()
{
return ((APikaGodStonePlayerController *)GetOuterAPlayerController());
}
APikaGodStonePlayerState * UPikaGameManager::PikaGetTowersPlayerState()
{
return PikaGetPC()->PikaGetTowerPlayerState();
}
APikaGodStoneCamera * UPikaGameManager::PikaGetTowerCamera()
{
return PikaGetPC()->PikaGetTowreCamera();
}PikaGameResource.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "Engine/Texture2D.h"
#include "Sound/SoundAttenuation.h"
#include "PikaGameResource.generated.h"
class APikaGodStonePlayerController;
USTRUCT()
struct FPikaMiniMap
{
GENERATED_BODY()
//Minimap的地图
UPROPERTY(EditDefaultsOnly, Category = "PikaMiniMap")
UTexture2D* PikaMiniMapTexture;
//地图的宽
UPROPERTY(EditDefaultsOnly, Category = "PikaMiniMap")
float PikaMiniMapSizeX;
//地图的高
UPROPERTY(EditDefaultsOnly, Category = "PikaMiniMap")
float PikaMiniMapSizeY;
//地图的宽与X轴屏幕的间隔
UPROPERTY(EditDefaultsOnly, Category = "PikaMiniMap")
float PikaMiniMapSizeXInterval;
//地图的高与Y轴屏幕的间隔
UPROPERTY(EditDefaultsOnly, Category = "PikaMiniMap")
float PikaMiniMapSizeYInterval;
//真实地图的大小
UPROPERTY(EditDefaultsOnly, Category = "PikaMap")
float PikaMapSizeX;
//真实地图的大小
UPROPERTY(EditDefaultsOnly, Category = "PikaMap")
float PikaMapSizeY;
FPikaMiniMap()
{
PikaMiniMapSizeX = 256;
PikaMiniMapSizeY = 256;
PikaMiniMapSizeXInterval = 30;
PikaMiniMapSizeYInterval = 30;
//PikaMapSizeX和PikaMapSizeY的值需要在UE编辑器里的非透视图里,按下鼠标中键进行测量
PikaMapSizeX = 15000;
PikaMapSizeY = 15000;
}
};
/**
*
*/
UCLASS(Blueprintable)
class PIKAGODSTONE_API UPikaGameResource : public UObject
{
GENERATED_BODY()
public:
UPikaGameResource();
/*******************MapStart********************/
UPROPERTY(EditDefaultsOnly, Category = "Mini Map")
TArray<FPikaMiniMap> PikaLevelMiniMap;
UPROPERTY(EditDefaultsOnly, Category = "Mini Map")
UTexture2D* PikaNewCameraBoard;
UPROPERTY(EditDefaultsOnly, Category = "Mini Map")
FVector2D PikaNewCameraBoardSize;
/*******************MapEnd********************/
//hover声音
UPROPERTY(EditDefaultsOnly, Category = "PikaSound")
TArray <USoundBase*> PikaHoverSound;
//unHover声音
UPROPERTY(EditDefaultsOnly, Category = "PikaSound")
TArray <USoundBase*> PikaUnHoverSound;
//初始化我们的资源
void PikaInitializationResource(class APikaGodStonePlayerController* MyController);
FVector2D PikaPlayerLocConverMiniMapCoord(int32 CurrentLevel, AActor* NewTargetActor, APawn* Player);
//战斗的声音衰减体积框
UPROPERTY(EditDefaultsOnly, Category = "PikaSoundVolume")
USoundAttenuation* PikaFightingSoundVolume;
};PikaGameResource.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGameResource.h"
UPikaGameResource::UPikaGameResource()
{
}
void UPikaGameResource::PikaInitializationResource(class APikaGodStonePlayerController* MyController)
{
}
FVector2D UPikaGameResource::PikaPlayerLocConverMiniMapCoord(int32 CurrentLevel, AActor* NewTargetActor, APawn* Player)
{
FVector2D PikaMiniMapSize = FVector2D::ZeroVector;
if (Player && NewTargetActor)
{
FVector PikaPlayerLocation = (-1 * (NewTargetActor->GetActorRotation())).RotateVector(Player->GetActorLocation() - NewTargetActor->GetActorLocation());
PikaMiniMapSize = FVector2D(PikaPlayerLocation.X / PikaLevelMiniMap[CurrentLevel].PikaMapSizeX, PikaPlayerLocation.Y / (PikaLevelMiniMap[CurrentLevel].PikaMapSizeY));
}
return PikaMiniMapSize;
}PikaGameSaveData.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/SaveGame.h"
#include "PikaGodStoneMacroLib.h"
#include "PikaGameSaveData.generated.h"
#define LevelMax (5)
//读存数据表
USTRUCT()
struct FPikaReadGameData
{
GENERATED_USTRUCT_BODY()
//我们存了多少个档,存储的内容和日期
UPROPERTY(SaveGame)
TArray<FString> PikaSaveDataText;
//对应有存档的角标
UPROPERTY(SaveGame)
TArray<int32> PikaSaveGameBoxNumberArray;
//关卡完成度
UPROPERTY(SaveGame)
TArray<float> PikaDegreeOfCompletion;
//最大关卡
UPROPERTY(SaveGame)
int32 PikaMaxLevel;
//还原某个数据
void PikaClearReadGameDataAt(int32 IndexNumber)
{
if (PikaSaveDataText.IsValidIndex(IndexNumber))
{
PikaSaveDataText[IndexNumber] = PIKA_SAVE_PIKA;
int32 PikaNewIndexGameBox = PikaSaveGameBoxNumberArray.Find(IndexNumber);
if (PikaNewIndexGameBox != INDEX_NONE)
{
PikaSaveGameBoxNumberArray[PikaNewIndexGameBox] = -1;
}
else
{
PIKA_UE_PRINT(FString::Printf(TEXT("SaveGameBoxNumberArray[NewIndexGameBox] = !&&**%&^@$ ,NewIndexGameBox = %i"), PikaNewIndexGameBox));
}
}
else
{
PIKA_UE_PRINT(FString::Printf(TEXT("Nothingness %i"), IndexNumber));
}
}
//清空数据
void PikaClearData()
{
PikaSaveDataText.Empty();
PikaSaveGameBoxNumberArray.Empty();
PikaDegreeOfCompletion.Empty();
}
//初始化数据尺寸
void PikaInitDataSzie()
{
PikaSaveDataText.SetNum(Pika_SAVE_SaveBarNumber);
PikaSaveGameBoxNumberArray.SetNum(Pika_SAVE_SaveBarNumber);
PikaDegreeOfCompletion.SetNum(LevelMax);
PikaMaxLevel = 0;
for (int32 i = 0; i < Pika_SAVE_SaveBarNumber; i++)
{
PikaSaveDataText[i] = PIKA_SAVE_PIKA;
PikaSaveGameBoxNumberArray[i] = INDEX_NONE;
}
for (int32 i = 0; i < LevelMax; i++)
{
PikaDegreeOfCompletion[i] = 0;
}
}
//获取PIKA_SAVE_SLOT_NAME存档里第一个空位置的index
int32 PikaGetSerialNumber()
{
int32 PikaSaveBarNumber = Pika_SAVE_SaveBarNumber;
if (!((PikaSaveDataText.Num() & PikaSaveGameBoxNumberArray.Num())) == PikaSaveBarNumber)
return INDEX_NONE;
int32 PikaIntIndex = INDEX_NONE;
for (int32 i = 0; i < Pika_SAVE_SaveBarNumber; i++)
{
if (PikaSaveDataText[i] == PIKA_SAVE_PIKA)
{
PikaIntIndex = i;
break;
}
}
return PikaIntIndex;
}
FPikaReadGameData()
{
if (PikaSaveGameBoxNumberArray.Num() == 0)
{
PikaInitDataSzie();
}
}
//需要载入operator=,如果是基础的数据元素,不需要,但是其中有TArray<>,该类需要operator=
FPikaReadGameData& operator=(const FPikaReadGameData& object)
{
PikaSaveDataText = object.PikaSaveDataText;
PikaSaveGameBoxNumberArray = object.PikaSaveGameBoxNumberArray;
PikaDegreeOfCompletion = object.PikaDegreeOfCompletion;
PikaMaxLevel = PikaMaxLevel;
return *this;
}
};
//此数据是我们游戏角色在场景内的缓存
USTRUCT()
struct FPikaTemporaryCacheData
{
GENERATED_USTRUCT_BODY()
//角色生成的混合ID
UPROPERTY(SaveGame)
TArray<int32> PikaCharacterSpawnID;
//角色队伍
UPROPERTY(SaveGame)
TArray<bool> PikaCharacterTeam;
//角色存活
UPROPERTY(SaveGame)
TArray<bool> PikaCharacterActive;
//角色位置
UPROPERTY(SaveGame)
TArray<FVector> PikaCharacterLocation;
//角色旋转
UPROPERTY(SaveGame)
TArray<FRotator> PikaCharacterRotator;
//角色名字(通过角色的名字寻找到该角色)
UPROPERTY(SaveGame)
TArray<FName> PikaCharacterName;
//当前生命值
UPROPERTY(SaveGame)
TArray<float> PikaCharacterCurrentHealth;
//当前经验值
UPROPERTY(SaveGame)
TArray<float> PikaCharacterCurrentExp;
//当前等级
UPROPERTY(SaveGame)
TArray<int32> PikaCharacterCurrentLevel;
FPikaTemporaryCacheData()
{
}
//全部移除
~FPikaTemporaryCacheData()
{
for (int32 IndexNumber = 0; IndexNumber < PikaCharacterSpawnID.Num(); IndexNumber++)
{
PikaRemoveIt(IndexNumber);
}
}
//获取当前的角标
int32 PikaGetCurrentCharacterSpawnIDIndex(int32 PawnSpawnID)
{
return PikaCharacterSpawnID.Find(PawnSpawnID);
}
//判断角标是不是存在数组范围内 判断当前是不是锁住状态
bool PikaIsActive(int32 Index)
{
return (Index >= 0 && Index < PikaCharacterSpawnID.Num()) ? true : false;
}
//判断ID是否有相同的
bool PikaIsExistSpawnID(int32 SpawnID)
{
return (PikaCharacterSpawnID.Find(SpawnID) != INDEX_NONE) ? true : false;
}
//移除单个
void PikaRemoveIt(int32 Index = INDEX_NONE)
{
if (PikaIsActive(Index))
{
if(PikaCharacterSpawnID.IsValidIndex(Index))
PikaCharacterSpawnID.RemoveAt(Index);
if (PikaCharacterTeam.IsValidIndex(Index))
PikaCharacterTeam.RemoveAt(Index);
if (PikaCharacterActive.IsValidIndex(Index))
PikaCharacterActive.RemoveAt(Index);
if (PikaCharacterLocation.IsValidIndex(Index))
PikaCharacterLocation.RemoveAt(Index);
if (PikaCharacterRotator.IsValidIndex(Index))
PikaCharacterRotator.RemoveAt(Index);
if (PikaCharacterName.IsValidIndex(Index))
PikaCharacterName.RemoveAt(Index);
if (PikaCharacterCurrentHealth.IsValidIndex(Index))
PikaCharacterCurrentHealth.RemoveAt(Index);
if (PikaCharacterCurrentExp.IsValidIndex(Index))
PikaCharacterCurrentExp.RemoveAt(Index);
if (PikaCharacterCurrentLevel.IsValidIndex(Index))
PikaCharacterCurrentLevel.RemoveAt(Index);
}
}
FPikaTemporaryCacheData & operator=(const FPikaTemporaryCacheData &object)
{
PikaCharacterSpawnID = object.PikaCharacterSpawnID;
PikaCharacterTeam = object.PikaCharacterTeam;
PikaCharacterActive = object.PikaCharacterActive;
PikaCharacterLocation = object.PikaCharacterLocation;
PikaCharacterRotator = object.PikaCharacterRotator;
PikaCharacterName = object.PikaCharacterName;
PikaCharacterCurrentHealth = object.PikaCharacterCurrentHealth;
PikaCharacterCurrentExp = object.PikaCharacterCurrentExp;
PikaCharacterCurrentLevel = object.PikaCharacterCurrentLevel;
return *this;
}
};
USTRUCT()
struct FPikaTowersData
{
GENERATED_USTRUCT_BODY()
float PikaTimeInterval;
FPikaTowersData()
{
PikaTimeInterval = .5;
}
};
//关卡管理
USTRUCT()
struct FPikaGameLevelManangenment
{
GENERATED_USTRUCT_BODY()
//该关卡内怪物数量
UPROPERTY(SaveGame)
int32 PikaNumberOfMonster;
//怪物等级(和游戏难度有关)
UPROPERTY(SaveGame)
int32 PikaAddMonsterLevel;
//如果所有的主塔死亡,该值为true,并且禁止建造任何建筑
UPROPERTY(SaveGame)
uint8 PikaIsAllMainTowerDie : 1;
//所有塔死亡,游戏结束
UPROPERTY(Transient)
uint8 PikaGameOver : 1;
//所有塔死亡,则游戏结束
UPROPERTY(Transient)
uint8 PikaCurrentLevelMissionSuccess : 1;
//塔等级
UPROPERTY(SaveGame)
int32 PikaTowersLevel;
//生成怪物阶段
UPROPERTY(SaveGame)
int32 PikaSpawnMonsterStage;
//当前关卡
UPROPERTY(SaveGame)
int32 PikaCurrentLevel;
//时间间隔(多久生成一次怪物)
UPROPERTY(SaveGame)
float PikaTimeInterval;
//生成怪物的时间记录
UPROPERTY(SaveGame)
float PikaSetTimeMnanagenment;
//第几部分内容
UPROPERTY(SaveGame)
int32 PikaParts;
//有多少波怪物
UPROPERTY(SaveGame)
int32 PikaMaxStagesAreMonsters;
//当前是哪一波怪物
UPROPERTY(SaveGame)
int32 PikaCurrentStagesAreMonsters;
//每波怪物当前数量
UPROPERTY(SaveGame)
TArray<int32> PikaPerNumberOfMonsters;
//判定怪物全部消灭没
void PikaDataSubtraction()
{
if (PikaCurrentStagesAreMonsters < PikaPerNumberOfMonsters.Num())
{
if (PikaPerNumberOfMonsters[PikaCurrentStagesAreMonsters] > 0)
{
PikaPerNumberOfMonsters[PikaCurrentStagesAreMonsters]--;
}
else
{
PikaLock();
}
}
else
{
PikaCurrentLevelMissionSuccess = true;
PikaLock();
}
}
//分配数量梯度,数量从少变多
void PikaAssignedMonsterAmount()
{
//检查构成条件,怪物数量需要大于阶段数量,负责会按照阶段数生成至少一个怪物
if (PikaNumberOfMonster <= PikaMaxStagesAreMonsters)
PikaNumberOfMonster = PikaMaxStagesAreMonsters;
//多少的怪物
int32 PikaCurrentMonsterNumber = PikaNumberOfMonster;
//最大阶段
int32 PikaCurrentStagesNumber = PikaMaxStagesAreMonsters;
//每阶段的数量
int32 PikaCurrentAssignedNum = INDEX_NONE;
for (int32 i = 0; i < PikaMaxStagesAreMonsters; i++)
{
if (PikaCurrentStagesNumber > 0)
{
//每阶段的平均值
int32 PikaStagesNumber = PikaCurrentMonsterNumber / PikaCurrentStagesNumber;
if (PikaCurrentMonsterNumber > 1)
{
//减去该阶段
PikaCurrentStagesNumber--;
if (PikaCurrentStagesNumber != 0)
{
//随机阶段,从平均值一般到平均值分配
PikaCurrentAssignedNum = FMath::RandRange(PikaStagesNumber / 2, PikaStagesNumber);
}
else
{
PikaCurrentAssignedNum = PikaStagesNumber;
}
PikaPerNumberOfMonsters.Add(PikaCurrentAssignedNum);
//减去分配的数量
PikaCurrentMonsterNumber -= PikaCurrentAssignedNum;
}
else if (PikaCurrentMonsterNumber == 1)
{
//对于最后一个阶段
PikaPerNumberOfMonsters.Add(PikaCurrentAssignedNum);
break;
}
}
}
}
//是否大于生成怪物的时间间隔
bool PikaIsTimeRight() { return PikaSetTimeMnanagenment > PikaTimeInterval; }
FPikaGameLevelManangenment()
{
PikaNumberOfMonster = 455;
PikaAddMonsterLevel = 2;
PikaSpawnMonsterStage = 3;
PikaTimeInterval = 6;
PikaSetTimeMnanagenment = 0;
PikaTowersLevel = 1;
PikaCurrentLevel = 0;
PikaIsAllMainTowerDie = false;
PikaGameOver = false;
//PikaMaxStagesAreMonsters = INDEX_NONE;
PikaMaxStagesAreMonsters = 6;
PikaCurrentStagesAreMonsters = 0;
PikaLockSpanwData = false;
PikaParts = 0;
}
FPikaGameLevelManangenment& operator=(const FPikaGameLevelManangenment& NewObj)
{
PikaNumberOfMonster = NewObj.PikaNumberOfMonster;
PikaAddMonsterLevel = NewObj.PikaAddMonsterLevel;
PikaSpawnMonsterStage = NewObj.PikaSpawnMonsterStage;
PikaSetTimeMnanagenment = NewObj.PikaSetTimeMnanagenment;
PikaTowersLevel = NewObj.PikaTowersLevel;
PikaCurrentLevel = NewObj.PikaCurrentLevel;
PikaTimeInterval = NewObj.PikaTimeInterval;
PikaIsAllMainTowerDie = NewObj.PikaIsAllMainTowerDie;
PikaPerNumberOfMonsters = NewObj.PikaPerNumberOfMonsters;
PikaMaxStagesAreMonsters = NewObj.PikaMaxStagesAreMonsters;
PikaCurrentStagesAreMonsters = NewObj.PikaCurrentStagesAreMonsters;
PikaLockSpanwData = NewObj.PikaLockSpanwData;
PikaParts = NewObj.PikaParts;
return *this;
}
//数据锁
FORCEINLINE void PikaLock() { PikaLockSpanwData = true; }
FORCEINLINE void PikaUnLock() { PikaLockSpanwData = false; }
FORCEINLINE bool PikaGetLock() const { return PikaLockSpanwData; }
FORCEINLINE bool PikaIsExistDataMonster() const { return PikaPerNumberOfMonsters.IsValidIndex(PikaCurrentStagesAreMonsters) ? (PikaPerNumberOfMonsters[PikaCurrentStagesAreMonsters] > 0) : false; }
private:
//锁住数据
UPROPERTY(SaveGame)
uint8 PikaLockSpanwData : 1;
};
//故事
struct FPikaGameStory
{
TArray<FString> PikaStoryNor;
TArray<FString> PikaStorySuc;
TArray<FString> PikaStoryFai;
};
//游戏本地的玩家数据
USTRUCT()
struct FPikaGodStoneSaveGameData
{
GENERATED_BODY()
//总时间的倒计时
UPROPERTY(SaveGame)
float PikaGameCount;
//总时间的倒计时
UPROPERTY(SaveGame)
float PikaMaxGameCount;
UPROPERTY(Transient)
float PikaGoldGrowthTime;
UPROPERTY(Transient)
float PikaGoldGrowthMaxTime;
//杀死敌人总数量
UPROPERTY(SaveGame)
float PikaKillSoldierNumber;
//杀死Boss数量
UPROPERTY(SaveGame)
float PikaKillBossNumber;
//塔死亡总数
UPROPERTY(SaveGame)
float PikaTowersDeathNumber;
//主塔死亡数
UPROPERTY(SaveGame)
float PikaMainTowersDeathNumber;
//准备建造塔的数量
UPROPERTY(SaveGame)
TArray<int32> PikaTowerPrepareBuildingNumber;
//已完成的塔的数量
UPROPERTY(SaveGame)
TArray<int32> PikaTowerConstructionNumber;
//已经完成的数量
UPROPERTY(SaveGame)
TArray<int32> PikaTowerLikeID;
//显示数字的CD
UPROPERTY(SaveGame)
TArray<float> PikaTowersCurrentCDNumber;
//是否更新TowerCD
UPROPERTY(SaveGame)
TArray<bool> PikaIsUpdateTowersCDArray;
/*****************玩家技能********************/
//当前技能(4个技能)
UPROPERTY(SaveGame)
TArray<float> PikaCurrentSkillCDArray;
//处于技能中状态
UPROPERTY(SaveGame)
TArray<bool> PikaIsSkillCDArray;
//技能数量
UPROPERTY(SaveGame)
TArray<int32> PikaSkillNumberArray;
//最大技能值
UPROPERTY(SaveGame)
TArray<int32> PikaMaxSkillCDArray;
FPikaGodStoneSaveGameData(int32 Set_Size, bool IsSkill = false)
{
if (IsSkill)
{
PikaReSkillSzie(Set_Size);
}
else
{
PikaReSzie(Set_Size);
}
}
FPikaGodStoneSaveGameData()
{
PikaMaxGameCount = 3600;
PikaGameCount = 1800;
PikaKillSoldierNumber = 0;
PikaGold = 6000;
PikaTowersDeathNumber = 0;
PikaTowersCurrentCDNumber.Empty();
PikaIsUpdateTowersCDArray.Empty();
PikaTowerLikeID.Empty();
PikaTowerConstructionNumber.Empty();
PikaNumSize = 0;
PikaSkillNumSize = 0;
PikaCurrentSkillCDArray.Empty();
PikaIsSkillCDArray.Empty();
PikaSkillNumberArray.Empty();
PikaMaxSkillCDArray.Empty();
PikaGoldGrowthMaxTime = 1.0;
PikaGoldGrowthTime = 0;
}
FPikaGodStoneSaveGameData& operator=(const FPikaGodStoneSaveGameData& NewObj)
{
PikaGameCount = NewObj.PikaGameCount;
PikaMaxGameCount = NewObj.PikaMaxGameCount;
PikaKillSoldierNumber = NewObj.PikaKillSoldierNumber;
PikaTowersDeathNumber = NewObj.PikaTowersDeathNumber;
PikaTowerPrepareBuildingNumber = NewObj.PikaTowerPrepareBuildingNumber;
PikaTowerConstructionNumber = NewObj.PikaTowerConstructionNumber;
PikaTowersCurrentCDNumber = NewObj.PikaTowersCurrentCDNumber;
PikaGold = NewObj.PikaGetGlobalGold();
PikaTowerLikeID = NewObj.PikaTowerLikeID;
PikaIsUpdateTowersCDArray = NewObj.PikaIsUpdateTowersCDArray;
PikaNumSize = NewObj.PikaNumSize;
PikaSkillNumSize = NewObj.PikaSkillNumSize;
PikaCurrentSkillCDArray = NewObj.PikaCurrentSkillCDArray;
PikaIsSkillCDArray = NewObj.PikaIsSkillCDArray;
PikaSkillNumberArray = NewObj.PikaSkillNumberArray;
PikaMaxSkillCDArray = NewObj.PikaMaxSkillCDArray;
return *this;
}
//获取金币
int32 PikaGetGlobalGold()const { return PikaGold; }
//添加金币
void PikaAddGlobalGold(int32 AddGold) { PikaGold += AddGold; }
//减去金币
void PikaConsumeGlobalGold(int32 ConsumeGold) { PikaGold -= ConsumeGold;}
//判断金币增长时间
bool PikaIsJudgement() const { return PikaGoldGrowthTime > PikaGoldGrowthMaxTime; }
//关卡进度百分比
float PikaGetLevelPercentage() { return (PikaGameCount >= 0) ? PikaGameCount / PikaMaxGameCount : 0; }
//清除某个数据
void PikaClearIndexData(int32 PIndex)
{
check(PikaTowerPrepareBuildingNumber.IsValidIndex(PIndex));
PikaTowerPrepareBuildingNumber[PIndex] = 0;
PikaTowerConstructionNumber[PIndex] = 0;
PikaTowersCurrentCDNumber[PIndex] = 0;
PikaTowerLikeID[PIndex] = INDEX_NONE;
PikaIsUpdateTowersCDArray[PIndex] = false;
}
//移动数据
void PikaDataMoveTo(int32 Index, int32 TargetIndex)
{
if (Index != TargetIndex)
{
PikaTowerPrepareBuildingNumber[TargetIndex] = PikaTowerPrepareBuildingNumber[Index];
PikaTowerConstructionNumber[TargetIndex] = PikaTowerConstructionNumber[Index];
PikaTowersCurrentCDNumber[TargetIndex] = PikaTowersCurrentCDNumber[Index];
PikaTowerLikeID[TargetIndex] = PikaTowerLikeID[Index];
PikaIsUpdateTowersCDArray[TargetIndex] = PikaIsUpdateTowersCDArray[Index];
PikaClearIndexData(Index);
}
}
//是否有意义(和塔相关)
bool IsActive(int32 Index)
{
return (PikaNumSize != 0) ? (Index >= 0 && Index < PikaNumSize) : false;
}
//是否有意义(和技能相关)
bool IsSkillActive(int32 Index)
{
return (PikaSkillNumSize != 0) ? (Index >= 0 && Index < PikaSkillNumSize) : false;
}
//交换数据
//@:Index 需要交换的数据
//@:TargetIndex 交换的目标数据
void SwapMyData(int32 Index, int32 TargetIndex)
{
if (IsActive(Index) && IsActive(TargetIndex) && Index != TargetIndex)
{
FPikaGodStoneSaveGameData PikaTmpData(PikaNumSize);
PikaTmpData.PikaTowerPrepareBuildingNumber[TargetIndex] = PikaTowerPrepareBuildingNumber[TargetIndex];
PikaTmpData.PikaTowerConstructionNumber[TargetIndex] = PikaTowerConstructionNumber[TargetIndex];
PikaTmpData.PikaTowersCurrentCDNumber[TargetIndex] = PikaTowersCurrentCDNumber[TargetIndex];
PikaTmpData.PikaTowerLikeID[TargetIndex] = PikaTowerLikeID[TargetIndex];
PikaTmpData.PikaIsUpdateTowersCDArray[TargetIndex] = PikaIsUpdateTowersCDArray[TargetIndex];
PikaTowerPrepareBuildingNumber[TargetIndex] = PikaTowerPrepareBuildingNumber[Index];
PikaTowerConstructionNumber[TargetIndex] = PikaTowerConstructionNumber[Index];
PikaTowersCurrentCDNumber[TargetIndex] = PikaTowersCurrentCDNumber[Index];
PikaTowerLikeID[TargetIndex] = PikaTowerLikeID[Index];
PikaIsUpdateTowersCDArray[TargetIndex] = PikaIsUpdateTowersCDArray[Index];
PikaTowerPrepareBuildingNumber[Index] = PikaTmpData.PikaTowerPrepareBuildingNumber[TargetIndex];
PikaTowerConstructionNumber[Index] = PikaTmpData.PikaTowerConstructionNumber[TargetIndex];
PikaTowersCurrentCDNumber[Index] = PikaTmpData.PikaTowersCurrentCDNumber[TargetIndex];
PikaTowerLikeID[Index] = PikaTmpData.PikaTowerLikeID[TargetIndex];
PikaIsUpdateTowersCDArray[Index] = PikaTmpData.PikaIsUpdateTowersCDArray[TargetIndex];
}
}
//重新设置尺寸
void PikaReSzie(int32 MySize)
{
for (int32 i = 0; i < MySize; i++)
{
PikaTowerPrepareBuildingNumber.Add(0);
PikaTowerConstructionNumber.Add(0);
PikaTowersCurrentCDNumber.Add(0.0f);
PikaTowerLikeID.Add(INDEX_NONE);
PikaIsUpdateTowersCDArray.Add(false);
}
//赋值
PikaNumSize = MySize;
}
//重新Skill设置尺寸
void PikaReSkillSzie(int32 MySize)
{
for (int32 i = 0; i < MySize; i++)
{
PikaCurrentSkillCDArray.Add(0.f);
PikaIsSkillCDArray.Add(false);
PikaSkillNumberArray.Add(0);
PikaMaxSkillCDArray.Add(0);
}
//赋值
PikaSkillNumSize = MySize;
}
private:
//金币
UPROPERTY(SaveGame)
int32 PikaGold;
//Towers数据数量
UPROPERTY(SaveGame)
int32 PikaNumSize;
//Skill数据数量
UPROPERTY(SaveGame)
int32 PikaSkillNumSize;
};
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaGameSaveData : public USaveGame
{
GENERATED_BODY()
public:
UPROPERTY()
FPikaGodStoneSaveGameData PikaGodStongSaveData;
UPROPERTY(SaveGame)
uint64 PikaSaveCount;
UPikaGameSaveData();
UPROPERTY(SaveGame)
bool PikaIsSave;
//UPROPERTY(SaveGame)
//FMissionState MissionState;
UPROPERTY()
FPikaGameLevelManangenment PikaGameLevelManangenment;
UPROPERTY()
FPikaTowersData PikaTowersData;
UPROPERTY()
FPikaTemporaryCacheData PikaTemporaryCacheData;
UPROPERTY()
FPikaReadGameData PikaReadGameData;
void AddStorageTime() { PikaSaveCount++; }
};PikaGameSaveData.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGameSaveData.h"
UPikaGameSaveData::UPikaGameSaveData()
{
PikaIsSave = false;
}PikaGameSettingsAudio.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 "PikaGameSettingsAudio.generated.h"
class UPikaUIHallGameSetting;
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaGameSettingsAudio : public UPikaUIWidgetBase
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaSoundControllSliderName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaSoundEffectSliderName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaMusicSliderName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaAudioSliderName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaSoundControllSliderTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaSoundEffectSliderTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaMusicSliderTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaAudioSliderTextName;
public:
//调用去初始化我们的UI
virtual void PikaDrawUIToScreen()override;
void PikaSetHallGameSettings(UPikaUIHallGameSetting* NewWidget) { PikaHallGameSettings = NewWidget; }
virtual void PikaChangedValue(float Val) override;
virtual void PikaUpdateAttibe() override;
FORCEINLINE UPikaUIHallGameSetting* PikaGetHallGameSettings() const { return PikaHallGameSettings; }
FORCEINLINE USlider* PikaGetSoundControllSlider() const { return PikaSoundControllSlider; }
FORCEINLINE USlider* PikaGetSoundEffectSlider() const { return PikaSoundEffectSlider; }
FORCEINLINE USlider* PikaGetAudioSlider() const { return PikaAudioSlider; }
FORCEINLINE USlider* PikaGetMusicSlider() const { return PikaMusicSlider; }
private:
//总声音控件
USlider* PikaSoundControllSlider;
//特效音乐
USlider* PikaSoundEffectSlider;
//背景音乐
USlider* PikaMusicSlider;
//按钮音效
USlider* PikaAudioSlider;
UTextBlock* PikaSoundControllSliderText;
UTextBlock* PikaSoundEffectSliderText;
UTextBlock* PikaMusicSliderText;
UTextBlock* PikaAudioSliderText;
UPikaUIHallGameSetting* PikaHallGameSettings;
};PikaGameSettingsAudio.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGameSettingsAudio.h"
void UPikaGameSettingsAudio::PikaDrawUIToScreen()
{
PikaSoundControllSlider = PikaGetSliderFormBlueprint(PikaSoundControllSliderName);
PikaSoundEffectSlider = PikaGetSliderFormBlueprint(PikaSoundEffectSliderName);
PikaMusicSlider = PikaGetSliderFormBlueprint(PikaMusicSliderName);
PikaAudioSlider = PikaGetSliderFormBlueprint(PikaAudioSliderName);
PikaSoundControllSliderText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaSoundControllSliderTextName));
PikaSoundEffectSliderText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaSoundEffectSliderTextName));
PikaMusicSliderText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaMusicSliderTextName));
PikaAudioSliderText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaAudioSliderTextName));
}
void UPikaGameSettingsAudio::PikaChangedValue(float Val)
{
PikaUpdateAttibe();
}
void UPikaGameSettingsAudio::PikaUpdateAttibe()
{
if (PikaSoundControllSliderText && PikaSoundControllSlider)
{
uint16 PikaIndexNumber = PikaSoundControllSlider->GetValue() * 10;
FString PikaString_Text = FString::Printf(TEXT("%02d"), PikaIndexNumber);
PikaSoundControllSliderText->SetText(FText::FromString(PikaString_Text));
}
if (PikaSoundEffectSliderText && PikaSoundEffectSlider)
{
uint16 PikaIndexNumber = PikaSoundEffectSlider->GetValue() * 10;
FString PikaString_Text = FString::Printf(TEXT("%02d"), PikaIndexNumber);
PikaSoundEffectSliderText->SetText(FText::FromString(PikaString_Text));
}
if (PikaMusicSliderText && PikaMusicSlider)
{
uint16 PikaIndexNumber = PikaMusicSlider->GetValue() * 10;
FString PikaString_Text = FString::Printf(TEXT("%02d"), PikaIndexNumber);
PikaMusicSliderText->SetText(FText::FromString(PikaString_Text));
}
if (PikaAudioSliderText && PikaAudioSlider)
{
uint16 PikaIndexNumber = PikaAudioSlider->GetValue() * 10;
FString PikaString_Text = FString::Printf(TEXT("%02d"), PikaIndexNumber);
PikaAudioSliderText->SetText(FText::FromString(PikaString_Text));
}
}PikaGameSettingsGameSettings.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "PikaGameSettingsGameSettings.generated.h"
class UPikaUIHallGameSetting;
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaGameSettingsGameSettings : public UPikaUIWidgetBase
{
GENERATED_BODY()
public:
//调用去初始化我们的UI
virtual void PikaDrawUIToScreen()override;
void PikaSetHallGameSettings(UPikaUIHallGameSetting* NewWidget) { PikHallGameSettings = NewWidget; }
private:
UPikaUIHallGameSetting* PikHallGameSettings;
};PikaGameSettingsGameSettings.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGameSettingsGameSettings.h"
void UPikaGameSettingsGameSettings::PikaDrawUIToScreen()
{
}PikaGameSettingsOtherSettings.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PikaUIWidgetBase.h"
#include "PikaGameSettingsOtherSettings.generated.h"
class UPikaUIHallGameSetting;
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaGameSettingsOtherSettings : public UPikaUIWidgetBase
{
GENERATED_BODY()
public:
//调用去初始化我们的UI
virtual void PikaDrawUIToScreen()override;
void PikaSetHallGameSettings(UPikaUIHallGameSetting* NewWidget) { PikHallGameSettings = NewWidget; }
private:
UPikaUIHallGameSetting* PikHallGameSettings;
};PikaGameSettingsOtherSettings.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGameSettingsOtherSettings.h"
void UPikaGameSettingsOtherSettings::PikaDrawUIToScreen()
{
}PikaGameSettingsVideo.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 "PikaGameSettingsVideo.generated.h"
class UPikaUIHallGameSetting;
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaGameSettingsVideo : public UPikaUIWidgetBase
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaResolutionBoxStringName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaFullScreenCheckBoxName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaWindowScreenCheckBoxName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaOverallScalabilityLevelSliderName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaTextureQualitySliderName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaShadowQualitySliderName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaAntiAliasingSliderName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaPostProcessingSliderName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaEffectsSliderName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaFoliageSliderName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaViewDistanceSliderName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUI")
FName PikaFOVSliderName;
//----------------------------------------------------------------
UPROPERTY(EditDefaultsOnly, Category = "PikaUIText")
FName PikaOverallScalabilityLevelSliderTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUIText")
FName PikaTextureQualityTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUIText")
FName PikaShadowQualityTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUIText")
FName PikaAntiAliasingTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUIText")
FName PikaPostProcessingTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUIText")
FName PikaEffectsTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUIText")
FName PikaFoliageTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUIText")
FName PikaViewDistanceTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUIText")
FName PikaFOVTextName;
UPROPERTY(EditDefaultsOnly, Category = "PikaUIText")
FName PikaLanguageStringName;
public:
//调用去初始化我们的UI
virtual void PikaDrawUIToScreen()override;
virtual void PikaUpdateAttibe() override;
virtual void PikaSelectionChangedBySelf(UWidget* MyWidget, FString SelectedItem, ESelectInfo::Type SelectionType) override;
virtual void PikaChangedValue(float Val) override;
virtual void PikaClickedCheckBox(UWidget* MyWidget, bool ClickedWidget);
void PikaSetHallGameSettings(UPikaUIHallGameSetting* NewWidget) { PikaHallGameSettings = NewWidget; }
FORCEINLINE UPikaUIHallGameSetting* PikaGetHallGameSettings() const { return PikaHallGameSettings; }
FORCEINLINE UComboBoxString* PikaGetResolutionBoxString() const { return PikaResolutionBoxString; }
//FORCEINLINE UComboBoxString* PikaGetLanguageString() const { return PikaLanguageString; }
FORCEINLINE USlider* PikaGetAntiAliasingSlider() const { return PikaAntiAliasingSlider; }
FORCEINLINE USlider* PikaGetShadowQualitySlider() const { return PikaShadowQualitySlider; }
FORCEINLINE USlider* PikaGetTextureQualitySlider() const { return PikaTextureQualitySlider; }
FORCEINLINE USlider* PikaGetFOVSlider() const { return PikaFOVSlider; }
FORCEINLINE UCheckBox* PikaGetFullScreenCheckBox() const { return PikaFullScreenCheckBox; }
FORCEINLINE UCheckBox* PikaGetWindowScreenCheckBox() const { return PikaWindowScreenCheckBox; }
FORCEINLINE USlider* PikaGetPostProcessingSlider() const { return PikaPostProcessingSlider; }
FORCEINLINE USlider* PikaGetEffectsSlider() const { return PikaEffectsSlider; }
FORCEINLINE USlider* PikaGetFoliageSlider() const { return PikaFoliageSlider; }
FORCEINLINE USlider* PikaGetViewDistanceSlider() const { return PikaViewDistanceSlider; }
FORCEINLINE USlider* PikaGetOverallScalabilityLevelSlider() const { return PikaOverallScalabilityLevelSlider; }
private:
//分辨率
UComboBoxString* PikaResolutionBoxString;
//全屏checkBox
UCheckBox* PikaFullScreenCheckBox;
//窗口checkBox
UCheckBox* PikaWindowScreenCheckBox;
//总级别控制
USlider* PikaOverallScalabilityLevelSlider;
//贴图
USlider* PikaTextureQualitySlider;
//阴影
USlider* PikaShadowQualitySlider;
//抗锯齿
USlider* PikaAntiAliasingSlider;
//后期
USlider* PikaPostProcessingSlider;
//特效
USlider* PikaEffectsSlider;
//Foliage叶子
USlider* PikaFoliageSlider;
//视距
USlider* PikaViewDistanceSlider;
//摄像机FOV
USlider* PikaFOVSlider;
//语言
//UComboBoxString* PikaLanguageString;
//总级别控制数字显示
UTextBlock* PikaOverallScalabilityLevelSliderText;
//贴图数字显示
UTextBlock* PikaTextureQualityText;
//阴影数字显示
UTextBlock* PikaShadowQualityText;
//抗锯齿数字显示
UTextBlock* PikaAntiAliasingText;
//后期数字显示
UTextBlock* PikaPostProcessingText;
//特效数字显示
UTextBlock* PikaEffectsText;
//Foliage叶子数字显示
UTextBlock* PikaFoliageText;
//视距数字显示
UTextBlock* PikaViewDistanceText;
//摄像机FOV数字显示
UTextBlock* PikaFOVText;
UPikaUIHallGameSetting* PikaHallGameSettings;
};PikaGameSettingsVideo.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGameSettingsVideo.h"
#include "Public/PikaWorldSettings.h"
void UPikaGameSettingsVideo::PikaDrawUIToScreen()
{
PikaResolutionBoxString = PikaGetComboBoxStringFormBlueprint(PikaResolutionBoxStringName);
PikaFullScreenCheckBox = PikaGetCheckBoxFormBlueprint(PikaFullScreenCheckBoxName);
PikaWindowScreenCheckBox = PikaGetCheckBoxFormBlueprint(PikaWindowScreenCheckBoxName);
PikaOverallScalabilityLevelSlider = PikaGetSliderFormBlueprint(PikaOverallScalabilityLevelSliderName);
PikaTextureQualitySlider = PikaGetSliderFormBlueprint(PikaTextureQualitySliderName);
PikaShadowQualitySlider = PikaGetSliderFormBlueprint(PikaShadowQualitySliderName);
PikaAntiAliasingSlider = PikaGetSliderFormBlueprint(PikaAntiAliasingSliderName);
PikaPostProcessingSlider = PikaGetSliderFormBlueprint(PikaPostProcessingSliderName);
PikaEffectsSlider = PikaGetSliderFormBlueprint(PikaEffectsSliderName);
PikaFoliageSlider = PikaGetSliderFormBlueprint(PikaFoliageSliderName);
PikaViewDistanceSlider = PikaGetSliderFormBlueprint(PikaViewDistanceSliderName);
PikaFOVSlider = PikaGetSliderFormBlueprint(PikaFOVSliderName);
//PikaLanguageString = GetComboBoxStringFormBlueprint(LanguageStringName);
PikaOverallScalabilityLevelSliderText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaOverallScalabilityLevelSliderTextName));
//贴图数字显示
PikaTextureQualityText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaTextureQualityTextName));
//阴影数字显示
PikaShadowQualityText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaShadowQualityTextName));
//抗锯齿数字显示
PikaAntiAliasingText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaAntiAliasingTextName));
//后期数字显示
PikaPostProcessingText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaPostProcessingTextName));
//特效数字显示
PikaEffectsText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaEffectsTextName));
//Foliage叶子数字显示
PikaFoliageText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaFoliageTextName));
//视距数字显示
PikaViewDistanceText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaViewDistanceTextName));
//摄像机FOV数字显示
PikaFOVText = Cast<UTextBlock>(PikaqiuGetBlueprintWidget(PikaFOVTextName));
}
void UPikaGameSettingsVideo::PikaUpdateAttibe()
{
//材质质量级别
if (PikaOverallScalabilityLevelSliderText && PikaOverallScalabilityLevelSlider)
{
uint16 PikaIndexNumber = PikaOverallScalabilityLevelSlider->GetValue() * 5;
FString PikaString_Text = FString::Printf(TEXT("%02d"), PikaIndexNumber);
PikaOverallScalabilityLevelSliderText->SetText(FText::FromString(PikaString_Text));
}
//贴图
if (PikaTextureQualityText && PikaTextureQualitySlider)
{
uint16 PikaIndexNumber = PikaTextureQualitySlider->GetValue() * 5;
FString PikaString_Text = FString::Printf(TEXT("%02d"), PikaIndexNumber);
PikaTextureQualityText->SetText(FText::FromString(PikaString_Text));
}
//阴影
if (PikaShadowQualityText && PikaShadowQualitySlider)
{
uint16 PikaIndexNumber = PikaShadowQualitySlider->GetValue() * 5;
FString PikaString_Text = FString::Printf(TEXT("%02d"), PikaIndexNumber);
PikaShadowQualityText->SetText(FText::FromString(PikaString_Text));
}
//锯齿
if (PikaAntiAliasingText && PikaAntiAliasingSlider)
{
uint16 PikaIndexNumber = PikaAntiAliasingSlider->GetValue() * 5;
FString PikaString_Text = FString::Printf(TEXT("%02d"), PikaIndexNumber);
PikaAntiAliasingText->SetText(FText::FromString(PikaString_Text));
}
//后期
if (PikaPostProcessingText && PikaPostProcessingSlider)
{
uint16 PikaIndexNumber = PikaPostProcessingSlider->GetValue() * 5;
FString PikaString_Text = FString::Printf(TEXT("%02d"), PikaIndexNumber);
PikaPostProcessingText->SetText(FText::FromString(PikaString_Text));
}
//特效
if (PikaEffectsText && PikaEffectsSlider)
{
uint16 PikaIndexNumber = PikaEffectsSlider->GetValue() * 5;
FString PikaString_Text = FString::Printf(TEXT("%02d"), PikaIndexNumber);
PikaEffectsText->SetText(FText::FromString(PikaString_Text));
}
//Foliage
if (PikaFoliageText && PikaFoliageSlider)
{
uint16 PikaIndexNumber = PikaFoliageSlider->GetValue() * 5;
FString PikaString_Text = FString::Printf(TEXT("%02d"), PikaIndexNumber);
PikaFoliageText->SetText(FText::FromString(PikaString_Text));
}
//视距
if (PikaViewDistanceText && PikaViewDistanceSlider)
{
uint16 PikaIndexNumber = PikaViewDistanceSlider->GetValue() * 5;
FString PikaString_Text = FString::Printf(TEXT("%02d"), PikaIndexNumber);
PikaViewDistanceText->SetText(FText::FromString(PikaString_Text));
}
//相机FOV
if (PikaFOVText && PikaFOVSlider)
{
//最大值
float PikaMaxValue = 240;
float PikaIndexNumber = PikaFOVSlider->GetValue() * PIKA_FOVMAX_VALUE + 40.0f;
FString PikaString_Text = FString::Printf(TEXT("%02d"), (int32)PikaIndexNumber);
PikaFOVText->SetText(FText::FromString(PikaString_Text));
}
}
void UPikaGameSettingsVideo::PikaSelectionChangedBySelf(UWidget* MyWidget, FString SelectedItem, ESelectInfo::Type SelectionType)
{
//关于分辨率的一些设置
if (MyWidget == PikaResolutionBoxString)
{
}
}
void UPikaGameSettingsVideo::PikaChangedValue(float Val)
{
PikaUpdateAttibe();
}
void UPikaGameSettingsVideo::PikaClickedCheckBox(UWidget* MyWidget, bool ClickedWidget)
{
if (MyWidget == PikaFullScreenCheckBox)
{
if (PikaWindowScreenCheckBox && PikaWindowScreenCheckBox->GetCheckedState() == ECheckBoxState::Checked)
{
PikaWindowScreenCheckBox->SetCheckedState(ECheckBoxState::Unchecked);
}
}
if (MyWidget == PikaWindowScreenCheckBox)
{
if (PikaFullScreenCheckBox && PikaFullScreenCheckBox->GetCheckedState() == ECheckBoxState::Checked)
{
PikaFullScreenCheckBox->SetCheckedState(ECheckBoxState::Unchecked);
}
}
}PikaGameUserSettings.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameUserSettings.h"
#include "Sound/SoundClass.h"
#include "PikaGameUserSettings.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaGameUserSettings : public UGameUserSettings
{
GENERATED_BODY()
public:
//用UPROPERTY(config)形式定义的变量,会自动存储到ini设置里
//背景音乐
UPROPERTY(config)
float PikaBackgroundSoundControl;
//特效音乐
UPROPERTY(config)
float PikaEffectsSoundControl;
//分辨率
UPROPERTY(config)
float PikaResolution_HControl;
UPROPERTY(config)
float PikaResolution_WControl;
//屏幕模式
//0-窗口 1-全屏
UPROPERTY(config)
float PikaScreenModeControl;
//总控制
UPROPERTY(config)
float PikaOverallScalabilityLevelControl;
//贴图
UPROPERTY(config)
float PikaTextureQualityControl;
//阴影
UPROPERTY(config)
float PikaShadowQualityControl;
//抗锯齿
UPROPERTY(config)
float PikaAntiAliasingControl;
//后期
UPROPERTY(config)
float PikaPostProcessingControl;
//特效
UPROPERTY(config)
float PikaEffectsControl;
//Foliage叶子
UPROPERTY(config)
float PikaFoliageControl;
//视距
UPROPERTY(config)
float PikaViewDistanceControl;
//FOV
UPROPERTY(config)
float PikaCameraFOV;
UPikaGameUserSettings();
static UPikaGameUserSettings* PikaGetGameUserSettings();
virtual void ApplySettings(bool bCheckForCommandLineOverrides)override;
TArray<USoundClass*> PikaGetAllMusicClass();
virtual void LoadSettings(bool bForceReload = false) override;
virtual void SaveSettings() override;
void PikaSeveIni();
bool PikaLoadIni();
virtual void SetToDefaults()override;
void PikaPlayBGM();
//设置屏幕模式和分辨率
void PikaSetVideo();
/*PiksWorldStart*/
virtual class UWorld* GetWorld() const;
void PikaSetretrieveWorldContext(UWorld* NewWorld);
/*PiksWorldEnd*/
private:
class UWorld * PikaWorld;
};PikaGameUserSettings.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGameUserSettings.h"
#include "Sound/AmbientSound.h"
#include "Components/AudioComponent.h"
//PikaGameUserSettings属于ini配置类,该构造函数只会在代码编译时调用一次,在运行中不会再次执行
UPikaGameUserSettings::UPikaGameUserSettings()
{
if (!PikaLoadIni())
{
SetToDefaults();
}
}
UPikaGameUserSettings* UPikaGameUserSettings::PikaGetGameUserSettings()
{
return GEngine != NULL ? ((UPikaGameUserSettings*)GEngine->GetGameUserSettings()) : NULL;
}
void UPikaGameUserSettings::ApplySettings(bool bCheckForCommandLineOverrides)
{
Super::ApplySettings(bCheckForCommandLineOverrides);
//背景音乐
if (GetWorld())
{
TArray<USoundClass*> PikaTmpSound = PikaGetAllMusicClass();
for (USoundClass* PikaNewSoundClass : PikaTmpSound)
{
if (PikaNewSoundClass->GetFullName().Contains(TEXT("Master")))
{
//总体音量
PikaNewSoundClass->Properties.Volume = PikaBackgroundSoundControl * PikaqiuTotalSoundControl;
}
}
TArray<AActor*> PikaClassArrayTmp;
TArray<USoundClass*> PikaSoundClassArray;
PikaGETALLACTOR(GetWorld(), AAmbientSound::StaticClass(), PikaClassArrayTmp);
for (AActor* PikaSound_m : PikaClassArrayTmp)
{
AAmbientSound* PikaAmbient_sound = Cast<AAmbientSound>(PikaSound_m);
PikaAmbient_sound->AdjustVolume(1, PikaBackgroundSoundControl * PikaqiuTotalSoundControl);
}
}
// Apply the new settings and save them
Scalability::SetQualityLevels(ScalabilityQuality);
Scalability::SaveState(GGameUserSettingsIni);
//存储到配置
PikaSeveIni();
}
TArray<USoundClass*> UPikaGameUserSettings::PikaGetAllMusicClass()
{
TArray<AActor*> PikaClassArrayTmp;
TArray<USoundClass*> PikaSoundClassArray;
PikaGETALLACTOR(GetWorld(), AAmbientSound::StaticClass(), PikaClassArrayTmp);
for (AActor* PikaSound_m : PikaClassArrayTmp)
{
AAmbientSound* PikaAmbient_sound = Cast<AAmbientSound>(PikaSound_m);
if (PikaAmbient_sound &&
PikaAmbient_sound->GetAudioComponent() &&
PikaAmbient_sound->GetAudioComponent()->Sound &&
PikaAmbient_sound->GetAudioComponent()->Sound->DefaultSoundClassObject
)
{
PikaSoundClassArray.Add(PikaAmbient_sound->GetAudioComponent()->Sound->DefaultSoundClassObject);
}
}
return PikaSoundClassArray;
}
void UPikaGameUserSettings::LoadSettings(bool bForceReload /*= false*/)
{
Super::LoadSettings(bForceReload);
PikaLoadIni();
}
void UPikaGameUserSettings::SaveSettings()
{
Super::SaveSettings();
}
void UPikaGameUserSettings::PikaSeveIni()
{
const TCHAR* PikaSection = TEXT("PikaGodStoneINI");
// looks like cvars but here we just use the name for the ini
GConfig->SetFloat(PikaSection, TEXT("PikaIni_BackgroundSoundControl"), PikaBackgroundSoundControl, GGameUserSettingsIni);
GConfig->SetFloat(PikaSection, TEXT("PikaIni_EffectsSoundControl"), PikaEffectsSoundControl, GGameUserSettingsIni);
GConfig->SetFloat(PikaSection, TEXT("PikaIni_ButtonSoundControl"), PikaqiuButtonSoundControl, GGameUserSettingsIni);
GConfig->SetFloat(PikaSection, TEXT("PikaIni_TotalSoundControl"), PikaqiuTotalSoundControl, GGameUserSettingsIni);
/*//图像设置
//分辨率
GConfig->SetFloat(PikaSection, TEXT("PikaIni_Resolution_H"), PikaResolution_HControl, GGameUserSettingsIni);
GConfig->SetFloat(PikaSection, TEXT("PikaIni_Resolution_W"), PikaResolution_WControl, GGameUserSettingsIni);
//屏幕模式
//0-窗口 1-全屏
GConfig->SetFloat(PikaSection, TEXT("PikaIni_ScreenMode"), PikaScreenModeControl, GGameUserSettingsIni);
//总控制
GConfig->SetFloat(PikaSection, TEXT("PikaIni_OverallScalabilityLevel"), PikaOverallScalabilityLevelControl, GGameUserSettingsIni);
//贴图
GConfig->SetFloat(PikaSection, TEXT("PikaIni_TextureQuality"), PikaTextureQualityControl, GGameUserSettingsIni);
//阴影
GConfig->SetFloat(PikaSection, TEXT("sg.ShadowQuality"), PikaShadowQualityControl, GGameUserSettingsIni);
//抗锯齿
GConfig->SetFloat(PikaSection, TEXT("PikaIni_AntiAliasing"), PikaAntiAliasingControl, GGameUserSettingsIni);
//后期
GConfig->SetFloat(PikaSection, TEXT("PikaIni_PostProcessing"), PikaPostProcessingControl, GGameUserSettingsIni);
//特效
GConfig->SetFloat(PikaSection, TEXT("PikaIni_Effects"), PikaEffectsControl, GGameUserSettingsIni);
//Foliage叶子
GConfig->SetFloat(PikaSection, TEXT("PikaIni_Foliage"), PikaFoliageControl, GGameUserSettingsIni);
//视距
GConfig->SetFloat(PikaSection, TEXT("PikaIni_ViewDistance"), PikaViewDistanceControl, GGameUserSettingsIni);
//FOV
GConfig->SetFloat(PikaSection, TEXT("PikaIni_CameraFOV"), PikaCameraFOV, GGameUserSettingsIni);*/
//GConfig->SetString(PikaSection, TEXT("sg.TDLanguage"), *GetCurrentLanguageType(), GGameUserSettingsIni);
}
bool UPikaGameUserSettings::PikaLoadIni()
{
const TCHAR* PikaSection = TEXT("PikaGodStoneINI");
FString PikaLanguageStr = "";
bool PikaIsLoadSuc =
GConfig->GetFloat(PikaSection, TEXT("PikaIni_BackgroundSoundControl"), PikaBackgroundSoundControl, GGameUserSettingsIni) &&
GConfig->GetFloat(PikaSection, TEXT("PikaIni_EffectsSoundControl"), PikaEffectsSoundControl, GGameUserSettingsIni) &&
GConfig->GetFloat(PikaSection, TEXT("PikaIni_ButtonSoundControl"), PikaqiuButtonSoundControl, GGameUserSettingsIni) &&
GConfig->GetFloat(PikaSection, TEXT("PikaIni_TotalSoundControl"), PikaqiuTotalSoundControl, GGameUserSettingsIni);
/*GConfig->GetFloat(PikaSection, TEXT("PikaIni_Resolution_H"), PikaResolution_HControl, GGameUserSettingsIni) &&
GConfig->GetFloat(PikaSection, TEXT("PikaIni_Resolution_W"), PikaResolution_WControl, GGameUserSettingsIni) &&
GConfig->GetFloat(PikaSection, TEXT("PikaIni_ScreenMode"), PikaScreenModeControl, GGameUserSettingsIni) &&
GConfig->GetFloat(PikaSection, TEXT("PikaIni_OverallScalabilityLevel"), PikaOverallScalabilityLevelControl, GGameUserSettingsIni) &&
GConfig->GetFloat(PikaSection, TEXT("PikaIni_TextureQuality"), PikaTextureQualityControl, GGameUserSettingsIni) &&
GConfig->GetFloat(PikaSection, TEXT("PikaIni_ShadowQuality"), PikaShadowQualityControl, GGameUserSettingsIni) &&
GConfig->GetFloat(PikaSection, TEXT("PikaIni_AntiAliasing"), PikaAntiAliasingControl, GGameUserSettingsIni) &&
GConfig->GetFloat(PikaSection, TEXT("PikaIni_PostProcessing"), PikaPostProcessingControl, GGameUserSettingsIni) &&
GConfig->GetFloat(PikaSection, TEXT("PikaIni_Effects"), PikaEffectsControl, GGameUserSettingsIni) &&
GConfig->GetFloat(PikaSection, TEXT("PikaIni_Foliage"), PikaFoliageControl, GGameUserSettingsIni) &&
GConfig->GetFloat(PikaSection, TEXT("PikaIni_ViewDistance"), PikaViewDistanceControl, GGameUserSettingsIni) &&
GConfig->GetFloat(PikaSection, TEXT("PikaIni_CameraFOV"), PikaCameraFOV, GGameUserSettingsIni);*/
//GConfig->GetString(PikaSection, TEXT("sg.TDLanguage"), PikaLanguageStr, GGameUserSettingsIni) &&
//设置语言
//if (LanguageStr != "")
//SetCuurrLanguage(LanguageStr);
//return PikaIsLoadSuc;
return true;
}
void UPikaGameUserSettings::SetToDefaults()
{
Super::SetToDefaults();
//背景音乐
PikaBackgroundSoundControl = 1.0f;
//特效音乐
PikaEffectsSoundControl = 1.0f;
PikaqiuTotalSoundControl = 1.0f;
PikaqiuButtonSoundControl = 1.0f;
//图像设置
//分辨率
PikaResolution_HControl = 800;
PikaResolution_WControl = 600;
//屏幕模式
PikaScreenModeControl = 1.0f;
//总控制
PikaOverallScalabilityLevelControl = 0.5f;
//贴图
PikaTextureQualityControl = 0.5f;
//阴影
PikaShadowQualityControl = 0.5f;
//抗锯齿
PikaAntiAliasingControl = 0.5f;
//后期
PikaPostProcessingControl = 0.5f;
//特效
PikaEffectsControl = 0.5f;
//Foliage叶子
PikaFoliageControl = 0.5f;
//视距
PikaViewDistanceControl = 0.5f;
//FOV
PikaCameraFOV = 90.f;
}
void UPikaGameUserSettings::PikaPlayBGM()
{
//背景音乐,由gameMode调用
if (GetWorld())
{
TArray<AActor*> PikaClassArrayTmp;
TArray<USoundClass*> PikaSoundClassArray;
PikaGETALLACTOR(GetWorld(), AAmbientSound::StaticClass(), PikaClassArrayTmp);
for (AActor* PikaSound_m : PikaClassArrayTmp)
{
AAmbientSound* PikaAmbient_sound = Cast<AAmbientSound>(PikaSound_m);
PikaAmbient_sound->AdjustVolume(1, PikaBackgroundSoundControl * PikaqiuTotalSoundControl);
}
}
}
//由gameMode调用
void UPikaGameUserSettings::PikaSetVideo()
{
//分辨率
SetScreenResolution(GetScreenResolution());
//屏幕模式
SetFullscreenMode(GetLastConfirmedFullscreenMode());
}
class UWorld* UPikaGameUserSettings::GetWorld() const
{
return PikaWorld;
}
void UPikaGameUserSettings::PikaSetretrieveWorldContext(UWorld* NewWorld)
{
PikaWorld = NewWorld;
}PikaGameViewportClient.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/GameViewportClient.h"
#include "SlateDynamicImageBrush.h"
#include "SCompoundWidget.h"
#include "PikaGameViewportClient.generated.h"
struct PikaFShooterGameLoadingScreenBrush : public FSlateDynamicImageBrush, public FGCObject
{
PikaFShooterGameLoadingScreenBrush(const FName InTextureName, const FVector2D& InImageSize)
: FSlateDynamicImageBrush(InTextureName, InImageSize)
{
ResourceObject = LoadObject<UObject>(NULL, *InTextureName.ToString());
}
virtual void AddReferencedObjects(FReferenceCollector& Collector)
{
if (ResourceObject)
{
Collector.AddReferencedObject(ResourceObject);
}
}
};
class PikaSShooterLoadingScreen : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(PikaSShooterLoadingScreen) {}
SLATE_END_ARGS()
void Construct(const FArguments& InArgs);
private:
EVisibility PikaGetLoadIndicatorVisibility() const
{
return EVisibility::Visible;
}
/** loading screen image brush */
TSharedPtr<FSlateDynamicImageBrush> PikaLoadingScreenBrush;
};
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaGameViewportClient : public UGameViewportClient
{
GENERATED_BODY()
public:
UPikaGameViewportClient();
void PikaShowLoadingScreen();
void PikaHideLoadingScreen();
private:
void PikaHideExistingWidgets();
void PikaShowExistingWidgets();
TSharedPtr<PikaSShooterLoadingScreen> PikaLoadingScreenWidget;
TArray<TSharedRef<class SWidget>> PikaHiddenViewportContentStack;
TArray<TSharedRef<class SWidget>> PikaViewportContentStack;
};PikaGameViewportClient.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGameViewportClient.h"
UPikaGameViewportClient::UPikaGameViewportClient()
{
}
void UPikaGameViewportClient::PikaShowLoadingScreen()
{
if (PikaLoadingScreenWidget.IsValid())
{
return;
}
PikaLoadingScreenWidget = SNew(PikaSShooterLoadingScreen);
AddViewportWidgetContent(PikaLoadingScreenWidget.ToSharedRef());
}
void UPikaGameViewportClient::PikaHideLoadingScreen()
{
if (!PikaLoadingScreenWidget.IsValid())
{
return;
}
//销毁LoadingScreenWidget
RemoveViewportWidgetContent(PikaLoadingScreenWidget.ToSharedRef());
PikaLoadingScreenWidget = NULL;
}
void UPikaGameViewportClient::PikaHideExistingWidgets()
{
check(PikaHiddenViewportContentStack.Num() == 0);
TArray<TSharedRef<class SWidget>> PikaCopyOfViewportContentStack = PikaViewportContentStack;
for (int32 i = PikaViewportContentStack.Num() - 1; i >= 0; i--)
{
RemoveViewportWidgetContent(PikaViewportContentStack[i]);
}
PikaHiddenViewportContentStack = PikaCopyOfViewportContentStack;
}
void UPikaGameViewportClient::PikaShowExistingWidgets()
{
check(PikaViewportContentStack.Num() == 0);
for (int32 i = 0; i < PikaHiddenViewportContentStack.Num(); i++)
{
AddViewportWidgetContent(PikaHiddenViewportContentStack[i]);
}
check(PikaViewportContentStack.Num() == PikaHiddenViewportContentStack.Num());
PikaHiddenViewportContentStack.Empty();
}
void PikaSShooterLoadingScreen::Construct(const FArguments& InArgs)
{
//static const FName PikaLoadingScreenName(TEXT("/Game/Movies/PikaLoading"));
//PikaLoadingScreenBrush = MakeShareable(new PikaFShooterGameLoadingScreenBrush(PikaLoadingScreenName, FVector2D(1920, 1080)));
/*ChildSlot
[
SNew(SOverlay)
+ SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
[
SNew(SImage)
.Image(PikaLoadingScreenBrush.Get())
]
+ SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
[
SNew(SSafeZone)
.VAlign(VAlign_Bottom)
.HAlign(HAlign_Right)
.Padding(10.0f)
.IsTitleSafe(true)
[
SNew(SThrobber)
.Visibility(this, &PikaSShooterLoadingScreen::GetLoadIndicatorVisibility)
]
]
];*/
}PikaGlobalConfig.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "PikaGameSaveData.h"
#include "PikaGlobalConfig.generated.h"
//鼠标全局配置结构体
USTRUCT()
struct FPikaMouseSettingConfiguration
{
GENERATED_USTRUCT_BODY()
//蓝图的配置方式
//UPROPERTY(EditDefaultsOnly, Category = "PikaGlobal")
//float MouseSpeed;
public:
//c++的配置方式
float MouseSpeed;
//QE键模型的旋转角度
float PikaAngleOfRotation;
FPikaMouseSettingConfiguration();
};
/**
*
*/
//蓝图下的配置方式
//UCLASS(Blueprintable)
UCLASS()
class PIKAGODSTONE_API UPikaGlobalConfig : public UObject
{
GENERATED_BODY()
UPROPERTY(Transient)
bool PikaSkillPermissions;
public:
UPikaGlobalConfig();
//蓝图的配置方式
//UPROPERTY(EditDefaultsOnly , Category = "GlobalConfig")
//FPikaMouseSettingConfiguration PikaMouseSetConf;
//c++的配置方式
UPROPERTY()
FPikaMouseSettingConfiguration PikaMouseSetConf;
//游戏UI相关数据,包括游戏快捷栏内物品,玩家技能等
UPROPERTY()
FPikaGodStoneSaveGameData PikaGameData;
//是否是存储的数据经过读取而来,默认是非读取状态
bool PikaIsSave;
//鼠标缩放数据记录
float PikaMouseZoom;
//游戏存储
uint64 PikaSaveCount;
//关卡游戏规则相关的数据
UPROPERTY()
FPikaGameLevelManangenment PikaGameLevelManangenment;
//
UPROPERTY()
FPikaTowersData PikaTowersData;
//游戏场景内角色的数据
UPROPERTY()
FPikaTemporaryCacheData PikaTemporaryCacheData;
//描述数据的数据
//UPROPERTY()
//FPikaReadGameData PikaReadGameData;
//GameStory
FPikaGameStory PikaGameStory;
//UPROPERTY()
//FCurrentLevelCondition CurrentLevelCondition;
//UPROPERTY()
//FMissionState MissionState;
void PikaSetSkillPermissions(bool IsPermissions) { PikaSkillPermissions = IsPermissions; }
//数据初始化完毕
FORCEINLINE void PikaInitializationDataComplete() { PikaIsSave = false; }
//使用技能的权限
FORCEINLINE bool PikaGetPlayerSkillPermissions() const { return PikaSkillPermissions; }
};PikaGlobalConfig.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGlobalConfig.h"
FPikaMouseSettingConfiguration::FPikaMouseSettingConfiguration()
{
//c++方式配置的实始化
MouseSpeed = 50.f;
PikaAngleOfRotation = 15.f;
}
UPikaGlobalConfig::UPikaGlobalConfig() :
PikaSkillPermissions(true),
PikaIsSave(false)
{
PikaSaveCount = 0;
PikaMouseZoom = 1;
}PikaGodStoneCamera.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/BoxComponent.h"
#include "PikaGodStoneCamera.generated.h"
UCLASS()
class PIKAGODSTONE_API APikaGodStoneCamera : public APawn
{
GENERATED_BODY()
//摄像机组件
//根组件
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
USceneComponent* PikaCameraRootComponent;
//控制摄像机离场景的距离
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
USpringArmComponent * PikaCameraBoom;
//主摄像机
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
UCameraComponent * PikaMainCamera;
//摄像机的碰撞标识
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
UBoxComponent * PikaMarkBox;
public:
// Sets default values for this pawn's properties
APikaGodStoneCamera();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
//摄像机缩放,MouseSpeed该值由playerController传进来
void PikaCameraZoom(bool ZoomDirection, float MouseSpeed);
void PikaSetCameraFOV(float NewFOV);
//获取摄像机
FORCEINLINE UCameraComponent* PikaGetMainCamera() const { return PikaMainCamera; }
//获取FOV
FORCEINLINE float PikaGetCameraFOV() const { return PikaGetMainCamera() ? PikaGetMainCamera()->FieldOfView : 0; }
};PikaGodStoneCamera.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGodStoneCamera.h"
// Sets default values
APikaGodStoneCamera::APikaGodStoneCamera()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//创建组件
//CreateDefaultSubobject该创建object的方法只能用在构造函数里,非构造函数要用其它创建方式,如newObject
PikaCameraRootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("PikaCameraRootComponent"));
PikaCameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("PikaCameraBoom"));
PikaMainCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("PikaMainCamera"));
PikaMarkBox = CreateDefaultSubobject<UBoxComponent>(TEXT("PikaHitSign"));
//赋值根组件
RootComponent = PikaCameraRootComponent;
//绑定组件
PikaCameraBoom->AttachToComponent(PikaCameraRootComponent, FAttachmentTransformRules::KeepRelativeTransform);
PikaMainCamera->AttachToComponent(PikaCameraBoom, FAttachmentTransformRules::KeepRelativeTransform);
PikaMarkBox->AttachToComponent(PikaCameraRootComponent, FAttachmentTransformRules::KeepRelativeTransform);
//设置摄像机角距离地面的长度
PikaCameraBoom->TargetArmLength = 800.f;
PikaCameraBoom->RelativeRotation = FRotator(-60.f, 0, 0);
//碰撞,QueryOnly表示只能有碰撞和重叠
PikaMarkBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
//忽略所有通道,然后单独开启ECC_Visibility和ECC_WorldDynamic这两个通道
PikaMarkBox->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
PikaMarkBox->SetCollisionResponseToChannel(ECollisionChannel::ECC_Visibility, ECollisionResponse::ECR_Overlap);
PikaMarkBox->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldDynamic, ECollisionResponse::ECR_Overlap);
}
// Called when the game starts or when spawned
void APikaGodStoneCamera::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void APikaGodStoneCamera::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void APikaGodStoneCamera::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
//缩放控制
void APikaGodStoneCamera::PikaCameraZoom(bool ZoomDirection, float MouseSpeed)
{
if (ZoomDirection)
{
//判断摄像机组件是否存在
if (PikaCameraBoom)
{
//PikaMinZoomVal为缩放的最小值
int32 PikaMinZoomVal = 400;
if (PikaCameraBoom->TargetArmLength > PikaMinZoomVal)
{
PikaCameraBoom->TargetArmLength -= (MouseSpeed * 2);
}
}
}
else
{
if (PikaCameraBoom)
{
//PikaMaxZoomVal为缩放的最大值
int32 PikaMaxZoomVal = 1600;
if (PikaCameraBoom->TargetArmLength < PikaMaxZoomVal)
{
PikaCameraBoom->TargetArmLength += (MouseSpeed * 2);
}
}
}
}
void APikaGodStoneCamera::PikaSetCameraFOV(float NewFOV)
{
if (PikaGetMainCamera())
{
PikaGetMainCamera()->SetFieldOfView(NewFOV);
}
}PikaGodStoneGameInstance.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "PikaGameSaveData.h"
#include "PikaGlobalConfig.h"
#include "PikaGodStoneGameInstance.generated.h"
#define PikaSTANDARD_VALUE 1
/**
*
*/
UCLASS()
class PIKAGODSTONE_API UPikaGodStoneGameInstance : public UGameInstance
{
GENERATED_BODY()
UPROPERTY()
FString PikaCurrentSaveSlotName;
//Loading界面
//Loading需要在PikaGodStone.Build.cs里添加"MoviePlayer"模块
TSubclassOf<UUserWidget> PikaUI_LoadingTemplate;
UUserWidget* PikaLoadingWidget;
UPikaGameSaveData* PikaGodStoneGaveSaveDataPtr;
public:
UPikaGodStoneGameInstance();
virtual void Init();
//解决UPikaGodStoneGameInstance的构造执行时,GetWorld还没有初始化完成的问题
virtual FGameInstancePIEResult InitializeForPlayInEditor(int32 PIEInstanceIndex, const FGameInstancePIEParameters& Params) override;
UPikaGameSaveData* PikaGetGameSaveData() { return PikaGodStoneGaveSaveDataPtr;}
//游戏全局的时间增量的设置
void PikaSetGlobalGameTime(float TimeDilation = 0);
//Loading
void PikaShowLoadingScreen();
UFUNCTION()
virtual void BeginLoadingScreen(const FString& MapName);
UFUNCTION()
virtual void EndLoadingScreen(UWorld* NewWorld);
bool PikaIsLoadingFinsh();
//////////////////////////////////////读取和存储////////////////////////////////////
//作为临时读取之用
int32 PikaTmpArchive;
//验证存档,如果没有就创建一个
UPikaGameSaveData* PikaVerificationSaveData()const;
//存储我们的游戏数据
bool PikaSaveGameData(UPikaGlobalConfig* EnvironmentConfiguration, PikaFSaveSlotDataChannel SaveSlotDataChannel);
//读取存档的序列号
void PikaSetCurrentSaveSloatNmber(int32 NewNumber);
FORCEINLINE FString PikaGetCurrentGameSaveName() const { return PikaCurrentSaveSlotName; }
//是否可以读取进度
bool PikaIsLoadingGameData(int32 SaveNumber);
//获取当前存储了多少个存档,返回值将做为下一次创建新存档时的index
int32 PikaGetCurrentSaveArchiveNumber()const;
//删除存档
bool PikaDeleteGameData(int32 SaveNumber);
private:
//关联我们的游戏数据搭配存储点
bool PikaCorrelationGameData(UPikaGlobalConfig* EnvironmentConfiguration, PikaFSaveSlotDataChannel SaveSlotDataChannel);
};PikaGodStoneGameInstance.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGodStoneGameInstance.h"
#include "ConstructorHelpers.h"
#include "../MoviePlayer/Public/MoviePlayer.h"
#include "UserWidget.h"
#include "Public/PikaGameViewportClient.h"
UPikaGodStoneGameInstance::UPikaGodStoneGameInstance()
{
//载入Loading
ConstructorHelpers::FClassFinder<UUserWidget> PikaTmpLoading(TEXT("/Game/HUD/OtherUI/LoadingBP"));
PikaUI_LoadingTemplate = PikaTmpLoading.Class;
PikaTmpArchive = INDEX_NONE;
}
void UPikaGodStoneGameInstance::Init()
{
Super::Init();
//对两个Loading代理进行绑定
FCoreUObjectDelegates::PreLoadMap.AddUObject(this, &UPikaGodStoneGameInstance::BeginLoadingScreen);
FCoreUObjectDelegates::PostLoadMapWithWorld.AddUObject(this, &UPikaGodStoneGameInstance::EndLoadingScreen);
}
FGameInstancePIEResult UPikaGodStoneGameInstance::InitializeForPlayInEditor(int32 PIEInstanceIndex, const FGameInstancePIEParameters& Params)
{
FGameInstancePIEResult PIEResult = Super::InitializeForPlayInEditor(PIEInstanceIndex , Params);
TSubclassOf<UPikaGameSaveData> PikaMySaveGame = UPikaGameSaveData::StaticClass();
if (GetWorld() && PikaMySaveGame)
{
PikaGodStoneGaveSaveDataPtr = NewObject<UPikaGameSaveData>(GetWorld(), PikaMySaveGame);
}
return PIEResult;
}
//游戏全局的时间增量的设置
void UPikaGodStoneGameInstance::PikaSetGlobalGameTime(float TimeDilation /*= 0*/)
{
if (GetWorld() && GetWorld()->GetWorldSettings())
{
float const PikaActualTimeDilation = GetWorld()->GetWorldSettings()->SetTimeDilation(TimeDilation);
/*if (TimeDilation != PikaActualTimeDilation)
{
UE_LOG(LogBlueprintUserMessages, Warning, TEXT("Time Dilation must be between %f and %f. Clamped value to that range."), GetWorld()->GetWorldSettings()->MinGlobalTimeDilation, GetWorld()->GetWorldSettings()->MaxGlobalTimeDilation);
}*/
}
}
void UPikaGodStoneGameInstance::PikaShowLoadingScreen()
{
if (!IsRunningDedicatedServer())
{
FLoadingScreenAttributes PikaLoadingScreen;
PikaLoadingScreen.bAutoCompleteWhenLoadingCompletes = true;
PikaLoadingScreen.bMoviesAreSkippable = true;//任意键打断如果加载完成
PikaLoadingScreen.bWaitForManualStop = false;//
PikaLoadingScreen.PlaybackType = EMoviePlaybackType::MT_Looped;
if (!PikaLoadingWidget)
PikaLoadingWidget = CreateWidget<UUserWidget>(this, PikaUI_LoadingTemplate);
if (PikaLoadingWidget)
{
PikaLoadingScreen.WidgetLoadingScreen = PikaLoadingWidget->TakeWidget();
//添加mp4文件,位置为Content\Movies\PikaLoading.mp4
PikaLoadingScreen.MoviePaths.Add("PikaLoading");
GetMoviePlayer()->SetupLoadingScreen(PikaLoadingScreen);
}
}
UPikaGameViewportClient * PikaShooterViewport = Cast<UPikaGameViewportClient>(GetGameViewportClient());
if (PikaShooterViewport != NULL)
{
PikaShooterViewport->PikaShowLoadingScreen();
}
}
void UPikaGodStoneGameInstance::BeginLoadingScreen(const FString& MapName)
{
PikaShowLoadingScreen();
if (GetGameViewportClient())
GetGameViewportClient()->SetDisableSplitscreenOverride(false);
}
void UPikaGodStoneGameInstance::EndLoadingScreen(UWorld* NewWorld)
{
UPikaGameViewportClient * PikaShooterViewport = Cast<UPikaGameViewportClient>(GetGameViewportClient());
if (PikaShooterViewport != NULL)
{
if (PikaLoadingWidget)
{
PikaLoadingWidget = nullptr;
}
//进行销毁工作
PikaShooterViewport->PikaHideLoadingScreen();
}
}
bool UPikaGodStoneGameInstance::PikaIsLoadingFinsh()
{
return false;
}
//验证存档,如果没有就创建一个
UPikaGameSaveData* UPikaGodStoneGameInstance::PikaVerificationSaveData() const
{
//读取游戏存档在本地
UPikaGameSaveData* PikaGameSaveData = Cast<UPikaGameSaveData>(PIKA_LOADGAME_SLOT(PIKA_SAVE_SLOT_NAME, 0));
//获取存档信息
if (!PikaGameSaveData)
{
PikaGameSaveData = Cast<UPikaGameSaveData>(PIKA_CREATESAVE_SLOT(UPikaGameSaveData::StaticClass()));
if (PikaGameSaveData)
PIKA_SAVE_SLOT(PikaGameSaveData, PIKA_SAVE_SLOT_NAME, 0);
else
UE_LOG(LogTemp, Error, TEXT("There was a problem with the stored content at initialization time"));
}
return PikaGameSaveData;
}
bool UPikaGodStoneGameInstance::PikaSaveGameData(UPikaGlobalConfig* EnvironmentConfiguration, PikaFSaveSlotDataChannel SaveSlotDataChannel)
{
if (EnvironmentConfiguration)
{
//存档,提取数据
return PikaCorrelationGameData(EnvironmentConfiguration, SaveSlotDataChannel);
}
return false;
}
void UPikaGodStoneGameInstance::PikaSetCurrentSaveSloatNmber(int32 NewNumber)
{
PikaCurrentSaveSlotName = PIKA_SAVE_GAME_NAME + FString::FromInt(NewNumber);
}
bool UPikaGodStoneGameInstance::PikaIsLoadingGameData(int32 SaveNumber)
{
if (SaveNumber != INDEX_NONE)
{
//读取游戏存档在本地
UPikaGameSaveData* PikaNewSaveDatas = Cast<UPikaGameSaveData>(PIKA_LOADGAME_SLOT(PIKA_SAVE_GAME_NAME + FString::FromInt(SaveNumber), 0));
if (PikaNewSaveDatas)
{
//还原游戏数据
return true;
}
}
return false;
}
//获取PIKA_SAVE_SLOT_NAME存档里第一个空位置的index,以该index还作为本次存档的index
int32 UPikaGodStoneGameInstance::PikaGetCurrentSaveArchiveNumber() const
{
UPikaGameSaveData* PikaSaveSlot = Cast<UPikaGameSaveData>(PIKA_LOADGAME_SLOT(PIKA_SAVE_SLOT_NAME, 0));
if (PikaSaveSlot)
{
return PikaSaveSlot->PikaReadGameData.PikaGetSerialNumber();
}
else
{
PikaSaveSlot = PikaVerificationSaveData();
if (PikaSaveSlot)
{
return PikaSaveSlot->PikaReadGameData.PikaGetSerialNumber();
}
else
{
UE_LOG(LogTemp, Error, TEXT("There was a problem with the stored content at initialization time"));
}
}
return INDEX_NONE;
}
bool UPikaGodStoneGameInstance::PikaDeleteGameData(int32 SaveNumber)
{
if (SaveNumber != INDEX_NONE)
{
if (PIKA_ISSAVE_SLOT(PIKA_SAVE_GAME_NAME + FString::FromInt(SaveNumber), 0))
{
//让数据默认显示,防止溢出
UPikaGameSaveData* PikaNewSoltGameData = Cast<UPikaGameSaveData>(PIKA_LOADGAME_SLOT(PIKA_SAVE_SLOT_NAME, 0));
if (PikaNewSoltGameData)
{
//将PIKA_SAVE_SLOT_NAME存档里对应的数据项删除
PikaNewSoltGameData->PikaReadGameData.PikaClearReadGameDataAt(SaveNumber);
return (PIKA_DELETEGAME_SLOT(PIKA_SAVE_GAME_NAME + FString::FromInt(SaveNumber), 0) && PIKA_SAVE_SLOT(PikaNewSoltGameData, PIKA_SAVE_SLOT_NAME, 0));
}
}
}
return false;
}
//关联我们的游戏数据搭配存储点
bool UPikaGodStoneGameInstance::PikaCorrelationGameData(UPikaGlobalConfig* GlobalConfig, PikaFSaveSlotDataChannel SaveSlotDataChannel)
{
//存储的序列号ID
//PikaGameSaveSlot为游戏里整个存档数组里,存档时间和存档编号的信息
//PikaGameSaveDatas为单个PikaUISaveLoadBar里对应的存档信息
bool PikaIsGameSaveDatas = false;
bool PikaIsGameSaveSlot = false;
UPikaGameSaveData* PikaGameSaveDatas = Cast<UPikaGameSaveData>(PIKA_CREATESAVE_SLOT(UPikaGameSaveData::StaticClass()));
UPikaGameSaveData* PikaGameSaveSlot = Cast<UPikaGameSaveData>(PIKA_LOADGAME_SLOT(PIKA_SAVE_SLOT_NAME, 0));
//////////////////////////////////数据判断////////////////////////////////////////
//判断GameSaveSlot是否存在
if (PikaGameSaveSlot)
{
PikaIsGameSaveSlot = true;
}
else
{
PikaGameSaveSlot = Cast<UPikaGameSaveData>(PIKA_CREATESAVE_SLOT(UPikaGameSaveData::StaticClass()));
if (PikaGameSaveSlot)
{
PikaIsGameSaveSlot = true;
}
}
//判断GameSaveDatas是否存在
if (PikaGameSaveDatas)
{
PikaIsGameSaveDatas = true;
}
else
{
PikaGameSaveDatas = Cast<UPikaGameSaveData>(PIKA_CREATESAVE_SLOT(UPikaGameSaveData::StaticClass()));
if (PikaGameSaveDatas)
PikaIsGameSaveDatas = true;
}
//////////////////////////////////数据保存////////////////////////////////////////
//执行GameSaveSlot保存
if (PikaIsGameSaveSlot)
{
//PikaSaveGameBoxNumberArray数组里,index为循环出来的PikaUISaveLoadBar的编号
//value为存档的编号,默认值为-1的那个,该值由UPikaUIReadAndWrite::PikaSaveArchiveSlot里的新建逻辑,获取当前存档数的最大值来设置
if (PikaGameSaveSlot->PikaReadGameData.PikaSaveGameBoxNumberArray.IsValidIndex(SaveSlotDataChannel.PikaCurrentSaveGameBoxNumber))
PikaGameSaveSlot->PikaReadGameData.PikaSaveGameBoxNumberArray[SaveSlotDataChannel.PikaCurrentSaveGameBoxNumber] = SaveSlotDataChannel.PikaCurrentGameArchiveNumber;
//该存储条内的信息
if (PikaGameSaveSlot->PikaReadGameData.PikaSaveDataText.IsValidIndex(SaveSlotDataChannel.PikaCurrentGameArchiveNumber))
PikaGameSaveSlot->PikaReadGameData.PikaSaveDataText[SaveSlotDataChannel.PikaCurrentGameArchiveNumber] = FDateTime::Now().ToString();
}
//执行GameSaveDatas保存
if (PikaIsGameSaveDatas)
{
//存储到我们的SavePoint
//PikaGameSaveDatas->PikaMissionState = EnvironmentConfiguration->PikaMissionState;
PikaGameSaveDatas->PikaGodStongSaveData = GlobalConfig->PikaGameData;
PikaGameSaveDatas->PikaGameLevelManangenment = GlobalConfig->PikaGameLevelManangenment;
PikaGameSaveDatas->PikaTemporaryCacheData = GlobalConfig->PikaTemporaryCacheData;
PikaGameSaveDatas->PikaSaveCount = GlobalConfig->PikaSaveCount;
}
//////////////////////////////////////////////////////////////////////////
PikaIsGameSaveDatas = PIKA_SAVE_SLOT(PikaGameSaveDatas, PIKA_SAVE_GAME_NAME + FString::FromInt(SaveSlotDataChannel.PikaCurrentGameArchiveNumber), 0);
PikaIsGameSaveSlot = PIKA_SAVE_SLOT(PikaGameSaveSlot, PIKA_SAVE_SLOT_NAME, 0);
return PikaIsGameSaveDatas && PikaIsGameSaveSlot;
}PikaGodStoneGameStateBase.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameStateBase.h"
#include "PikaGodStoneGameStateBase.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API APikaGodStoneGameStateBase : public AGameStateBase
{
GENERATED_BODY()
};PikaGodStoneGameStateBase.cpp
// Fill out your copyright notice in the Description page of Project Settings. #include "Public/PikaGodStoneGameStateBase.h"
PikaGodStonePlayerController.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "Public/PikaGlobalConfig.h"
#include "Public/PikaAITargetPoint.h"
#include "Engine/DataTable.h"
#include "Public/PikaGodStonePlayerState.h"
#include "Public/PikaGodStoneCamera.h"
#include "PikaTowerDoll.h"
#include "Public/PikaCharacterInfoDataTable.h"
#include "PikaCharacterBase.h"
#include "PikaMonster.h"
#include "PikaGameResource.h"
#include "PikaGodStoneGameInstance.h"
#include "PikaGodStonePlayerController.generated.h"
//带参数的代理
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPikaMouseMiddleButtonPressed, APikaGodStonePlayerController*, APikaGodStonePlayerController);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPikaMouseMiddleButtonReleased, APikaGodStonePlayerController*, APikaGodStonePlayerController);
/**
*
*/
UCLASS()
class PIKAGODSTONE_API APikaGodStonePlayerController : public APlayerController
{
GENERATED_BODY()
//替身类指针
UPROPERTY()
APikaTowerDoll* PikaTowerDollPtr;
//是否运行建造塔
UPROPERTY()
bool PikaIsAllowBuillingTowers;
FHitResult PikaMouseTraceHit;
//保存我们的指针
APikaCharacterBase* PikaTempCharacterBasePtr;
//uint8 BlockingProgram : 1;
uint8 PikaIsSuccessLevel : 1;
//uint8 IsFire : 1;
//集中火力的目标
UPROPERTY()
APikaMonster* PikaMonstersTarget;
UPROPERTY()
ATargetPoint* PikaMapMarkPoint;
public:
APikaGodStonePlayerController();
virtual void Tick(float DeltaTime) override;
virtual void BeginPlay() override;
/****************************************代理Start****************************************/
//按键响应在本类的SetupInputComponent里进行绑定
//按下鼠标的代理
FPikaMouseMiddleButtonPressed PikaEventMouseMiddlePressed;
//松开鼠标的代理
FPikaMouseMiddleButtonReleased PikaEventFMouseMiddleReleased;
/****************************************代理End****************************************/
/****************************************数据Start****************************************/
//数据配置
UDataTable * PikaAITowrerData;
UDataTable * PikaAIMonsterData;
UPikaGameResource * PikaGameResourcePtr;
//指向全局配置的指针
UPikaGlobalConfig * PikaGlobalConfigPrePlayerCon;
//和上面一样,指向同一个内存地址
UPikaGlobalConfig * PikaGlobalConfigPre;
float** PikaTowersCharacterData;
float** PikaMonsterCharacterData;
//注册角色信息
float** PikaRegisterCharacterData(UDataTable* CharacterData);
/****************************************数据End****************************************/
/****************************************塔相关函数Start****************************************/
//获取塔的图片
TArray<UTexture2D*> PikaGetTowerIocn();
//名字
TArray<FName> PikaGetTowersName();
//简介
TArray<FText> PikaGetTowersIntroduction();
//获取塔的建造CD
TArray<float> PikaGetBuildCD();
//获取塔的Mesh,即特效内部的模型
TArray<UStaticMesh*> PikaGetTowerMeshFromParticle(int32 TowerID , FPikaComponentSpaceInfo& MyPikaComponentSpaceInfo);
//获取建造所需的金币
TArray<int32> PikaGetTowerComsumeGold();
//GM,读取数据表中的数据,并将其中的数据转换成蓝图实例
//如果用该方法在场景里进行拖拽生成模型时,角色内部是没有数据的
AActor* PikaSpawnTowers(int32 TowerID, int32 TowerLevel , bool PikaIsLoading = false, int32 CharacterIndex = INDEX_NONE , FVector CharacterLocation = FVector::ZeroVector);
//生成替身类
APikaTowerDoll* PikaSpawnTowerDoll(int32 SerialNum);
//销毁替身类
void PikaDestoryTowerDoll();
//获取替换模型
APikaTowerDoll* PikaGetTowersDoll() { return PikaTowerDollPtr; }
//设置替换模型
void PikaSetTowerDoll(APikaTowerDoll* NewTowerDoll) { PikaTowerDollPtr = NewTowerDoll; }
//获取允许建筑的塔
bool PikaGetAllowBuillingTowers() { return PikaIsAllowBuillingTowers; }
//运行建造塔
void PikaSetAllowBuillingTowers(bool AllowBuillingCondition) { PikaIsAllowBuillingTowers = AllowBuillingCondition; }
//获取塔的数据
TArray<float> PikaGetTowerData(EPikaCharacterInfoDataTableType::Type CharacterInformationDataType);
//获取塔的当前等级
int32 PikaGetCurrentTowersAverageLevel()const;
//获取当前关卡所有Towers
TArray<APikaCharacterBase*> PikaGetCurrentLevelTowers();
/****************************************塔相关函数End****************************************/
/****************************************怪物相关函数Start****************************************/
//获取怪物图片
TArray<UTexture2D*> PikaGetMonsterIocn();
//简介
TArray<FText> PikaGetMonsterIntroduction();
//名字
TArray<FName> PikaGetMonsterName();
//获取怪物的Mesh,即特效内部的模型
TArray<UStaticMesh*> PikaGetMonsterMeshFromParticle(int32 MonsterID , FPikaComponentSpaceInfo& MyPikaComponentSpaceInfo);
//GM,读取数据表中的数据,并将其中的数据转换成蓝图实例
//如果用该方法在场景里进行拖拽生成模型时,角色内部是没有数据的
AActor* PikaSpawnMonster(int32 MonsterID, int32 MonsterLevel , bool PikaIsLoading = false, int32 CharacterIndex = INDEX_NONE , FVector CharacterLocation = FVector::ZeroVector);
//获取怪物的数据
TArray<float> PikaGetMonsterData(EPikaCharacterInfoDataTableType::Type CharacterInformationDataType);
//获取当前关卡所有Monsters
TArray<APikaCharacterBase*> PikaGetCurrentLevelMonsters();
//获取手动目标
FORCEINLINE APikaMonster* PikaGetTargetMonster() const { return PikaMonstersTarget; }
/****************************************怪物相关函数End****************************************/
/****************************************控制函数Start****************************************/
//允许玩家自己更新自己的绑定响应
virtual void SetupInputComponent() override;
//鼠标上滚的响应函数
void PikaMouseWheelUp();
//鼠标下滚的响应函数
void PikaMouseWheelDown();
//判断鼠标移动的方向
void PikaCursorMoveDirection();
//根据鼠标移动的方向移动摄像机
void PikaCameraMove(bool Direction, bool Axle);
//鼠标中键控制
void PikaMouseMiddleButtonPressed();
void PikaMouseMiddleButtonReleased();
//键盘的Q和E旋转模型设置
void PikaCounterClockWiseRotationKey();
void PikaClockWiseRotationKey();
/****************************************控制函数End****************************************/
/****************************************其它函数Start****************************************/
//获取场景中已经设置的目标点,目标点会作为GM命令的出生点(测试中)
//获取场景所有出生点,作为怪物的生成点
TArray<APikaAITargetPoint*> PikaGetAllOfTargetPoint();
ATargetPoint* PikaGetAllOfLevelMapTargetPoint(TSubclassOf<ATargetPoint> MyTargetPointCalss);
//获取玩家数据实例
APikaGodStonePlayerState * PikaGetTowerPlayerState();
//获取场景相机实例(Pawn)
APikaGodStoneCamera * PikaGetTowreCamera();
//测试打印函数
void PikaPrint(FString PikaStr);
//清除临时指针
void PikaClearTmpRuleOfTheCharacter() { PikaTempCharacterBasePtr = NULL; }
//获取当前关卡的地图
UTexture2D* PikaGetCurrentLevelMiniMap() const;
//获取地图标记点
FVector PikaGetMapMarkPointLocation();
FRotator PikaGetMapMarkPointRotator();
FORCEINLINE AActor* PikaGetMapMarkPoint()const { return PikaMapMarkPoint; }
UPikaGodStoneGameInstance* PikaGetGameInstance() const;
//载入数据到场景角色(载入数据)
bool PikaReductionGameData(bool IsReduction);
//存储游戏数据的功能(储存数据)
bool PikaSaveGameData(PikaFSaveSlotDataChannel SaveSlotDataChannel);
//获取读取信息
FText PikaGetSaveInformation(int32 NumData);
//播放随机声音
void PikaPlaySoundAtVetor(TArray<USoundBase*> CharacterSound, FVector CharcterLocation = FVector::ZeroVector, PikaETowerDefenceSoundType TowerDefenceSoundType = PikaETowerDefenceSoundType::SOUND_NONE);
//播放声音
void PikaPlaySoundAtVetor(USoundBase* CharacterSound, FVector CharcterLocation = FVector::ZeroVector, PikaETowerDefenceSoundType TowerDefenceSoundType = PikaETowerDefenceSoundType::SOUND_NONE);
/****************************************其它函数End****************************************/
private:
//数据导入,GM,读取数据表中的数据,并将其中的数据转换成蓝图实例
AActor* PikaCreateAndDataImport(int32 CharacterID, int32 CharacterLevel, UDataTable* CharacterData , bool PikaIsLoading = false, int32 CharacterIndex = INDEX_NONE , FVector CharacterLocation = FVector::ZeroVector);
//获取物品栏图标
TArray<UTexture2D*> PikaGetCharacterIocn(UDataTable* CharacterData);
//获取特效中的Mesh
TArray<UStaticMesh*> PikaGetDataStaticMeshFormPartcle(UDataTable* MyCharacterDataTable , int32 CharacterID , FPikaComponentSpaceInfo& MyPikaComponentSpaceInfo);
//名字
TArray<FName> PikaGetCharacterName(UDataTable* CharacterData);
//简介
TArray<FText> PikaGetCharacterIntroduction(UDataTable* CharacterData);
//获取角色数据
TArray<float> PikaGetCharacterData(UDataTable* CharacterData, float** NewFloatArray, EPikaCharacterInfoDataTableType::Type CharacterInformationDataType);
//释放掉我们的角色数据
void PikaReleaseCharacterData();
//获取场景内一个标准的等级(全部塔的平均等级)
int32 PikaGetCurrentCharacterAverageLevel(bool CharacterClass = true) const;
};PikaGodStonePlayerController.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGodStonePlayerController.h"
#include "Public/PikaGodStonePlayerState.h"
#include "Public/PikaGodStoneCamera.h"
#include "Public/PikaGameManager.h"
#include "Engine.h"
#include "ConstructorHelpers.h"
#include "Particles/ParticleLODLevel.h"
#include "Particles/TypeData/ParticleModuleTypeDataMesh.h"
#include "Particles/Size/ParticleModuleSize.h"
#include "Particles/Location/ParticleModuleLocation.h"
#include "Particles/Rotation/ParticleModuleMeshRotation.h"
#include "Public/PikaMonster.h"
#include "Public/PikaTowers.h"
#include "Public/PikaGameUserSettings.h"
APikaGodStonePlayerController::APikaGodStonePlayerController()
{
//显示鼠标
bShowMouseCursor = true;
//初始GM类
CheatClass = UPikaGameManager::StaticClass();
static ConstructorHelpers::FClassFinder<ATargetPoint> PikaMapPointClass(TEXT("/Game/ToolActor/MapPointBP"));
if (GetWorld())
{
//地图标记点
if (PikaMapPointClass.Class)
{
PikaMapMarkPoint = PikaGetAllOfLevelMapTargetPoint(PikaMapPointClass.Class);
}
}
PikaIsAllowBuillingTowers = true;
PikaMonstersTarget = nullptr;
}
void APikaGodStonePlayerController::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//获取鼠标移动的方向
PikaCursorMoveDirection();
//皮卡射线
if (PikaTowerDollPtr)
{
if (PikaMouseTraceHit.Location != FVector::ZeroVector)
PikaMouseTraceHit.Location = FVector::ZeroVector;
FHitResult PikaTraceOutHit;
//ECC_EngineTraceChannel4为自定义的射线检测的通道
GetHitResultUnderCursor(ECollisionChannel::ECC_GameTraceChannel4, true, PikaTraceOutHit);
//利用射线设置替身类的坐标
PikaTowerDollPtr->SetActorLocation(PikaTraceOutHit.Location);
}
else
{
//鼠标扫描场景,通道名称为PikaScanTrace
GetHitResultUnderCursor(ECollisionChannel::ECC_GameTraceChannel7, true, PikaMouseTraceHit);
}
if (PikaMouseTraceHit.Actor.IsValid())
{
APikaCharacterBase* PikaNewCharacterBase = Cast<APikaCharacterBase>(PikaMouseTraceHit.Actor.Get());
if (PikaNewCharacterBase)
{
PikaTempCharacterBasePtr = PikaNewCharacterBase;
PikaTempCharacterBasePtr->PikaCharacterAttributeDisplay(true);
}
}
else if (PikaTempCharacterBasePtr && PikaTempCharacterBasePtr->IsA(APikaCharacterBase::StaticClass()))
{
PikaTempCharacterBasePtr->PikaCharacterAttributeDisplay(false);
}
//关卡中角色控制
if (PikaGlobalConfigPre && !PikaIsSuccessLevel && !PikaGlobalConfigPre->PikaGameLevelManangenment.PikaGameOver)
{
/*//添加灵力
Confo->TDGameData.GoldGrowthTime += DeltaSeconds;
if (Confo->TDGameData.IsJudgement())
{
Confo->TDGameData.GoldGrowthTime = 0;
Confo->TDGameData.AddGlobalGold(2);
//验证条件否成功
GameCondition(ELevelCondition::ExceedingSpiritualForce);
}*/
//时间倒计时
if (PikaGlobalConfigPre->PikaGameData.PikaGameCount > 0)
{
PikaGlobalConfigPre->PikaGameData.PikaGameCount -= DeltaTime;
}
else
{
//GameOver();
}
//检测玩家是否死亡
//存在数量
int32 PikaExistNumber = 0;
int32 PikaTowersNum = 0;
TArray<APikaCharacterBase*> PikaARuleOfTheTowers = PikaGetCurrentLevelTowers();
for (APikaCharacterBase* PikaAloneTower : PikaARuleOfTheTowers)
{
if (PikaAloneTower->PikaIsActive())
{
PikaExistNumber++;
APikaTowers* PikaTowers = Cast<APikaTowers>(PikaAloneTower);
if (PikaTowers)
PikaTowersNum++;
}
}
//场景内没有塔,玩家输
if (PikaTowersNum == 0)
{
//GameOver();
}
//当前关卡是否胜利
if (!PikaGlobalConfigPre->PikaGameLevelManangenment.PikaCurrentLevelMissionSuccess)
{
//输掉比赛没
if (!PikaGlobalConfigPre->PikaGameLevelManangenment.PikaGameOver)
{
//准备开始怪物登场
if (!PikaGlobalConfigPre->PikaGameLevelManangenment.PikaGetLock())
{
if (PikaGlobalConfigPre->PikaGameLevelManangenment.PikaPerNumberOfMonsters.Num())
{
PikaGlobalConfigPre->PikaGameLevelManangenment.PikaSetTimeMnanagenment += DeltaTime;
//是否大于生成怪物的时间间隔
if (PikaGlobalConfigPre->PikaGameLevelManangenment.PikaIsTimeRight())
{
PikaGlobalConfigPre->PikaGameLevelManangenment.PikaSetTimeMnanagenment = PIKA_ZERO;
//获取怪物生成点
TArray<APikaAITargetPoint*> PikaSpawnPointArr = PikaGetAllOfTargetPoint();
TArray<APikaAITargetPoint*> PikaSpawnMonsterPoint;
if (PikaSpawnPointArr.Num() > 0)
{
for (APikaAITargetPoint* PikaMySpawnPoint : PikaSpawnPointArr)
{
if (!PikaMySpawnPoint->PikaTeam)
{
PikaSpawnMonsterPoint.Add(PikaMySpawnPoint);
}
}
}
//生成怪物
int32 PikaSpawnPoint = FMath::RandRange(0, PikaSpawnMonsterPoint.Num() - 1);
if (PikaSpawnPoint != INDEX_NONE && PikaSpawnMonsterPoint.IsValidIndex(PikaSpawnPoint))
{
//数据中是否存在角色
if (PikaGlobalConfigPre->PikaGameLevelManangenment.PikaIsExistDataMonster())
{
int32 PikaCurrentTowersLevelAverage = PikaGetCurrentTowersAverageLevel();
FVector PikaMonsterLocation = PikaSpawnMonsterPoint[PikaSpawnPoint]->GetActorLocation();
AActor* PikaMyMonster = PikaSpawnMonster(FMath::RandRange(0, 3), PikaGlobalConfigPre->PikaGameLevelManangenment.PikaAddMonsterLevel + PikaCurrentTowersLevelAverage , false , -1 , PikaMonsterLocation);
if ((APikaCharacterBase*)PikaMyMonster)
{
PikaMyMonster->SetActorLocation(PikaMonsterLocation);
//((APikaCharacterBase*)PikaMyMonster)->PikaPlayBornSound();
}
}
//对数据进行操作
PikaGlobalConfigPre->PikaGameLevelManangenment.PikaDataSubtraction();
}
}
}
}
else
{
//存在数量
int32 PikaExistNumber = 0;
//获取怪物
TArray<APikaCharacterBase*> PikaCurrentMonters = PikaGetCurrentLevelMonsters();
//是否活着
for (APikaCharacterBase* PikaRuleOfTheMonster : PikaCurrentMonters)
{
if (PikaRuleOfTheMonster->PikaIsActive())
{
PikaExistNumber++;
}
}
if (PikaExistNumber == 0)
{
//解锁,开始下一波怪物登场
PikaGlobalConfigPre->PikaGameLevelManangenment.PikaUnLock();
//准备下一个阶段
PikaGlobalConfigPre->PikaGameLevelManangenment.PikaCurrentStagesAreMonsters++;
}
}
}
}
else
{
//GameSuccess();
}
}
}
void APikaGodStonePlayerController::BeginPlay()
{
Super::BeginPlay();
//获取playerState类中的蓝图配置
APikaGodStonePlayerState * PikaPlayerStatePre = Cast<APikaGodStonePlayerState>(PlayerState);
if (PikaPlayerStatePre)
{
PikaGlobalConfigPrePlayerCon = PikaPlayerStatePre->PikaGlobalConfigPre;
if (PikaGlobalConfigPrePlayerCon)
{
}
}
//PikaGetTowerIocn();
//初始化主塔
if (PikaGlobalConfigPre)
{
if (!PikaGlobalConfigPre->PikaIsSave)
{
TArray<APikaAITargetPoint*> PikaSpawnPointArr = PikaGetAllOfTargetPoint();
if (PikaSpawnPointArr.Num() > 0)
{
for (APikaAITargetPoint* MySpawnPoint : PikaSpawnPointArr)
{
if (MySpawnPoint->PikaTeam)
{
APikaCharacterBase* PikaMianTowers = Cast<APikaCharacterBase>(PikaSpawnTowers(4, PikaGlobalConfigPre->PikaGameLevelManangenment.PikaTowersLevel));
if (PikaMianTowers)
PikaMianTowers->SetActorLocation(MySpawnPoint->GetActorLocation());
//上传我们的位置信息数据
if (PikaGlobalConfigPrePlayerCon)
{
int32 PikaCharacterIndex = PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaGetCurrentCharacterSpawnIDIndex(PikaMianTowers->PikaGetCharacterSpawnID());
if (PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaIsActive(PikaCharacterIndex))
{
PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterLocation[PikaCharacterIndex] = PikaMianTowers->GetActorLocation();
PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterRotator[PikaCharacterIndex] = PikaMianTowers->GetActorRotation();
}
}
}
}
}
//初始化怪物梯度
PikaGlobalConfigPre->PikaGameLevelManangenment.PikaAssignedMonsterAmount();
}
else
{
/*//数据读取完毕
Confo->InitializationDataComplete();
//将数据读取完毕告诉数据
if (GetTowerDefenceGameInstance())
GetTowerDefenceGameInstance()->InitializationDataComplete();
//解锁
UnTDLock();*/
}
}
}
void APikaGodStonePlayerController::PikaPrint(FString PikaStr)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, PikaStr);
}
}
UTexture2D* APikaGodStonePlayerController::PikaGetCurrentLevelMiniMap() const
{
if (PikaGameResourcePtr && PikaGlobalConfigPrePlayerCon && PikaGameResourcePtr->PikaLevelMiniMap.IsValidIndex(PikaGlobalConfigPrePlayerCon->PikaGameLevelManangenment.PikaCurrentLevel))
{
int32 PikaCurrentLevel = PikaGlobalConfigPrePlayerCon->PikaGameLevelManangenment.PikaCurrentLevel;
if (PikaGameResourcePtr->PikaLevelMiniMap[PikaCurrentLevel].PikaMiniMapTexture)
return PikaGameResourcePtr->PikaLevelMiniMap[PikaCurrentLevel].PikaMiniMapTexture;
}
return NULL;
}
FVector APikaGodStonePlayerController::PikaGetMapMarkPointLocation()
{
return PikaMapMarkPoint != NULL ? PikaMapMarkPoint->GetActorLocation() : FVector::ZeroVector;
}
FRotator APikaGodStonePlayerController::PikaGetMapMarkPointRotator()
{
return PikaMapMarkPoint != NULL ? PikaMapMarkPoint->GetActorRotation() : FRotator::ZeroRotator;
}
UPikaGodStoneGameInstance* APikaGodStonePlayerController::PikaGetGameInstance() const
{
return GetWorld() != NULL ? ((UPikaGodStoneGameInstance*)GetWorld()->GetGameInstance()) : NULL;
}
bool APikaGodStonePlayerController::PikaSaveGameData(PikaFSaveSlotDataChannel SaveSlotDataChannel)
{
if (PikaGetGameInstance())
{
if (PikaGlobalConfigPrePlayerCon)
return PikaGetGameInstance()->PikaSaveGameData(PikaGlobalConfigPrePlayerCon, SaveSlotDataChannel);
}
return false;
}
FText APikaGodStonePlayerController::PikaGetSaveInformation(int32 NumData)
{
FText PikaNewText;
UPikaGameSaveData* PikaNewGameSaveData = Cast<UPikaGameSaveData>(PIKA_LOADGAME_SLOT(PIKA_SAVE_SLOT_NAME, 0));
if (PikaNewGameSaveData)
{
if (PikaNewGameSaveData->PikaReadGameData.PikaSaveDataText.IsValidIndex(NumData))
PikaNewText = FText::FromString(PikaNewGameSaveData->PikaReadGameData.PikaSaveDataText[NumData]);
}
return PikaNewText;
}
//播放随机声音
void APikaGodStonePlayerController::PikaPlaySoundAtVetor(TArray<USoundBase*> CharacterSound, FVector CharcterLocation /*= FVector::ZeroVector*/, PikaETowerDefenceSoundType TowerDefenceSoundType /*= PikaETowerDefenceSoundType::SOUND_NONE*/)
{
//随机序列
int32 PikaRandomIndex = FMath::RandRange(0, (CharacterSound.Num() - 1));
if (!CharacterSound.IsValidIndex(PikaRandomIndex))
return;
//播放声音
PikaPlaySoundAtVetor(CharacterSound[PikaRandomIndex], CharcterLocation, TowerDefenceSoundType);
}
//播放声音
void APikaGodStonePlayerController::PikaPlaySoundAtVetor(USoundBase* CharacterSound, FVector CharcterLocation /*= FVector::ZeroVector*/, PikaETowerDefenceSoundType TowerDefenceSoundType /*= PikaETowerDefenceSoundType::SOUND_NONE*/)
{
if (GetWorld() && CharacterSound)
{
//设置塔防播放类型
CharacterSound->PikaqiuTowerDefenceSoundType = TowerDefenceSoundType;
//总声音收益
float PikaCurrentSound = 1;
//声音大小调节
if (UPikaGameUserSettings::PikaGetGameUserSettings())
{
switch (TowerDefenceSoundType)
{
case PikaETowerDefenceSoundType::SOUND_MUSIC:
PikaCurrentSound = UPikaGameUserSettings::PikaGetGameUserSettings()->PikaqiuTotalSoundControl * UPikaGameUserSettings::PikaGetGameUserSettings()->PikaBackgroundSoundControl;
break;
case PikaETowerDefenceSoundType::SOUND_EFFECT_SOUND:
PikaCurrentSound = UPikaGameUserSettings::PikaGetGameUserSettings()->PikaqiuTotalSoundControl * UPikaGameUserSettings::PikaGetGameUserSettings()->PikaEffectsSoundControl;
break;
case PikaETowerDefenceSoundType::SOUND_KEY_SOUND:
PikaCurrentSound = UPikaGameUserSettings::PikaGetGameUserSettings()->PikaqiuTotalSoundControl * UPikaGameUserSettings::PikaGetGameUserSettings()->PikaqiuButtonSoundControl;
break;
}
}
//播放声音
if (PikaCurrentSound > 0)
{
float pika = PikaCurrentSound > 1 ? 1 : PikaCurrentSound;
//是否有衰减
if (CharcterLocation != FVector::ZeroVector)
{
USoundAttenuation* PikaFightingSoundVolume = nullptr;
//获取战斗衰减框
if (PikaGameResourcePtr)
PikaFightingSoundVolume = PikaGameResourcePtr->PikaFightingSoundVolume;
if (PikaFightingSoundVolume != nullptr)
PIKA_SPAWN_SOUND_LOCATION(GetWorld(), CharacterSound, CharcterLocation, PikaCurrentSound > 1 ? 1 : PikaCurrentSound, 1, 0, PikaFightingSoundVolume, nullptr);
}
else
{
PIKA_SPAWN_SOUND_LOCATION(GetWorld(), CharacterSound, CharcterLocation, PikaCurrentSound > 1 ? 1 : PikaCurrentSound, 1, 0, nullptr, nullptr);
}
}
}
}
void APikaGodStonePlayerController::PikaCursorMoveDirection()
{
//屏幕尺寸
int32 PikaScreenSize_X, PikaScreenSize_Y;
//鼠标位置
float PikaMousePosi_X, PikaMousePosi_Y;
//获取屏幕尺寸
GetViewportSize(PikaScreenSize_X, PikaScreenSize_Y);
//获取鼠标位置
GetMousePosition(PikaMousePosi_X, PikaMousePosi_Y);
//IsNearlyEqual的第三个参数为误差宽容度
float ErrorTolerance = 6;
if (FMath::IsNearlyEqual(PikaMousePosi_X, PikaScreenSize_X, ErrorTolerance))
{
PikaCameraMove(0, 0);
return;
}
else if (FMath::IsNearlyEqual(PikaMousePosi_X, 0.0f, ErrorTolerance))
{
PikaCameraMove(1, 0);
return;
}
if (FMath::IsNearlyEqual(PikaMousePosi_Y, PikaScreenSize_Y, ErrorTolerance))
{
PikaCameraMove(1, 1);
return;
}
else if (FMath::IsNearlyEqual(PikaMousePosi_Y, 0.0f, ErrorTolerance))
{
PikaCameraMove(0, 1);
return;
}
}
void APikaGodStonePlayerController::PikaCameraMove(bool Direction, bool Axle)
{
if (Direction)
{
if (Axle)
{
//x轴正方向
FVector PikaTmpLocation = FVector(PikaGlobalConfigPrePlayerCon->PikaMouseSetConf.MouseSpeed, 0.0f, 0.0f);
//视角移动
GetPawn()->AddActorWorldOffset(PikaTmpLocation);
}
else
{
//y轴正方向
FVector PikaTmpLocation = FVector(0.0f, PikaGlobalConfigPrePlayerCon->PikaMouseSetConf.MouseSpeed, 0.0f);
GetPawn()->AddActorWorldOffset(PikaTmpLocation);
}
}
else
{
if (Axle)
{
//x轴负方向
FVector PikaTmpLocation = FVector(PikaGlobalConfigPrePlayerCon->PikaMouseSetConf.MouseSpeed*(-1), 0.0f, 0.0f);
GetPawn()->AddActorWorldOffset(PikaTmpLocation);
}
else
{
//y轴负方向
FVector PikaTmpLocation = FVector(0.0f, PikaGlobalConfigPrePlayerCon->PikaMouseSetConf.MouseSpeed*(-1), 0.0f);
GetPawn()->AddActorWorldOffset(PikaTmpLocation);
}
}
}
void APikaGodStonePlayerController::PikaMouseMiddleButtonPressed()
{
PikaEventMouseMiddlePressed.Broadcast(this);
}
void APikaGodStonePlayerController::PikaMouseMiddleButtonReleased()
{
PikaEventFMouseMiddleReleased.Broadcast(this);
}
void APikaGodStonePlayerController::PikaCounterClockWiseRotationKey()
{
if (PikaTowerDollPtr && PikaGlobalConfigPrePlayerCon)
PikaTowerDollPtr->AddActorLocalRotation(FRotator(0, -1 * PikaGlobalConfigPrePlayerCon->PikaMouseSetConf.PikaAngleOfRotation , 0));
}
void APikaGodStonePlayerController::PikaClockWiseRotationKey()
{
if (PikaTowerDollPtr && PikaGlobalConfigPrePlayerCon)
PikaTowerDollPtr->AddActorLocalRotation(FRotator(0, PikaGlobalConfigPrePlayerCon->PikaMouseSetConf.PikaAngleOfRotation , 0));
}
void APikaGodStonePlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
/*按键绑定需要在UE4编辑器里的输入里设置绑定的键位信息*/
//鼠标滚轮
InputComponent->BindAction("PikaWheelUp", IE_Pressed, this, &APikaGodStonePlayerController::PikaMouseWheelUp);
InputComponent->BindAction("PikaWheelDown", IE_Pressed, this, &APikaGodStonePlayerController::PikaMouseWheelDown);
//鼠标中间绑定
InputComponent->BindAction("PikaMiddleButtonPressed", IE_Pressed, this, &APikaGodStonePlayerController::PikaMouseMiddleButtonPressed);
InputComponent->BindAction("PikaMiddleButtonReleased", IE_Released, this, &APikaGodStonePlayerController::PikaMouseMiddleButtonReleased);
//键盘Q和E绑定
InputComponent->BindAction("PikaCounterClockWiseRotation", IE_Pressed, this, &APikaGodStonePlayerController::PikaCounterClockWiseRotationKey);
InputComponent->BindAction("PikaClockWiseRotation", IE_Pressed, this, &APikaGodStonePlayerController::PikaClockWiseRotationKey);
}
void APikaGodStonePlayerController::PikaMouseWheelUp()
{
if (GetPawn())
{
APikaGodStoneCamera * PikaPartCamera = Cast<APikaGodStoneCamera>(GetPawn());
if (PikaPartCamera)
{
PikaPartCamera->PikaCameraZoom(1, PikaGlobalConfigPrePlayerCon->PikaMouseSetConf.MouseSpeed);
}
}
}
void APikaGodStonePlayerController::PikaMouseWheelDown()
{
if (GetPawn())
{
APikaGodStoneCamera * PikaPartCamera = Cast<APikaGodStoneCamera>(GetPawn());
if (PikaPartCamera)
{
PikaPartCamera->PikaCameraZoom(0, PikaGlobalConfigPrePlayerCon->PikaMouseSetConf.MouseSpeed);
}
}
}
AActor* APikaGodStonePlayerController::PikaCreateAndDataImport(int32 CharacterID, int32 CharacterLevel, UDataTable* CharacterData , bool PikaIsLoading , int32 CharacterIndex , FVector CharacterLocation)
{
AActor* PikaMyActor = NULL;
if (CharacterData && CharacterID >= 0 && CharacterID < PikaAITowrerData->RowMap.Num())
{
TArray<FPikaCharacterInfoDataTable*> PikaInfomationData;
TArray<FName> PikaCharacterNameArray = PikaGetCharacterName(CharacterData);
CharacterData->GetAllRows("PikaInfo", PikaInfomationData);
//获取角色蓝图实例
UClass * PikaMyClass = PikaInfomationData[CharacterID]->PikaCharacterBlueprintKey.LoadSynchronous();
if (PikaMyClass)
{
//获取场景中已经设置的目标点
//TArray<APikaAITargetPoint*> PikaMyPoint = PikaGetAllOfTargetPoint();
//if (PikaMyPoint.Num() > 0)
//{
//PikaMyActor = GetWorld()->SpawnActor<AActor>(PikaMyClass, PikaMyPoint[0]->GetActorLocation(), FRotator::ZeroRotator);
//生成模型
PikaMyActor = GetWorld()->SpawnActor<AActor>(PikaMyClass, FVector::ZeroVector, FRotator::ZeroRotator);
//更新模型数据到面板UI
if (PikaMyActor)
{
APikaCharacterBase * PikaMyCharacterBase = Cast<APikaCharacterBase>(PikaMyActor);
FName PikaCurrentCharacterName;
if (PikaMyCharacterBase)
{
//播放蒙太奇和绑定蒙太奇
PikaMyCharacterBase->PikaPlayAnimationForBegin(PikaIsLoading);
//获取角色ID和金币
PikaMyCharacterBase->PikaCharDataPre->PikaCharBaseData.PikaCharacterID = PikaInfomationData[CharacterID]->PikaCharacterID;
PikaMyCharacterBase->PikaCharDataPre->PikaCharBaseData.PikaComsumeGold = PikaInfomationData[CharacterID]->PikaComsumeGold;
//获取名字
if (PikaCharacterNameArray.IsValidIndex(CharacterLevel))
{
PikaMyCharacterBase->PikaCharDataPre->PikaCharBaseData.PikaCharacterName = PikaCharacterNameArray[CharacterID];
PikaCurrentCharacterName = PikaCharacterNameArray[CharacterID];
}
//数据导入
PikaMyCharacterBase->PikaCharDataPre->PikaCharBaseData.PikaInitCharacterAttrubute(
PikaInfomationData[CharacterID]->PikaMaxHealth,
PikaInfomationData[CharacterID]->PikaPhysicalAttack,
PikaInfomationData[CharacterID]->PikaAttackSpeed,
PikaInfomationData[CharacterID]->PikaMaxExperienceValue,
PikaInfomationData[CharacterID]->PikaArmor
);
PikaMyCharacterBase->PikaCharDataPre->PikaCharBaseData.PikaInitAddCharacterAttribute(
PikaInfomationData[CharacterID]->PikaAddHealth,
PikaInfomationData[CharacterID]->PikaAddPhysicalAttack,
PikaInfomationData[CharacterID]->PikaAddAttackSpeed,
PikaInfomationData[CharacterID]->PikaAddExperienceValue,
PikaInfomationData[CharacterID]->PikaAddArmor
);
}
//自定义角色等级
if (CharacterLevel >= 1)
{
for (int32 i = 0; i < CharacterLevel; i++)
{
PikaMyCharacterBase->PikaCharDataPre->PikaCharBaseData.PikaUpdateLevel();
}
}
//更新角色数据到面板
PikaMyCharacterBase->PikaInitCharacterInformation();
//注册我们的生成序列
if (PikaGlobalConfigPrePlayerCon)
{
//是否是载入类型的spawn
if (PikaIsLoading)
{
if (CharacterIndex != INDEX_NONE)
{
/*//载入我们的数据
MyRuleOfTheCharacter->SetCharacterSpawnID(Confo->TemporaryCacheData.CharacterSpawnID[CharacterIndex]);
MyRuleOfTheCharacter->SetActorLocation(Confo->TemporaryCacheData.CharacterLocation[CharacterIndex] + FVector(0, 0, 100));//防止生成的角色掉下去
MyRuleOfTheCharacter->SetActorRotation(Confo->TemporaryCacheData.CharacterRotator[CharacterIndex]);
MyRuleOfTheCharacter->SetCharacterCurrentLevel(Confo->TemporaryCacheData.CharacterCurrentLevel[CharacterIndex]);
MyRuleOfTheCharacter->SetCharacterCurrentHealth(Confo->TemporaryCacheData.CharacterCurrentHealth[CharacterIndex]);
MyRuleOfTheCharacter->SetCharacterCurrentEXP(Confo->TemporaryCacheData.CharacterCurrentExp[CharacterIndex]);
MyRuleOfTheCharacter->SetCharacterActive(Confo->TemporaryCacheData.CharacterActive[CharacterIndex]);*/
}
else
{
UE_LOG(LogTemp, Error, TEXT(" Generation failed"));
}
}
else
{
int32 PikaMySpawnID = 10000 + FMath::RandRange(0, 10000);
while (PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaIsExistSpawnID(PikaMySpawnID))
{
PikaMySpawnID = 10000 + FMath::RandRange(0, 10000);
}
PikaMyCharacterBase->PikaSetCharacterSpawnID(PikaMySpawnID);
//上传信息到我们的数据包
PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterSpawnID.Add(PikaMySpawnID);
PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterActive.Add(true);
PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterTeam.Add(PikaMyCharacterBase->PikaIsTeam());
PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterLocation.Add(CharacterLocation);
PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterRotator.Add(PikaMyCharacterBase->GetActorRotation());
PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterName.Add(PikaCurrentCharacterName);
PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterCurrentHealth.Add(PikaInfomationData[CharacterID]->PikaMaxHealth);
PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterCurrentLevel.Add(CharacterLevel);
PikaGlobalConfigPrePlayerCon->PikaTemporaryCacheData.PikaCharacterCurrentExp.Add(0);
}
}
}
//}
}
}
return PikaMyActor;
}
//GM,读取数据表中的数据,并将其中的数据转换成蓝图实例
AActor* APikaGodStonePlayerController::PikaSpawnTowers(int32 TowerID, int32 TowerLevel , bool PikaIsLoading , int32 CharacterIndex , FVector CharacterLocation)
{
return PikaCreateAndDataImport(TowerID, TowerLevel, PikaAITowrerData , PikaIsLoading, CharacterIndex , CharacterLocation);
}
AActor* APikaGodStonePlayerController::PikaSpawnMonster(int32 MonsterID, int32 MonsterLevel , bool PikaIsLoading , int32 CharacterIndex , FVector CharacterLocation)
{
return PikaCreateAndDataImport(MonsterID, MonsterLevel, PikaAIMonsterData , PikaIsLoading, CharacterIndex , CharacterLocation);
}
TArray<float> APikaGodStonePlayerController::PikaGetMonsterData(EPikaCharacterInfoDataTableType::Type CharacterInformationDataType)
{
return PikaGetCharacterData(PikaAIMonsterData, PikaMonsterCharacterData, CharacterInformationDataType);
}
TArray<APikaCharacterBase*> APikaGodStonePlayerController::PikaGetCurrentLevelMonsters()
{
TArray<APikaCharacterBase*> PikaCurrentLevelTowers;
//临时
TArray<AActor*> PikaTempCharacter;
if (GetWorld())
{
PikaGETALLACTOR(GetWorld(), APikaCharacterBase::StaticClass(), PikaTempCharacter);
for (AActor* PikaCurrentActor : PikaTempCharacter)
{
if (PikaCurrentActor->IsA(APikaMonster::StaticClass()))
{
PikaCurrentLevelTowers.Add(Cast<APikaCharacterBase>(PikaCurrentActor));
}
}
}
return PikaCurrentLevelTowers;
}
//获取场景中已经设置的目标点
TArray<APikaAITargetPoint*> APikaGodStonePlayerController::PikaGetAllOfTargetPoint()
{
TArray<APikaAITargetPoint*> PikaTargetPointArr;
if (!GetWorld())
{
UE_LOG(LogTemp , Error , TEXT("Pika:GetWorld() is fail"));
return PikaTargetPointArr;
}
TSubclassOf<APikaAITargetPoint> PikaAITargetPointInstance = APikaAITargetPoint::StaticClass();
if (PikaAITargetPointInstance)
{
for (TActorIterator<APikaAITargetPoint>It(GetWorld() , PikaAITargetPointInstance); It; ++It)
{
APikaAITargetPoint * PikaMySpawnPoint = *It;
if (PikaMySpawnPoint)
{
PikaTargetPointArr.Add(PikaMySpawnPoint);
}
}
}
else
{
UE_LOG(LogTemp , Error , TEXT("Pika:PikaTargetPointArr is fail"));
return PikaTargetPointArr;
}
UE_LOG(LogTemp , Log , TEXT("Pika:Successfully"));
return PikaTargetPointArr;
}
ATargetPoint* APikaGodStonePlayerController::PikaGetAllOfLevelMapTargetPoint(TSubclassOf<ATargetPoint> MyTargetPointCalss)
{
if (MyTargetPointCalss)
{
for (TActorIterator<ATargetPoint>It(GetWorld(), MyTargetPointCalss); It; ++It)
{
ATargetPoint* MySpawnPoint = *It;
if (MySpawnPoint && !MySpawnPoint->IsA(APikaAITargetPoint::StaticClass()))
return MySpawnPoint;
}
}
return NULL;
}
APikaGodStonePlayerState * APikaGodStonePlayerController::PikaGetTowerPlayerState()
{
return ((APikaGodStonePlayerState*)PlayerState);
}
APikaGodStoneCamera * APikaGodStonePlayerController::PikaGetTowreCamera()
{
return ((APikaGodStoneCamera*)GetPawn());
}
TArray<UTexture2D*> APikaGodStonePlayerController::PikaGetTowerIocn()
{
return PikaGetCharacterIocn(PikaAITowrerData);
}
TArray<FName> APikaGodStonePlayerController::PikaGetTowersName()
{
return PikaGetCharacterName(PikaAITowrerData);
}
TArray<FText> APikaGodStonePlayerController::PikaGetTowersIntroduction()
{
return PikaGetCharacterIntroduction(PikaAITowrerData);
}
TArray<float> APikaGodStonePlayerController::PikaGetTowerData(EPikaCharacterInfoDataTableType::Type CharacterInformationDataType)
{
return PikaGetCharacterData(PikaAITowrerData, PikaTowersCharacterData, CharacterInformationDataType);
}
int32 APikaGodStonePlayerController::PikaGetCurrentTowersAverageLevel() const
{
return PikaGetCurrentCharacterAverageLevel();
}
TArray<APikaCharacterBase*> APikaGodStonePlayerController::PikaGetCurrentLevelTowers()
{
TArray<APikaCharacterBase*> PikaCurrentLevelTowers;
//临时
TArray<AActor*> PikaTempCharacter;
if (GetWorld())
{
PikaGETALLACTOR(GetWorld(), APikaCharacterBase::StaticClass(), PikaTempCharacter);
for (AActor* PikaCurrentActor : PikaTempCharacter)
{
if (PikaCurrentActor->IsA(APikaTowers::StaticClass()))
{
PikaCurrentLevelTowers.Add(Cast<APikaCharacterBase>(PikaCurrentActor));
}
}
}
return PikaCurrentLevelTowers;
}
TArray<UTexture2D*> APikaGodStonePlayerController::PikaGetMonsterIocn()
{
return PikaGetCharacterIocn(PikaAIMonsterData);
}
TArray<FText> APikaGodStonePlayerController::PikaGetMonsterIntroduction()
{
return PikaGetCharacterIntroduction(PikaAIMonsterData);
}
TArray<FName> APikaGodStonePlayerController::PikaGetMonsterName()
{
return PikaGetCharacterName(PikaAIMonsterData);
}
TArray<float> APikaGodStonePlayerController::PikaGetBuildCD()
{
TArray<float> PikaArrayFloat;
if (PikaAITowrerData)
{
TArray<FPikaCharacterInfoDataTable*> PikaInfomationData;
PikaAITowrerData->GetAllRows("PikaInfo", PikaInfomationData);
for (int32 i = 0; i < PikaAITowrerData->RowMap.Num(); i++)
{
float PikaFloat = PikaInfomationData[i]->PikaConstructionTime;
PikaArrayFloat.Add(PikaFloat);
}
}
return PikaArrayFloat;
}
TArray<int32> APikaGodStonePlayerController::PikaGetTowerComsumeGold()
{
TArray<int32> PikaArrayGlod;
if (PikaAITowrerData)
{
TArray<FPikaCharacterInfoDataTable*> PikaInfomationData;
PikaAITowrerData->GetAllRows("PikaInfo", PikaInfomationData);
for (int32 i = 0; i < PikaAITowrerData->RowMap.Num(); i++)
{
float PikaGlod = PikaInfomationData[i]->PikaComsumeGold;
PikaArrayGlod.Add(PikaGlod);
}
}
return PikaArrayGlod;
}
TArray<UStaticMesh*> APikaGodStonePlayerController::PikaGetTowerMeshFromParticle(int32 TowerID , FPikaComponentSpaceInfo& MyPikaComponentSpaceInfo)
{
return PikaGetDataStaticMeshFormPartcle(PikaAITowrerData , TowerID , MyPikaComponentSpaceInfo);
}
TArray<UStaticMesh*> APikaGodStonePlayerController::PikaGetMonsterMeshFromParticle(int32 MonsterID , FPikaComponentSpaceInfo& MyPikaComponentSpaceInfo)
{
return PikaGetDataStaticMeshFormPartcle(PikaAIMonsterData , MonsterID , MyPikaComponentSpaceInfo);
}
APikaTowerDoll* APikaGodStonePlayerController::PikaSpawnTowerDoll(int32 SerialNum)
{
TSubclassOf<APikaTowerDoll> PikaMyDoll = APikaTowerDoll::StaticClass();
//记录我们的空间位置
FPikaComponentSpaceInfo PikaComponentSpaceInformation;
if (GetWorld() && PikaMyDoll)
{
PikaTowerDollPtr = GetWorld()->SpawnActor<APikaTowerDoll>(PikaMyDoll, FVector::ZeroVector, FRotator::ZeroRotator);
if (PikaTowerDollPtr)
{
//注册
PikaTowerDollPtr->PikaSetController(this);
TArray<UStaticMesh*> PikaMeshArray = PikaGetTowerMeshFromParticle(SerialNum, PikaComponentSpaceInformation);
if (PikaMeshArray.Num() < 1)
{
PikaMeshArray = PikaGetTowerMeshFromParticle(SerialNum, PikaComponentSpaceInformation);
if (PikaMeshArray.Num() < 1)
{
return nullptr;//无Mesh载入
}
}
//生成替身的颜色
PikaTowerDollPtr->PikaSetMeshAddToMeshComponet(PikaMeshArray , PikaComponentSpaceInformation);
PikaTowerDollPtr->PikaSetMeshColor(true);
}
return PikaTowerDollPtr;
}
return NULL;
}
void APikaGodStonePlayerController::PikaDestoryTowerDoll()
{
if (PikaTowerDollPtr)
PikaTowerDollPtr->Destroyed();
PikaTowerDollPtr = NULL;
}
TArray<UTexture2D*> APikaGodStonePlayerController::PikaGetCharacterIocn(UDataTable* CharacterData)
{
TArray<UTexture2D*> PikaArrayTexture;
if (CharacterData)
{
TArray<FPikaCharacterInfoDataTable*> PikaInfomationData;
CharacterData->GetAllRows("PikaInfo", PikaInfomationData);
for (int32 i = 0; i < CharacterData->RowMap.Num(); i++)
{
UTexture2D* PikaTexture = PikaInfomationData[i]->PikaIcon.LoadSynchronous();
if (PikaTexture)
{
PikaArrayTexture.Add(PikaTexture);
}
}
}
return PikaArrayTexture;
}
//获取特效中的Mesh
TArray<UStaticMesh*> APikaGodStonePlayerController::PikaGetDataStaticMeshFormPartcle(UDataTable* MyCharacterDataTable, int32 CharacterID , FPikaComponentSpaceInfo& MyPikaComponentSpaceInfo)
{
TArray<UStaticMesh*> PikaMyStaticMeshArray;
if (MyCharacterDataTable)
{
TArray<FPikaCharacterInfoDataTable*> PikaInfomationData;
MyCharacterDataTable->GetAllRows("PikaInfo", PikaInfomationData);
if (CharacterID >= 0 && CharacterID < PikaInfomationData.Num())
{
//获取蓝图实例
UClass* PikaMyClass = PikaInfomationData[CharacterID]->PikaCharacterBlueprintKey.LoadSynchronous();
if (PikaMyClass && GetWorld())
{
APikaCharacterBase* PikaMyCharacter = GetWorld()->SpawnActor<APikaCharacterBase>(PikaMyClass, FVector::ZeroVector, FRotator::ZeroRotator);
//PikaMyCharacter->GetParticleMesh()->Template为加载特效的地方,此处相当于获取了特效
if (PikaMyCharacter && PikaMyCharacter->GetParticleMesh() && PikaMyCharacter->GetParticleMesh()->Template)
{
//判断该特效中的发射器个数是否大于0
if (PikaMyCharacter->GetParticleMesh()->Template->Emitters.Num())
{
//从特效中的发射器中搜索Mesh
for (int32 i = 0; i < PikaMyCharacter->GetParticleMesh()->Template->Emitters.Num(); i++)
{
const UParticleEmitter* PikaMyEmitter = PikaMyCharacter->GetParticleMesh()->Template->Emitters[i];
if (PikaMyEmitter)
{
UParticleLODLevel* PikaMyLOD = PikaMyEmitter->LODLevels[0];
//PikaMyLOD->bEnabled表示当前LOD是否为启动状态
if (PikaMyLOD && PikaMyLOD->bEnabled)
{
UParticleModuleTypeDataMesh* PikaMyParticleDataMesh = Cast<UParticleModuleTypeDataMesh>(PikaMyLOD->TypeDataModule);
//获取特效中的Mesh
if (PikaMyParticleDataMesh && PikaMyParticleDataMesh->Mesh)
{
//复制Mesh
UStaticMesh* PikaMyParticleMeshCopy = Cast<UStaticMesh>(StaticDuplicateObject(PikaMyParticleDataMesh->Mesh, this));
if (PikaMyParticleMeshCopy)
{
PikaMyStaticMeshArray.Add(PikaMyParticleMeshCopy);
//获取特效的尺寸,用来控制生成绿色模型的大小
//PikaMyLOD->Modules是指特效个每个发射器里的一行,如Lifetime、Inital Size等
for (int32 IndexMesh = 0 ; IndexMesh < PikaMyLOD->Modules.Num() ; IndexMesh++)
{
bool PikaIsComponentSpaceInformation = false;
UParticleModuleSize* PikaMeshSize = Cast<UParticleModuleSize>(PikaMyLOD->Modules[IndexMesh]);
UParticleModuleLocation* PikaMeshLocation = Cast<UParticleModuleLocation>(PikaMyLOD->Modules[IndexMesh]);
UParticleModuleMeshRotation* PikaMeshRotation = Cast<UParticleModuleMeshRotation>(PikaMyLOD->Modules[IndexMesh]);
//判断是不是MeshSize
if (PikaMeshSize)
{
MyPikaComponentSpaceInfo.PikaComponentSize.Add(PikaMeshSize->StartSize.PikaqiuGetMaxValueVec());
PikaIsComponentSpaceInformation = true;
}
//判断是不是MeshLocation
if (PikaMeshLocation)
{
MyPikaComponentSpaceInfo.PikaComponentLocation.Add(PikaMeshLocation->StartLocation.PikaqiuGetMaxValueVec());
PikaIsComponentSpaceInformation = true;
}
//判断是不是MeshRotation
if (PikaMeshRotation)
{
MyPikaComponentSpaceInfo.PikaComponentRotation.Add((PikaMeshRotation->StartRotation.PikaqiuGetMaxValueVec()).Rotation());
PikaIsComponentSpaceInformation = true;
}
if (PikaIsComponentSpaceInformation)
{
if (!MyPikaComponentSpaceInfo.PikaComponentRotation.IsValidIndex(MyPikaComponentSpaceInfo.PikaGetMax() - 1))
{
//MyPikaComponentSpaceInfo.PikaComponentRotation为无效值时,添加一个基本值
MyPikaComponentSpaceInfo.PikaComponentRotation.Add(FRotator::ZeroRotator);
}
if (!MyPikaComponentSpaceInfo.PikaComponentLocation.IsValidIndex(MyPikaComponentSpaceInfo.PikaGetMax() - 1))
{
//MyPikaComponentSpaceInfo.PikaComponentLocation为无效值时,添加一个基本值
MyPikaComponentSpaceInfo.PikaComponentLocation.Add(FVector::ZeroVector);
}
if (!MyPikaComponentSpaceInfo.PikaComponentSize.IsValidIndex(MyPikaComponentSpaceInfo.PikaGetMax() - 1))
{
//MyPikaComponentSpaceInfo.PikaComponentSize为无效值时,添加一个基本值
MyPikaComponentSpaceInfo.PikaComponentSize.Add(FVector(1, 1, 1));
}
}
}
}
}
}
}
}
}
PikaMyCharacter->Destroy(true);
PikaMyCharacter = NULL;
}
}
}
}
return PikaMyStaticMeshArray;
}
TArray<FName> APikaGodStonePlayerController::PikaGetCharacterName(UDataTable* CharacterData)
{
TArray<FName> PikaTArrayFName;
return CharacterData != NULL ? CharacterData->GetRowNames() : PikaTArrayFName;
}
TArray<FText> APikaGodStonePlayerController::PikaGetCharacterIntroduction(UDataTable* CharacterData)
{
TArray<FText> PikaTArrayFText;
TArray<FPikaCharacterInfoDataTable*> PikaInformationData;
CharacterData->GetAllRows("InformationData", PikaInformationData);
for (int32 i = 0; i < PikaInformationData.Num(); i++)
{
PikaTArrayFText.Add(PikaInformationData[i]->PikaComment);
}
return PikaTArrayFText;
}
float** APikaGodStonePlayerController::PikaRegisterCharacterData(UDataTable* CharacterData)
{
float** PikaSaveCharacterData = NULL;
if (CharacterData)
{
TArray<FPikaCharacterInfoDataTable*> PikaInformationData;
CharacterData->GetAllRows("InformationData", PikaInformationData);
//申请行空间
PikaSaveCharacterData = new float*[PikaInformationData.Num()];
//申请列排空间
for (int32 i = 0; i < PikaInformationData.Num(); i++)
{
PikaSaveCharacterData[i] = new float[EPikaCharacterInfoDataTableType::DATA_PikaCharacterMax];
}
for (int32 i = 0; i < PikaInformationData.Num(); i++)
{
for (int32 indexI = 0; indexI < PikaInformationData.Num(); indexI++)
{
switch (indexI)
{
case EPikaCharacterInfoDataTableType::DATA_PikaCharacterHealth:
PikaSaveCharacterData[i][indexI] = PikaInformationData[i]->PikaMaxHealth;
break;
case EPikaCharacterInfoDataTableType::DATA_PikaCharacterAttack:
PikaSaveCharacterData[i][indexI] = PikaInformationData[i]->PikaPhysicalAttack;
break;
case EPikaCharacterInfoDataTableType::DATA_PikaCharacterArm:
PikaSaveCharacterData[i][indexI] = PikaInformationData[i]->PikaArmor;
break;
case EPikaCharacterInfoDataTableType::DATA_PikaCharacterEmpircalValue:
PikaSaveCharacterData[i][indexI] = PikaInformationData[i]->PikaMaxExperienceValue;
break;
case EPikaCharacterInfoDataTableType::DATA_PikaCharacterAttackSpeed:
PikaSaveCharacterData[i][indexI] = PikaInformationData[i]->PikaAttackSpeed;
break;
case EPikaCharacterInfoDataTableType::DATA_PikaCharacterComsumeGlod:
PikaSaveCharacterData[i][indexI] = PikaInformationData[i]->PikaComsumeGold;
break;
case EPikaCharacterInfoDataTableType::DATA_PikaCharacterConstructionTime:
PikaSaveCharacterData[i][indexI] = PikaInformationData[i]->PikaConstructionTime;
break;
case EPikaCharacterInfoDataTableType::DATA_PikaCharacterAddGlod:
PikaSaveCharacterData[i][indexI] = PikaInformationData[i]->PikaAddComsume;
break;
case EPikaCharacterInfoDataTableType::DATA_PikaCharacterAddHealth:
PikaSaveCharacterData[i][indexI] = PikaInformationData[i]->PikaAddHealth;
break;
case EPikaCharacterInfoDataTableType::DATA_PikaCharacterAddPhysicalAttack:
PikaSaveCharacterData[i][indexI] = PikaInformationData[i]->PikaAddPhysicalAttack;
break;
case EPikaCharacterInfoDataTableType::DATA_PikaCharacterAddArmor:
PikaSaveCharacterData[i][indexI] = PikaInformationData[i]->PikaAddArmor;
break;
case EPikaCharacterInfoDataTableType::DATA_PikaCharacterAddAttackSpeed:
PikaSaveCharacterData[i][indexI] = PikaInformationData[i]->PikaAddAttackSpeed;
break;
case EPikaCharacterInfoDataTableType::DATA_PikaCharacterAddEmpiricalValue:
PikaSaveCharacterData[i][indexI] = PikaInformationData[i]->PikaAddExperienceValue;
break;
}
}
}
}
return PikaSaveCharacterData;
}
TArray<float> APikaGodStonePlayerController::PikaGetCharacterData(UDataTable* CharacterData, float** NewFloatArray, EPikaCharacterInfoDataTableType::Type CharacterInformationDataType)
{
TArray<float> PikaBaseArrayCharacterData;
if (CharacterData && NewFloatArray)
{
TArray<FPikaCharacterInfoDataTable*> PikaInformationData;
CharacterData->GetAllRows("InformationData", PikaInformationData);
for (int32 i = 0; i < PikaInformationData.Num(); i++)
{
PikaBaseArrayCharacterData.Add(NewFloatArray[i][CharacterInformationDataType]);
}
}
return PikaBaseArrayCharacterData;
}
void APikaGodStonePlayerController::PikaReleaseCharacterData()
{
if (PikaAITowrerData)
{
TArray<FPikaCharacterInfoDataTable*> PikaInformationData;
PikaAITowrerData->GetAllRows("InformationData", PikaInformationData);
for (int32 i = 0; i < PikaInformationData.Num(); i++)
{
delete[] PikaMonsterCharacterData[i];
}
delete[] PikaMonsterCharacterData;
}
if (PikaAIMonsterData)
{
TArray<FPikaCharacterInfoDataTable*> PikaInformationData;
PikaAIMonsterData->GetAllRows("InformationData", PikaInformationData);
for (int32 i = 0; i < PikaInformationData.Num(); i++)
{
delete[] PikaMonsterCharacterData[i];
}
delete[] PikaMonsterCharacterData;
}
}
int32 APikaGodStonePlayerController::PikaGetCurrentCharacterAverageLevel(bool CharacterClass /*= true*/) const
{
if (GetWorld())
{
TArray<AActor*> PikaOutArray;
//总和
int32 PikaTheSum = PIKA_ZERO;
int32 PikaCharacterNumber = PIKA_ZERO;
if (CharacterClass)
{
PikaGETALLACTOR(GetWorld(), APikaTowers::StaticClass(), PikaOutArray);
}
else
{
PikaGETALLACTOR(GetWorld(), APikaMonster::StaticClass(), PikaOutArray);
}
//获取数量
PikaCharacterNumber = PikaOutArray.Num();
for (AActor* PikaCharacterOriginal : PikaOutArray)
{
APikaCharacterBase* PikaCurrentRuleOfTheCharacter = (APikaCharacterBase*)PikaCharacterOriginal;
if (PikaCurrentRuleOfTheCharacter)
{
//获取值
PikaTheSum += PikaCurrentRuleOfTheCharacter->PikaGetCharacterLevel();
}
}
if (PikaCharacterNumber != PIKA_ZERO)
{
return PikaTheSum / PikaCharacterNumber;
}
}
return INDEX_NONE;
}PikaGodStonePlayerState.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerState.h"
#include "PikaGlobalConfig.h"
#include "Public/PikaGodStoneGameInstance.h"
#include "PikaGameResource.h"
#include "PikaGodStonePlayerState.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API APikaGodStonePlayerState : public APlayerState
{
GENERATED_BODY()
public:
//UPROPERTY()
//TSubclassOf<UPikaGlobalConfig> PikaGlobalConfigInstance;
UPROPERTY()
UPikaGlobalConfig * PikaGlobalConfigPre;
UPROPERTY()
UPikaGameResource* PikaGameResources;
APikaGodStonePlayerState();
void Tick(float DeltaTime) override;
UPikaGodStoneGameInstance* PikaGetGameInstance();
void PikaPrint(FString PikaStr);
};PikaGodStonePlayerState.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaGodStonePlayerState.h"
#include "ConstructorHelpers.h"
#include "Public/PikaGodStonePlayerController.h"
APikaGodStonePlayerState::APikaGodStonePlayerState()
{
PrimaryActorTick.bCanEverTick = true;
//加载蓝图中的全局配置
//static ConstructorHelpers::FClassFinder<UPikaGlobalConfig>PikaGConfig(TEXT("/Game/GlobalConfig/PikaGlobalConfigBP"));
//PikaGlobalConfigInstance = PikaGConfig.Class;
//加载C++方式的全局配置
//PikaGlobalConfigInstance = UPikaGlobalConfig::StaticClass();
//在c++中引用蓝图中的全局配置
/*if (GetWorld() && PikaGlobalConfigInstance)
{
PikaGlobalConfigPre = NewObject<UPikaGlobalConfig>(GetWorld(), PikaGlobalConfigInstance);
}*/
//数据配置
static ConstructorHelpers::FClassFinder<UPikaGameResource> PikaMyGameResourceClass(TEXT("/Game/MinMap/BP/PikaGameResourceBP"));
static ConstructorHelpers::FObjectFinder<UDataTable> PikaMyDataTable(TEXT("/Game/TowerAI/DataTable/PikaTower"));
static ConstructorHelpers::FObjectFinder<UDataTable> PikaMyDataTableMonster(TEXT("/Game/MonsterAI/DataTable/PikaMonster"));
if (GetWorld())
{
if (UPikaGlobalConfig::StaticClass())
{
PikaGlobalConfigPre = NewObject<UPikaGlobalConfig>(GetWorld(), UPikaGlobalConfig::StaticClass());
//将存档进行赋值
if (PikaGetGameInstance())
{
//获取当前正确的读取名字
FString DataName = PikaGetGameInstance()->PikaGetCurrentGameSaveName();
UPikaGameSaveData* PikaNewGameSaveData = Cast<UPikaGameSaveData>(PIKA_LOADGAME_SLOT(DataName, 0));
if (PikaNewGameSaveData)
{
PikaGlobalConfigPre->PikaGameData = PikaNewGameSaveData->PikaGodStongSaveData;
PikaGlobalConfigPre->PikaGameLevelManangenment = PikaNewGameSaveData->PikaGameLevelManangenment;
PikaGlobalConfigPre->PikaTowersData = PikaNewGameSaveData->PikaTowersData;
PikaGlobalConfigPre->PikaTemporaryCacheData = PikaNewGameSaveData->PikaTemporaryCacheData;
//PikaGlobalConfigPre->IsSave = NewGameSaveData->IsSave;
//PikaGlobalConfigPre->MissionState = NewGameSaveData->MissionState;
}
}
//加载资源
if (PikaMyGameResourceClass.Class)
{
PikaGameResources = NewObject<UPikaGameResource>(GetWorld(), PikaMyGameResourceClass.Class);
/*//关卡条件载入
if (PikaGlobalConfigPre &&
PikaGameResources &&
PikaGameResources->CLevel.IsValidIndex(EnvironmentConfiguration->TDGameLevelManangenment.CurrentLevel)
)
{
//PikaGlobalConfigPre->PikaCurrentLevelCondition = TDGameResources->GetCurrentCondition(EnvironmentConfiguration->TDGameLevelManangenment.CurrentLevel);
}*/
}
//初始化Control数据
if (((APikaGodStonePlayerController*)GetWorld()->GetFirstPlayerController()))
{
//PikaAITowrerData = PikaMyDataTable.Object;
//PikaAIMonsterData = PikaMyDataTableMonster.Object;
//注册信息
//PikaTowersCharacterData = PikaRegisterCharacterData(PikaAITowrerData);
//PikaMonsterCharacterData = PikaRegisterCharacterData(PikaAIMonsterData);
//载入角色
((APikaGodStonePlayerController*)GetWorld()->GetFirstPlayerController())->PikaAITowrerData = PikaMyDataTable.Object;
((APikaGodStonePlayerController*)GetWorld()->GetFirstPlayerController())->PikaAIMonsterData = PikaMyDataTableMonster.Object;
//注册信息
((APikaGodStonePlayerController*)GetWorld()->GetFirstPlayerController())->PikaTowersCharacterData = ((APikaGodStonePlayerController*)GetWorld()->GetFirstPlayerController())->PikaRegisterCharacterData(PikaMyDataTable.Object);
((APikaGodStonePlayerController*)GetWorld()->GetFirstPlayerController())->PikaMonsterCharacterData = ((APikaGodStonePlayerController*)GetWorld()->GetFirstPlayerController())->PikaRegisterCharacterData(PikaMyDataTableMonster.Object);
//数据
((APikaGodStonePlayerController*)GetWorld()->GetFirstPlayerController())->PikaGlobalConfigPre = PikaGlobalConfigPre;
((APikaGodStonePlayerController*)GetWorld()->GetFirstPlayerController())->PikaGameResourcePtr = PikaGameResources;
//((APikaGodStonePlayerController*)GetWorld()->GetFirstPlayerController())->InitConditionUI();
}
}
}
}
void APikaGodStonePlayerState::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (PikaGlobalConfigPre)
{
float PikaMouseSpeed = PikaGlobalConfigPre->PikaMouseSetConf.MouseSpeed;
return;
}
}
UPikaGodStoneGameInstance* APikaGodStonePlayerState::PikaGetGameInstance()
{
return GetWorld() ? ((UPikaGodStoneGameInstance*)GetWorld()->GetGameInstance()) : NULL ;
}
void APikaGodStonePlayerState::PikaPrint(FString PikaStr)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 6.0f, FColor::Red, PikaStr);
}
}PikaHallGameMode.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "Matinee/MatineeActor.h"
#include "PikaHallGameMode.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API APikaHallGameMode : public AGameModeBase
{
GENERATED_BODY()
//描边时间
//float PikaStrokeCurrentTime;
public:
APikaHallGameMode();
virtual void BeginPlay()override;
private:
//Matinee
TArray<TWeakObjectPtr<AMatineeActor>> PikaMatineeArray;
TArray<TWeakObjectPtr<ACameraActor>> PikaCameraArray;
//描边材质
//UMaterialInstanceDynamic* PikaM_PostProcessBase;
};PikaHallGameMode.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaHallGameMode.h"
#include "Public/PikaHallHUD.h"
#include "Public/PikaHallPawn.h"
#include "Public/PikaGameUserSettings.h"
APikaHallGameMode::APikaHallGameMode()
{
//加载PlayerState
PlayerStateClass = APikaGodStonePlayerState::StaticClass();
HUDClass = APikaHallHUD::StaticClass();
DefaultPawnClass = APikaHallPawn::StaticClass();
}
void APikaHallGameMode::BeginPlay()
{
TArray<AActor*> PikaCurrentLevelActor;
//获取场景内的ACameraActor
PikaGETALLACTOR(GetWorld(), ACameraActor::StaticClass(), PikaCurrentLevelActor);
//PikaCameraArray.SetNum(PikaCurrentLevelActor.Num());
//初始化相机
for (AActor* ElemCamera : PikaCurrentLevelActor)
{
ACameraActor* PikaCurrentCamera = Cast<ACameraActor>(ElemCamera);
if (PikaCurrentCamera)
{
//游戏开始的相机
if (PikaCurrentCamera->GetName() == "CameraNewGame")
{
GetWorld()->GetFirstPlayerController()->SetViewTargetWithBlend(PikaCurrentCamera, 0);
//CameraArray[ECameraArray::Camera_NewGame] = CurrentCamera;
//continue;
}
}
}
//获取场景内的Matinee
PikaCurrentLevelActor.Empty();
PikaGETALLACTOR(GetWorld(), AMatineeActor::StaticClass(), PikaCurrentLevelActor);
PikaMatineeArray.SetNum(PikaCurrentLevelActor.Num());
//初始化Matinee
for (AActor* ElemMatinee : PikaCurrentLevelActor)
{
AMatineeActor* PikaCurrentMatinee = Cast<AMatineeActor>(ElemMatinee);
if (PikaCurrentMatinee)
{
//播放进入
if (PikaCurrentMatinee->GetName() == "MatineeNewGame")
{
PikaCurrentMatinee->Play();
//PikaMatineeArray[EMatineeArray::Matinee_Coming] = CurrentMatinee;
continue;
}
}
}
//设置PikaGameUserSettings的UWorld
if (UPikaGameUserSettings::PikaGetGameUserSettings())
{
UPikaGameUserSettings::PikaGetGameUserSettings()->PikaSetretrieveWorldContext(GetWorld());
//播放背景音乐
UPikaGameUserSettings::PikaGetGameUserSettings()->PikaPlayBGM();
//设置分辨率和窗口模式
UPikaGameUserSettings::PikaGetGameUserSettings()->PikaSetVideo();
}
}PikaHallHUD.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/HUD.h"
#include "PikaUIMainHall.h"
#include "PikaHallHUD.generated.h"
/**
*
*/
UCLASS()
class PIKAGODSTONE_API APikaHallHUD : public AHUD
{
GENERATED_BODY()
public:
APikaHallHUD();
UPROPERTY()
UPikaUIData* PikaUIDataPtr;
//virtual void Tick(float DeltaSeconds)override;
//释放
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
private:
UPikaUIMainHall* PikaMianHallPtr;
};PikaHallHUD.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaHallHUD.h"
#include "ConstructorHelpers.h"
APikaHallHUD::APikaHallHUD()
{
if (GetWorld())
{
//加载我们的mainHall
PikaUIDataPtr = NewObject<UPikaUIData>(GetWorld(), UPikaUIData::StaticClass());
static ConstructorHelpers::FClassFinder<UPikaUIMainHall> PikaMyGameInterface(TEXT("/Game/HUD/HallUI/PikaUIMainHallBP"));
if (PikaMyGameInterface.Class && PikaUIDataPtr)
{
PikaMianHallPtr = CreateWidget<UPikaUIMainHall>(GetWorld(), PikaMyGameInterface.Class);
PikaMianHallPtr->PikaUIDataPtr = PikaUIDataPtr;
PikaMianHallPtr->AddToViewport();
PikaMianHallPtr->PikaDrawUIToScreen();
}
//打开我们的鼠标箭头
if (GetWorld()->GetFirstPlayerController())
GetWorld()->GetFirstPlayerController()->bShowMouseCursor = true;
}
}
void APikaHallHUD::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
if (PikaMianHallPtr)
PikaMianHallPtr->RemoveFromViewport();
PikaMianHallPtr = NULL;
Super::EndPlay(EndPlayReason);
}PikaHallPawn.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "PikaHallPawn.generated.h"
UCLASS()
class PIKAGODSTONE_API APikaHallPawn : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
APikaHallPawn();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};PikaHallPawn.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/PikaHallPawn.h"
// Sets default values
APikaHallPawn::APikaHallPawn()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void APikaHallPawn::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void APikaHallPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void APikaHallPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}11
22