Unity3D心得分享
本篇文章和大家分享的是在使用Unity3D游戏引擎做开发时的一些心得分享,希望能帮到那些有需要的人。
运行时修改代码不自动刷新
然后按Ctrl R手动刷新,或者在Project面板下右键刷新
在代码中指定,暂停当前帧
Debug.Break或者Debug.LogError然后在控制台勾选报错暂停。
查看非闭合的MeshCollider
关闭MeshRenderer组件,即可显示出Collider的网格。
让游戏第一帧就暂停的方法
先按暂停,再开游戏
unity刚运行的时候会卡一下,导致动画调试不太方便,也可以用这个方法解决
Console控制台中,让代码文件提示再次出现
有时候报错了,点一下报错内容会在错误内容的.cs代码文件上提示一下。
但如果只有一条报错信息,就会一直保持选中状态,这个时候点一下错误信息的筛选按钮,再点开。就可以还原选中状态
选中错误代码了
去除当前脚本警告
#pragma warning disable 0168
此示例可以清除变量未使用警告,具体对应警告ID。并且该预编译指令只对本文件有效。
也可以包裹使用
#pragma warning disable 0168 .... #pragma warning restore 0168
改变编辑器Scene窗口相机的Fov
鼠标右键滑动 Alt
编辑器Scene窗口,便捷操控3D场景的方法
按住鼠标右键,wasdqe按键移动,分别是3个轴向
将选中物品立刻移动到编辑器相机位置
ctrl shift f
Unity查找KeyCode Ascii码的快捷方法
选中KeyCode按F12,转到定义去查看
快速修改脚本执行顺序优先级
打开代码的meta文件,修改executionOrder选项数值
打印Vector3类型,但不保留2位小数
vector3有一个重载,可以指定format,其中f10就是保留到小数10位
不过由于是自己实现的,不能在string.format里用
xx.position.ToString("f10")
获得GameObject挂载任意Component中的接口
unity5.x可以直接GetComponent得到接口(unity5.3.4或更高版本有效)
高效数组索引循环遍历(出自愤怒机器人demo)
void Update() { var collectionLength = 5; var a = (mIndex ) % collectionLength; Debug.Log("a: " a);//0,1,2,3,4 ... 0,1,2,3,4 }
比较浮点数一致
Mathf.Approximately
删除Project面板里文件夹的展开状态
在Library/expandedItems,删除这个文件会重置展开状态
Unity5 GI缓存目录
C:\Users\...\AppData\LocalLow\Unity\Caches\GiCache
unity资源商店缓存目录
C:\Users\...\AppData\Roaming\Unity
unity资源商店下载的资源包目录
...\AppData\Roaming\Unity\Asset Store-(具体unity版本).x\
清除WebPlayer缓存,可以直接去官网提供的链接清
http://unity3d.com/cn/webplayer/setup
在Unity中使用快捷键重命名
按F2
从中间删除数组元素,或者复制数组中间元素
复制中间元素:ctrl d
从中间删除数组元素:shift delete
或者右键数组中某个元素也会出现操作选项
快速打开所有可展开内容
Shift Ctrl Alt 点击可展开内容
Unity Optimize Tips
===========================
遍历list或者数组时,缓存count,可以减少调用次数(10万次循环测试)
for (int i = 0, iMax = temp.Count; i < iMax; i ) temp[i].GetHashCode();
在极端情况下,直接用枚举器遍历字典会更快,而且不会产生GC
UnityEngine.Profiling.Profiler.BeginSample("-----1"); foreach (var item in temp) item.Value.GetHashCode(); UnityEngine.Profiling.Profiler.EndSample(); UnityEngine.Profiling.Profiler.BeginSample("-----2"); foreach (var item in temp.Values) item.GetHashCode(); UnityEngine.Profiling.Profiler.EndSample(); UnityEngine.Profiling.Profiler.BeginSample("-----3"); var handle = temp.GetEnumerator(); while (handle.MoveNext()) handle.Current.Value.GetHashCode(); UnityEngine.Profiling.Profiler.EndSample();
关于Unity事件函数空调用
尽量少使用封装Unity事件的通用基类,这样会造成函数空调
unity会在C 层面检测是否实现某个事件函数(Start,Update,LateUpdate...etc)
如果没有这个函数则不会加入调用列表中
Unity Editor Tips
===========================
在Editor下获得时间
EditorApplication.timeSinceStartup
获得编译器自打开到当前的时间。
Editor下获得滚轮滑动值
Event.current.delta
https://docs.unity3d.com/ScriptReference/Event-delta.html
注意要先判断当前鼠标按钮id,滚轮的id是1
获取Project面板中当前选中物体的路径
AssetDatabase.GetAssetPath(Selection.activeObject);
取Unity当前目录的路径(是Unity自身安装目录,取当前项目目录请用Directory.GetCurrentDirectory())
EditorApplication.applicationPath
EditorApplication.applicationContentsPath
显示对话框
EditorUtility.DisplayDialog
UnityDatabase拷贝文件
AssetDatabase.CopyAsset(需要拷贝文件,目标目录);
1.只能拷贝单个文件,不能拷贝目录
2.目标必须是目录路径,不能是文件路径
3.不用System.io而用它,因为插件能够跨平台
Editor状态下设置Scene窗口的相机位置
SceneView.lastActiveSceneView.pivot = ...;
SceneView.lastActiveSceneView.Repaint();
Editor下使用右键菜单
使用GenericMenu可以直接调出Unity的右键菜单
Editor下检查prefab是否都打了标签/读写标签Labels
AssetDatabase.GetLabels
AssetDatabase.SetLabels
Editor下拿到当前拖拽对象(跨窗口)
DragAndDrop.objectReferences
在DragExited时处理拖拽内容,就可以在松手时触发了
if (Event.current.type == EventType.DragExited && DragAndDrop.objectReferences.Length > 0) { var dragItem = DragAndDrop.objectReferences[0]; ...
如果是多选拖拽,数组里的就是多选的所有对象,否则就是一个。
Editor下控制控件的焦点
通常只要把focus设为空,就可以取消焦点
GUI.FocusControl("");
一些特殊的情况,比如弹出性组件,需要知道控件是否被改变过,而非值是否改变过
可以这么做,通过GetNameOfFocusedControl拿到Focus的name进行比较
var oldFocus = GUI.GetNameOfFocusedControl(); var changedIndex = EditorGUI.Popup(rect, index, array); var newFocus = GUI.GetNameOfFocusedControl(); if (newFocus != oldFocus) { //Do something... GUI.FocusControl(""); }
Editor下获得'剪切','拷贝','撤销'等命令
可以使用commandName获得
Event.current.commandName == "Copy"
EditorWindow窗口大小锁死后没有边框的解决方法
var window = GetWindow(typeof(MyWindow), true); window.minSize = new Vector2(960, 540); window.maxSize = window.minSize;
用GetWindow创建窗口时,第二个参数填true。创建为独立的工具窗口,即可恢复边框
Editor下Dirty掉当前修改过的场景对象内容
一般非场景对象用
EditorUtility.SetDirty(target);
而场景对象则用
EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
Editor下BeginScrollView报错InvalidCastException
和调用顺序有关,也是Layout/Repaint和输入之间的问题。
改变调用先后顺序有可能解决。
在Editor下绘制自定义光标
比如缩放需要绘制缩放的自定义光标,滑动又需要滑动的
使用下方法即可绘制,Rect自定义Cursor区域的Rect。
需要每次OnGUI更新都调,而非只Add一次
EditorGUIUtility.AddCursorRect(Rect, MouseCursor.Pan);