在UnityEditor下热更Lua代码.自动

源文出自:https://zhuanlan.zhihu.com/p/91022294,进行修改了,针对自身项目进行修改了,本文为记录

此脚本挂到场景中:FileWatcher
using UnityEngine;
using System.IO;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// 监听文件改变
/// </summary>
public sealed class FileWatcher : MonoBehaviour
{
#if UNITY_EDITOR_WIN 
    class WatchInfo
    {
        FileSystemWatcher watcher;
        string fileter;
        List<string> changeFiles;
        System.Action<string> changeAction;
        string dirPath;
        public WatchInfo(string _dirPath, string _filter, System.Action<string> _changeAction)
        {
            watcher = new FileSystemWatcher();
            changeFiles = new List<string>();
            fileter = _filter;
            dirPath = _dirPath;
            changeAction = _changeAction;
            CreateWatcher(watcher, dirPath, changeFiles, fileter);
        }
        public void UpdateLs()
        {
            if (changeFiles.Count > 0 && null != changeAction)
            {
                foreach (var changeFile in changeFiles)
                {
                    changeAction(changeFile);
                }
                changeFiles.Clear();
            }
        }
        private void AddToLs(List<string> ls, string elem)
        {
            if (!ls.Contains(elem))
            {
                ls.Add(elem);
            }
        }
        private void CreateWatcher(FileSystemWatcher watcher, string path, List<string> changeLs, string fileFilter)
        {
            CreateWatcher(watcher, path, fileFilter, (object source, FileSystemEventArgs e) =>
            {
                AddToLs(changeLs, e.FullPath);
            }, (object source, RenamedEventArgs e) =>
            {
                AddToLs(changeLs, e.FullPath);
            });
        }
        private void CreateWatcher(FileSystemWatcher watcher, string path, string fileFilter, FileSystemEventHandler onChanged, RenamedEventHandler onRenamed)
        {
            watcher.Path = Path.GetFullPath(path);
            watcher.NotifyFilter = NotifyFilters.LastWrite;
            watcher.Filter = fileFilter;
            watcher.IncludeSubdirectories = true;
            watcher.Changed += onChanged;
            watcher.Created += onChanged;
            watcher.Deleted += onChanged;
            watcher.Renamed += onRenamed;
            // Begin watching.
            watcher.EnableRaisingEvents = true;
        }

    }
    private static FileWatcher _instance;
    private List<WatchInfo> watchInfos = new List<WatchInfo>();
    public static void Create(GameObject go)
    {
        _instance = go.AddComponent<FileWatcher>();
    }
    string codePath = @"G:\AOE_SLG\logicenv\UnityLogic\Assets\LuaScripts";
    IEnumerator Start()
    {
        watchInfos.Add(new WatchInfo(codePath, "*.lua", (changeCode) =>
        {
            string s =  System.IO.Path.GetFileNameWithoutExtension(changeCode);//文件名  
            LuaInterface.LuaState L = LuaClient.GetMainState();
            L.Call("OnCodeChange", s, true);//传入Lua中    
        }));
        yield return null;
    }
    void LateUpdate()
    {
        foreach (var watcher in watchInfos)
        {
            watcher.UpdateLs();
        }
    }
# endif
}

这个Lua脚本要启动时加入呀.require(“HotCode”)

local function setFuncUpValue(newFunc, oldFunc)
    local uvIndex = 1
    while true do
        local name, value = debug.getupvalue(oldFunc, uvIndex)
        if name == nil then
            break
        end
        debug.setupvalue(newFunc, uvIndex, value)
        uvIndex = uvIndex + 1
    end
end
function OnCodeChange(codePath)
    for file, _ in pairs(package.loaded) do
        local data = string.split(file, ".")
        if IsListHasContains(data, codePath) then
            local oldCodeObj = package.loaded[file]
            package.loaded[file] = nil
            xpcall(function()
                local newCodeObj = require(file)
                for k, v in pairs(newCodeObj) do
                    if type(v) == "function" and oldCodeObj[k] ~= v then
                        setFuncUpValue(v, oldCodeObj[k])
                        oldCodeObj[k] = v
                    end
                end
            end, function()
                logerror(debug.traceback())
            end)
            package.loaded[file] = oldCodeObj
        end
    end
end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值