{"id":1247,"date":"2025-03-13T13:27:55","date_gmt":"2025-03-13T13:27:55","guid":{"rendered":"https:\/\/www.portalsunited.com:443\/?post_type=docs&#038;p=1247"},"modified":"2025-03-13T13:40:50","modified_gmt":"2025-03-13T13:40:50","password":"","slug":"worldbuilder-runtime-component-tutorials","status":"publish","type":"docs","link":"https:\/\/www.portalsunited.com:443\/docs\/worldbuilder-runtime-component-tutorials\/","title":{"rendered":"World Builder &#8211; Runtime Scripting Tutorials"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"1-myhovercomponent-tutorial\">1. MyHoverComponent Tutorial<\/h2>\n\n\n\n<p>The Hover Component creates a simple up-and-down floating motion &#8211; perfect for highlighting objects or creating ambient movement in educational scenes!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"purpose\">Purpose<\/h3>\n\n\n\n<p>This component makes objects float up and down using a sine wave function, creating a smooth, natural-looking hover effect.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"step-by-step-tutorial\">Step-by-Step Tutorial<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"1-create-the-component-script\">1. Create the Component Script<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code><span class=\"hljs-keyword\">using<\/span> System.Collections.Generic;\n<span class=\"hljs-keyword\">using<\/span> UnityEngine;\n<span class=\"hljs-keyword\">using<\/span> Newtonsoft.Json;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Core.Components;\n\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">MyComponents<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyHoverComponent<\/span>: <span class=\"hljs-title\">DataComponentBase<\/span>\n    {\n        &#91;JsonProperty(<span class=\"hljs-string\">\"Speed\"<\/span>)]\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">float<\/span> Speed = <span class=\"hljs-number\">1.0<\/span>f;\n\n        &#91;JsonProperty(<span class=\"hljs-string\">\"Height\"<\/span>)]\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">float<\/span> Height = <span class=\"hljs-number\">2.0<\/span>f;\n\n        <span class=\"hljs-keyword\">private<\/span> Vector3 m_InitialPosition;\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Start<\/span>(<span class=\"hljs-params\"><\/span>)\n        <\/span>{\n            m_InitialPosition = transform.position;\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Update<\/span>(<span class=\"hljs-params\"><\/span>)\n        <\/span>{\n            <span class=\"hljs-keyword\">float<\/span> newY = Mathf.Sin(Time.time * Speed) * Height + m_InitialPosition.y;\n            transform.position = <span class=\"hljs-keyword\">new<\/span> Vector3(transform.position.x, newY, transform.position.z);\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> List&lt;<span class=\"hljs-keyword\">string<\/span>&gt; <span class=\"hljs-title\">GetAssetReferences<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{ <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">null<\/span>; }\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">AfterDeserialization<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{ }\n    }\n}\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"2-create-the-inspector-view\">2. Create the Inspector View<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code><span class=\"hljs-keyword\">using<\/span> UnityEngine;\n<span class=\"hljs-keyword\">using<\/span> UnityEngine.UIElements;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.UI;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Plugins;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Plugins.UI;\n<span class=\"hljs-keyword\">using<\/span> System;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Core.Components.Inspectors;\n\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">MyComponents<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyHoverComponentInspectorView<\/span> : <span class=\"hljs-title\">DataComponentInspectorViewBase<\/span>\n    {\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> Type TypeOfDataComponent { <span class=\"hljs-keyword\">get<\/span> =&gt; <span class=\"hljs-keyword\">typeof<\/span>(MyHoverComponent); }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">MyHoverComponentInspectorView<\/span>(<span class=\"hljs-params\">Texture2D icon<\/span>) : <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">icon<\/span>) <\/span>{ }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">CreateInspectorEntries<\/span>(<span class=\"hljs-params\">VisualElement window, IReferenceProvider referenceProvider, IUIElementFactory elementFactory, <span class=\"hljs-keyword\">object<\/span> instance<\/span>)\n        <\/span>{\n            <span class=\"hljs-keyword\">var<\/span> hoverComponent = instance <span class=\"hljs-keyword\">as<\/span> MyHoverComponent;\n\n            elementFactory.CreateInspectorFloatField(window, <span class=\"hljs-string\">\"Speed\"<\/span>, hoverComponent.Speed, (oldValue, newValue) =&gt;\n            {\n                hoverComponent.Speed = newValue;\n            });\n\n            elementFactory.CreateInspectorFloatField(window, <span class=\"hljs-string\">\"Height\"<\/span>, hoverComponent.Height, (oldValue, newValue) =&gt;\n            {\n                hoverComponent.Height = newValue;\n            });\n        }\n    }\n}\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"3-how-it-works\">3. How It Works<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Component Properties:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><code>Speed<\/code>: Controls how quickly the object moves up and down (oscillation frequency)<\/li>\n\n\n\n<li><code>Height<\/code>: Determines the maximum distance the object moves from its starting position<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>The Math Behind It:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>The sine function creates a smooth wave pattern between -1 and 1<\/li>\n\n\n\n<li>Multiplying by <code>Height<\/code> scales the wave to the desired amplitude<\/li>\n\n\n\n<li>Adding the initial Y position centers the wave around the object&#8217;s starting point<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Runtime Behavior:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><code>Start()<\/code>: Captures the initial position when the component is initialized<\/li>\n\n\n\n<li><code>Update()<\/code>: Recalculates the position every frame using the sine wave<\/li>\n\n\n\n<li>Only the Y-axis changes; X and Z remain constant<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"4-using-the-component\">4. Using the Component<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Add the component to any object you want to hover<\/li>\n\n\n\n<li>Adjust the <code>Speed<\/code> parameter to control how quickly it moves (lower = slower)<\/li>\n\n\n\n<li>Adjust the <code>Height<\/code> parameter to control how far it moves from its starting position<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"2-myinteractivepulsecomponent-tutorial\">2. MyInteractivePulseComponent Tutorial<\/h2>\n\n\n\n<p>The Pulse Component creates a rhythmic scaling effect &#8211; perfect for drawing attention to objects or creating breathing-like animations!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"purpose\">Purpose<\/h3>\n\n\n\n<p>This component repeatedly scales an object up and down, creating a pulsing visual effect.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"step-by-step-tutorial\">Step-by-Step Tutorial<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"1-create-the-component-script\">1. Create the Component Script<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code><span class=\"hljs-keyword\">using<\/span> System.Collections.Generic;\n<span class=\"hljs-keyword\">using<\/span> UnityEngine;\n<span class=\"hljs-keyword\">using<\/span> Newtonsoft.Json;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Core.Components;\n\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">MyComponents<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyInteractivePulseComponent<\/span> : <span class=\"hljs-title\">DataComponentBase<\/span>\n    {\n        &#91;JsonProperty(<span class=\"hljs-string\">\"PulseSpeed\"<\/span>)]\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">float<\/span> PulseSpeed = <span class=\"hljs-number\">2.0<\/span>f;\n\n        &#91;JsonProperty(<span class=\"hljs-string\">\"PulseScale\"<\/span>)]\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">float<\/span> PulseScale = <span class=\"hljs-number\">1.5<\/span>f;\n\n        <span class=\"hljs-keyword\">private<\/span> Vector3 m_OriginalScale;\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Start<\/span>(<span class=\"hljs-params\"><\/span>)\n        <\/span>{\n            m_OriginalScale = transform.localScale;\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Update<\/span>(<span class=\"hljs-params\"><\/span>)\n        <\/span>{\n            <span class=\"hljs-keyword\">float<\/span> scale = Mathf.Abs(Mathf.Sin(Time.time * PulseSpeed)) * PulseScale;\n            transform.localScale = m_OriginalScale * (<span class=\"hljs-number\">1<\/span> + scale);\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> List&lt;<span class=\"hljs-keyword\">string<\/span>&gt; <span class=\"hljs-title\">GetAssetReferences<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>=&gt; <span class=\"hljs-literal\">null<\/span>;\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">AfterDeserialization<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{ }\n    }\n}\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"2-create-the-inspector-view\">2. Create the Inspector View<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code><span class=\"hljs-keyword\">using<\/span> UnityEngine;\n<span class=\"hljs-keyword\">using<\/span> UnityEngine.UIElements;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.UI;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Plugins;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Plugins.UI;\n<span class=\"hljs-keyword\">using<\/span> System;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Core.Components.Inspectors;\n\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">MyComponents<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyInteractivePulseInspectorView<\/span> : <span class=\"hljs-title\">DataComponentInspectorViewBase<\/span>\n    {\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> Type TypeOfDataComponent =&gt; <span class=\"hljs-keyword\">typeof<\/span>(MyInteractivePulseComponent);\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">MyInteractivePulseInspectorView<\/span>(<span class=\"hljs-params\">Texture2D icon<\/span>) : <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">icon<\/span>) <\/span>{ }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">CreateInspectorEntries<\/span>(<span class=\"hljs-params\">VisualElement window, IReferenceProvider referenceProvider, IUIElementFactory elementFactory, <span class=\"hljs-keyword\">object<\/span> instance<\/span>)\n        <\/span>{\n            <span class=\"hljs-keyword\">var<\/span> pulseComponent = instance <span class=\"hljs-keyword\">as<\/span> MyInteractivePulseComponent;\n\n            elementFactory.CreateInspectorFloatField(window, <span class=\"hljs-string\">\"Pulse Speed\"<\/span>, pulseComponent.PulseSpeed, (oldValue, newValue) =&gt;\n            {\n                pulseComponent.PulseSpeed = newValue;\n            }, <span class=\"hljs-string\">\"Hz\"<\/span>);\n\n            elementFactory.CreateInspectorFloatField(window, <span class=\"hljs-string\">\"Pulse Scale\"<\/span>, pulseComponent.PulseScale, (oldValue, newValue) =&gt;\n            {\n                pulseComponent.PulseScale = newValue;\n            }, <span class=\"hljs-string\">\"x\"<\/span>);\n        }\n    }\n}\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"3-how-it-works\">3. How It Works<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Component Properties:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><code>PulseSpeed<\/code>: Controls how quickly the object pulses (in cycles per second)<\/li>\n\n\n\n<li><code>PulseScale<\/code>: Determines how much the object&#8217;s size changes during pulsing<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>The Math Behind It:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Uses a sine wave like the Hover component, but takes the absolute value<\/li>\n\n\n\n<li>This creates a &#8220;bouncing&#8221; effect between 0 and 1 instead of -1 and 1<\/li>\n\n\n\n<li>Multiplies by <code>PulseScale<\/code> to determine maximum size increase<\/li>\n\n\n\n<li>Adds 1 to maintain the original size as the minimum<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Runtime Behavior:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><code>Start()<\/code>: Captures the initial scale when the component is initialized<\/li>\n\n\n\n<li><code>Update()<\/code>: Recalculates the scale every frame using the sine wave<\/li>\n\n\n\n<li>All axes scale uniformly (the object grows\/shrinks in all dimensions)<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"4-using-the-component\">4. Using the Component<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Add the component to any object you want to pulse<\/li>\n\n\n\n<li>Adjust the <code>PulseSpeed<\/code> parameter (higher values make it pulse faster)<\/li>\n\n\n\n<li>Adjust the <code>PulseScale<\/code> parameter (higher values make it grow larger)<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3-mylookatcomponent-tutorial\">3. MyLookAtComponent Tutorial<\/h2>\n\n\n\n<p>The LookAt Component makes objects track and face a target &#8211; perfect for creating attention-directing elements in educational scenes!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"purpose\">Purpose<\/h3>\n\n\n\n<p>This component makes an object continuously rotate to face another specified object in the scene.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"step-by-step-tutorial\">Step-by-Step Tutorial<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"1-create-the-component-script\">1. Create the Component Script<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code><span class=\"hljs-keyword\">using<\/span> System.Collections.Generic;\n<span class=\"hljs-keyword\">using<\/span> UnityEngine;\n<span class=\"hljs-keyword\">using<\/span> Newtonsoft.Json;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Core.Components;\n\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">MyComponents<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyLookAtComponent<\/span> : <span class=\"hljs-title\">DataComponentBase<\/span>\n    {\n        &#91;JsonProperty(<span class=\"hljs-string\">\"TargetObjectName\"<\/span>)]\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">string<\/span> TargetObjectName;\n\n        <span class=\"hljs-keyword\">private<\/span> Transform m_TargetTransform;\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Start<\/span>(<span class=\"hljs-params\"><\/span>)\n        <\/span>{\n            <span class=\"hljs-keyword\">var<\/span> target = GameObject.Find(TargetObjectName);\n            <span class=\"hljs-keyword\">if<\/span> (target)\n                m_TargetTransform = target.transform;\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Update<\/span>(<span class=\"hljs-params\"><\/span>)\n        <\/span>{\n            <span class=\"hljs-keyword\">if<\/span> (m_TargetTransform)\n                transform.LookAt(m_TargetTransform);\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> List&lt;<span class=\"hljs-keyword\">string<\/span>&gt; <span class=\"hljs-title\">GetAssetReferences<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>=&gt; <span class=\"hljs-literal\">null<\/span>;\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">AfterDeserialization<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{ }\n    }\n}\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"2-creating-the-inspector-view\">2. Creating the Inspector View<\/h4>\n\n\n\n<p>For this component, we could create an inspector view similar to the others. Here&#8217;s how it might look:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><span class=\"hljs-keyword\">using<\/span> UnityEngine;\n<span class=\"hljs-keyword\">using<\/span> UnityEngine.UIElements;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.UI;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Plugins;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Plugins.UI;\n<span class=\"hljs-keyword\">using<\/span> System;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Core.Components.Inspectors;\n\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">MyComponents<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyLookAtComponentInspectorView<\/span> : <span class=\"hljs-title\">DataComponentInspectorViewBase<\/span>\n    {\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> Type TypeOfDataComponent =&gt; <span class=\"hljs-keyword\">typeof<\/span>(MyLookAtComponent);\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">MyLookAtComponentInspectorView<\/span>(<span class=\"hljs-params\">Texture2D icon<\/span>) : <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">icon<\/span>) <\/span>{ }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">CreateInspectorEntries<\/span>(<span class=\"hljs-params\">VisualElement window, IReferenceProvider referenceProvider, IUIElementFactory elementFactory, <span class=\"hljs-keyword\">object<\/span> instance<\/span>)\n        <\/span>{\n            <span class=\"hljs-keyword\">var<\/span> lookAtComponent = instance <span class=\"hljs-keyword\">as<\/span> MyLookAtComponent;\n\n            elementFactory.CreateInspectorTextField(window, <span class=\"hljs-string\">\"Target Object\"<\/span>, lookAtComponent.TargetObjectName, (oldValue, newValue) =&gt;\n            {\n                lookAtComponent.TargetObjectName = newValue;\n            });\n        }\n    }\n}\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"3-how-it-works\">3. How It Works<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Component Properties:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><code>TargetObjectName<\/code>: The name of the object this component should face toward<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Implementation Details:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Uses Unity&#8217;s built-in <code>LookAt()<\/code> method, which rotates an object to face a target<\/li>\n\n\n\n<li>Finds the target by name at startup using <code>GameObject.Find()<\/code><\/li>\n\n\n\n<li>Caches the target&#8217;s transform for efficiency<\/li>\n\n\n\n<li>Only rotates if a valid target is found<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Runtime Behavior:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><code>Start()<\/code>: Finds the target object by name and caches its transform<\/li>\n\n\n\n<li><code>Update()<\/code>: Continuously updates rotation to face the target every frame<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"4-using-the-component\">4. Using the Component<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Add the component to any object that should face another object<\/li>\n\n\n\n<li>Set the <code>TargetObjectName<\/code> to match the exact name of the target object<\/li>\n\n\n\n<li>The object will now always rotate to face the target<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4-myorbitcomponent-tutorial\">4. MyOrbitComponent Tutorial<\/h2>\n\n\n\n<p>The Orbit Component creates circular movement around a target &#8211; perfect for simulating planetary motion or creating dynamic, circling elements!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"purpose\">Purpose<\/h3>\n\n\n\n<p>This component makes an object orbit around another specified object (or its initial position if no target is found).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"step-by-step-tutorial\">Step-by-Step Tutorial<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"1-create-the-component-script\">1. Create the Component Script<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code><span class=\"hljs-keyword\">using<\/span> System.Collections.Generic;\n<span class=\"hljs-keyword\">using<\/span> UnityEngine;\n<span class=\"hljs-keyword\">using<\/span> Newtonsoft.Json;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Core.Components;\n\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">MyComponents<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyOrbitComponent<\/span> : <span class=\"hljs-title\">DataComponentBase<\/span>\n    {\n        &#91;JsonProperty(<span class=\"hljs-string\">\"OrbitSpeed\"<\/span>)]\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">float<\/span> OrbitSpeed = <span class=\"hljs-number\">6.0<\/span>f;\n\n        &#91;JsonProperty(<span class=\"hljs-string\">\"OrbitRadius\"<\/span>)]\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">float<\/span> OrbitRadius = <span class=\"hljs-number\">10.0<\/span>f;\n\n        &#91;JsonProperty(<span class=\"hljs-string\">\"TargetObjectName\"<\/span>)]\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">string<\/span> TargetObjectName;\n\n        <span class=\"hljs-keyword\">private<\/span> Transform m_TargetTransform;\n        <span class=\"hljs-keyword\">private<\/span> Vector3 m_CenterPoint;\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Start<\/span>(<span class=\"hljs-params\"><\/span>)\n        <\/span>{\n            <span class=\"hljs-keyword\">var<\/span> target = GameObject.Find(TargetObjectName);\n            <span class=\"hljs-keyword\">if<\/span> (target)\n                m_TargetTransform = target.transform;\n            <span class=\"hljs-keyword\">else<\/span>\n                m_CenterPoint = transform.position;\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Update<\/span>(<span class=\"hljs-params\"><\/span>)\n        <\/span>{\n            Vector3 center = m_TargetTransform ? m_TargetTransform.position : m_CenterPoint;\n            transform.position = center + <span class=\"hljs-keyword\">new<\/span> Vector3(\n                Mathf.Cos(Time.time * OrbitSpeed) * OrbitRadius, \n                transform.position.y, \n                Mathf.Sin(Time.time * OrbitSpeed) * OrbitRadius\n            );\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> List&lt;<span class=\"hljs-keyword\">string<\/span>&gt; <span class=\"hljs-title\">GetAssetReferences<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>=&gt; <span class=\"hljs-literal\">null<\/span>;\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">AfterDeserialization<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{ }\n    }\n}\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"2-create-the-inspector-view\">2. Create the Inspector View<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>using UnityEngine<span class=\"hljs-comment\">;<\/span>\nusing UnityEngine.UIElements<span class=\"hljs-comment\">;<\/span>\nusing WorldBuilder.UI<span class=\"hljs-comment\">;<\/span>\nusing WorldBuilder.Plugins<span class=\"hljs-comment\">;<\/span>\nusing WorldBuilder.Plugins.UI<span class=\"hljs-comment\">;<\/span>\nusing System<span class=\"hljs-comment\">;<\/span>\nusing WorldBuilder.Core.Components.<span class=\"hljs-keyword\">Inspectors;\n<\/span>\nnamespace MyComponents\n{\n    public class MyOrbitComponentInspectorView : DataComponentInspectorViewBase\n    {\n        public override Type TypeOfDataComponent =&gt; typeof(MyOrbitComponent)<span class=\"hljs-comment\">;<\/span>\n\n        public MyOrbitComponentInspectorView(Texture2D icon) : <span class=\"hljs-keyword\">base(icon) <\/span>{}\n\n        public override void CreateInspectorEntries(VisualElement window, IReferenceProvider referenceProvider, IUIElementFactory elementFactory, object <span class=\"hljs-keyword\">instance)\n<\/span>        {\n            var <span class=\"hljs-keyword\">orbitComponent <\/span>= <span class=\"hljs-keyword\">instance <\/span>as MyOrbitComponent<span class=\"hljs-comment\">;<\/span>\n\n            elementFactory.CreateInspectorFloatField(window, <span class=\"hljs-string\">\"Orbit Speed\"<\/span>, <span class=\"hljs-keyword\">orbitComponent.OrbitSpeed, <\/span>(oldValue, newValue) =&gt;\n            {\n                <span class=\"hljs-keyword\">orbitComponent.OrbitSpeed <\/span>= newValue<span class=\"hljs-comment\">;<\/span>\n            }, <span class=\"hljs-string\">\"\u00b0\/s\"<\/span>, tooltip: <span class=\"hljs-string\">\"Speed at which object orbits around center\"<\/span>)<span class=\"hljs-comment\">;<\/span>\n\n            elementFactory.CreateInspectorFloatField(window, <span class=\"hljs-string\">\"Orbit Radius\"<\/span>, <span class=\"hljs-keyword\">orbitComponent.OrbitRadius, <\/span>(oldValue, newValue) =&gt;\n            {\n                <span class=\"hljs-keyword\">orbitComponent.OrbitRadius <\/span>= newValue<span class=\"hljs-comment\">;<\/span>\n            }, <span class=\"hljs-string\">\"m\"<\/span>)<span class=\"hljs-comment\">;<\/span>\n\n            elementFactory.CreateInspectorTextField(window, <span class=\"hljs-string\">\"Target Object\"<\/span>, <span class=\"hljs-keyword\">orbitComponent.TargetObjectName, <\/span>(oldValue, newValue) =&gt;\n            {\n                <span class=\"hljs-keyword\">orbitComponent.TargetObjectName <\/span>= newValue<span class=\"hljs-comment\">;<\/span>\n            })<span class=\"hljs-comment\">;<\/span>\n        }\n    }\n}\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"3-how-it-works\">3. How It Works<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p><strong>Component Properties:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><code>OrbitSpeed<\/code>: Controls how quickly the object moves around its target (angular velocity)<\/li>\n\n\n\n<li><code>OrbitRadius<\/code>: Determines the distance from the center point<\/li>\n\n\n\n<li><code>TargetObjectName<\/code>: The name of the object to orbit around<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>The Math Behind It:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>Uses sine and cosine functions to create circular motion<\/li>\n\n\n\n<li>Cosine controls X position, Sine controls Z position<\/li>\n\n\n\n<li>Multiplying by <code>OrbitRadius<\/code> sets the circle size<\/li>\n\n\n\n<li>Multiplying by <code>Time.time * OrbitSpeed<\/code> creates continuous movement<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p><strong>Runtime Behavior:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li><code>Start()<\/code>: Finds the target object or defaults to orbiting the initial position<\/li>\n\n\n\n<li><code>Update()<\/code>: Recalculates position every frame to create circular movement<\/li>\n\n\n\n<li>Maintains the original Y position (orbits in the XZ plane)<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"4-using-the-component\">4. Using the Component<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Add the component to any object that should orbit<\/li>\n\n\n\n<li>Set the <code>TargetObjectName<\/code> to the name of the center object (or leave empty to orbit initial position)<\/li>\n\n\n\n<li>Adjust <code>OrbitSpeed<\/code> to control how quickly it circles (higher = faster)<\/li>\n\n\n\n<li>Adjust <code>OrbitRadius<\/code> to control how far from the center it orbits<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>1. MyHoverComponent Tutorial The Hover Component creates a simple up-and-down floating motion &#8211; 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 2. Create the Inspector&#8230;<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"footnotes":""},"doc_category":[16],"doc_tag":[],"class_list":["post-1247","docs","type-docs","status-publish","hentry","doc_category-world-builder-extensions"],"year_month":"2025-08","word_count":1426,"total_views":0,"reactions":{"happy":0,"normal":0,"sad":0},"author_info":{"name":"maximilian.winter","author_nicename":"maximilian-winter","author_url":"https:\/\/www.portalsunited.com:443\/author\/maximilian-winter\/"},"doc_category_info":[{"term_name":"World Builder - Extensions","term_url":"https:\/\/www.portalsunited.com:443\/docs-category\/world-builder-extensions\/"}],"doc_tag_info":[],"_links":{"self":[{"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/docs\/1247","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/types\/docs"}],"author":[{"embeddable":true,"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/comments?post=1247"}],"version-history":[{"count":3,"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/docs\/1247\/revisions"}],"predecessor-version":[{"id":1253,"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/docs\/1247\/revisions\/1253"}],"wp:attachment":[{"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/media?parent=1247"}],"wp:term":[{"taxonomy":"doc_category","embeddable":true,"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/doc_category?post=1247"},{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/doc_tag?post=1247"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}