Unity开发时遇到的各种需要注意的地方

前言:

最近在做东西的时候突然想到,自己以前做过的项目有很多地方需要注意的,然而并没有记录下来,导致下次还会出现这样的问题。于是就有了这个想法,把之前各种各样奇奇怪怪的问题都记录下来,解决方案也写下了。

一是加深记忆,二是万一又遇到了好歹也有个参考;

正文:

1、Transform.GetComponentsInChildren 找不到组件!?

这是因为Transform.GetComponentsInChildren这个方法默认是不包含不激活的物体的。所以如果被查找的组件一开始没有激活,那么在不填写参数的情况下就会找不到该组件。

如果要找未激活的组件,则需要在括号里写ture:

2、在使用Queue.Peek 的时候报错:InvalidOperationException: Operation is not valid due to the current state of the object .

遇到过一次,这个原因是在队列中元素为空的时候就会抛出这个错误。

所以在Peek的时候需要判断一下队列的元素数量。

public T Peek() {
            if (_size == 0)
                ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyQueue);
    
            return _array[_head];
        }

参考:c# Queue源码解析_BlueBones_fan的博客-CSDN博客_c# queue源代码

3、编辑器下调用协程的问题;

编辑器下不能直接调用协程,毕竟没有MonoBehavior,但是可以用别的方法来模拟协程的运作。

参考:Unity协程&在编辑器中使用协程_cai612781的博客-CSDN博客_unity 编辑器下怎么用协程

4、在编辑器下用WWW加载Textrue2D的问题:

在根据上述方法能使用协程之后,用WWW来加载某个Texture(png)。一直弄出来是一个白图,而且没名字,很神奇。但是实际上图片是有加载进来的,如果分别打印www.texture的宽和高是正确的,byte[]的数据也是有的。但是名字没有,而且texlsize肯定是(0,0)。

其实这个只是API调用的问题。如果使用 EditorGUI.DrawTextureAlpha 这种方法肯定是画不出来的,白图。但是如果使用GUI.Draw又是可以的。当然最后推荐使用 GUILayout.Box,还可以自动布局。

至于图片名字肯定是没了的不用纠结了,所以要在加载之后手动给这张图片赋值一次名字。

5、自由缩放的EditorWindow如何获取当前尺寸

window = (T)GetWindow(typeof(T), false, "...");

获取window,之后在window.position.size可以获取到当前的窗口的尺寸。

6、关于应用失去焦点的问题

最近发现过应用失去焦点导致的问题,在点击事件中出现过。比如我们设定手指悬浮或者按下在某个区域的时候触发某个操作,然而抬起手指或者鼠标移开的时候操作取消。但是如果在鼠标按下/进入之后,应用失去了焦点,然后鼠标抬起/离开,然后再获得焦点,不会再接收到鼠标抬起/离开的信息。这样就导致本来是该悬浮在某个地方的tips,就没有悬浮而是一直存在了。

在电脑上的操作很简单,就是鼠标按下,然后Alt+Tab切换出去,然后再切回来就可以重现。

但是手机上怎么操作呢?一开始我以为手机上是没法做到这一点的,但实际上也是可以的。那就是先按住,然后另一个手指按手机的Home键就可以了,和电脑的Alt+Tab是一个道理。但这个前提是手机要有Home键,所以可以预见如果有全面屏、没有Home键的手机是不存在这个问题的。

7、Android Device Monitor (LogCat)在哪里?

就是那个可以在电脑上看到手机报错的的Log的AndroidStudio插件在哪里。实际上这是个bat文件,在SDK的tools目录中的monitor.bat。其实挺好找的。

8、如何让一个空物体(Empty)也能相应点击?

给他挂上如下脚本:

    /// <summary>
    /// 点击目标;
    /// </summary>
    public class RaycastTarget : Graphic
    {
        public override void SetMaterialDirty() { return; }
        public override void SetVerticesDirty() { return; }
        
        protected override void OnPopulateMesh(VertexHelper vh)
        {
            vh.Clear();
            return;
        }
    }

原理:和Image、Text一样继承自Graphic,然后把绘制网格的部分给干掉了。

9、重写Unity组件的Inspector面板后,属性不刷新?

最近重写了一个Image,在Image里面有个布尔值。使用如下方法写后发现这个IsCricleImage值不刷新:

      public override void OnInspectorGUI()
        {
            serializedObject.Update();
            EditorGUILayout.PropertyField(IsCricleImage);

            EditorGUILayout.Space();
            if (!IsCricleImage.boolValue)
                base.OnInspectorGUI();
            serializedObject.ApplyModifiedProperties();
        }

这可就奇了怪了,但是如果我把 serializedObject.ApplyModifiedProperties();这一行移动到 EditorGUILayout.PropertyField(IsCricleImage);下面,就像这样:

        public override void OnInspectorGUI()
        {
            serializedObject.Update();
            EditorGUILayout.PropertyField(IsCricleImage);
            serializedObject.ApplyModifiedProperties();
            EditorGUILayout.Space();
            if (!IsCricleImage.boolValue)
                base.OnInspectorGUI();            
        }

就毫无问题了。真是奇怪……难道是因为中间间隔了一行EditorGUILayout.Space();的缘故吗?

10、如何正确地导入Job System系列:

一些JobSystem需要用到的类,如Unity.Entities找不到?那么应该怎样才能连接进去呢?

1、更改框架为4.x

2、VS升级到最新;

3、manifest.json文件,将以下内容合并进去:

{
    "dependencies": 
{
    "com.unity.entities": "0.0.12-preview.5"
},
    "registry": "https://packages.unity.com",
    "testables": 
    [
        "com.unity.collections",
        "com.unity.entities",
        "com.unity.jobs"
    ]
}

4、重启Unity;

11、16进制的颜色如何变成Color?

如下:

  Color DisableColor;
  ColorUtility.TryParseHtmlString("#86969f", out DisableColor);

12、获取HostName的时候报错?

项目从5.6.6升级到2018.3.5的时候出现的,在使用 System.Net.Dns.GetHostName(); 时直接抛出报错:

System.ExecutionEngineException:String conversion error : Illegal byte sequence encounted in the input.at (wrapper managed-to-native) System.net.Dns.GetHostName_internal(string&) at & ……

结果大概如上。

此时你需要点击我的电脑→右键→属性,看看你的计算机名是不是设置为中文了。我是这样的情况,改成英文然后重启就OK了。

13、Unity 的 RectTransfrom 中关于锚点(Anchor Presets)的设置

 就是如下图的这个东西:

如何用代码来设置呢?参考以下两篇连接:

Unity 代码设置锚点 anchorPreset - 简书

[SOLUTION] set UI RectTransform Anchor Presets from code c# - Unity Answers

13、反射获取子类:

    public static class TypeExt
    {
        static List<Type> subTypes = new List<Type>();
        public static List<Type> SubTypes(this Type aThis)
        {
            subTypes.Clear();
            Type[] types = aThis.Assembly.GetTypes();

            //接口需要用不同的判定方法;
            bool IsInterface = aThis.IsInterface;

            for (int i = 0; i < types.Length; i++)
            {
                Type type = types[i];
                if (type == null)
                    continue;

                if (IsInterface)
                {
                    var arr = type.GetInterfaces();
                    foreach (Type temp in arr)
                    {
                        if (temp == aThis)
                        {
                            subTypes.Add(type);
                            break;
                        }
                    }
                }
                else if (type.IsSubclassOf(aThis))
                {
                    subTypes.Add(type);
                }
            }

            return subTypes;
        }
    }

14、直线与平面的交点

    /// <summary>
    /// 计算直线与平面的交点
    /// <param name="point">直线上某一点</param>
    /// <param name="direct">直线的方向</param>
    /// <param name="planeNormal">垂直于平面的的向量</param>
    /// <param name="planePoint">平面上的任意一点</param>
    /// <returns></returns>
    private Vector3 GetIntersectWithLineAndPlane(Vector3 point, Vector3 direct, Vector3 planeNormal, Vector3 planePoint)
    {
        float d = Vector3.Dot(planePoint - point, planeNormal) / Vector3.Dot(direct.normalized, planeNormal);
        //直线与平面的交点
        Vector3 hitPoint = d * direct.normalized + point;
        return hitPoint ;
    }

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值