Unity Hot update Ulua on the pit

Source: Internet
Author: User
Tags lua naming convention require static class

Unity's native C # cannot be hot-updated on the mobile side, then if the online release encounters a major flash-back accident, then you can not through the in-game hot update bug fix, can only resubmit the version, and often in the submission version to release time, there must be players encounter this problem, resulting in loss, For the team, this is very serious.

So I Google, now there are developers to achieve this function, there are c#light, Ulua,nlua and so on, Lua can be said to be very successful in the Cocos, and the strong interaction with C + +, the ability of small and high speed, in the C + + embodiment of very good.

Recently began to engage in unity, learning the next Ulua (Ulua, data), putting aside Luajit 64-bit pits. First, open ulua_v1.08.unitypackage, import Ulua, as shown in figure:

The Ulua folder contains some examples, as well as luainterface documentation that you can learn.

After the import is successful, we create a new folder scripts, create a new Lua file

, and then create a new C # file in the subfolder global, then in order to invoke the Luaenterance.lua file in C #, you have to include code in C # and introduce namespaces using Luainterface so that you can call luascriptmgr. It is recommended that you declare the Luascriptmgr object as a class member. Then compile it, no problem. Then run the program and find the first pit.

	void Start ()
	{
		mgr = new Luascriptmgr ();
		Mgr. Start ();
		Mgr. Dofile ("Luaenterance.lua");

	}

When you run the Dofile function, get the path of the file through

 	Luadll.lua_pushstdcallcfunction (l,tracebackfunction);
        int Oldtop=luadll.lua_gettop (L);

            Load with Unity3d resources            
        byte[] Text = Luastatic.load (fileName);

Using Deletage, a function pointer similar to C + +

Public delegate byte[] Readluafile (string name);
	
	public static class Luastatic
	{public
        static readluafile Load = null;
        private static int trace = 0;

        Static luastatic ()
        {
            Load = Defaultloader;
        }

        Static byte[] Defaultloader (string name)
        {
            byte[] str = NULL;
            String path = Util.luapath (name);

            using (FileStream file = new FileStream (path, FileMode.Open))
            {
                str = new byte[(int) file. Length];
                File. Read (str, 0, str. Length);
                File. Close ();
            }

            return str;
        }


Then in order to get the exact path, call Util.luapath,

    <summary>
    ///Get LUA path
    ///</summary> public static string Luapath (string name) {
        String path = Application.datapath + "/";
        String lowername = name. ToLower ();
        if (Lowername.endswith (". Lua")) {
            return path + "lua/" + Name;
        }
        Return path + "lua/" + name + ". Lua";
    }

I finally found out that Dofile always went to the Lua folder to find LUA files, which was not free. Of course I think of other possibilities, perhaps the author has handled the Ulua package, and the Lua folder files have special benefits. Or it has something to do with unity's mechanism. It is not clear yet.

Regardless of these circumstances, we can do a simple processing.

	void Start ()
	{
		mgr = new Luascriptmgr ();
		Mgr. Start ();
		Mgr. Dofile (Reviseluapath ("Luaenterance.lua"));
	}

	public void Doluafile (string filepath)
	{
		if (mgr! = null)
			Mgr. Dofile (Reviseluapath (filepath));
		else
			Debug.Log ("Doluafile error! PLZ Create luascriptmgr First ");
	}

	public string Reviseluapath (string path)
	{
		Return]: /scripts/"+ Path;
	}
Then run it and find out ...

Then proceed to the next step, running the LUA function in C #, first defining a function in the Lua file

and get it in C #

	Private Luafunction funcupdate;
	void Start ()
	{
		mgr = new Luascriptmgr ();
		Mgr. Start ();
		Mgr. Dofile (Reviseluapath ("Luaenterance.lua"));
		Funcupdate = Mgr. Getluafunction ("Update");

	}
Then run in update
	void Update ()
	{
		if (mgr! = null)
		{
			funcupdate.call (time.deltatime);
		}
	}
The result is that nothing is output ... Drunk, drunk. If you have a problem, check it.

It is assumed that the update function was not obtained. Look at getluafunction.

Cache luafunction Public
    luafunction getluafunction (string name)
    {
        luabase func = null;

        if (!dict. TryGetValue (name, out func))
        {
            IntPtr L = Lua. L;
            int oldtop = Luadll.lua_gettop (L);

            if (Pushluafunction (l, name))
            {
                int reference = Luadll.lual_ref (L, luaindexes.lua_registryindex);
                Func = new Luafunction (reference, LUA);                
                Func.name = name;
                Dict. ADD (name, func);
            }
            else
            {
                debuger.logwarning ("Lua function {0} NOT exists", name);
            }

            Luadll.lua_settop (L, oldtop);            
        }
        else
        {
            func. AddRef ();
        }

        return func as luafunction;
    }

Every time you get a cached Lua function, you try to get it from dictionary<string, Luabase> dict, and then the key is based on the name you passed in, so the question is, what about the same name function under different files? Because some functions are ulua built-in, are under the _g, sometimes accidentally can be named consistent, the problem here is also because of this caused, Ulua with a Main.lua file, the Lua file has a function of the same name update. So what we getluafunction actually get is this function. Because its first is called and exists in Dict.  look! There's a luascriptmgr in this.

   public void Start () {onbundleloaded ();
        } void Onbundleloaded () {dofile ("Golbal.lua");
        UNPACKVEC3 = Getluafunction ("Vector3.get");
        UNPACKVEC2 = Getluafunction ("Vector2.get");
        UNPACKVEC4 = Getluafunction ("Vector4.get");
        Unpackquat = Getluafunction ("Quaternion.get");
        Unpackcolor = Getluafunction ("Color.get");

        Unpackray = Getluafunction ("Ray.get");        
        PACKVEC3 = Getluafunction ("vector3.new");
        PACKVEC2 = Getluafunction ("vector2.new");
        PACKVEC4 = Getluafunction ("vector4.new");
        Packquat = Getluafunction ("quaternion.new");
        Packraycasthit = Getluafunction ("raycast.new");
        Packcolor = Getluafunction ("color.new");
        Packray = Getluafunction ("ray.new");

Packtouch = Getluafunction ("touch.new"); #if!
Multi_state traceback = getluafunction ("Traceback");
        #endif dofile ("Main.lua");
        Callluafunction ("Main"); UpdAtefunc = Getluafunction ("Update");
        Lateupdatefunc = Getluafunction ("Lateupdate");
        Fixedupdatefunc = Getluafunction ("Fixedupdate");
    levelloaded = Getluafunction ("onlevelwasloaded"); }

It has loaded some basic Ulua library files and also ran Main.lua, which caused this error.

How to resolve. This problem can be avoided through a unified naming convention. Once also thought that according to Dofile name to sail for the getluafunction, but also have the problem, is require, because LUA require do is almost also dofile dry things, so the positioning is not accurate, prone to problems, so give up, It feels better to be normative.

Later I tested the next Ulua, the results found also have problems, error. The Red fork looks really uncomfortable.


Write a Coroutine test code first. The discovery was cut off in wait. = =.

Change and change. Repair and repair.

Coroutine.start automatically creates a new process for the incoming function as a coroutine.create parameter, and immediately resume execution, enters the test function, outputs "a simple coroutine test", and then wait, Rely on Cotimer, calculate the time, here need to do a processing: in C # execution

	void Update ()
	{
		if (mgr! = null)
		{
			mgr. Update ();
		}
	}
	
	void Lateupdate ()
	{
		if (mgr! = null)
		{
			mgr. Lateupate ();
		}
	}
Lateupdate purpose is to execute coupdatebeat (), this function is placed in main, otherwise Cotimer will not be updated,

Update is intended to set deltatime, otherwise the deltatime in Lua will always be 0, affecting the timer.

Then modify several places and add a function to the Functions.lua

Look at Cotimer.

Start is dependent on coupdatebeat, and Coupdatebeat is an event, and add is declared in the event, called functor, and then modified

In the 44 lines, using the handler just defined to let xpacall, so that all the parameters of the function, all become the invisible parameter (ignore the hidden argument self) function, more importantly, to solve the Cfunc and Luafunc call problem, You can refer to the QUICK-COCOS2DX approach.

Modify again

Also use handler to construct Cotimer, the above is to solve the problem of self-loss of cotimer:update.

Last Run ...

The time error here is because Lua uses os.clock, and wait is based on unity, which is exactly what the frame rate is, and the 1s has gone through unity, so it's a matter of unity.

over~~~~~

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.