首页 > 其他分享 >奇技淫巧-Unity运行时运行自定义lua代码

奇技淫巧-Unity运行时运行自定义lua代码

时间:2022-09-21 12:56:31浏览次数:67  
标签:socket 自定义 代码 py lua Unity using null

  在利用lua开发游戏的过程中经常会遇到需要查询某些数据或调用某些方法,以往查询数据的方法不是用断点就是写好代码后重新运行游戏,lua的断点被吐槽太卡顿,我用的也比较少,重新运行游戏效率太低,这里可以利用lua的doString方法实时运行你想要执行的lua代码,最简单的方法就是在UnityEditor下写一个输入框,在这里输入代码后执行doString即可,下面说一个更方便的方法。

  利用sublime+upd远程执行lua代码

  首先需要了解sublime的build,点击Tools-BuildSystem-NewBuildSystem,把下面代码拷进去,udp.py的路径要改成本地真实路径,后面会提到,这里实际就是在sublime中build的时候会调用udp.py这个脚本,新建好之后点击Tools-BuildSystem,选中你刚刚新建的buildSystem。

{
	"shell_cmd": "python E:/udp.py"
}

  接下来是udp.py,这里实际是读取同目录下的sendToUnity.lua文本并将文本内容发送到127.0.0.1::8001上,sendToUnity.lua无任何要求,只要是lua代码即可,udp.py的路径可以放在磁盘根目录,也可以放项目工程里,这个无所谓,注意事项是sendToUnity.lua和udp.py必须在同一个目录,因为upd.py代码中是从自身目录下打开sendToUnity.lua的

import sys
defaultencoding = 'utf-8'
if sys.getdefaultencoding() != defaultencoding:
    reload(sys)
    sys.setdefaultencoding(defaultencoding)
    
import socket

with open('./sendToUnity.lua',"r", encoding='utf-8') as f:
	str = f.read()
msg = str


BUFSIZE = 1024
client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)


ip_port = ('127.0.0.1', 8001)
client.sendto(msg.encode('utf-8'),ip_port)

client.close()

  完成以上步骤后,sublime的配置就已经完成了,接下来是Unity开启udp接收代码并运行,这里也直接贴出C#代码,这个代码是不能直接用的,会缺少一些类,自己改一下也很简单。游戏运行时调用StartUdpServer,游戏关闭时调用CloseUdpServer,close是必须调用的,不然子线程会一直运行,另一个问题是MainDriver.Instance.Invoke(() => GameLuaManager.instance.GetLuaState().DoString(str))这行代码,这里只是把DoString的操作放在了主线程,也必须在主线程执行lua,否则日志不显示,Unity的组件也无法用。由于不同lua框架,doString可能在不同的类里,这里需要自己去找一下了。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Text;
using Comlib;

public class LuaDebug
{
    static UdpServer udpServer = null;
    public static void StartUdpServer()
    {
        if (SystemConfig.IsDebug)
        {
            GLog.Info("StartLuaUdp");
            if (udpServer == null)
            {
                udpServer = new UdpServer();
                udpServer.Start();
            }
        }
    }

    public static void CloseUdpServer()
    {
        if (SystemConfig.IsDebug)
        {
            GLog.Info("CloseLuaUdp");
            if (udpServer != null)
            {
                udpServer.Close();
                udpServer = null;
            }
        }
    }
}

public class UdpServer
{
    Socket socket = null;
    EndPoint ipany;
    bool isServer = false;

    public void Start()
    {
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        IPEndPoint ip = new IPEndPoint(IPAddress.Any, 8001);
        socket.Bind(ip);

        IPEndPoint end = new IPEndPoint(IPAddress.Any, 0);
        ipany = (EndPoint)end;

        isServer = true;
        Thread ReceiveListern = new Thread(Receive);
        ReceiveListern.Start();
    }

    public void Close()
    {
        isServer = false;
/*        if (socket.Connected)
        {
            socket.Disconnect(false);
        }*/
        if(socket != null)
        {
            socket.Close();
            socket.Dispose();
            socket = null;
        }


    }

    private byte[] byt = new byte[1024];
    private void Receive()
    {
        while (isServer)
        {
            if (socket != null)
            {
                if (socket.Available <= 0) continue;
                int length = socket.ReceiveFrom(byt, ref ipany);
                if (length > 0)
                {
                    string str = Encoding.UTF8.GetString(byt, 0, length);
                    MainDriver.Instance.Invoke(() => GameLuaManager.instance.GetLuaState().DoString(str));
                }
            }
            
        }
    }
}

  以上步骤都完成后,用sublime打开sendToUnity.lua,输入print("this is a lua msg"),ctrl+b,这时unity就会打印这条日志了,同理也可以打印某些游戏数据,调用你想执行的方法,甚至可以替换现有的方法

  如果upd.py里的ip改成同一个局域网手机的ip,就可以直接联调手机了

标签:socket,自定义,代码,py,lua,Unity,using,null
From: https://www.cnblogs.com/muhoor/p/16715211.html

相关文章