教程:编写脚本API/动态属性

来自Minecraft基岩版开发Wiki
动态属性
系列教程
所属系列
难度
初级
实践设备
WindowsAndroid
所需软件

引言[编辑]

动态属性(DynamicProperties) 是脚本系统存储自定义数据的一种格式。目前动态属性可以存储在实体、物品和世界上。相较于数据驱动中属性(或状态)的“静态性”,动态属性可以实时增删,且动态属性的类型不固定,脚本系统以此可以实现数据的动态存储。

动态属性以NBT的形式存储,其数据内容位于DynamicProperties复合标签下。每个行为包的动态属性存储在以该行为包UUID命名的复合标签内。

动态属性NBT结构:
  •  DynamicProperties
    •  <UUID>
      •  <dynamic_property_id1>
      •  <dynamic_property_id2>
        •  X
        •  Y
        •  Z
      •  ……

获取和设置[编辑]

旧版动属相对复杂,在新版,提供了以下5个方法来对动态属性进行操作:

  • clearDynamicProperties:清除该对象上的所有动态属性
  • getDynamicProperty:获取该对象上指定动态属性的值
  • getDynamicPropertyIds:获取该对象上所有动态属性的ID
  • getDynamicPropertyTotalByteCount:获取该对象上存储的所有动态属性的总字节数
  • setDynamicProperty:在该对象上设置一个动态属性

这些方法可从World、​EntityItemStack三个类中调用。

  注意:ItemStack类上此ItemStack必须不可堆叠,这要求在本质上不能堆叠,同时利用nbt修改的堆叠也无效。

动态属性可以存储布尔型、数值型、字符串型和三维向量型的数据,单个动态属性的数据大小限制在32KB以内。大量的动态属性数据可能会导致某些设备上加载缓慢。

设置[编辑]

对任意可使用动属的对象,使用setDynamicProperty可设置其动属。

import {
    ItemStack
} from "@minecraft/server";

// setDynamicProperty(identifier: string, value?: boolean | number | string | Vector3): void
const exampleItem = new ItemStack("minecraft:diamond_axe");

exampleItem.setDynamicProperty("example", "Test");
exampleItem.setDynamicProperty("示例", true);
// identifier 在此不是命名空间,可为任意字符串,但推荐使用命名空间

setDynamicProperty的数据可为一个字符串,大小限制为32767KB,这是相当大的空间了,用于存储文字是足够的了,部分脚本代码总和都很难超过32767KB,因此可以用来存储用户数据。

JSON是一种好的方法,JSON.stringify()可以把JSON转为字符串,JSON.parse()又可以把字符串转回JSON。所以可以像下面这么做:

import {
    world
} from "@minecraft/server";

function setData(id, json, Class = world) {
    Class.setDynamicProperty(id, JSON.stringify(json));
}

除此外我们也可以清除动属。

import {
    ItemStack
} from "@minecraft/server";

// clearDynamicProperties(): void
const exampleItem = new ItemStack("minecraft:diamond_axe");
exampleItem.setDynamicProperty("example", "Test");
exampleItem.clearDynamicProperties();

clearDynamicProperties()可以清除对象上的所有动属。

获取[编辑]

对任意使用了动属的对象,使用以下方法可获取其动属。

getDynamicProperty()可获取目标动属,示例如下:

import {
    ItemStack
} from "@minecraft/server";

// getDynamicProperty(identifier: string): boolean | number | string | Vector3 | undefined
// ...
// 省略定义和设置动属的过程。
let result = exampleItem.getDynamicProperty("example");
console.warn(result);

getDynamicPropertyIds()可获取对象上使用的可用动态属性标识符集,示例如下:

import {
    ItemStack
} from "@minecraft/server";

// getDynamicPropertyIds(): string[]
// ...
// 省略定义和设置动属的过程。

let result = exampleItem.getDynamicPropertyIds();
console.warn(result);

getDynamicPropertyTotalByteCount()可获得对象存储的所有动态属性的总大小(以字节为单位)。这包括键和值的大小。这对于诊断性能警告标志非常有用 - 例如,如果一个实体具有许多兆字节的关联动态属性,则在各种设备上加载它可能会很慢,示例如下:

import {
    ItemStack
} from "@minecraft/server";

// getDynamicPropertyTotalByteCount(): number
// ...
// 省略定义和设置动属的过程。
let result = exampleItem.getDynamicPropertyTotalByteCount();
console.warn(result);

再结合上面的setData,我们可以使用它:

import {
    world
} from "@minecraft/server";

function getData(id, Class = world) {
    return JSON.parse(Class.getDynamicProperty(id));
}

引用[编辑]

  1. 官方文档: ItemStack Class