前言:
最近在做东西的时候突然想到,自己以前做过的项目有很多地方需要注意的,然而并没有记录下来,导致下次还会出现这样的问题。于是就有了这个想法,把之前各种各样奇奇怪怪的问题都记录下来,解决方案也写下了。
一是加深记忆,二是万一又遇到了好歹也有个参考;
正文:
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 ;
}