Can I Modify Needle-Component?

Can I Modify Needle-Component in node_modules or i should new script and add to object in Unity?
Such as … Button-Component
start() will Create Button in HTML
or onDestroy Remove That Button in HTML

eg. I want to create own unity ui and html sync system.

Hi oot4chi! I’m an AI powered assistant here to help you. I can assist with questions regarding Needle Engine, three.js, and basic Unity or Blender help. Please reply with your question, including your OS, and the versions of Needle Engine and Unity (or Blender) you’re using for more tailored support.

2 replies left - GPT 4O
thread_mc0ebLmwBGfU9xbSrjQTAJNf
Reply to this message to continue the conversation

use unity 2022.3.21f1

Hi oot4chi! To modify the Needle-Component, it’s generally recommended not to directly modify the node_modules. Instead, you can create a new script to extend or customize the functionality.

Here’s a basic outline of how you can set up your custom Button component to handle adding and removing HTML elements:

  1. Create a new script in Unity, for example, CustomButtonComponent.cs.
  2. Inside that script, you can manage the lifecycle of the button’s HTML element using start() and onDestroy().

Here’s a pseudocode outline:

using UnityEngine;

public class CustomButtonComponent : MonoBehaviour
{
    private GameObject buttonElement;

    void Start()
    {
        // Create the button HTML element
        buttonElement = new GameObject("Button");
        // Add your HTML creation logic here
        CreateButtonHtml();
    }

    void OnDestroy()
    {
        // Remove the button HTML element
        RemoveButtonHtml();
    }

    private void CreateButtonHtml()
    {
        // Logic to create <button></button> in HTML
    }

    private void RemoveButtonHtml()
    {
        // Logic to remove <button></button> in HTML
    }
}

You can replace CreateButtonHtml() and RemoveButtonHtml() with the specific logic to interact with your HTML system. This way, your implementation is more modular and maintainable.

Feel free to ask further questions or specify any additional details!

0 replies left - GPT 4O
thread_mc0ebLmwBGfU9xbSrjQTAJNf
Reply to this message to continue the conversation

Hi, modifying code in node_modules is not good practice and will break once a package gets updated. You can for your case just create a new component that has your desired behaviour.

If I understand you correctly you want to use the Unity components for setting up your UI in Unity but handle how the buttons look in the web yourself and create HTML UI from that?

1 Like

Thank you for the suggestion. I will try the concept of referencing Unity UI with HTML using HTMLElement in typescript. This way, I can control the HTML elements within the Needle component. This approach should allow me to manage the functionality of the HTML elements while utilizing Unity components for setting up the UI.

import { Behaviour, Button, NeedleEngine, RectTransform, serializable, Text } from "@needle-tools/engine";

// Documentation → https://docs.needle.tools/scripting

export class CustomButtonComponent extends Behaviour {
    @serializable(Button)
    myButton?: Button;
    @serializable(Text)
    buttonText?: Text;

    private htmlElement?: HTMLElement;

    start() {
        //for create new html
        this.htmlElement = document.createElement('button');
        if (this.htmlElement) {
            NeedleEngine.Current.appendHTMLElement(this.htmlElement);

            if (this.buttonText)
                this.htmlElement.textContent = this.buttonText.text;

            if (this.myButton) {
                const onClicked = () => {
                    this.myButton?.onClick?.invoke();
                }

                this.htmlElement.addEventListener('click', onClicked);
            }
        }


    }

    setText(text: string) {
        if (this.htmlElement)
            this.htmlElement.textContent = text;
    }

    setActive(isActive: boolean) {
        if (this.htmlElement) {
            if (isActive) {
                this.htmlElement.style.display = "block";
            } else {
                this.htmlElement.style.display = "none";
            }
        }

    }
}

example use cases

import { Behaviour, serializable,FrameEvent, WaitForSeconds} from "@needle-tools/engine";
import { CustomButtonComponent } from "./CustomButtonComponent";

export class TestScript extends Behaviour {
    @serializable(CustomButtonComponent)
    customButton?: CustomButtonComponent;

    start() {
        this.startCoroutine(this.updateTime(),FrameEvent.Update)
    }

    private *updateTime() {
        let counter = 10;
        while (counter > 0) {
            if (this.customButton)
                this.customButton.setText("counter" + counter.toString());
           
            yield WaitForSeconds(1);
            counter--;
        }
        this.customButton?.setActive(false);
    };
}

Btw instead of doing NeedleEngine.Current in your component you can just use this.context

1 Like

How about get Image URL in Image Component directly?
Do I need to use Addressable (Image Reference)?

The image component uses the texture that is exported as part of the glTF file so there is no URL for it. If you want a texture/image to be copied to the output directory (instead of being embedded) you can use a ImageReference type yes - but keep in mind that this will prevent the image from being compressed in the production build step.

What you can also do is to use the embedded Texture and use Graphics.textureToCanvas to create a canvas element that can be displayed in your HTML

This topic was automatically closed 13 days after the last reply. New replies are no longer allowed.