# 关于 CharmingCraft

<figure><img src="/files/5hCEI7YuLvCZQzRiRJnN" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
CharmingCraft 使用的资源来自于游戏 Minecraft 和第三方网站购买的模型. 另外,许多模型及游戏资产也由 Caizii 制作请标明作者进行二次使用.
{% endhint %}

## 概述

This project build based on Unreal Engine 5.3 to create a Top-Down low poly RPG game. It draws inspiration from Minecraft, such as its inventory system and artistic style, as well as the Top-Down view, combat system, and isometric indoor scene design of the game Minecraft: Dungeon. CharmingCraft aims to offer a more relaxed gameplay experience, where players can freely explore the map, gather resources to craft weapons, complete quests, and more...

{% embed url="<https://www.bilibili.com/video/BV1vr421b7Bj/>" fullWidth="false" %} <mark style="color:green;">**Demo for the item ablility system**</mark>
{% endembed %}

## 快速探索

{% content-ref url="/pages/QoMT5erZYzW5wBSe6Vtu" %}
[游戏内容](/you-xi-nei-rong)
{% endcontent-ref %}

{% content-ref url="/pages/lfqGNZOStY1lLORKfwF2" %}
[游戏机制](/you-xi-ji-zhi)
{% endcontent-ref %}


# 常见问题与解答

一些经常遇到的问题以及对应答复

{% hint style="warning" %}
该项目处于早期开发阶段
{% endhint %}

## 这是什么项目 ?

一个使用Unreal Engine 5 制作的俯视视角RPG游戏

## 为什么不提供构建文件 ?

项目的结构和核心内容仍未完成, 构建文件意义不大


# 游戏内容


# 种植与收获


# 物品栏模式


# 战斗模式


# 物品模式


# 建造模式


# 地牢与副本

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>探索地牢结构</strong></td><td>在这里了解地牢系统的结构, 以及管理这些地牢结构的组件</td><td><a href="/pages/mP8B1m5THSPcXkLyPaoV">/pages/mP8B1m5THSPcXkLyPaoV</a></td></tr><tr><td><strong>探索固定地牢</strong></td><td>在这里了解固定地牢的规则以及特性</td><td><a href="/pages/ihwGOWn3GdatfCuek7m0">/pages/ihwGOWn3GdatfCuek7m0</a></td></tr><tr><td><strong>探索自然地牢</strong></td><td>在这里了解自然地牢的规则以及特性</td><td><a href="/pages/g6fksARig0PPamWPUF9I">/pages/g6fksARig0PPamWPUF9I</a></td></tr></tbody></table>


# 固定地牢

## 概述

固定地牢在游戏地图上位置固定, 玩家首次进入固定地牢即可开始副本关卡 (地牢关卡). 该地牢在完成后可以进行刷新也可以解锁场景.&#x20;

## 场景解锁

部分固定地牢在玩家第一次探索并且完成时会解锁该地牢,及地牢变为玩家可以交互的场景不在拥有地牢的性质 (怪物生成, 奖励刷新, 地牢增益与减益等). 该解锁地区可以引导玩家去往下一个地牢

## 地牢刷新

非场景解锁类地牢会依照游戏时间单位进行刷新和重置, 重置完毕后玩家即可再次以更高难度挑战该地牢并且获取更多的战利品等

## 地牢结构


# 自然地牢

{% hint style="warning" %}
自然地牢为程序化生成的地牢, 该技术目前正在学习中
{% endhint %}

## 概述

自然地牢的入口会在世界的地图中生成, 玩家可以在探险中发现他们. 地牢的入口会存在一定游戏时间随后坍塌, 玩家在进入自然地牢后游戏会为玩家生成一个随机的地牢

{% hint style="warning" %}
玩家离开或者死亡后依照不同的地牢等级, 地牢会存在或者直接消失
{% endhint %}


# 多层地牢

{% hint style="info" %}
任何地牢都可以是复数/多层地牢, 层数的大小由地牢入口决定并且层数相关数据均存放至第一层(父地牢)的GameState中
{% endhint %}

## 概述

多层地牢是地牢的性质,意味着玩家在进入地牢后可以通过地牢内的通道进入下一层地牢也可以回到上一层地牢 (取决于地牢是否允许返回上层)

## 层数存档

在一些固定地牢中,玩家探索的地牢层数会被记录, 玩家下次探索可以选择指定的层数来进行探索.


# 地牢结构

## 概述

## 进入地牢

## 大厅

## 地牢层数

## 离开地牢

## 模块结构

### 地牢实例 Dungeon Instance

<pre class="language-cpp" data-title="DungeonInstance.c" data-overflow="wrap" data-line-numbers><code class="lang-cpp">class CHARMINGCRAFT_API ANativeBaseDungeonInstance : public AInfo
{
	GENERATED_BODY()

public:
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool bHasHub = true;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	int32 MaxChildDungeonsPerInstance = 1;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
<strong>	bool bLoadDungeonsWorldsByNeed = true; 
</strong>	
	// Predefine the map for each child dungeons
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TArray&#x3C;TSoftObjectPtr&#x3C;UWorld>> ChildDungeonsWorlds;
	// 
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TArray&#x3C;FCharmingCraftWorld> ChildDungeonsWorldsInstance;
	// Define player in which child dungeons, for example, &#x3C;PlayerA, 3> means
	// PlayerA is in 3rd ChildDungeon;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TMap&#x3C;ACharacter *, int> DungeonInstancePlayerData;
};
</code></pre>

地牢实例包含该地牢的所有层的地图 **Uworld** 并且在玩家加载地牢时动态地生成在场景中并由**DungeonHandler** 管理,当玩家退出地牢时该实例会被 **DungeonHandler** 摧毁.

{% hint style="warning" %}
地牢实例并非指向单一玩家,而是由整个世界管理器和地牢管理器共同管理, 若为团体地牢则多个玩家可以进入同一个地牢实例中
{% endhint %}

`ChildDungeonsWorlds` 该数组存储地牢实例的所有地图模板, `index 0` 指向的是 *地牢大厅/准备场所*

`ChildDungeonsWorldsInstance` 该数组存储当前地牢实例加载的世界实例, 地牢加载的世界实例应当与世界管理器中也存在一份引用并且在地牢实例摧毁时也应该在世界管理器中摧毁

`DungeonInstancePlayerData` 存储玩家当前在这个地牢实例中的探索进度, `TMap`的第一个元素是玩家对象,第二个元素是当前地牢层数

{% hint style="info" %}
在最初版本地牢中不提供额外的房间比如说购买或者功能性房间, 要拓展这部分内容需要对玩家在地牢中探索的数据结构进行更换
{% endhint %}

### 地牢处理器 Dungeon Handler

{% code title=" DungeonHandler.c" lineNumbers="true" fullWidth="false" %}

```cpp
class CHARMINGCRAFT_API UNativeDungeonHandler : public UObject, public ICoreManagerInterface
{
	GENERATED_BODY()

public:
	UPROPERTY(BlueprintReadWrite, VisibleAnywhere)
	TSet<TObjectPtr<ANativeBaseDungeonInstance>> LoadedDungeonInstances;

public:
	UNativeDungeonHandler();

	bool AddInstanceToSet(ANativeBaseDungeonInstance * DungeonInstance);
	

public:
	virtual UCharmingCraftInstance* GetGameInstance_Implementation() override;
};
```

{% endcode %}

**地牢处理器** 存储游戏加载的 **地牢实例** ,每当玩家创建新的地牢时地牢处理器会加载地牢实例到 `LoadedDungeonInstances` 中并通知世界管理器加载当前玩家探索地牢层的世界地图随时准备展示到玩家视野中. 当地牢内所有玩家退出或地牢关闭/失效时, 地牢处理器则会首先通知世界管理器移除该地牢实例所加载的地牢地图并在移除完毕后再移除地牢实例.


# 物品与技能


# 物品组件

{% hint style="info" %}
物品组件 (CraftItemComponents) 允许多个组件存在物品以及实体中, 这个系统旨在使游戏的自定义和扩展更加容易。
{% endhint %}

## 概述

引入了一个全新的组件系统，这个系统旨在使游戏的自定义和扩展更加容易。这个新系统主要包括以下几个方面

<details>

<summary><strong>数据驱动</strong></summary>

组件系统允许通过JSON文件定义物品和方块的行为。这使得玩家和开发者可以更容易地添加或修改游戏内容，而不需要直接修改游戏代码。

</details>

<details>

<summary><strong>模块化</strong></summary>

组件系统是模块化的，意味着不同的组件可以被组合在一起，为物品和方块赋予多种行为。这种设计使得定制和扩展变得非常灵活。

</details>

<details>

<summary><strong>易用性</strong></summary>

通过组件系统，创建新物品和方块的过程更加直观和易于理解。玩家只需要编辑一些配置文件，就可以实现复杂的游戏机制。

</details>

<details>

<summary><strong>支持扩展</strong></summary>

该系统为未来的扩展和更新奠定了基础。

</details>

## 物品组件结构

物品堆实例

* 组件 TArray
  * 组件 1
  * 组件 2
  * 组件 3
  * ...

## 物品组件基类

{% code title="NativeCraftComponent.h" %}

```cpp
UCLASS()
class CHARMINGCRAFT_API UNativeCraftComponent : public UObject
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintCallable)
	bool IsAllowMultipleInstance() const;
	UFUNCTION(BlueprintCallable)
	void SetIsAllowMultipleInstance(bool bIsAllowMultipleInstance);
	UFUNCTION(BlueprintCallable)
	bool IsActive() const;
	UFUNCTION(BlueprintCallable)
	void SetIsActive(bool bIsActive);

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FString Description;

public:
	
	UNativeCraftComponent();

private:
	// Whether allow item or entity have multiple same class of components
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool bIsAllowMultipleInstance = true;

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool bIsActive = false;
};
```

{% endcode %}

## 有物品组件的物品堆结构

{% code title="ItemStack.h" %}

```cpp
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class CHARMINGCRAFT_API UItemStack : public UPersistentDataContainer, public IComponentizedObjectInterface
{
	GENERATED_BODY()

public:
	// Sets default values for this component's properties
	UItemStack();

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category= "ItemStack Fields")
	int32 Amount;
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category= "ItemStack Fields")
	EMaterial Material; //
	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category="ItemStack InternalData")
	TSubclassOf<UItem> ItemClass;
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category= "ItemStack Fields")
	UItemMeta* ItemMeta;

	UPROPERTY()
	TArray<UNativeCraftComponent*> Components;

	virtual UNativeCraftComponent* AddComponents_Implementation(UNativeCraftComponent* AddedComponents) override;
	virtual bool RemoveComponents_Implementation(UNativeCraftComponent* RemovededComponents) override;
	virtual TArray<UNativeCraftComponent*> GetObjectComponentsByClass_Implementation(TSubclassOf<UNativeCraftComponent> ComponentsClass) override;
	virtual TArray<UNativeCraftComponent*> GetObjectComponents_Implementation() override;
	
};
```

{% endcode %}

{% hint style="warning" %}
注意: 如果想使用物品组件相关功能请让该类实现接口 `IComponentizedObjectInterface` 该接口包含了物品组件和其对应的物品对象基本操作函数

\
另外, 你需要在实现该接口的对象中提供 `TArray<UNativeCraftComponent*> Components;` 这是必须的
{% endhint %}

## 物品组件接口

{% code title="ComponentizedObjectInterface.h" %}

```cpp
UINTERFACE()
class UComponentizedObjectInterface : public UInterface
{
	GENERATED_BODY()
};
class CHARMINGCRAFT_API IComponentizedObjectInterface
{
	GENERATED_BODY()
public:
	UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
	TArray<UNativeCraftComponent*> GetObjectComponents();
	UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
	TArray<UNativeCraftComponent*> GetObjectComponentsByClass(TSubclassOf<UNativeCraftComponent> ComponentsClass);
	UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
	UNativeCraftComponent* AddComponents(UNativeCraftComponent* AddedComponents);
	UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
	bool RemoveComponents(UNativeCraftComponent* RemovededComponents);
};
```

{% endcode %}

<table><thead><tr><th width="347">基本格式</th><th width="212">参数描述</th><th>作用</th></tr></thead><tbody><tr><td><code>GetObjectComponents()</code></td><td>无</td><td>获取该UObject所有组件</td></tr><tr><td><code>GetObjectComponentsByClass(TSubclassOf ComponentsClass)</code></td><td><code>ComponentsClass</code> 为期望搜索组件的类</td><td>按照组件类型获取该UObject所有组件</td></tr><tr><td><code>AddComponents(UNativeCraftComponent* AddedComponents)</code></td><td><code>AddedComponents</code> 添加到UObject的组件</td><td>添加组件到UObject</td></tr><tr><td><code>RemoveComponents(UNativeCraftComponent* RemovededComponents)</code></td><td><code>RemovededComponents</code> 从UObject移除的组件</td><td>从UObject移除指定组件</td></tr></tbody></table>


# 技能组件

{% hint style="info" %}
物品技能组件 (CraftItemSkillComponents) 允许该物品存储多个技能相关的组件, 技能组件包含正在执行的技能实例,可以被GAS系统执行和控制
{% endhint %}

## 概述

物品技能组件是物品组件的子类, 它顶一个物品携带的技能. 这些技能组件在物品堆上时可以被GAS系统执行来达到物品自定义技能. 一个物品堆对象可以携带多个物品技能组件.


# 生物和实体


# 世界与场景


# 游戏机制


# 世界保存


# 地图区块


# 地图传送


