Unity3D —— 报错解决方案和常用功能集

1.在Dictionary迭代器进行修改:

                    var _key = index2factionDic.Keys.GetEnumerator();
                    string item;
                    while (_key.MoveNext())
                    {
                        item = index2factionDic[_key.Current];
                        if (item.Equals(id))
                        {
                            tempDelete.Add(_key.Current);
                            //index2factionDic.Remove(_key.Current);
                        }
                    }
此时会报错:

InvalidOperationException: out of sync
报错原因:

       在迭代过程中,Dictionary 变量及Value是只读的,C#有保护机制,不允许在这个过程中修改这些变量。

解决方案:

       创建一个列表List,来存储需要进行操作的key,然后在迭代器之外执行操作而不直接操作迭代器,便可解决报错问题:

                List tempDelete = new List();
                //Index发生变化,移除旧的索引
                if (index2factionDic.ContainsValue(id))
                {
                    var _key = index2factionDic.Keys.GetEnumerator();
                    string item;
                    while (_key.MoveNext())
                    {
                        item = index2factionDic[_key.Current];
                        if (item.Equals(id))
                        {
                            tempDelete.Add(_key.Current);
                            //index2factionDic.Remove(_key.Current);
                        }
                    }
                }
                for(int i = 0; i < tempDelete.Count; i++)
                {
                    index2factionDic.Remove(tempDelete[i]);
                }
                tempDelete.Clear();


2.UITable排序问题:

        一般将Item添加到UITable的子节点上之后,给每个Item取名,这里假设是在一个List循环中进行添加的,取名根据循环指针i来取,例如:

        //显示列表
        for (int i = 0; i < cardlist.Count; i++)
        {
            nameStr = "card" + i;
            Transform itemtrans = cardTable.transform.Find(nameStr);
            if (itemtrans == null)
            {
                item = CreateOneCard(cardTable.transform);
            }
            else
            {
                item = itemtrans.gameObject;
                item.SetActive(true);
            }
            item.name = nameStr;
        }

        记得勾选UITable排序的Sorted选项:

Unity3D —— 报错解决方案和常用功能集_第1张图片

        运行UITable.Reposition() 方法,会根据item的名称后面得序号来进行排序,但是有个问题,假如i大于10,如下图为生成后在Hierarchy中:

Unity3D —— 报错解决方案和常用功能集_第2张图片

        这里我一行显示5个Item,按照正常顺序应该如下:

        结果出现了如下排序穿插

Unity3D —— 报错解决方案和常用功能集_第3张图片

        原因:UITable在进行排序的时候,会从item命名字符串中取第一个数字来作为排序参考,所以“Card2”和“Card10”去到的第一个数字分别是“2”和“1”,所以“Card2”排到了“Card10”后面。

        解决方案:命名小于10的item进行修改,“Card2”改成"Card02",修改代码:

        //显示列表
        for (int i = 0; i < cardlist.Count; i++)
        {
            if (i < 10)
            {
                nameStr = "card0" + i;
            }
            else
            {
                nameStr = "card" + i;
            }
            Transform itemtrans = cardTable.transform.Find(nameStr);
            if (itemtrans == null)
            {
                item = CreateOneCard(cardTable.transform);
            }
            else
            {
                item = itemtrans.gameObject;
                item.SetActive(true);
            }
            item.name = nameStr;
        }
        如此,排序的问题就解决了。


3.每次将预制拖到Hierachy窗口中就错:

NullReferenceException: Object reference not set to an instance of an object
PVPMatchPlayerScene..ctor ()
UnityEditorInternal.InternalEditorUtility:HierarchyWindowDrag(HierarchyProperty, Boolean, HierarchyDropMode)
UnityEditor.DockArea:OnGUI()

参考资料:

  • What are pairs?

报错原因:大致原因是同一个UI预制中,物理碰撞框的数量太多,所以导致绘制报错,但不会影响功能

解决方案:对UI预制进行分割,减少单个Prefab的碰撞框数量,尽量降低UI预制的复杂度


4.NGUI中,使用UILabel,假如在创建诸如聊天输出窗口或者展示窗口,希望超出设定区域的内容,以省略号代替,可以使用一下方式来完成,前提是当前的NGUI版本的UILabel提供了Wrap这个接口,教程:NGUI:UILabel用省略号替换超出显示区域的内容


5.修改粒子特效染色的简单方法:

    /// 
    /// 修改粒子特效染色
    /// 
    /// 
    /// 
    public static void SetParticleSystemToColor(GameObject gameObj, Color color)
    {
        var partSyses = gameObj.GetComponentsInChildren(true);
        foreach (ParticleSystem _partSys in partSyses)
        {
            _partSys.startColor = color;
        }
    }

6.修改Shader中的指定属性,例如Tint Color:

Unity3D —— 报错解决方案和常用功能集_第4张图片

通过以下代码获取Mesh Renderer组件,然后设置对应的属性:

    MeshRenderer mesh_renders = gameObj.GetComponentsInChildren();
    mesh_renders.material.SetColor("_TintColor",selfcolor);


7.在一个继承自MonoBehaviour的脚本中调用gameObject或者transform时,出现了如下错误:

NullReferenceException UnityEngine.Component.get_transform()”或者“NullReferenceException UnityEngine.Component.get_gameObject()”,可以先判断this是否为空再调用gameObject或者transform,如下:

if (this == null || gameObject == null|| transform == null)
{
    return;
}

8.用代码控制Unity编辑器的运行和暂停状态:

运行: UnityEditor.EditorApplication.isPlaying = true;

暂停:UnityEditor.EditorApplication.isPaused = true;

停止:UnityEditor.EditorApplication.isPlaying = false;

你可能感兴趣的:(随笔,Unity学习笔记)