weixin_33538392 2018-07-30 08:35 采纳率: 100%
浏览 1402
已结题

unity动态生成类,动态添加dll库的问题

目的是通过解析Excel动态生成类,所生成的类希望序列化而且继承ScriptObject

源代码:

 using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using NUnit.Framework;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Text;

public class ExcelManager : MonoBehaviour
{

    public List<string> _valType;
    public List<string> _valName;
    public string _className;

    public Assembly _assembly;
    public static StringBuilder _classSource;

    public void ReadExcel(string path)
    {
        IWorkbook workbook = null;
        FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
        if (path.IndexOf(".xlsx") > 0)
        {
            //2007版
            workbook = new XSSFWorkbook(fileStream);
        }
        else if (path.IndexOf(".xls") > 0)
        {
            //2003版
            workbook = new HSSFWorkbook(fileStream);
        }
        else
        {
            Debug.LogError("Invalid path.");
        }

        ISheet sheet = workbook.GetSheetAt(0);
        _className = sheet.SheetName.Substring(1, sheet.SheetName.Length - 1);

        IRow row;
        for (int i = 0; i <= sheet.LastRowNum; ++i)
        {
            row = sheet.GetRow(i);
            if (row != null)
            {
                //若该行首列内容以'#'开头,则为无效列
                string tmp = row.GetCell(0).ToString();
                if (tmp[0] == '#')
                {
                    continue;
                }

                for (int j = 0; j < row.LastCellNum; ++j)
                {
                    string cellValue = row.GetCell(j).ToString();

                    if (cellValue[0] == '&')
                    {
                        //内容以'&'开头则记录变量名和类型
                        int index = cellValue.IndexOf('|');
                        string tmpVarName = cellValue.Substring(1, index - 1);
                        tmpVarName.ToLower();
                        string tmpVarType = cellValue.Substring(index + 1, cellValue.Length - (index + 1));
                        tmpVarName.ToLower();

                        _valType.Add(tmpVarType);
                        _valName.Add(tmpVarName);
                    }

                    //---TODO---
                    //是否记录数据
                }
            }
        }

        fileStream.Close();
        workbook.Close();
    }

    public void NewAssembly()
    {
        CSharpCodeProvider provider = new CSharpCodeProvider();
        CompilerParameters paras = new CompilerParameters();

        paras.GenerateExecutable = false;
        paras.GenerateInMemory = true;
        paras.OutputAssembly = "Assets/Plugins" + _className + ".dll";

        _classSource = GetClassSource();

        CompilerResults result = provider.CompileAssemblyFromSource(paras, _classSource.ToString());

        //验证编译错误
        if (result.Errors.HasErrors)
        {
            foreach (var error in result.Errors)
            {
                _classSource.AppendLine(error.ToString());
            }

            //验证文本
            FileStream fst = new FileStream("/Users/lijiesheng/Desktop/Error.txt", FileMode.Create);
            byte[] data = System.Text.Encoding.Default.GetBytes(_classSource.ToString());
            fst.Write(data, 0, data.Length);
            fst.Flush();
            fst.Close();
        }

        _assembly = result.CompiledAssembly;
    }

    public StringBuilder GetClassSource()
    {
        StringBuilder stringBuilder = new StringBuilder();

        stringBuilder.Append("using System;\n");
        stringBuilder.Append("using UnityEngine;\n");
        stringBuilder.Append("using System.Collections;\n");
        stringBuilder.Append("using System.Collections.Generic;\n\n");
        stringBuilder.Append("public class NewClass\n");
        stringBuilder.Append("{\n");
        stringBuilder.Append("\t[System.Serializable]\n");
        stringBuilder.Append("\tpublic class " + _className + " : ScriptableObject\n");
        stringBuilder.Append("\t{\n");
        int len = _valType.Count;
        for (int i = 0; i < len; ++i)
        {
            stringBuilder.Append("\t\tpublic " + _valType[i] + " " + _valName[i] + ";\n");
        }
        stringBuilder.Append("\t}\n");
        stringBuilder.Append("\n\t[SerializeField]\n");
        stringBuilder.Append("\tpublic List<" + _className + "> Fields;\n");
        stringBuilder.Append("}\n");

        return stringBuilder;
    }

    void Start()
    {
        ReadExcel("/Users/lijiesheng/Desktop/test.xlsx");
        NewAssembly();
    }
}

但是动态生成类的时候报错如下,打印到了文本里:

 using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class NewClass
{
    [System.Serializable]
    public class Field : ScriptableObject
    {
        public int VarName1;
        public float VarName2;
        public string VarName3;
        public bool VarName4;
    }

    [SerializeField]
    public List<Field> Fields;
}
/var/folders/19/xjrl577j315f2vjb0ddrl2h40000gn/T/26505f4c/65304a7e.0.cs(2,7) : error CS0246: The type or namespace name `UnityEngine' could not be found. Are you missing an assembly reference?
/var/folders/19/xjrl577j315f2vjb0ddrl2h40000gn/T/26505f4c/65304a7e.0.cs(9,23) : error CS0246: The type or namespace name `ScriptableObject' could not be found. Are you missing an assembly reference?

上面是我希望生成类的结构,下面是生成时候的报错信息,为什么解析不了UnityEngin,有没有上面解决办法

动态添加dll好像也不行:
parameters.ReferencedAssemblies.Add("UnityEngine.dll");

报错变成:error CS0006: Metadata file `UnityEngine.dll' could not be found

  • 写回答

2条回答

  • threenewbee 2018-07-30 13:20
    关注

    parameters.ReferencedAssemblies.Add("UnityEngine.dll"); UnityEngine.dll带路径试试看
    看下.net框架版本号是否匹配

    评论

报告相同问题?

悬赏问题

  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题