> 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-es/scene-editor/extender-con-codigo/script-component.md).

# Usando el Script Component

Usa el component Script para dar funcionalidad al código, sin necesidad de profundizar en toda la estructura del proyecto.

Con el nuevo Script Component, es posible crear Entities que ejecutan código personalizado desde dentro de la propia Entity.

Script Components permiten la ejecución del comportamiento personalizado de una Entity sin necesidad de trabajar directamente en el `index.ts` y potencialmente otros archivos.

## Configuración del Script Component

1. Añade el Script Component a una Entity haciendo clic en el `+` botón y selecciónalo. Crea un nuevo Script haciendo clic en **+ Add New Script Module** y elige un nombre, o usando la File Path (busca o arrastra y suelta un archivo existente).

![](https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-79378b201ff5d7fd7334d821c9c2ab0224da46b8%2Fnew-script-component.png?alt=media)

2. Haz clic en el botón CODE del component para abrir el editor de código predeterminado. Veamos su estructura. Para más detalles sobre cómo seleccionar y gestionar tu editor predeterminado, por favor ve a [Combinar con código](/creator/content-creator-es/scene-editor/extender-con-codigo/overview.md).

## Entendiendo la estructura del Script

Cuando el Script se abre por primera vez, tiene el siguiente código:

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

export class BuildingScript {
  /**
   * Propiedades
   * Define los campos de clase que quieras reutilizar entre métodos.
   * Ejemplo de uso: this.myVariable
   */
   // private myVariable: boolean = true

  /**
   * Constructor / Entradas
   * Los parámetros declarados aquí aparecen en la UI del Script component en Creator Hub.
   * Tipos compatibles: Entity, String, Number, Boolean, ActionCallback y Slider
   * para un número editado con un slider, p. ej. public speed: Slider<0, 10, 0.5> = 1
   *
   * Nota: después de editar este archivo, haz clic en el icono de refresh en la UI del Script component
   * para ver las entradas actualizadas.
   *
   * Los campos `src` y `entity` en el constructor son requeridos por referencias internas.
   */
  constructor(
    public src: string,     // DO NOT REMOVE
    public entity: Entity,   // DO NOT REMOVE
    // Add your custom inputs below
  ) {}

  /**
   * start()
   * Se llama una vez cuando se inicializa el script.
   */
  start() {
    // Inicialización del script
    console.log("BuildingScript initialized for entity:", this.entity);
  }

  /**
   * update(dt)
   * Se llama en cada frame.
   * @param dt - (opcional) tiempo transcurrido desde el último frame (en segundos)
   */
  update(dt: number) {
    // Called every frame
  }
}
```

La clase se compone de tres partes principales:

* La **constructor**,
* el **start()** método
* el **update()** método.

## Constructor

El constructor contiene los parámetros que quieres exponer y modificar dinámicamente desde tu escena en Creator Hub.

```ts
export class BuildingScript {
  constructor(
    public src: string,
    public entity: Entity,
    public numericVariable: number, 
  ) {}
...
}
```

Una vez guardado el archivo, el **Refresh** button in the Script Component updates all changes done.

<img src="https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-0e88676864e337ab55bf98ae8bd23e2775ec0c60%2Fscript-refresh-button.png?alt=media" alt="Botón Refresh" width="360">

Una vez actualizado, el Script Component ahora muestra el `numericVariable` añadido en el código.

![](https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-8729a660cd9b4cd056ff33ad0a28fefe1b7814b1%2Fparameter-script-component.png?alt=media)

## Parámetros

Si diferentes Entities usan el mismo archivo en el Script component, cada una sigue teniendo parámetros independientes: si la escena tiene dos edificios, `building1` y `building2`, ambos con un Script Component apuntando al `BuildingScript.ts` archivo, cada edificio tiene su propio `numericVariable` parámetro que puede modificarse de forma independiente.

{% hint style="warning" %}
**Nota importante**: No modifiques/elimine `public src: string` y `public entity: Entity`. Puedes añadir nuevas entradas siguiendo estas.
{% endhint %}

Los tipos permitidos para los parámetros del constructor son:

* `Entity`
* `string`
* `número`
* `boolean`
* `ActionCallback`
* `Slider<Min, Max, Step>`

### Parámetros numéricos con un slider

Escribe un parámetro numérico como `Slider<Min, Max, Step>` para editarlo con un slider en lugar de un cuadro numérico simple. Creator Hub muestra tanto un slider como un cuadro numérico.

```ts
constructor(
  public src: string,
  public entity: Entity,
  // Un slider de 0 a 10, con pasos de 0.5
  public speed: Slider<0, 10, 0.5> = 1,
) {}
```

* `Step` es opcional y su valor predeterminado es `1`.
* Se permiten límites negativos, por ejemplo `Slider<-90, 90>`.
* En tiempo de ejecución el valor es un simple `número`, así que `this.speed` se comporta como cualquier otro parámetro numérico.

{% hint style="info" %}
**📔 Nota**: Ambos `public` y `private` parámetros del constructor se exponen a Creator Hub. La `private` palabra clave solo restringe el acceso dentro de la `BuildingScript` clase. Para más detalles, consulta la documentación oficial de TypeScript sobre\
[Propiedades de parámetros](https://www.typescriptlang.org/docs/handbook/2/classes.html#parameter-properties).
{% endhint %}

### Accediendo a los parámetros dentro del Script

Para acceder al valor de un parámetro desde tu código, usa la notación `this.definedParameter`. Por ejemplo, `this.numericVariable` ni `this.entity`.

La plantilla Script predeterminada incluye esta línea en el método start():

`console.log("BuildingScript initialized for entity:", this.entity);`.

Cámbialo así para registrar el valor de un valor que definiste en el constructor:

`console.log("BuildingScript initialized with numericVariable:`, `this.numericVariable);`

Ten en cuenta que cuando cambies el valor del parámetro en la UI de Creator Hub, también deberías ver que ese valor registrado se actualiza.

### Parámetros predeterminados

El constructor, de forma predeterminada, contiene un `src` y un `entity` parámetro, estos son muy útiles para el código de tu script:

* `this.entity` siempre se refiere a la Entity que contiene el `panel Script` component, úsalo para acceder a información sobre la Entity o añadirle Components.
* `this.src` es la ruta donde se almacena el script. Esto es especialmente útil cuando creas Smart Items que están pensados para ser usados por otros. Usa este campo para construir la ruta a archivos que se incluyen con tu smart item, incluso si la ruta del smart item cambia o se renombra.

```ts
export class BuildingScript {
  constructor(
    public src: string,
    public entity: Entity,
  ) {}

  start() {
    Material.setPbrMaterial(this.entity, {
      texture: Material.Texture.Common({
        src: this.src + '/images/myImage.png',
      })
    });
  }
}
```

El script anterior obtiene la Entity que posee el script y le aplica una textura. Obtiene la textura de un `.png` archivo que se empaqueta en la carpeta del smart item, en una subcarpeta llamada `/images`. Al usar `this.src`, nos aseguramos de que la ruta del archivo siempre se conozca, sin importar si el smart item se importa a la escena bajo `/assets/custom/itemName` ni `/assets/asset-packs/itemName`

### Tooltips en los parámetros

Añade tooltips a tus parámetros de entrada, para que los usuarios sepan para qué se usan estos campos o qué valores se aceptan. Los usuarios verán un icono de tooltip junto a cada campo en la UI del Script component, y podrán leer texto personalizado al pasar el cursor sobre el icono.

Para añadir tooltips a tu constructor, agrega un bloque comentado justo antes del constructor, y escribe una línea con `@param` más el nombre del campo, seguido de una descripción, para cada tooltip.

```ts
  /**
   * @param startDate - La fecha de inicio del evento en formato YYYY-MM-DD
   * @param yOffset - Cuántos metros por encima del suelo mostrar el elemento
   */
  constructor(
    public src: string,
    public entity: Entity,
    public startDate?: string,
    public yOffset: number = 0.5,
  ) {
  }
```

Puede que necesites hacer clic en el icono de refresh en la UI del Script component para ver los cambios en tus tooltips.

<img src="https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-0e88676864e337ab55bf98ae8bd23e2775ec0c60%2Fscript-refresh-button.png?alt=media" alt="Botón Refresh" width="360">

## Método start() & update()

La **start()** el método contiene código que se ejecuta solo una vez, cuando se crea la Entity (en este caso, cuando la escena se carga por primera vez).

Previsualiza la escena y revisa los logs (**Consejo**: puedes usar el `` ` `` atajo): muestra el nuevo mensaje incluyendo el `numericVariable` parámetro.

![](https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-a8d756ab46337ed47bf6d1d7ae97641abd4cee64%2Fscript-log-message.png?alt=media)

La **update()** el método, por otro lado, ejecuta su código en cada frame del juego (igual que hacen los Systems). Por ejemplo, comprobando valores de la `PlayerEntity` para disparar comportamientos en el script.

El siguiente código imprime logs en cada frame del juego en el que la `PlayerEntity` es mayor que la `numericVariable`definida previamente, que la persona creadora proporciona dinámicamente desde la UI del Script Component.

```ts
update(dt: number) {
    if (Transform.get(engine.PlayerEntity).position.y > this.numericVariable ) {
      console.log("The player's height is over ", this.numericVariable);
    }}
```

<img src="https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-07e4722b53743d2bac04744175a46fc25488cc36%2Fupdate-script-logs.png?alt=media" alt="Update Method" data-size="line">

El primer log pertenece al método start(), indicando que establecimos numericVariable. El segundo pertenece al método update(), cuando el jugador es más alto que ese valor.

## Exponer Actions al Creator Hub

Es posible definir una `Action` dentro de un script de Script Component y hacer que esté accesible en la UI de Creator Hub. Esto habilita la posibilidad de disparar esta `Action` con otra Entity.

```ts
  /**
   * Expón esta action para que se dispare
   * @action
   */
  exposedAction(creatorHubParameter: number) {
    console.log("Triggered from another entity using parameter: ", this.creatorHubParameter);
  }
```

`creatorHubParameter` se expondrá como un `Action` parámetro para darle un valor personalizado. Después de actualizar el Script Component, la nueva action estará disponible como una opción en el dropdown de Actions.

![](https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-d7b71673260d80622c4b5635526aa3444d84ccff%2Fscript-component-action.png?alt=media)

Después de añadir la Action, cualquier Entity en Creator Hub puede dispararla usando `Triggers`

![](https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-33aa38670114e43b0bb1beb493e2233642530167%2Fscript-component-action-trigger.png?alt=media)

{% hint style="info" %}
**📔 Nota**: Puedes añadir tantas Actions como necesites dentro del Script. Todas ellas serán accesibles de forma independiente desde el `Action` dropdown.
{% endhint %}

## Llamar métodos del Script desde fuera

Para llamar a un método del Script desde otro Script o desde `src/index.ts`, se deben seguir los siguientes pasos:

1. Crea un `public` método dentro de la clase Script.
2. Ejecuta `npm run build` desde el directorio raíz de la escena.
3. Desde el archivo donde quieras usar el método público, añade `import { callScriptMethod } from '~sdk/script-utils'`.
4. Llama a `callScriptMethod` con los parámetros necesarios (en este caso, `someParamter`).

Aquí hay un ejemplo con un `public` método expuesto

```ts
export class BuildingScript {
  constructor(
    public src: string,
    public entity: Entity,
    ...,
  ) {}

  public publicMethod(boolParameter: boolean, someNumberParameter: number) {
    if (boolParameter) {
      console.log("Public method called with parameter true!: ", someNumberParameter);
    } else {
      console.log("Public method called with parameter: false!", someNumberParameter);
    }
  }
...
}
```

Para llamarlo desde `src/index.ts`, usa:

```ts
import { callScriptMethod } from '~sdk/script-utils'


export function main() {
    const buildingEntity = engine.getEntityOrNullByName("building")
    if (buildingEntity) {
        const scriptMethod = callScriptMethod(
            buildingEntity,
            "assets/scene/Scripts/BuildingScript.tsx",
            "publicMethod",
            false,
            3,
        )

        scriptMethod
    }
}
```

Primero, el `main` function looks for the `Entity` that has the Script component. Second, if the `Entity` exists, `callScriptMethod` is called with the following parameters:

1. `entity`: `Entity` that has the `public` método.
2. `scriptPath`: `ruta` donde vive la `panel Script` clase.
3. `methodName`: nombre del `public` método a llamar.
4. `...args`: argumentos del método. En este caso, hay dos. Deben añadirse en orden, uno después del otro.

Tercero, llamamos al `callScriptMethod`definido, en este caso, `scriptMethod`.

Con los valores de los parámetros dados, el resultado es:

![](https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-32c18509225406a1f8162b0d9719fc1e38ed8da0%2Fscript-component-public-method.png?alt=media)

{% hint style="info" %}
**📔 Nota**: Puedes seguir la misma lógica para llamar a un `public` método del Script desde otro script o archivo. Puedes usarlo para obtener o cambiar valores de `public` variables en la clase Script.
{% endhint %}

## Disparar Actions de otras Entities desde un Script

Es posible usar un parámetro de tipo `ActionCallback` en el constructor de la clase Script. Esto permite disparar otro `Entity`de `Action` definido a través de la UI de Creator Hub desde los métodos del Script.

En este ejemplo, `anotherEntityAction` se añade como un `public` parámetro.

```ts
export class BuildingScript {
  constructor(
    public src: string,
    public entity: Entity,
    public anotherEntityAction: ActionCallback,
    ...,
  ) {}
  ...
}
```

Una acción seleccionable `Entity` y `Action` ya están disponibles cuando el Script Component se actualiza en la UI de Creator Hub. `Sphere` es una Entity ya existente en la escena que tiene una action llamada `Escala`.

![](https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-a264fa3fe8ceb754877b1022f0c653d3cb29ece6%2Fscript-component-action-callback.png?alt=media)

La action de la otra Entity ahora es accesible en la clase Script. Podría usarse de muchas maneras distintas. En el siguiente ejemplo, pulsar E disparará `this.anotherEntityAction` definiendo un `pointerEventsSystem` en la `start` método.

```ts
  start() {
    pointerEventsSystem.onPointerDown(
      {
        entity: this.entity,
        opts: {
          button: InputAction.IA_PRIMARY,
          hoverText: "Presiona E para disparar una Action de otra Entity.",
        },
      },
      () => {
        this.anotherEntityAction();
      }
    );
  }
```

### Llamadas de acción opcionales

Una `ActionCallback` El parámetro que la persona creadora deja sin conectar es `undefined`, y su tipo es `ActionCallback | undefined`. Compruébalo antes de llamarlo, para que un script funcione tanto si la action está conectada como si no:

```ts
if (this.anotherEntityAction) {
  this.anotherEntityAction();
}
```

{% hint style="info" %}
**📔 Nota**: Combinar exposición y disparo `Actions` es una herramienta muy poderosa. Puedes definir un Script Component en una Entity, exponer una action usando un `public` método, y luego dispararla desde el Script Component de otra Entity usando un `ActionCallback` parámetro.
{% endhint %}

## Ver también

* [Smart items - Aspectos básicos](/creator/content-creator-es/scene-editor/interactividad/smart-items.md)
* [Smart items - Avanzado](/creator/content-creator-es/scene-editor/interactividad/smart-items-advanced.md)
* [Estados y condiciones](/creator/content-creator-es/scene-editor/interactividad/states-and-conditions.md)
* [Convertir cualquier elemento en smart](/creator/content-creator-es/scene-editor/interactividad/make-any-item-smart.md)
* [Inicio rápido de SDK](/creator/content-creator-es/scenes-sdk7/primeros-pasos/sdk-101.md): sigue este mini tutorial para un curso rápido.
* [Flujo de trabajo de desarrollo](/creator/content-creator-es/scenes-sdk7/primeros-pasos/dev-workflow.md): léelo para entender la creación de escenas de principio a fin.
* [Ejemplos](https://studios.decentraland.org/resources?sdk_version=SDK7): sumérgete directamente en escenas de ejemplo funcionales.


---

# 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-es/scene-editor/extender-con-codigo/script-component.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.
