环境:Unity2017.2 语言:C#
总起:
今天主要介绍以下内容:
1.通过MenuCommand、Selection获取选中对象;
2.通过Undo编写可撤销的命令;
3.窗口小部件的显示。
MenuCommand:
我们先来看一个点击增加血量的例子:
[MenuItem("CONTEXT/PlayerInfo/Plus 5 Hp", false, 20)]
public static void Plus5Hp(MenuCommand cmd)
{
Debug.Log(cmd.userData);
PlayerInfo playerInfo = (PlayerInfo)cmd.context;
playerInfo.hp += 5;
}
这边唯一有用的变量就是MenuCommand.context提供当前右键的组件,它本身是个object,所以需要进行强转。
至于MenuCommand.userData,在MenuItem的使用方式中它没有被赋值。
Selection:
重点是Selection,我们使用该类来重写上面的例子:
[MenuItem("CONTEXT/PlayerInfo/Plus 5 Hp2", false, 20)]
public static void Plus5Hp2()
{
var playerInfo = Selection.activeTransform.GetComponent<PlayerInfo>();
if (playerInfo != null)
playerInfo.hp += 5;
}
同样能达到以上的效果。
Selection可以获取到当前选中的各类物体:
1.Selection.activeGameObject,可以获取到当前的选中的节点和资源文件中的Prefab(gameObjects是其复数形式);
2.Selection.activeObject,不仅是GameObject,cs脚本这类文件都能获取(objects是其复数形式);
3.Selection.activeTransform,只有场景中的节点才有(transforms是其复数形式);
4.Selection.activeInstanceID,Unity中的唯一id(instanceIDs是其复数形式);
5.Selection.assetGUIDs,资源的唯一ID。
Undo命令撤销:
使用Editor功能将GameObject删除了,但按Ctrl+Z却没有反应,此时便陷入了绝望,之前做的工作可能都白费了。
这时就轮到Undo类登场了:
[MenuItem("Tools/Delete This", false, 20)]
public static void Delete()
{
if (Selection.activeGameObject != null)
{
//GameObject.DestroyImmediate(Selection.activeGameObject);
Undo.DestroyObjectImmediate(Selection.activeGameObject);
}
}
使用Undo代替普通的删除便可以了,下面是举几个重要的方法:
// 记录当前位置
Undo.RecordObject(Selection.activeTransform, "Zero Transform Position");
Selection.activeTransform.position = Vector3.zero;
// 记录添加component
Undo.AddComponent<Rigidbody>(Selection.activeGameObject);
// 记录创建GameObject
var go = new GameObject();
Undo.RegisterCreatedObjectUndo(go, "Create go");
// 记录设置父节点
Undo.SetTransformParent(Selection.activeTransform, tr, "Set new parent");
重要的是改变习惯,做功能的时候首先想想是否能用Undo。
几个常用的窗口小部件:
显示进度条:
[MenuItem("Tools/Show Progress Bar")]
public static void ShowBar()
{
EditorUtility.DisplayProgressBar("进度条", "读取中", 0);
Thread.Sleep(TimeSpan.FromSeconds(0.2f));
EditorUtility.DisplayProgressBar("进度条", "读取中", 0.5f);
Thread.Sleep(TimeSpan.FromSeconds(0.2f));
EditorUtility.DisplayProgressBar("进度条", "读取中", 1f);
Thread.Sleep(TimeSpan.FromSeconds(0.2f));
EditorUtility.ClearProgressBar();
}
一个可以取消的进度条:
[MenuItem("Tools/Show Cancel Progress Bar")]
public static void ShowCancelProgressBar()
{
EditorUtility.DisplayCancelableProgressBar("进度条", "读取中", 0);
Thread.Sleep(TimeSpan.FromSeconds(1f));
if(EditorUtility.DisplayCancelableProgressBar("进度条", "读取中", 1f))
Debug.Log("取消");
EditorUtility.ClearProgressBar();
}
显示小提示窗口:
[MenuItem("Tools/Show Dialog")]
public static void ShowDialog()
{
EditorUtility.DisplayDialog("警告", "操作失误了", "确定");
}
显示有三个选项的窗口(值得一提的是按红叉也是最后一个选项):
[MenuItem("Tools/Show Complex Dialog")]
public static void ShowComplexDialog()
{
int choice = EditorUtility.DisplayDialogComplex("三个选择", "你的性别", "男", "女", "都不是");
Debug.Log("玩家的选择是:" + choice);
}
文件打开窗口:
[MenuItem("Tools/Show File Panel")]
public static void ShowFilePanel()
{
string path = EditorUtility.OpenFilePanel("选择文件", "", "");
Debug.Log("玩家选择了" + path);
}
文件夹窗口:
[MenuItem("Tools/Show Folder Panel")]
public static void ShowFolderPanel()
{
string path = EditorUtility.OpenFolderPanel("选择路径", "", "");
Debug.Log("玩家选择了" + path);
}