Horizon World Tutorial - Color Animated Entities
LNATION

LNATION @lnation

About: I blog about perl.

Joined:
May 30, 2025

Horizon World Tutorial - Color Animated Entities

Publish Date: Jul 17
1 0

In this tutorial, we will learn how to dynamically change the color of entities in Horizon Worlds using TypeScript. You will discover how to apply color changes programmatically to enhance the visual experience of your worlds. By the end of this guide, you'll have a solid understanding of how to manipulate entity colors to create engaging and interactive environments.

First lets create a new project in your horizon world editor:

new project

Then rename the project to "Color Animation":

rename setting

rename

Now we have our new world ready, lets add a new shape. Open the menu, click shape and choose for my example I will use a simple cube. Drag this into your world and then rename to be 'Cube1' and set the property position to be (0, 0.5, 2) change the tint strength to be 1 and set the motion to be animated. This will ensure the shape renders directly in front of your player when you start the game and we will be able to modify it's color. You can test this after placing your shape and using the default color picker in the UI.

shape settings

search cube

set props

Optionally you can set the brightness from 1 to a value up to 100.

With the shape in place next we need to start configuring our logic to animate. First create a new object and place it in the world. Rename it to 'LogicController' and Set the coords to (0,0,0).

new object

logic controller

Now we need to create our script to attach to the new object. Open the menu and create a new script called LogicController, then attach it to your object in the properties menu.

new script

set name

attach

Next open the script (by clicking on it in the UI) in visual studios. First we will add the property needed to attach our shape to our script. Change the code to the following:

import * as hz from 'horizon/core';

class LogicController extends hz.Component<typeof LogicController> {
  static propsDefinition = {
    shapeOne: { type: hz.PropTypes.Entity },
  };

  start() {

  }
}
hz.Component.register(LogicController);
Enter fullscreen mode Exit fullscreen mode

Save and then go back to the Worlds editor and attach the shape to the script via the option now provided.

shape

In programming in general it is good to write re-usable classes so for our example today we will do just that and create a simple typescript class that we will then import into our LogicController to animate our shape.

In visual studios with your project open, create a new file called 'EntityAnimator.ts'. Then at the top of that file import the components we need from the horizon core package.

import { Color, Entity } from  'horizon/core'
Enter fullscreen mode Exit fullscreen mode

Next define a new typescript class that will be exported and contain the logic needed to animate entities.

export class EntityAnimator<T> {

}
Enter fullscreen mode Exit fullscreen mode

Our class will require a few properties: one to hold the list of entities we want to animate, another to store the colors we'll cycle through during the animation and finally one to store the index we are currently on. To store the list of entities add the following property.

    private all: Entity[] = [];
Enter fullscreen mode Exit fullscreen mode

Then define a property to store the list of colors, for now we will just have a static list. Feel free to customise and extend this array.

    private colors: Color[] = [
        Color.fromHex('#39FF14'), // Neon Green
        Color.fromHex('#FF073A'), // Neon Red
        Color.fromHex('#00FFFF'), // Neon Cyan
        Color.fromHex('#FFFB00'), // Neon Yellow
    ];
Enter fullscreen mode Exit fullscreen mode

And to store the index it's just a simple number property.

    private index: number = 0;
Enter fullscreen mode Exit fullscreen mode

Next we need a function that will allow us to add entities to the private all array. Define the following after the colors property.

    addEntity(entity: Entity | Readonly<Entity> | undefined): void {
        if (entity) {
            this.all.push(entity as Entity);
        }
    }
Enter fullscreen mode Exit fullscreen mode

This function simply accepts a Entity and then pushes it to the all attribute if it's defined.

Now with that in place we need the function to actually itterate and animate the entities. Add the following after the addEntity defintion.

    animateEntities(): void {
        this.all.forEach((entity) => {
            const color = this.colors[this.index % this.colors.length];
            entity.color.set(color);
        });

        this.index++;
        if (this.index >= this.colors.length) {
            this.index = 0;
        }
    } 
Enter fullscreen mode Exit fullscreen mode

This function itterates all entities apply the color of the current index, it then increments the index and confirms that doesn't take the index greater than the number in our list. If it does it sets that index back to the start 0.

Your final EntityAnimator file should look like:

import { Color, Entity } from  'horizon/core'

export class EntityAnimator<T> {
    private all: Entity[] = [];
    private colors: Color[] = [
        Color.fromHex('#39FF14'), // Neon Green
        Color.fromHex('#FF073A'), // Neon Red
        Color.fromHex('#00FFFF'), // Neon Cyan
        Color.fromHex('#FFFB00'), // Neon Yellow
    ];
    private index: number = 0;

    addEntity(entity: Entity | Readonly<Entity> | undefined): void {
        if (entity) {
            this.all.push(entity as Entity);
        }
    }

    animateEntities(): void {
        this.all.forEach((entity) => {
            const color = this.colors[this.index % this.colors.length];
            entity.color.set(color);
        });

        this.index++;
        if (this.index >= this.colors.length) {
            this.index = 0;
        }
    }   
}
Enter fullscreen mode Exit fullscreen mode

We are now ready to animate our shape, return to the LogicController and add an import statement to bring in our new class.

import { EntityAnimator } from 'EntityAnimator';
Enter fullscreen mode Exit fullscreen mode

Then add a new property that we can use to store a reference to our instantiated class. Add the following after the propDefintion.

    private animator: EntityAnimator<hz.Entity> = new EntityAnimator<hz.Entity>();
Enter fullscreen mode Exit fullscreen mode

Next we need to add our shape to the EntityAnimator using the method we defined earlier. Inside the default start function add the following line.

    this.animator.addEntity(this.props.shapeOne);
Enter fullscreen mode Exit fullscreen mode

With that setup we are ready to trigger the animation, there are many ways we could do this, for now we will choose the simplest and just add a setInterval from within the same start function. Add the following after the addEntity line.

    this.async.setInterval(() => {
      this.animator.animateEntities();
    }, 1000);
Enter fullscreen mode Exit fullscreen mode

This uses setInterval to call the inner function every second, this inner function simply calls the animateEntities function we defined previously in our EntityAnimator class. Now save the file and run the world in the UI. You should see your shape changing color in front of you.

output

Your final script should look like:

import * as hz from 'horizon/core';
import { EntityAnimator } from 'EntityAnimator';

class LogicController extends hz.Component<typeof LogicController> {
  static propsDefinition = {
    shapeOne: { type: hz.PropTypes.Entity },
  };
  private animator: EntityAnimator<hz.Entity> = new EntityAnimator<hz.Entity>();

  start() {
    this.animator.addEntity(this.props.shapeOne);

    this.async.setInterval(() => {
      this.animator.animateEntities();
    }, 1000);
  }
}
hz.Component.register(LogicController);

Enter fullscreen mode Exit fullscreen mode

Now to extend this you have a few options, you could add propDefinitions to each of the entities you want to animate OR you can group your entities under an object and then just attach that object to the script instead of the shape.

I hope this tutorial was helpful in getting you started with animating entity colors in Horizon Worlds. If you have any questions or suggestions, please share your feedback below!

Comments 0 total

    Add comment