ialex32x / unity-jsb

It brings Javascript runtime capability to Unity3D by integrating QuickJS.
MIT License
335 stars 41 forks source link

Unity methods are not called when inheriting from my MonoBehaviour-class #75

Closed aleverdes closed 2 years ago

aleverdes commented 2 years ago

@ialex32x Hi!

I am trying to put together my test logic. Faced a problem. If I create a class based on MonoBehaviour, then the Awake, OnEnable, etc. are called. If I make the class a successor of my MonoBehaviour (empty) successor, then the methods stop being called.

What am I doing wrong?

"use strict";
const UnityEngine = require("UnityEngine");
const Test = require("Test);
const jsb = require("jsb");
// let TestSceneLogic = class TestSceneLogic extends Test.SceneLogic {
let TestSceneLogic = class TestSceneLogic extends UnityEngine.MonoBehaviour {
    constructor() {
        super(...arguments);
        this.vv = 0;
        this._tick = 0;
    }
    Awake() {
        this.vv = 0;
        this._tick = 0;
        console.log("TestSceneLogic.Awake", this._tick++);
    }
    async OnEnable() {
        console.log("TestSceneLogic.OnEnable", this._tick++);
        await jsb.Yield(new UnityEngine.WaitForSeconds(1));
        console.log("TestSceneLogic.OnEnable (delayed)", this._tick++);
        this.test();
    }
    OnDisable() {
        console.log("TestSceneLogic.OnDisable", this._tick++);
    }
    OnDestroy() {
        console.log("TestSceneLogic.OnDestroy", this._tick++);
    }
    OnApplicationFocus(hasFocus) {
        console.log("OnApplicationFocus:", hasFocus);
    }
    OnApplicationPause(pause) {
        console.log("OnApplicationPause:", pause);
    }
    speak(text) {
        console.log("modified", text);
    }
    async test() {
        console.log("TestSceneLogic.test (will be destroied after 5 secs.", this.transform);
        await jsb.Yield(new UnityEngine.WaitForSeconds(5));
        UnityEngine.Object.Destroy(this.gameObject);
    }
};

console.log("Example TestSceneLogic");

let gameObject = new UnityEngine.GameObject();
let sceneLogic = gameObject.AddComponent(TestSceneLogic);

You need to uncomment line 5, and comment out line 6.

namespace Test
{
    public class SceneLogic : MonoBehaviour
    {
        public TestBehaviour TestBehaviour;

        public void Awake()
        {
            Debug.LogError("TEST");
        }

        protected void ProtectedMethod()
        {
            Debug.LogError("ProtectedMethod");
        }

        public void PublicMethod()
        {
            Debug.LogError("PublicMethod");
        }
    }
}
ialex32x commented 2 years ago

Hi @aleverdes, the classes from scripts could only directly extends MonoBehaviour by default for now.

It's possible to extend custom user classes, but a binding class (like JSBehaviour) is required as an adapter to achieve this for each. And it seems hard to implement it as a generic solution.

aleverdes commented 2 years ago

Thank you! Just got to the bottom of JSBehaviour and was trying to figure out how it works. Perhaps I will try to implement a clone class for myself for my needs, or a universal solution.