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:
Then rename the project to "Color Animation":
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.
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).
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.
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);
Save and then go back to the Worlds editor and attach the shape to the script via the option now provided.
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'
Next define a new typescript class that will be exported and contain the logic needed to animate entities.
export class EntityAnimator<T> {
}
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[] = [];
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
];
And to store the index it's just a simple number property.
private index: number = 0;
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);
}
}
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;
}
}
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;
}
}
}
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';
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>();
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);
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);
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.
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);
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!