【UE4】入门级,如何使用DataTable制作一个游戏技能属性表

1 篇文章 0 订阅
1 篇文章 0 订阅

【UE4】入门级,如何使用DataTable制作一个游戏技能属性表

DataTable

DataTable是UE4为了数据驱动而开发的便捷工具,一般我们做它可以在游戏里做数据的填写、归类等作用,便于策划进行游戏的设计。

官方的解释:源自数据驱动游戏性元素

数据表就是以有意义且有用的方式将各种相关的数据归类的表格, 其中,数据字段可以是任何有效的 UObject 属性,包括资产引用。在设计师将 CSV 文件导入数据表前,程序员必须创建行容器以指示引擎如何解释数据。 这些数据表包含了列名,这些列名和基于代码的UStruct结构以及它的(子)变量一一对应, 这个UStruct的结构必须继承自FTableRowBase才可以被导入器辨识。

就是注意如果在C++中编写一个表格,需要继承FTableRowBase

C++制作DataTable

下面我做了一个技能管理者的类,继承于Actor,作为演示

头文件

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Engine/DataTable.h"
#include "SkillManager.generated.h"



UENUM(BlueprintType)
enum class EDamageType : uint8
{
	//物理
	E_Physical,
	//魔法
	E_Mage

};



UENUM(BlueprintType)
enum class EAttackType : uint8
{
	//近战
	E_Close,

	//远程
	E_Remote

};


USTRUCT()
struct FSkillTable : public FTableRowBase
{

	GENERATED_USTRUCT_BODY();

	//技能ID
	UPROPERTY(BlueprintReadOnly, EditAnywhere)
		int32 SkillID;

	//技能图标
	UPROPERTY(BlueprintReadOnly, EditAnywhere)
		class UTexture2D* SkillIcon;
	
	//伤害类型
	UPROPERTY(BlueprintReadOnly, EditAnywhere)
		EDamageType DamageType;

	//攻击类型
	UPROPERTY(BlueprintReadOnly, EditAnywhere)
		EAttackType AttackType;

	//攻击伤害值
	UPROPERTY(BlueprintReadOnly, EditAnywhere)
		float InjuryValue;

};



/**
 * 
 */
UCLASS()
class PRACTICE_API ASkillManager : public AActor
{
	GENERATED_BODY()

public:

	virtual void BeginPlay()override;
	
	//加载当前技能表里的数据到管理者里
	UFUNCTION(BlueprintPure, Category = "Practice|DataTable")
	void LoadSkillDataTable();

	//通过ID在技能表里找内容
	UFUNCTION(BlueprintPure, Category = "Practice|DataTable")
	FSkillTable GetTableFromID(int32 ID);
	
	//通过ID判断角色身上是否应该有该技能
	UFUNCTION(BlueprintPure, Category = "Practice|DataTable")
	FSkillTable GetTargetSkillID(class ACharacter* Player,int32 SendID);



protected:

	//技能表
	TArray<FSkillTable*> SkillTable;

};

Cpp文件


#include "SkillManager.h"
#include "GameFramework/Character.h"
#include "Kismet/GameplayStatics.h"
#include "Roles/Role.h"
#include "Kismet/KismetSystemLibrary.h"

void ASkillManager::BeginPlay()
{
	Super::BeginPlay();


}

void ASkillManager::LoadSkillDataTable()
{
	if (SkillTable.Num() == 0)
	{
		UDataTable* TempSkillData = LoadObject<UDataTable>(this, TEXT("DataTable'/Game/Demo/Role/SkillDataTable.SkillDataTable'"));
		if (TempSkillData)
		{
			TempSkillData->GetAllRows(TEXT("Load SkillData Miss!"), SkillTable);
			UE_LOG(LogTemp, Log, TEXT("===========SUCCESS LOAD========="));
		}

	}
}

FSkillTable ASkillManager::GetTableFromID(int32 ID)
{
	for (auto SkillItem : SkillTable)
	{
		if (SkillItem->SkillID == ID)
		{
			return *SkillItem;
		}
	}

	FSkillTable TempSkillTable;

	return TempSkillTable;
}

FSkillTable ASkillManager::GetTargetSkillID(class ACharacter* Player, int32 SendID)
{
	//角色类
	ARole* _role = Cast<ARole>(UGameplayStatics::GetPlayerController(this, 0)->GetPawn());

	if (Player==_role)
	{
		for (auto Tempskill : _role->GetRoleSkillMap())
		{
			if (SendID== Tempskill.Value)
			{
				FSkillTable temp_=GetTableFromID(SendID);

				return temp_;
			}
		}
	}

	UKismetSystemLibrary::PrintString(this, TEXT("CurrentRole don't Have SkillID"));
	FSkillTable TempSkillTable;

	return TempSkillTable;
}

管理者中创建了一个表格,两个枚举,编译
创建完成后,直接在蓝图中右击
在这里插入图片描述

选中在C++中创建的DataTable的Name,即SkillTable
在这里插入图片描述

再填入表格内容,如下,这个可以由策划去填写,可以添加其他属性,比如远程技能可以添加一个需要释放的Mesh等。

在这里插入图片描述
回到C++中;

LoadSkillDataTable()
这个函数主要是为了将蓝图中创建并且填写的DataTable数据表格,在C++中加载,并在C++中使用,当然也可在蓝图中调用;

GetTableFromID()
这个函数主要是为了通过ID号,找到填写好的数据表格里的那一层的内容,比如获取ID号是0的那一层的数据,返回其结构体内容;

GetTargetSkillID
这个函数主要是为了判断传入的Player指针及需要发送的技能ID,首先先判断该角色身上是否能有该技能(可能是为学习,可能是职业不同),判断可以,再将此技能ID传入上面函数,返回结构体内容。

所以在角色身上少了一个,储存当前角色的技能背包
我在C++中创建了一个Role角色;

头文件

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Role.generated.h"

UCLASS()
class PRACTICE_API ARole : public ACharacter
{
	GENERATED_BODY()

public:
	// Sets default values for this character's properties
	ARole();

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;
	UFUNCTION(BlueprintPure)
	TMap<FString, int32> GetRoleSkillMap() { return RoleSkill; };

protected:
	UPROPERTY(EditAnywhere,Category="Role|Skill")
	TMap<FString, int32> RoleSkill;
	
};

Cpp文件

#include "Role.h"

// Sets default values
ARole::ARole()
{
 	// 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;

}

// Called when the game starts or when spawned
void ARole::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void ARole::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void ARole::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

}

为了测试方便,我在蓝图中创建了
一个BP_GameMode,继承于GameModeBase;
一个BP_Controller,继承于PlayerController;
一个BP_Role,继承于在C++中编写的ARole;

都绑定在BP_GameMode里

在这里插入图片描述

然后在BP_Controller里面创建了变量及逻辑
在这里插入图片描述

在这里插入图片描述

函数SetRoleSkillFromID的操作

在这里插入图片描述

在BP_Role里面给,角色填充了应该有得技能ID;

在这里插入图片描述

最后运行,分别按下1,2,3,4按键,打印结果如下。

在这里插入图片描述

在Controller里按下了技能按键,经过SkillManager,然后进入该角色里判断是否含有此技能,再从技能表格里面将传入的ID所对应的技能内容调出。

蓝图制作DataTable

在蓝图中建立DataTable,首先需要建立一个结构体

在这里插入图片描述

再结构体中填入相关属性

在这里插入图片描述

需要建立相关的枚举

在这里插入图片描述

再去建立数据表格DataTable,选择的是刚刚建的SkillStruct

在这里插入图片描述

在DataTable里填入相关内容

在这里插入图片描述

在BP_Role里面创一个TMap数组,填入该角色可使用的技能,及ID

在这里插入图片描述

在BP_Controller里面,编写BPSetRoleSkill函数;

在这里插入图片描述

调用函数,将SkillID传入;

在这里插入图片描述

最后按下1,2,3,4按钮打印效果如下;

在这里插入图片描述

结,关于UE4读取Excel表格方法

使用DataTable,可以更合理,更有条理性,更适合和策划配合使用。

一般策划写的Excel表格,我们也可以按照一定格式导入到UE4,可转换成DataTable使用。
想了解相关操作的可以点击参考文档<UE4 读取 Excel(SCV格式) 信息>

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值