Skip to content
provide typescript support for unity dynamic scripting
C JavaScript C# Python C++ CMake Other
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.vscode
cmake
duktape-2.3.0
examples/echoserver/src
res
scratch
thirdparty
unity
.gitignore
CMakeLists.txt
LICENSE
README.md
README_CN.md
TODO
configure_duktape.bat
configure_duktape_scratch.bat
make_duktape_android.sh
make_duktape_ios.sh
make_duktape_osx.sh
make_duktape_scratch.bat
make_duktape_windows_x64.bat
make_duktape_windows_x86.bat

README.md

中文说明

Brief

Integerate duktape (an embedded javascript engine) into unity, you can load and run javascript at runtime.
Typescript is a preferred choice, it provides type checks.

editing script

Features

  • nodejs-like module or browser-like singular js depends on you
  • generate C# to js type binding code, and coresponding d.ts type definition files
  • setTimeout/setInterval/clearTimeout/clearInterval compatible
  • c# delegates
  • optimized unity common valuetypes (Vector2/3,Quaternion,Color...)
  • fixed-point math support (libfixmath)
  • websocket (libwebsockets)
  • iOS (64bit, bitcode)
  • Android (v7a, v8a, x86)
  • live debugger (vscode) (not implemented)
  • tcp (not implemented)
  • udp with kcp (not implemented)

You can use lots of pure js libraries in your project, such as protobufjs. protobufjs

Type definition files

The generated d.ts files will improve auto-complete. It will give the information of exposed types from C# and C.

  • delegate type information type definition files
  • generic constraints for out/ref parameter type definition files
  • friendly interface for AddComponent/GetComponent type definition files

Environments

If you use typescript, install typescript at first

npm install -g typescript

If you need to compile duktape source code, python/pip/pyyaml is prerequisites.

pip install pyyaml

# duktape-2.3.0/src-input: duktape source code
# duktape-2.3.0/src-custom: combined duktape source code
./configure_duktape.bat 
./make_duktape_<platform>

'./scratch' is a playground for duktape testing in a simple command line app.

./configure_duktape_scratch.bat
./make_duktape_scratch.bat

Sample code

// if your tsconfig.json defined {"module": "commonjs"}, you can 'import' modules like node-js. 

// import module
import { B } from "base/b"
// import module with relative path (. or ..)
import { C } from "./base/c"

class MyPlayer {
    Start() {
        console.log("MyPlayer.Start")
        this.Jump()
    }

    // Update() {
    // }

    Jump() {
        console.log("MyPlayer.Jump")
    }
}

export class A {
    private go: GameObject
    constructor () {
        this.go = new GameObject("test go")
        this.go.transform.localPosition = new Vector3(1, 2, 3) 
        // use Bridge to receive Enable/Disable/Update 
        // don't use the approach a lot, it's better to dispatch futher logic in a single Bridge
        this.go.AddComponent(DuktapeJS.Bridge).SetBridge(new MyPlayer()) 

        let f = new Custom()
        // you can assign function to c# delegate
        f.onopen = function () {
            // ...
        }
        // if you want to register multiple listener, use DuktapeJS.Dispather 
        // you can also use typed Dispatcher generated in _DuktapeDelegates.d.ts, it provides type checks
        f.onload = new DuktapeJS.Dispatcher1<void, string>() 
        f.onload.on(this, this.onload)  // add listener
        f.onload.off(this, this.onload) // remove listener
        f.onload.off(this)              // clear all listeners of this
        f.onload.clear()                // clear all

        // 'out' parameter in c#
        let v = {}
        if (System.Int32.TryParse("123", v)) {
            console.log(v.target)
        }
    }

    private onload(ev: string) {
        let timer1 = setInterval(() => {
            console.log("interval")
        }, 1000)

        setTimeout((a, b) => {
            console.log("timeout", a, b)
            clearInterval(timer1)
        }, 5000, "Arg1", 123)
    }

    square() {
        console.log("A.square")
    }
}

// websocket
let ws = DuktapeJS.WebSocket()
ws.on("open", () => {
    console.log("connected")
    setInterval(() => {
        ws.send("hello, world") // string or buffer 
    }, 1000)
})
ws.on("data", data => {
    console.log("ws receive data", data) // string or buffer (depends on websocket message type you use)
})
ws.on("close", () => {
    console.log("connection lost")
})
ws.connect("ws://127.0.0.1:8080/echo")
setInterval(() => {
    ws.poll()
}, 50)

Dev status

It's not stable enough, do not use it in production environment.
Vector2/Matrix3x3/Matrix4x4/Quaternion valuetypes optimization is partially written in c, and not fully tested.

Usage

Execute menu item [Duktape -> Generate Bindings] to generate binding code. Typescript source files will be compiled into js after your modification and switch back to Unity Editor.

How to customize exported types

  • duktape.json modify the basic configuration at ProjectSettings\duktape.json (details in Assets\Duktape\Editor\Prefs.cs)
{
    "outDir": "Assets/Source/Generated",
    "implicitAssemblies": [
        "UnityEngine.CoreModule"
    ], 
    "explicitAssemblies": [
        "Assembly-CSharp"
    ],
    "tab": "    "
}
  • implements Duktape.IBindingProcess interface or extends AbstractBindingProcess class
public class MyCustomBinding : AbstractBindingProcess
{
    public override void OnPreCollectTypes(BindingManager bindingManager)
    {
        /*
        bindingManager.AddExportedType(typeof(MyCustomClass));
        bindingManager.TransformType(typeof(MyCustomClass))
            .SetMethodBlocked("AMethodName")
            .SetMethodBlocked("AMethodNameWithParameters", typeof(string), typeof(int))
        */
    }

    public override void OnCleanup(BindingManager bindingManager)
    {
        Debug.Log($"finish @ {DateTime.Now}");
    }
}

Sample scene

Assets/Scenes/main.unity (Sample.cs) demonstrate the basic usage.

Referenced libraries

Misc.

You can’t perform that action at this time.