<Unity Scripts ERROR> Unity 脚本报错合集(附带解决办法)

1. 前言

  • 用于汇总在代码书写中所遇到的错误,方便自己和一些同样在书写Unity脚本时遇到此类错误的同僚进行查找和解决问题。直接在网页中按住Ctrl + F进行报错问题的搜索即可!!该文档将会不断地得到完善,直到放弃Unity编程。

2. 错误名 && 错误原因 && 解决方法

2.1 The supplied array needs to be the same size as the Mesh.vertices array.

  • 问题提示,与顶点Vertices的数量不一致,超出边界,然后将三个值打印出来(创建MeshFilter之前),代码&&报错 如图:

  • 代码:

    Debug.Log("==========");
    Debug.Log("temp_Nor_List.Count: " + temp_Nor_List.Count);
    Debug.Log("points.Count:  " + points.Count);
    Debug.Log("newTriangles.Length:  " + newTriangles.Length);            
    Debug.Log("==========");
    //获得切面顶点法向量
    mesh.normals = temp_Nor_List.ToArray();
    //获得切面顶点坐标
    mesh.vertices = points.ToArray();
    //获得切面三角关系
    mesh.triangles = new int[newTriangles.Length];
    mesh.triangles = newTriangles;
    //绘制
    cutPlaneMark(mesh);
    Debug.Log("绘制结束!!!!");
    //绘制函数 将三角面生成新的物体 进行渲染 并绑定到原物体上,从而实现视觉上的"物体某一个面的渲染"
    //这个操作是不会Shader编程 而采取的替代手段
    //cutPlaneMark(Mesh mesh);
    cutPlaneMark(points, temp_Nor_List, newTriangles);
    
  • 报错:
    在这里插入图片描述
    在这里插入图片描述

    因此,可以确认的是:这跟三个量所对应的数量无关(属于正常,不存在问题)

  • 解决办法:
    绕开Mesh,而是直接给 cutPlaneMark()函数传入Mesh的三个数组数据,则不会报错

    void cutPlaneMark(List<Vector3> ver,List<Vector3> nor,int[] tri )
        {
            //Mesh meshToMark = new Mesh(mesh);
            //Mesh meshToMark = mesh;
            //meshToMark.vertices = mesh.vertices;
            //meshToMark.triangles = mesh.triangles;
            //meshToMark.normals = mesh.normals;
            //Graphics.DrawMeshNow(meshToMark, Vector3.zero,Quaternion.identity);
            GameObject PlaneMark = new GameObject("PlaneMark");
            PlaneMark.transform.SetParent(beCutThing.transform);
            PlaneMark.AddComponent<MeshFilter>();
            PlaneMark.GetComponent<MeshFilter>().mesh.vertices = ver.ToArray();
            PlaneMark.GetComponent<MeshFilter>().mesh.triangles = tri;
            PlaneMark.GetComponent<MeshFilter>().mesh.normals = nor.ToArray();
            PlaneMark.transform.position = Vector3.zero;
            PlaneMark.transform.rotation = Quaternion.Euler(Vector3.zero);
            PlaneMark.tag = "temp_cutplane_mark";
            PlaneMark.AddComponent<MeshRenderer>();
            PlaneMark.GetComponent<MeshRenderer>().material.color = Color.red;
            GameObject planeMark = GameObject.Instantiate(PlaneMark);
            Vector3[] temp_nor = planeMark.GetComponent<MeshFilter>().mesh.normals;
            for(int i=0;i<temp_nor.Length;i++)
            {
                temp_nor[i] = -temp_nor[i];
            }
            planeMark.GetComponent<MeshFilter>().mesh.normals = temp_nor;
        }
    
  • 效果如图:
    在这里插入图片描述
    (总结:结果不理想,标注未达到预期效果,重新考虑新的办法(Shader编程 GL来绘制线框(还未更新)),与上述代码报错无关)

2.2 Shader.Find()查找失败

  • NullReferenceException : UnityEngine.Material..ctor (UnityEngine.Shader shader) (at D:/unity/artifacts/generated/common/runtime/ShaderBindings.gen.cs:254)

    GameObject line1 = new GameObject("line1");
    line1.transform.SetParent(beCutThing.transform);
    line[0] = line1.AddComponent<LineRenderer>();
    line[0].material = new Material(Shader.Find("snapTurnArrow"));
    line1.GetComponent<LineRenderer>().useWorldSpace = false;
    line[0].positionCount = points.Count + 1;
    line[0].startWidth = 0.0003f;
    line[0].endWidth = 0.0003f;
    for (int i = 0; i < points.Count; i++)
        line[0].SetPosition(i, points[i]);//设置渲染顶点
    line[0].SetPosition(points.Count, points[0]);
    
  • 错误原因:
    此处是因为我查找的是一个格式为Material的材质,而非Shader类型。并且Shader只能找到Resources文件夹中的(来自于网络),但是可以采用如下办法进行规避该错误:public Shader shader;,并主动进行赋值,则不需要利用Shader.Find()方法进行查找。

  • 解决办法:
    首先在类开始处定义一个Material变量,并在Unity中赋值
    在这里插入图片描述
    然后line[0].material = new Material(Shader.Find("snapTurnArrow"));改为:line[1].material = material;

2.3 修改gameobject的Position和Rotation 不能达到预期

  • Position VS localPosition && Rotation VS localRotation(简单讲解)

  • 当前Unity版本为 2017.3.0f ,需要注意的是:在此版本中Transform中对旋转角和位置做了区分

  • 对比:

    项目Value
    position表示物体的世界坐标
    localRotation表示物体的局部坐标(以父物体为参照)
    rotation表示物体的世界旋转角度
    localRotation表示物体的局部旋转角度(以父物体为参照)
  • 代码:

    line1.transform.position = Vector3.zero;
    line2.transform.position = Vector3.zero;
    Debug.Log("line1.transform.position: " + line1.transform.position);
    Debug.Log("line2.transform.position: " + line2.transform.position);
    Debug.Log("=========修正位置&&角度==========");
    //line1.transform.position = Vector3.zero;
    //line2.transform.position = Vector3.zero;
    line1.transform.localPosition = Vector3.zero;
    line2.transform.localPosition = Vector3.zero;
    Debug.Log("line1.transform.position: " + line1.transform.position);
    Debug.Log("line2.transform.position: " + line2.transform.position);
    Debug.Log("============修正完成=============");
    

    在这里插入图片描述 在这里插入图片描述通过对比可知,localPosition才将其Position选项变为了(0,0,0)–>局部坐标,Position代表世界坐标,当物体的Position被赋值时,Unity会自动将其转化为当前的局部坐标进行赋值!!

  • 采用局部坐标和旋转角度后 获得预期效果

    Debug.Log("=========修正位置&&角度==========");
    line1.transform.localPosition = Vector3.zero;
    line2.transform.localPosition = Vector3.zero;
    Debug.Log("line1.transform.position: " + line1.transform.position);
    Debug.Log("line2.transform.position: " + line2.transform.position);
    line1.transform.localRotation = Quaternion.Euler(Vector3.zero);
    line2.transform.localRotation = Quaternion.Euler(Vector3.zero);
    Debug.Log("============修正完成=============");
    

    在这里插入图片描述

2.4 空指针报错 NullReferenceException -->(Unity三维模型导出插件 Exporter相关)

  • NullReferenceException: Object reference not set to an instance of an object (wrapper stelemref) object:stelemref (object,intptr,object)

  • 经过验证,是该数组在定义时未进行内存分配!
    在这里插入图片描述
    而在调用ImgSpcExporter.ObjectsToExport 时,直接进行赋值,导致出错imgSpcExporter.ObjectsToExport[0] = game;

    public void ObjExporter()
        {
            ImgSpcExporter imgSpcExporter = new ImgSpcExporter();
            string path = Application.dataPath + "/ExportFile/" + "第" + Export_num + "个导出的文件.obj";
            Directory.CreateDirectory(path + "ExportFile");
            Debug.Log("path: " + path);
            imgSpcExporter.SetFilename(path);//设置导出文件夹
            //执行导出操作
            GameObject game = GameObject.FindWithTag("ChosenObject");
            Debug.Log("game:" + (game == null ? "yes" : "no"));
            if (game != null)
            {
                imgSpcExporter.ObjectsToExport = new Object[1];//需要先进行内存分配 再赋值 避免报错
                imgSpcExporter.ObjectsToExport[0] = game;
                imgSpcExporter.Export();
                Debug.Log("已经导出!!");
            }
            else
            {
                Debug.Log("未找到物体");
            }
        }
    

2.5 LineRenderer渲染出错

  • 传入LineRenderer的为点集(SetPosition(index,position) 方法),但是渲染出来却是一整块正方形区域,并且大小和预设值不同。
    在这里插入图片描述

  • 问题原因:
    我给父物体也增加了LineRenderer组件,导致报错,删去即可。在给物体做额外的标记,仅需要给其子物体加上LineRenderer进行渲染就可以

  • 代码

GameObject line2 = new GameObject("line2");
Debug.Log("line2" + line2);
line2.tag = "temp_cutplane_mark";
line2.transform.SetParent(beCutThing.transform);
line[1] = line2.AddComponent<LineRenderer>();//line为LineRenderer数组
line[1].material = material;
//line[1].material = new Material(Shader.Find("snapTurnArrow"));        
line2.GetComponent<LineRenderer>().useWorldSpace = false;
line2.transform.localScale.Set(1, 1, 1);//设置其大小,避免出现过大情况 就不会附着在父物体上
line[1].positionCount = points.Count + 1;
line[1].startWidth = 0.0003f;
line[1].endWidth = 0.0003f;
for (int i = 0; i < points.Count; i++)
    line[1].SetPosition(i, points[i]);//设置渲染顶点
line[1].SetPosition(points.Count, points[0]);
line2.transform.localPosition = Vector3.zero;
line2.transform.localRotation = Quaternion.Euler(Vector3.zero);

在这里插入图片描述

2.6 Failed setting triangles. Some indices are referencing out of bounds vertices

  • Mesh中Triangles数组存储的顶点索引值超过了Vertices的大小
    在这里插入图片描述
  • 对于此类问题,首先可以大致确定问题出在Triangles数组的赋值过程中,
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值