Unity3D心得分享

发表于2017-07-19
评论0 2k浏览

本篇文章和大家分享的是在使用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

===========================

 

Animator在Editor状态下预览工具

 

Unity3D中Console控制台的扩展

 

在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);

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

标签: