> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-zh/chang-jing-bian-ji-qi/shi-yong-dai-ma-kuo-zhan/reference-items.md).

# 在代码中引用项目

在代码中通过名称或标签引用物品。

你可以在代码中引用通过 Creator Hub 拖放界面添加的项目。这对于为这些项目添加复杂行为，或从代码的其他部分引用它们很有用。

## 按名称获取

使用 Creator Hub 并通过将实体拖入画布来添加实体时，每个实体都有唯一的名称。使用 `engine.getEntityOrNullByName()` 函数从你的代码中引用其中一个实体。

使用 `EntityNames` 枚举可轻松访问你通过 Creator Hub 添加的实体名称，或者将场景编辑器中场景实体树视图所写的名称以字符串形式写出。

```ts
import { EntityNames } from '../assets/scene/entity-names'

function main() {

	// 使用 EntityNames 枚举
	const door1 = engine.getEntityOrNullByName(EntityNames.Door_1)

	// 将名称写为字符串
	const door2 = engine.getEntityOrNullByName('Door 2')

	// 确保两个门都存在于场景中
	if (door1 && door2) {
		// 
	}

}
```

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-f7f9f97c23a28e3a6021d602807f72c5914d417d%2Fdoor-names.png?alt=media)

该 `EntityNames` 枚举包含 Creator Hub 添加的完整实体列表，并会在你进行任何更改后立即更新。如果你将 `EntityNames.` 导入到代码中，IDE 会显示一个下拉菜单，其中包含所有可用实体的名称。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-2768bcc690ab20fce96c5b3f4345e4012b4633ed%2FEntityNames.png?alt=media)

你也可以使用 `engine.getEntityByName<EntityNames>()` 函数，并传入 `<EntityNames>` 作为 [TypeScript 泛型](https://www.typescriptlang.org/docs/handbook/2/generics.html)，以验证具有该名称的实体是否确实存在于场景中。如果 Creator Hub 中被引用的实体被重命名，此方法将以错误警告你。由于此函数的输出不可能是 `null`，你可以避免检查实体是否存在。

```ts
import { EntityNames } from '../assets/scene/entity-names'

function main() {

	const door1 = engine.getEntityByName<EntityNames>(EntityNames.Door_1)

	// 无需检查 null
	console.log(Transform.get(door1).position.x)

}
```

{% hint style="warning" %}
**📔 注意**：请确保你只在 `engine.getEntityOrNullByName()` 和 `engine.getEntityByName()` 在 `main()` 函数内、在 `main()`之后运行的函数内，或在系统中使用。如果在这些上下文之外使用，场景编辑器中创建的实体可能尚未实例化。
{% endhint %}

通过上述任一方法获取实体引用后，你可以自由地对其执行任何操作，例如添加或移除组件、修改现有组件的值，甚至从引擎中移除该实体。

```ts
import { EntityNames } from '../assets/scene/entity-names'

function main() {
	// 获取实体
	const door = engine.getEntityOrNullByName(EntityNames.Door_3)
	// 验证实体是否存在
	if (door) {
		// 添加指针事件回调
		pointerEventsSystem.onPointerDown(
			{
				entity: door,
				opts: { button: InputAction.IA_PRIMARY, hoverText: 'Open' },
			},
			function () {
				// 打开门
			}
		)
	}
}
```

通过场景编辑器添加的所有实体都具有一个 `名称` 组件，你也可以像这样遍历所有实体：

```ts
function main() {
	for (const [entity, name] of engine.getEntitiesWith(Name)) {
		console.log({ entity, name })
	}
}
```

## 按标签获取

你也可以通过标签获取实体。标签是一种将实体分组的方式，有助于识别具有相同用途或行为的实体。

通过 **标签** 部分为实体添加标签，该部分位于项目属性面板的顶部。你可以从通用标签中选择，例如 **标签组 1** 到 **标签组 4**，或者创建具有更具体名称的自定义标签。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-4a3c2b9800d4e65c22f83e5cabe22b51f8bdd9ec%2Ftags.png?alt=media)

{% hint style="info" %}
**💡 提示**：一个实体可以被分配多个标签。

<img src="https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-1a0b4fd1fa06352f4a6f3d5e4ab6019c1465df98%2Ftags-multiple.png?alt=media" alt="" data-size="original">
{% endhint %}

然后，你可以使用 `engine.getEntitiesByTag()` 函数获取具有特定标签的所有实体。这非常适合用于遍历具有相同用途或行为的一组实体。

```ts
import { engine } from '@dcl/sdk/ecs'

export function main() {
	const taggedEntities = engine.getEntitiesByTag('myTag')
  
	for (const entity of taggedEntities) {
      // 对每个实体执行操作
    }
}
```

你也可以从代码中为实体添加或移除标签。如果你想根据某些逻辑更改标签，或者动态生成带有特定标签的实体，这会很有用。

```ts
import { Tags } from '@dcl/sdk/ecs'

Tags.remove(entity, tagName);
Tags.add(entity, tagName);
```

## 获取项目的所有子项

获得特定项目的引用后，你可以获取屏幕左侧实体树中作为其子项分组的所有项目。以下脚本获取父实体，然后遍历其每个具有 Transform 组件的子项。遍历每个子项时，你可以应用任何所需的自定义逻辑。

```ts
import { engine, Entity, Transform, Name, getEntitiesWithParent } from '@dcl/sdk/ecs'
import { EntityNames } from '../assets/scene/entity-names'

function main() {
	// 获取父实体
	const parent = engine.getEntityByName<EntityNames>(EntityNames.ParentEntity)

	// 获取完整的子项列表
	const children = getEntitiesWithParent(engine, parent)
	for (const child of children) {
   		// 处理每个子实体
	}
}
```

## 智能项目触发器

你可以检测智能项目的 **触发事件**，并使用自定义代码来响应这些事件。例如，你可以放置一个按钮智能项目，并在按钮被点击时激活自定义代码。

使用 `getTriggerEvents` 以获取一个可处理特定智能项目触发事件的对象，然后使用 `.on()` 函数来订阅回调函数。每次触发事件发生时，都会执行此回调函数。

例如，如果场景中有一个带有以下通用 **点击时** 事件的按钮，你可以编写以下代码，以便在按钮被激活时运行自定义代码。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-8c5de89e8950aac8f10e9d799c7ab9a1410c8237%2Frestart-button.png?alt=media)

```ts
import { engine } from '@dcl/sdk/ecs'
import { getTriggerEvents, getActionEvents } from '@dcl/asset-packs/dist/events'
import { TriggerType } from '@dcl/asset-packs'
import { EntityNames } from '../assets/scene/entity-names'

function main() {
	const restart = engine.getEntityOrNullByName(EntityNames.Restart_Button)
	if (restart) {
		const restart_event = getTriggerEvents(restart)
		restart_event.on(TriggerType.ON_CLICK, () => {
			// restartGame()
		})
	}
}
```

你同样可以订阅任何其他类型的触发事件，例如 **ON\_PLAYER\_ENTERS\_AREA**, **ON\_SPAWN**, **ON\_TWEEN\_END**等。

## 智能项目操作

你可以检测智能项目的 **操作**，并使用自定义代码来响应这些操作。例如，你可以放置一个门智能项目，并在 **打开** 操作被调用时运行自定义代码。

使用 `getActionEvents` 以获取用于处理特定智能项目操作的对象。然后你可以使用 `.on()` 返回对象的函数来订阅回调函数。每次操作发生时，都会执行此回调函数，无论该操作是由另一个智能项目激活，还是由你自己的自定义代码激活。

例如，如果场景中有一扇带有以下默认 **打开** 操作的门，你可以编写以下代码，以便在门被打开时运行自定义代码。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-32fcce8d20d62bc71c830e43a35b18d0410a2910%2Fdoor-actions.png?alt=media)

```ts
import { engine } from '@dcl/sdk/ecs'
import { getTriggerEvents, getActionEvents } from '@dcl/asset-packs/dist/events'
import { TriggerType } from '@dcl/asset-packs'
import { EntityNames } from '../assets/scene/entity-names'

function main() {
	const door = engine.getEntityOrNullByName(EntityNames.Wooden_Door)
	if (door) {
		// 检测操作
		const actions = getActionEvents(door)
		actions.on('Open', () => {
			console.log('门已打开！！')
			// 自定义代码
		})

		// 检测触发器
		const triggers = getTriggerEvents(door)
		triggers.on(TriggerType.ON_CLICK, () => {
			console.log('门已点击！！')
			// 自定义代码
		})
	}
}
```

你也可以从代码中发出操作事件，这使你能够利用已在智能项目的 Action 组件中定义的操作。以下代码片段会在按钮智能项目被触发时，对门智能项目调用“打开”操作。

```ts
import { engine } from '@dcl/sdk/ecs'
import { getTriggerEvents, getActionEvents } from '@dcl/asset-packs/dist/events'
import { TriggerType } from '@dcl/asset-packs'
import { EntityNames } from '../assets/scene/entity-names'

function main() {
	const button = engine.getEntityOrNullByName(EntityNames.Red_Button)
	const door = engine.getEntityOrNullByName(EntityNames.Wooden_Door)
	if (button && door) {
		// 操作和触发器的引用
		const buttonTriggers = getTriggerEvents(button)
		const doorActions = getActionEvents(door)

		// 检测按钮上的触发器
		buttonTriggers.on(TriggerType.ON_INPUT_ACTION, () => {
			// 打开门
			doorActions.emit('Open', {})
		})
	}
}
```

{% hint style="info" %}
**💡 提示**：如果你并非要完成非常复杂的操作，除了编写代码外，你还可以创建自定义智能项目来处理想要执行的操作。请参阅 [让任意项目变为智能项目](/creator/content-creator-zh/chang-jing-bian-ji-qi/jiao-hu-xing/make-any-item-smart.md).
{% endhint %}

## 其他智能项目组件

智能项目可以包含属于 asset-packs 库的特殊组件，例如 `状态` 或 `计数器`。这些组件不属于 Decentraland SDK，但可以通过该库中的 `getComponents()` 函数获取。随后你可以从场景代码中读取或写入这些组件的值，从而让智能项目行为与代码之间实现更紧密的集成。

以下示例会在箱子的操作被触发时，读取并记录箱子智能项目的 State 组件值。

```ts

import { engine } from '@dcl/sdk/ecs'
import { getComponents } from '@dcl/asset-packs'
import { getTriggerEvents } from '@dcl/asset-packs/dist/events'
import { TriggerType } from '@dcl/asset-packs'
import { EntityNames } from '../assets/scene/entity-names'


export function main() {

    const chest = engine.getEntityByName<EntityNames>(EntityNames.chest)
 
    if (chest) {

        const chestTriggers = getTriggerEvents(chest)

        chestTriggers.on(TriggerType.ON_INPUT_ACTION, () => {
            const { States } = getComponents(engine)
            let state = States.getMutableOrNull(chest)?.currentValue
            console.log( "箱子的新状态 ", state)
        })
    }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-zh/chang-jing-bian-ji-qi/shi-yong-dai-ma-kuo-zhan/reference-items.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
