Tencent / puerts

PUER(普洱) Typescript. Let's write your game in UE or Unity with TypeScript.
Other
4.79k stars 682 forks source link

global object in javascrript #1734

Open Avatarchik opened 1 month ago

Avatarchik commented 1 month ago

detail | 详细描述

How can I specify a global object from C# so that it is available in JavaScript? MoonSharp example _scriptEngine.Globals["Engine"] = this;

chexiongsheng commented 1 month ago

There is no direct support, you can achieve this by calling js functions from c#. ps: It is not recommended to change global, whether from C# or js.

Avatarchik commented 1 month ago

Can you show an example for Unity? How can I do this or how can I pass an instance object to javascript by reference How can I do or do I want to make an API for modding the game?

chexiongsheng commented 1 month ago

js function

function setGlobal( key, value) {
    globalThis[key] = value;
}

Assign setGlobal to C# as a Action<string, object> variable, then call this delegate variable in C#.

Avatarchik commented 1 month ago

Hi! Thank you!

   private Action<string, object> setGlobal;

   jsEnv.Eval(@"
            global.setGlobal = function(key, value) {
                global[key] = value;
            }
               ");

                setGlobal = jsEnv.Eval<Action<string, object>>("setGlobal");

                setGlobal("Engine",this);

                jsEnv.Eval(@"
                  Engine.AddDATFile(""res:/main.dat"")
                ");

When calling a function it throws an error jsEnv.Eval(@" Engine.AddDATFile(""res:/main.dat"") ");

System.Exception: :-1: TypeError: not a function

chexiongsheng commented 1 month ago

AddDATFile is non public ? It is ok in my project.

Avatarchik commented 1 month ago

yes I'm using a dotnet project, a console application

PUERTS_GENERAL;

public void AddDatFile(string url, bool isCache = false) { }

Can you post your example please?

chexiongsheng commented 1 month ago

Add testcase to https://github.com/Tencent/puerts/blob/master/unity/test/Src/Cases/CrossLang/CrossLangTest.cs

        private string _url;

        public void AddDatFile(string url, bool isCache = false)
        {
            _url = url;
        }

        [Test]
        public void SetToGlobal()
        {
            var jsEnv = UnitTestEnv.GetEnv();

            jsEnv.Eval(@"
              global.setGlobal = function(key, value) {
                  global[key] = value;
              }
            ");

            var setGlobal = jsEnv.Eval<Action<string, object>>("setGlobal");

            setGlobal("Engine", this);

            jsEnv.Eval(@"
                  Engine.AddDatFile(""res:/main.dat"")
                ");
            Assert.AreEqual("res:/main.dat", _url);
        }

do test

cd puerts\unity\test\dotnet
node ../../cli dotnet-test v8_9.4