1. MyHoverComponent Tutorial #
The Hover Component creates a simple up-and-down floating motion – perfect for highlighting objects or creating ambient movement in educational scenes!
Purpose #
This component makes objects float up and down using a sine wave function, creating a smooth, natural-looking hover effect.
Step-by-Step Tutorial #
1. Create the Component Script #
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using WorldBuilder.Core.Components;
namespace MyComponents
{
public class MyHoverComponent: DataComponentBase
{
[JsonProperty("Speed")]
public float Speed = 1.0f;
[JsonProperty("Height")]
public float Height = 2.0f;
private Vector3 m_InitialPosition;
void Start()
{
m_InitialPosition = transform.position;
}
void Update()
{
float newY = Mathf.Sin(Time.time * Speed) * Height + m_InitialPosition.y;
transform.position = new Vector3(transform.position.x, newY, transform.position.z);
}
public override List<string> GetAssetReferences() { return null; }
public override void AfterDeserialization() { }
}
}
2. Create the Inspector View #
using UnityEngine;
using UnityEngine.UIElements;
using WorldBuilder.UI;
using WorldBuilder.Plugins;
using WorldBuilder.Plugins.UI;
using System;
using WorldBuilder.Core.Components.Inspectors;
namespace MyComponents
{
public class MyHoverComponentInspectorView : DataComponentInspectorViewBase
{
public override Type TypeOfDataComponent { get => typeof(MyHoverComponent); }
public MyHoverComponentInspectorView(Texture2D icon) : base(icon) { }
public override void CreateInspectorEntries(VisualElement window, IReferenceProvider referenceProvider, IUIElementFactory elementFactory, object instance)
{
var hoverComponent = instance as MyHoverComponent;
elementFactory.CreateInspectorFloatField(window, "Speed", hoverComponent.Speed, (oldValue, newValue) =>
{
hoverComponent.Speed = newValue;
});
elementFactory.CreateInspectorFloatField(window, "Height", hoverComponent.Height, (oldValue, newValue) =>
{
hoverComponent.Height = newValue;
});
}
}
}
3. How It Works #
Component Properties:
Speed
: Controls how quickly the object moves up and down (oscillation frequency)Height
: Determines the maximum distance the object moves from its starting position
The Math Behind It:
- The sine function creates a smooth wave pattern between -1 and 1
- Multiplying by
Height
scales the wave to the desired amplitude - Adding the initial Y position centers the wave around the object’s starting point
Runtime Behavior:
Start()
: Captures the initial position when the component is initializedUpdate()
: Recalculates the position every frame using the sine wave- Only the Y-axis changes; X and Z remain constant
4. Using the Component #
- Add the component to any object you want to hover
- Adjust the
Speed
parameter to control how quickly it moves (lower = slower) - Adjust the
Height
parameter to control how far it moves from its starting position
2. MyInteractivePulseComponent Tutorial #
The Pulse Component creates a rhythmic scaling effect – perfect for drawing attention to objects or creating breathing-like animations!
Purpose #
This component repeatedly scales an object up and down, creating a pulsing visual effect.
Step-by-Step Tutorial #
1. Create the Component Script #
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using WorldBuilder.Core.Components;
namespace MyComponents
{
public class MyInteractivePulseComponent : DataComponentBase
{
[JsonProperty("PulseSpeed")]
public float PulseSpeed = 2.0f;
[JsonProperty("PulseScale")]
public float PulseScale = 1.5f;
private Vector3 m_OriginalScale;
void Start()
{
m_OriginalScale = transform.localScale;
}
void Update()
{
float scale = Mathf.Abs(Mathf.Sin(Time.time * PulseSpeed)) * PulseScale;
transform.localScale = m_OriginalScale * (1 + scale);
}
public override List<string> GetAssetReferences() => null;
public override void AfterDeserialization() { }
}
}
2. Create the Inspector View #
using UnityEngine;
using UnityEngine.UIElements;
using WorldBuilder.UI;
using WorldBuilder.Plugins;
using WorldBuilder.Plugins.UI;
using System;
using WorldBuilder.Core.Components.Inspectors;
namespace MyComponents
{
public class MyInteractivePulseInspectorView : DataComponentInspectorViewBase
{
public override Type TypeOfDataComponent => typeof(MyInteractivePulseComponent);
public MyInteractivePulseInspectorView(Texture2D icon) : base(icon) { }
public override void CreateInspectorEntries(VisualElement window, IReferenceProvider referenceProvider, IUIElementFactory elementFactory, object instance)
{
var pulseComponent = instance as MyInteractivePulseComponent;
elementFactory.CreateInspectorFloatField(window, "Pulse Speed", pulseComponent.PulseSpeed, (oldValue, newValue) =>
{
pulseComponent.PulseSpeed = newValue;
}, "Hz");
elementFactory.CreateInspectorFloatField(window, "Pulse Scale", pulseComponent.PulseScale, (oldValue, newValue) =>
{
pulseComponent.PulseScale = newValue;
}, "x");
}
}
}
3. How It Works #
Component Properties:
PulseSpeed
: Controls how quickly the object pulses (in cycles per second)PulseScale
: Determines how much the object’s size changes during pulsing
The Math Behind It:
- Uses a sine wave like the Hover component, but takes the absolute value
- This creates a “bouncing” effect between 0 and 1 instead of -1 and 1
- Multiplies by
PulseScale
to determine maximum size increase - Adds 1 to maintain the original size as the minimum
Runtime Behavior:
Start()
: Captures the initial scale when the component is initializedUpdate()
: Recalculates the scale every frame using the sine wave- All axes scale uniformly (the object grows/shrinks in all dimensions)
4. Using the Component #
- Add the component to any object you want to pulse
- Adjust the
PulseSpeed
parameter (higher values make it pulse faster) - Adjust the
PulseScale
parameter (higher values make it grow larger)
3. MyLookAtComponent Tutorial #
The LookAt Component makes objects track and face a target – perfect for creating attention-directing elements in educational scenes!
Purpose #
This component makes an object continuously rotate to face another specified object in the scene.
Step-by-Step Tutorial #
1. Create the Component Script #
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using WorldBuilder.Core.Components;
namespace MyComponents
{
public class MyLookAtComponent : DataComponentBase
{
[JsonProperty("TargetObjectName")]
public string TargetObjectName;
private Transform m_TargetTransform;
void Start()
{
var target = GameObject.Find(TargetObjectName);
if (target)
m_TargetTransform = target.transform;
}
void Update()
{
if (m_TargetTransform)
transform.LookAt(m_TargetTransform);
}
public override List<string> GetAssetReferences() => null;
public override void AfterDeserialization() { }
}
}
2. Creating the Inspector View #
For this component, we could create an inspector view similar to the others. Here’s how it might look:
using UnityEngine;
using UnityEngine.UIElements;
using WorldBuilder.UI;
using WorldBuilder.Plugins;
using WorldBuilder.Plugins.UI;
using System;
using WorldBuilder.Core.Components.Inspectors;
namespace MyComponents
{
public class MyLookAtComponentInspectorView : DataComponentInspectorViewBase
{
public override Type TypeOfDataComponent => typeof(MyLookAtComponent);
public MyLookAtComponentInspectorView(Texture2D icon) : base(icon) { }
public override void CreateInspectorEntries(VisualElement window, IReferenceProvider referenceProvider, IUIElementFactory elementFactory, object instance)
{
var lookAtComponent = instance as MyLookAtComponent;
elementFactory.CreateInspectorTextField(window, "Target Object", lookAtComponent.TargetObjectName, (oldValue, newValue) =>
{
lookAtComponent.TargetObjectName = newValue;
});
}
}
}
3. How It Works #
Component Properties:
TargetObjectName
: The name of the object this component should face toward
Implementation Details:
- Uses Unity’s built-in
LookAt()
method, which rotates an object to face a target - Finds the target by name at startup using
GameObject.Find()
- Caches the target’s transform for efficiency
- Only rotates if a valid target is found
- Uses Unity’s built-in
Runtime Behavior:
Start()
: Finds the target object by name and caches its transformUpdate()
: Continuously updates rotation to face the target every frame
4. Using the Component #
- Add the component to any object that should face another object
- Set the
TargetObjectName
to match the exact name of the target object - The object will now always rotate to face the target
4. MyOrbitComponent Tutorial #
The Orbit Component creates circular movement around a target – perfect for simulating planetary motion or creating dynamic, circling elements!
Purpose #
This component makes an object orbit around another specified object (or its initial position if no target is found).
Step-by-Step Tutorial #
1. Create the Component Script #
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using WorldBuilder.Core.Components;
namespace MyComponents
{
public class MyOrbitComponent : DataComponentBase
{
[JsonProperty("OrbitSpeed")]
public float OrbitSpeed = 6.0f;
[JsonProperty("OrbitRadius")]
public float OrbitRadius = 10.0f;
[JsonProperty("TargetObjectName")]
public string TargetObjectName;
private Transform m_TargetTransform;
private Vector3 m_CenterPoint;
void Start()
{
var target = GameObject.Find(TargetObjectName);
if (target)
m_TargetTransform = target.transform;
else
m_CenterPoint = transform.position;
}
void Update()
{
Vector3 center = m_TargetTransform ? m_TargetTransform.position : m_CenterPoint;
transform.position = center + new Vector3(
Mathf.Cos(Time.time * OrbitSpeed) * OrbitRadius,
transform.position.y,
Mathf.Sin(Time.time * OrbitSpeed) * OrbitRadius
);
}
public override List<string> GetAssetReferences() => null;
public override void AfterDeserialization() { }
}
}
2. Create the Inspector View #
using UnityEngine;
using UnityEngine.UIElements;
using WorldBuilder.UI;
using WorldBuilder.Plugins;
using WorldBuilder.Plugins.UI;
using System;
using WorldBuilder.Core.Components.Inspectors;
namespace MyComponents
{
public class MyOrbitComponentInspectorView : DataComponentInspectorViewBase
{
public override Type TypeOfDataComponent => typeof(MyOrbitComponent);
public MyOrbitComponentInspectorView(Texture2D icon) : base(icon) {}
public override void CreateInspectorEntries(VisualElement window, IReferenceProvider referenceProvider, IUIElementFactory elementFactory, object instance)
{
var orbitComponent = instance as MyOrbitComponent;
elementFactory.CreateInspectorFloatField(window, "Orbit Speed", orbitComponent.OrbitSpeed, (oldValue, newValue) =>
{
orbitComponent.OrbitSpeed = newValue;
}, "°/s", tooltip: "Speed at which object orbits around center");
elementFactory.CreateInspectorFloatField(window, "Orbit Radius", orbitComponent.OrbitRadius, (oldValue, newValue) =>
{
orbitComponent.OrbitRadius = newValue;
}, "m");
elementFactory.CreateInspectorTextField(window, "Target Object", orbitComponent.TargetObjectName, (oldValue, newValue) =>
{
orbitComponent.TargetObjectName = newValue;
});
}
}
}
3. How It Works #
Component Properties:
OrbitSpeed
: Controls how quickly the object moves around its target (angular velocity)OrbitRadius
: Determines the distance from the center pointTargetObjectName
: The name of the object to orbit around
The Math Behind It:
- Uses sine and cosine functions to create circular motion
- Cosine controls X position, Sine controls Z position
- Multiplying by
OrbitRadius
sets the circle size - Multiplying by
Time.time * OrbitSpeed
creates continuous movement
Runtime Behavior:
Start()
: Finds the target object or defaults to orbiting the initial positionUpdate()
: Recalculates position every frame to create circular movement- Maintains the original Y position (orbits in the XZ plane)
4. Using the Component #
- Add the component to any object that should orbit
- Set the
TargetObjectName
to the name of the center object (or leave empty to orbit initial position) - Adjust
OrbitSpeed
to control how quickly it circles (higher = faster) - Adjust
OrbitRadius
to control how far from the center it orbits