Lua1.0使用与研究-array

本文详细介绍了Lua语言中数组的实现方式,包括使用table作为数组的基础结构、数组元素的动态增长特性及下标设置的灵活性。此外,还展示了如何利用next函数遍历数组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先看一下array.lua的代码

$debug
a = @()
i=0
while i<10 do
 a[i] = i*i
 i=i+1
end

r,v = next(a,nil)
while r ~= nil do
 print ("array["..r.."] = "..v)
 r,v = next(a,r)
end


$debug

    --在lua中起什么作用,暂时不清楚 2012.08.16
a = @()
    --在lua中起什么作用,暂时不清楚,但是根据代码上下文,应该是定义了一个数组a
      2012.08.16
    --定义table的语法,Lua通过table来实现数组
    --在Lua中习惯上数组的下标从1开始,Lua的标准库与此习惯保持一致。
      因此如果你的数组下标也是从1开始你就可以直接使用标准库的函数,
      否则就无法直接使用
    
i=0
while i<10 do
 a[i] = i*i
 i=i+1
end
    --上面这个代码在非交互式模式下,是一个语句块,在交互模式下i=0应该是一个独立的
      语句块。这些概念我是在lua5.1手册看到。先不管 2012.08.16
    --实现了为数组a的赋值
    --需要仔细关注table的

r,v = next(a,nil)
    --next是一个什么函数?作用?2012.08.16
    --在代码里应该是返回数组a的索引和值,因为lua里function可以返回多个值。2012.08.16
    --next(a,nil)应改返回数组a的第一个索引以及第一个值。2012.08.16
    --lua5.1 11..1
      --且数组不必事先指定大小,大小可以随需要动态的增长
      --可以根据需要定义数组的下标从0,1或者任意其他的数值开始
    --next的实现在hash.c文件lua_next函数
    
print ("array["..r.."] = "..v)
    --首先..是一个连接符号,挺像c++,java里的多个字符串相加的效果。
    --如果连接符号左右是数字,数值,将转化为字符串。2012.08.16
    --比c里打印数值要简单,如何实现打印不同格式的数值呢?2012.08.16

貌似lua代码里不支持中英文混排,起码在lua1.0里是这样。




using UnityEngine; using System; using System.Collections; //using System.Collections.Generic; using XLua; namespace LuaFramework { [LuaCallCSharp] public class ResourceManager : Manager { public static ResourceManager _instance; public LuaFunction onDestroy; private WWW _www; private LuaFunction onProgress; void Awake() { _instance = this; } public static ResourceManager Instance { get { return _instance; } } public void CreatUIObject(string UIPath, string objname, LuaFunction callBack = null) { #if UNITY_EDITOR if (!AppConst.UpdateMode) { string path = "datingui_" + AppConst.UIVersion.ToString() + "/" + UIPath + objname; UnityEngine.Object prefab = Resources.Load(path, typeof(GameObject)); if (prefab != null) { //GameObject obj = Instantiate(Resources.Load<GameObject>(path)); //if (obj != null) //{ GameObject obj = Instantiate(prefab) as GameObject; obj.transform.localScale = Vector3.one; obj.transform.localPosition = Vector3.zero; if (callBack != null) { callBack.Call(obj); } //} }else { if (callBack != null) { callBack.Call(null); } } }else { StartCoroutine(LoadObj(AppConst.FrameworkRoot + "/datingui_" + AppConst.UIVersion + "/" + UIPath + objname + ".u3d", objname, callBack)); } #else StartCoroutine(LoadObj(AppConst.FrameworkRoot + "/datingui_" + AppConst.UIVersion + "/" + UIPath + objname + ".u3d", objname, callBack)); #endif } public void CreatGameObject(string GameName, string path, string objname, LuaFunction callBack = null) { #if UNITY_EDITOR if (!AppConst.UpdateMode) { //try //{ GameObject obj = Instantiate(Resources.Load<GameObject>("gameui"+AppConst.UIVersion+"/" + GameName + "/" + path + objname)); obj.transform.localScale = Vector3.one; obj.transform.localPosition = Vector3.zero; if (callBack != null) { callBack.Call(obj); } //}catch (Exception ex) //{ // Debug.LogError(ex.Message); //} } else { string path_ = AppConst.FrameworkRoot + "/gameui" + AppConst.UIVersion + "/" + GameName + "/" + path + objname + ".u3d"; StartCoroutine(LoadObj(path_, objname, callBack)); } #else string path_ = AppConst.FrameworkRoot + "/gameui"+AppConst.UIVersion +"/" + GameName + "/" + path + objname + ".u3d"; StartCoroutine(LoadObj(path_, objname, callBack)); #endif } public void setProgressUpdate(LuaFunction callback) { onProgress = callback; } public void resetProgressUpdate() { onProgress = null; _www = null; } float jindus = 0.0f; void Update() { #if UNITY_ANDROID if (_www != null && onProgress != null) { onProgress.Call(_www.progress); //Debug.Log(www.progress); } #else //if (jindutiao) // jindutiao.value = jindus; if (onProgress != null) { onProgress.Call(jindus); //Debug.Log(www.progress); } #endif } IEnumerator LoadObj(string bundlePath, string ObjName, LuaFunction callBack = null) { AssetBundle built = null; #if UNITY_ANDROID string path_2 = "file:///" + bundlePath; WWW www = new WWW(@path_2); if (onProgress != null) { _www = www; } yield return www; if (www.error == null) { yield return built = www.assetBundle; } else { Debug.Log("www null-------- " + path_2); } #else string path_ = bundlePath; byte[] data = null;// = OpenFile.GetFileData(path_); if (System.IO.File.Exists(path_)) { System.IO.FileStream file_ = new System.IO.FileStream(path_, System.IO.FileMode.Open, System.IO.FileAccess.Read); data = new byte[file_.Length]; int redline = 0; int allnum = 0; while (true) { byte[] reddata = new byte[1024000]; redline = file_.Read(reddata, 0, (int)reddata.Length); if (redline <= 0) { jindus = 1.0f; break; } else { //Debug.LogError(redline); System.Array.Copy(reddata, 0, data, allnum, redline); allnum += redline; jindus = (float)allnum / (float)data.Length; } yield return null; } file_.Close(); file_.Dispose(); } if (data != null) { yield return built = AssetBundle.LoadFromMemory(data); } #endif if (built != null) { GameObject obj = Instantiate(built.LoadAsset(ObjName)) as GameObject; obj.transform.localScale = Vector3.one; obj.transform.localPosition = Vector3.zero; if (callBack != null) { callBack.Call(obj); } built.Unload(false); }else { if (callBack != null) { callBack.Call(null); } } #if UNITY_ANDROID www.Dispose(); #endif } void OnDestroy() { if (onDestroy != null) { onDestroy.Call(); } } } }using UnityEngine; using System; using System.Collections; //using System.Collections.Generic; using XLua; namespace LuaFramework { [LuaCallCSharp] public class ResourceManager : Manager { public static ResourceManager _instance; public LuaFunction onDestroy; private WWW _www; private LuaFunction onProgress; void Awake() { _instance = this; } public static ResourceManager Instance { get { return _instance; } } public void CreatUIObject(string UIPath, string objname, LuaFunction callBack = null) { #if UNITY_EDITOR if (!AppConst.UpdateMode) { string path = "datingui_" + AppConst.UIVersion.ToString() + "/" + UIPath + objname; UnityEngine.Object prefab = Resources.Load(path, typeof(GameObject)); if (prefab != null) { //GameObject obj = Instantiate(Resources.Load<GameObject>(path)); //if (obj != null) //{ GameObject obj = Instantiate(prefab) as GameObject; obj.transform.localScale = Vector3.one; obj.transform.localPosition = Vector3.zero; if (callBack != null) { callBack.Call(obj); } //} }else { if (callBack != null) { callBack.Call(null); } } }else { StartCoroutine(LoadObj(AppConst.FrameworkRoot + "/datingui_" + AppConst.UIVersion + "/" + UIPath + objname + ".u3d", objname, callBack)); } #else StartCoroutine(LoadObj(AppConst.FrameworkRoot + "/datingui_" + AppConst.UIVersion + "/" + UIPath + objname + ".u3d", objname, callBack)); #endif } public void CreatGameObject(string GameName, string path, string objname, LuaFunction callBack = null) { #if UNITY_EDITOR if (!AppConst.UpdateMode) { //try //{ GameObject obj = Instantiate(Resources.Load<GameObject>("gameui"+AppConst.UIVersion+"/" + GameName + "/" + path + objname)); obj.transform.localScale = Vector3.one; obj.transform.localPosition = Vector3.zero; if (callBack != null) { callBack.Call(obj); } //}catch (Exception ex) //{ // Debug.LogError(ex.Message); //} } else { string path_ = AppConst.FrameworkRoot + "/gameui" + AppConst.UIVersion + "/" + GameName + "/" + path + objname + ".u3d"; StartCoroutine(LoadObj(path_, objname, callBack)); } #else string path_ = AppConst.FrameworkRoot + "/gameui"+AppConst.UIVersion +"/" + GameName + "/" + path + objname + ".u3d"; StartCoroutine(LoadObj(path_, objname, callBack)); #endif } public void setProgressUpdate(LuaFunction callback) { onProgress = callback; } public void resetProgressUpdate() { onProgress = null; _www = null; } float jindus = 0.0f; void Update() { #if UNITY_ANDROID if (_www != null && onProgress != null) { onProgress.Call(_www.progress); //Debug.Log(www.progress); } #else //if (jindutiao) // jindutiao.value = jindus; if (onProgress != null) { onProgress.Call(jindus); //Debug.Log(www.progress); } #endif } IEnumerator LoadObj(string bundlePath, string ObjName, LuaFunction callBack = null) { AssetBundle built = null; #if UNITY_ANDROID string path_2 = "file:///" + bundlePath; WWW www = new WWW(@path_2); if (onProgress != null) { _www = www; } yield return www; if (www.error == null) { yield return built = www.assetBundle; } else { Debug.Log("www null-------- " + path_2); } #else string path_ = bundlePath; byte[] data = null;// = OpenFile.GetFileData(path_); if (System.IO.File.Exists(path_)) { System.IO.FileStream file_ = new System.IO.FileStream(path_, System.IO.FileMode.Open, System.IO.FileAccess.Read); data = new byte[file_.Length]; int redline = 0; int allnum = 0; while (true) { byte[] reddata = new byte[1024000]; redline = file_.Read(reddata, 0, (int)reddata.Length); if (redline <= 0) { jindus = 1.0f; break; } else { //Debug.LogError(redline); System.Array.Copy(reddata, 0, data, allnum, redline); allnum += redline; jindus = (float)allnum / (float)data.Length; } yield return null; } file_.Close(); file_.Dispose(); } if (data != null) { yield return built = AssetBundle.LoadFromMemory(data); } #endif if (built != null) { GameObject obj = Instantiate(built.LoadAsset(ObjName)) as GameObject; obj.transform.localScale = Vector3.one; obj.transform.localPosition = Vector3.zero; if (callBack != null) { callBack.Call(obj); } built.Unload(false); }else { if (callBack != null) { callBack.Call(null); } } #if UNITY_ANDROID www.Dispose(); #endif } void OnDestroy() { if (onDestroy != null) { onDestroy.Call(); } } } }The referenced script on this Behaviour is missing! UnityEngine.Resources:Load(String, Type) LuaFramework.ResourceManager:CreatUIObject(String, String, LuaFunction) (at Assets/Scripts/Manager/ResourceManager.cs:36) CSObjectWrap.LuaFrameworkResourceManagerWrap:CreatUIObject(IntPtr) (at Assets/XLua/Gen/LuaFrameworkResourceManagerWrap.cs:98) XLua.LuaDLL.Lua:lua_pcall(IntPtr, Int32, Int32, Int32) XLua.DelegateBridge:SystemVoid() (at Assets/XLua/Gen/DelegatesGensBridge.cs:32) LuaFramework.LuaManager:Update() (at Assets/Scripts/Manager/LuaManager.cs:111)
最新发布
07-08
<think>我们正在解决Unity中LuaFramework.ResourceManager.CreatUIObject方法导致的"The referenced script on this Behaviour is missing!"错误。根据之前的讨论,这个问题通常脚本命名不一致、Addressable配置或资源加载流程有关。结合用户提供的引用(虽然引用内容问题关联不大),我们将重点关注Unity引擎层面的解决方案。 核心解决方案步骤: 1. **验证脚本文件名类名一致性**(最常见原因) 检查LuaFramework.ResourceManager类对应的脚本文件名是否为"ResourceManager.cs",并确认类定义如下: ```csharp // 文件名: ResourceManager.cs namespace LuaFramework { public class ResourceManager : MonoBehaviour { // CreatUIObject方法实现... } } ``` 2. **Addressable系统配置修复**(关键步骤) 打开Addressable设置:`Window > Asset Management > Addressables > Settings` 修改配置: - 将`Advanced Settings > MonoScript Bundle Naming`设置为`Use Project Name`(或其他非Disabled选项)[^2] 重新构建Addressables资源: - `Addressables Groups`窗口 → `Build` → `New Build` → `Default Build Script` 3. **检查资源加载流程** 定位报错位置:`Assets/Scripts/Manager/ResourceManager.cs`第36行 检查`Resources.Load`调用参数: ```csharp // ResourceManager.cs 第36行附近 GameObject go = UnityEngine.Resources.Load<GameObject>(path); // 确保path路径正确 ``` 验证步骤: - 确认path参数指向的预制体存在于Resources目录 - 检查该预制体是否丢失脚本组件(在编辑器打开预制体查看) 4. **批量修复丢失脚本**(针对已损坏资源) 使用编辑器脚本清理: ```csharp using UnityEditor; using UnityEngine; public class ScriptCleaner : EditorWindow { [MenuItem("Tools/Fix Missing Scripts")] static void CleanMissingScripts() { foreach (GameObject go in Resources.FindObjectsOfTypeAll<GameObject>()) { // 递归处理预制体和场景对象 GameObjectUtility.RemoveMonoBehavioursWithMissingScript(go); } } } ``` 5. **LuaFramework特定修复** 检查Lua层调用CreatUIObject的参数: ```lua -- Lua调用示例: local resMgr = AppFacade.Instance:GetManager("ResourceManager") resMgr:CreatUIObject("UI/Prefabs/MyPanel", "MyPanel", callback) ``` 确保: - 第一个参数路径Unity项目中的Resources目录结构匹配 - 预制体"MyPanel"没有脚本丢失问题 6. **重新生成XLua代码**(排除绑定问题) 删除XLua生成代码:清空`Assets/XLua/Gen`目录 重新生成:菜单栏`XLua` → `Generate Code` 预防措施: - **资源检查器**:为关键预制体添加验证脚本 ```csharp #if UNITY_EDITOR [ExecuteInEditMode] public class PrefabValidator : MonoBehaviour { void OnEnable() { if (GetComponents<MonoBehaviour>().Any(c => c == null)) Debug.LogError($"丢失脚本检测: {name}", this); } } #endif ``` - **Addressable最佳实践**: - 避免直接使用`Resources.Load`,改用Addressables API异步加载 ```csharp // 替换ResourceManager中的加载方式 using UnityEngine.AddressableAssets; public void CreatUIObject(string path, string name, LuaFunction func) { Addressables.InstantiateAsync(path).Completed += (handle) => { // 实例化完成回调 }; } ``` 执行顺序建议: 1. 修复脚本命名 → 2. 配置Addressables → 3. 清理丢失脚本 → 4. 重新生成XLua代码 → 5. 测试加载流程 如果问题仍存在,请检查: - Unity版本兼容性(XLua当前Unity版本匹配) - AssetBundle打包策略(确保包含脚本依赖) 通过以上步骤,可系统解决"The referenced script on this Behaviour is missing!"错误。 §§相关问题§§ 1. 如何彻底解决Unity中Addressable资源系统的脚本丢失问题? 2. XLua框架下如何正确管理资源加载和卸载? 3. Unity预制体脚本丢失的自动化检测方案有哪些?</think>### 解决 Unity LuaFramework ResourceManager.CreatUIObject 脚本丢失错误 #### 一、核心修复步骤 1. **检查脚本命名一致性(首要步骤)** ```csharp // ResourceManager.cs 必须包含类定义 namespace LuaFramework { public class ResourceManager : Manager { // ✅ 类名必须文件名完全匹配 public void CreatUIObject(string path, string name, LuaFunction func) { // ... } } } ``` **验证**: - 确保文件路径:`Assets/Scripts/Manager/ResourceManager.cs` - 确认类名大小写完全一致(`ResourceManager` ≠ `Resourcemanager`) 2. **修复 Addressable 配置(关键步骤)** 打开 `Addressable Groups` 窗口: ```diff Addressables Settings > Advanced Settings > - MonoScript Bundle Naming: Disabled ❌ + MonoScript Bundle Naming: Use Project Name ✅ ``` 重新构建资源: `Addressables > Build > New Build > Default Build Script`[^2] 3. **验证资源加载路径** 在 `ResourceManager.cs` 第36行添加调试信息: ```csharp // 修改前 GameObject go = UnityEngine.Resources.Load<GameObject>(path); // 修改后(添加路径验证) Debug.Log($"Loading UI object from: {path}"); GameObject go = Resources.Load<GameObject>(path) as GameObject; if(go == null) Debug.LogError($"资源加载失败: {path}"); ``` 4. **检查预制体脚本引用** - 打开报错路径的预制体(如 `UI/Prefabs/LoginPanel.prefab`) - 在 Inspector 中检查所有组件: - 黄色警告图标 = 脚本丢失 - 右键选择 `Remove Broken Component` #### 二、LuaFramework 特定修复 1. **XLua 重新生成绑定** ```bash 删除目录: Assets/XLua/Gen/ 菜单操作: XLua > Generate Code 重启Unity ``` 2. **修复 Lua 调用链** 在 Lua 脚本中增加资源验证: ```lua -- 原始调用 resMgr:CreatUIObject("UI/Prefabs/LoginPanel", "LoginPanel", callback) -- 修改后(添加路径验证) local path = "UI/Prefabs/LoginPanel" if CS.UnityEngine.Resources.Load(path) == nil then print("[ERROR] 资源不存在: "..path) else resMgr:CreatUIObject(path, "LoginPanel", callback) end ``` 3. **资源加载流程优化** 修改 `ResourceManager.CreatUIObject` 方法: ```csharp public void CreatUIObject(string path, string name, LuaFunction func) { StartCoroutine(LoadUIAsync(path, name, func)); } private IEnumerator LoadUIAsync(string path, string name, LuaFunction func) { // 使用异步加载避免阻塞 ResourceRequest request = Resources.LoadAsync<GameObject>(path); yield return request; if(request.asset == null) { Debug.LogError($"资源加载失败: {path}"); yield break; } GameObject go = Instantiate(request.asset) as GameObject; // ...后续处理 } ``` #### 三、系统级预防措施 1. **资源验证工具** 创建编辑器工具脚本: ```csharp using UnityEditor; using UnityEngine; public class ResourceValidator : EditorWindow { [MenuItem("Tools/验证UI资源")] static void ValidateUIResources() { // 检查Resources目录 var paths = AssetDatabase.FindAssets("t:Prefab", new[] {"Assets/Resources"}); foreach(var guid in paths) { string path = AssetDatabase.GUIDToAssetPath(guid); GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path); // 检测丢失脚本 if(prefab.GetComponentsInChildren<Component>(true) .Any(c => c == null)) { Debug.LogError($"预制体包含丢失脚本: {path}", prefab); } } } } ``` 2. **Addressable 最佳实践** ```csharp // 替代Resources.Load的方案 using UnityEngine.AddressableAssets; public void LoadWithAddressables(string key) { Addressables.LoadAssetAsync<GameObject>(key).Completed += handle => { if(handle.Status == AsyncOperationStatus.Succeeded) { Instantiate(handle.Result); } }; } ``` 3. **自动化命名检查** 在 `ResourceManager.cs` 中添加: ```csharp #if UNITY_EDITOR void OnValidate() { // 运行时验证文件名匹配 string scriptName = GetType().Name + ".cs"; if(!System.IO.File.Exists($"{Application.dataPath}/Scripts/Manager/{scriptName}")) { Debug.LogError($"文件名不匹配! 应改为: {scriptName}", this); } } #endif ``` #### 四、错误处理流程 ```mermaid graph TD A[报错'The referenced script missing'] --> B{检查控制台} B --> C[定位ResourceManager.cs第36行] C --> D[验证Resources.Load路径] D --> E{路径正确?} E -->|是| F[检查预制体脚本引用] E -->|否| G[修正Lua调用路径] F --> H{脚本丢失?} H -->|是| I[移除损坏组件] H -->|否| J[检查Addressable配置] J --> K[重新构建资源] K --> L[测试验证] ``` > **关键提示**:80%的此类错误由脚本命名不一致或Addressable配置错误引起[^2]。优先检查`ResourceManager.cs`的文件名/类名匹配和Addressable的`MonoScript Bundle Naming`设置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值