[Released] OneJS: Typescript + React (JSX) for Unity

As a react developer… I have never hit purchase on an asset as quickly as I did here! Thank you so much to your team for sharing this with us!

I was wondering if there was an issue with your discord link? I tried to join but the link doesn’t seem to be working.

1 Like

Tyvm! The Discord link https://discord.gg/Nm5VdgMywa is working well on my side (just tried with a new browser session). Let me know if the problem persists for you. Hopefully it’s just a temporary/local issue.

1 Like

Ahh yes it works now. It was a local issue!

1 Like

Does this have debugging support for the js files? Is there anyway I can hookup some breakpoints?

Not right now. But debugger support based on Jither’s work (https://github.com/sebastienros/jint/pull/1113) is in the works. No specific ETA at this point yet, but some time in 2023 is safe to assume.

Have you done any testing on performance when heavily using the ts scripting? This actually looks like a pretty nice alternative to lua for a game built around modding. Typescript is productive enough (imo) you could move a lot of gameplay code to user accessible ts files if the performance is there.

Most of the testing so far has been on the UI side of things. OneJS works pretty well with UI Toolkit since it’s retained-mode UI, and you are not forced to do things every frame. I have some general notes about performance considerations here: https://github.com/DragonGround/OverwatchSample/blob/8a081fdc0351d134489bc9afe886130232ff2037/CharacterStats.tsx#L12

You can also refer here for benchmarks about Jint, the JS interpreter that OneJS uses.

Hello. Can the script packed into assetbundle which will be loaded from cloud runtime, and will it work on IOS in that case. ?
As for example other similar plugin(such as Bolt) not supporting this case, as IOS blocks not compiled scripts.

Hi @art1997 ! For completeness, I’m just pasting here some Discord messages we already exchanged. Jint is the JS interpreter that’s used under-the-hood, and it works on mobile and AOT platforms. OneJS has a built-in bundler that basically bundles your working TS directory and extracts it to persistentDataPath for standalone app runtime. However you want to bundle your scripts is up to you! At the end of the day, they are just text files.

1 Like

Thanks for this fantastic asset. I spent lots of time designing complex UI in Unity’s UGUI solution. It was a terrible experience most of the time. As a former front-end developer, after I saw your UI solution, I immediately bought it, and I think it has a bright future.

I like that the separation between UI and logic works great in Unity and Onejs. Also, I believe the most productivity of using OneJs + Preact will be seen in rendering repetitive elements such as lists with 1000+ elements, and 100+ cards… in Unity.

Although I worked for some time on it, I couldn’t quite know how to approach some parts of the architecture. For example, If I want to spawn a popup element that I designed using OneJs, how can I do it as this in the logic part?

Example:

...

return (
    <Popup ref={ref} title={popupTitle} desc={popupDesc} />
)

and in a MonoBehaviour script:

CreatePopup("title here", "description here");

In this case, the logic part will be sending the props to the UI, and with that, We’ll be able to create as many popups as we want. To implement that, do I need to spawn a UIDocument and set its elements manually in C# since I couldn’t find a way to interact with TSX in C#?

Another example is, after designing a shop panel using OneJs, if I want to create multiple item elements inside it dynamically, how can I do it in C#?

Example:

SpawnPanel(cards: new Card[100] { new Card("Sword"), new Card("Pistol") ... });

This way, the UI components will be mostly modular and will allow me to use the same component in different areas such as one for the shop panel, one for the collections panel, etc.

Thanks for the kind words. And Happy Turkey Day!

In general, I always separate game logic from UI. With OneJS, I put 100% of UI code in JS and never call UI code from C#. In other words, C# is used for game logic only and, when state changes, events are fired. JS code subscribe to these events and changes the UI accordingly.

The act of opening a Popup can be kept in JS-land as it’s pure UI logic. (Btw, A simple Modal example can be found on the community wiki: https://github.com/DragonGround/ScriptLib/wiki/Simple-Modal-Example )

(I’m pasting some past conversations from our Discord):

UI is a way to present game state to the player and also a way for them to make some input to change the game state. In OneJS context, a good (simplified) architecture is like this:

A good way to think about this is that if you replace UI and Input with AI or Test Actors, everything will still work out very cleanly. Game Logic sits at the top of the dependency chain (it depends on nothing) while UI is always at the bottom (it depends on almost everything: core logic, input, rendering, physics, audio, etc…)

Changing public APIs in the Game Logic will have a cascading effect on everything that depends on it. But changing UI code will not have any effect on others since nothing depends on it. (This is also why UI code can have the fastest iteration speed, especially as your project grows)

Anyhow, let me know if this helps. And hop in or search around in our Discord if you haven’t already.

3 Likes

I know OneJS implemented loading style sheets from string, which UI Toolkit still does not support.

Question: Can I use this style sheet loader independently from OneJS?
Use case: I have my UI already in UI Toolkit, but would like runtime loaded style sheets for user defined themes.

I am considering to buy OneJS specifically for this feature.

Yes, in OneJS there’s a public class and method you can use to build the StyleSheet at runtime. Here’s the actual code for OneJS’s document.addRuntimeUSS(string uss):

public void addRuntimeUSS(string uss) {
    var ss = ScriptableObject.CreateInstance<StyleSheet>();
    var builder = new OneJS.CustomStyleSheets.CustomStyleSheetImporterImpl();
    builder.BuildStyleSheet(ss, uss);
    if (builder.importErrors.hasErrors) {
        Debug.LogError($"Runtime USS Error(s)");
        foreach (var error in builder.importErrors) {
            Debug.LogError(error);
        }
        return;
    }
    _runtimeStyleSheets.Add(ss); // List<StyleSheet>
    _root.styleSheets.Add(ss); // VisualElement
}

There is limitation around the use of paths/urls/resources which you can refer to here: https://onejs.com/docs/runtimeuss#limitations

1 Like

it is possible to use it on world position? for like vr UI?

I have this addon but failing to see how I can use it effectively maybe not enough examples, I use ugui and extensions for that like new widgets ui etc… which add a lot of useful rich components to utilize… also hate react so that doesn’t help but I suppose maybe there is a combination of using other react libraries, suppose I want to see something more than jsut the basics of buttons and sliders… like a real rich interface with scrollviews and datatables nothing really sells it to me on spending my time with it.