教學:編寫腳本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