课程开发介绍
创建一个Unity3D工程,名字叫做Advanced Editor Scripting。 创建一个Editor的文件夹,在打包时不会被打包。
使用MenuItem添加菜单栏按钮
创建一个名为Tools的脚本,添加下面的代码
using UnityEditor;
using UnityEngine;
public class Tools
{
[MenuItem("Tools/test")]
static void Test()
{
Debug.Log("Test");
}
}
编辑器就会出现下面的按键
关于MenuItem的路径设置和现实的先后顺序设置
using UnityEditor;
using UnityEngine;
public class Tools
{
//[MenuItem("Tools/test")]
//static void Test()
//{
// Debug.Log("Test");
//}
//每一个菜单栏的priority优先级默认为1000
//priority在11之内是一个组,大于11就是另外一组
[MenuItem("Tool/Test1",false,1)]
static void Test1()
{
Debug.Log("Test1");
}
[MenuItem("Tool/Test2",false,12)]
static void Test2()
{
Debug.Log("Test2");
}
[MenuItem("Tool/Test3",false,0)]
static void Test3()
{
Debug.Log("Test3");
}
[MenuItem("GameObject/MyTool", false, 10)]
static void MyTool()
{
Debug.Log("MyTool");
}
}
导入射击项目
给组件的右键菜单栏添加按钮
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class PlayerEditor
{
//CONTEXT 组件名 按钮名
[MenuItem("CONTEXT/PlayerHealth/InitHealthAndSpeed")]
static void InitHealthAndSpeed()
{
Debug.Log("Init");
}
}
给Player上的脚本组件添加一个右键菜单单栏按钮
关于MenuCommand的使用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class PlayerEditor
{
//CONTEXT 组件名 按钮名
[MenuItem("CONTEXT/PlayerHealth/InitHealthAndSpeed")]
static void InitHealthAndSpeed(MenuCommand cmd)//menucommand是当前正在操作的组件
{
CompleteProject.PlayerHealth health = (CompleteProject.PlayerHealth)cmd.context;
health.startingHealth = 200;
health.flashSpeed = 10;
}
/// <summary>
/// 取消重力
/// </summary>
/// <param name="cmd"></param>
[MenuItem("CONTEXT/Rigidbody/Clear")]
static void ClearMassAndGravity(MenuCommand cmd)
{
Rigidbody rgd = cmd.context as Rigidbody;
rgd.mass = 0;
rgd.useGravity = false;
}
}
学习使用Selection获取选择的游戏物体
选择物体的操作
[MenuItem("Tool/show info",false,1)]
static void Test1()
{
Debug.Log(Selection.activeContext.name);//使我们第一个选择的游戏物体
Debug.Log(Selection.objects.Length);//获取选择游戏物体的数目
}
删除物体的操作
[MenuItem("GameObject/my delete", false, 11)]
static void Mydelete()
{
foreach (object o in Selection.objects)
{
GameObject.DestroyImmediate(o as GameObject);
}
//需要把删除操作注册到 操作记录里面,才能使用ctrl+z恢复
}
编写可以撤销的删除操作
[MenuItem("GameObject/my delete", false, 11)]
static void Mydelete()
{
foreach (object o in Selection.objects)
{
//GameObject.DestroyImmediate(o as GameObject);
//需要把删除操作注册到 操作记录里面,才能使用ctrl+z
Undo.DestroyObjectImmediate(o as GameObject);
//利用Undo进行的删除操作,是可以撤销的
}
}
如何给菜单项添加快捷键
//%=ctrl #=shift &=alt
//使用快捷键ctrl+q触发
[MenuItem("Tool/Test2 %q",false,12)]
static void Test2()
{
Debug.Log("Test2");
}
//使用快捷键t触发
[MenuItem("Tool/Test3 _t",false,0)]
static void Test3()
{
Debug.Log("Test3");
}
控制菜单项是否启用的功能
//Mydelete的验证函数,当下面的函数返回为true时,才能点击my delete
[MenuItem("GameObject/my delete", true, 11)]
static bool MydeleteValidate()
{
if (Selection.objects.Length > 0)
return true;
else
return false;
}
[MenuItem("GameObject/my delete", false, 11)]
static void Mydelete()
{
foreach (object o in Selection.objects)
{
//GameObject.DestroyImmediate(o as GameObject);
//需要把删除操作注册到 操作记录里面,才能使用ctrl+z
Undo.DestroyObjectImmediate(o as GameObject);
//利用Undo进行的删除操作,是可以撤销的
}
}
关于ContextMenu和ContextMenuItem的使用
ContextMenu的使用
[ContextMenu("SetColor")]
void SetColor()
{
flashColour = Color.green;
}
ContextMenuItem的使用
[ContextMenuItem("AddHp","AddHp")]
public int startingHealth = 100;
void AddHp()
{
startingHealth += 20;
}
学习如何创建对话框
创建一个EnemyChange脚本,用来创建对话框来快捷改变Enemy属性
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class EnemyChange : ScriptableWizard
{
[MenuItem("Tools/CreateWizard")]
static void CreateWizard()
{
ScriptableWizard.DisplayWizard<EnemyChange>("统一修改敌人");
}
public int changeHealthValue = 10;
public int changeFlashSpeedValue = 10;
}
如何兼容按钮点击统一修改字段
在EnemyChange脚本中添加 下列代码
//检测create按钮的点击
private void OnWizardCreate()
{
GameObject [] enemyPrefabs = Selection.gameObjects;
foreach (GameObject go in enemyPrefabs)
{
CompleteProject.EnemyHealth hp = go.GetComponent<CompleteProject.EnemyHealth>();
Undo.RecordObject(hp, "change health and speed");
hp.startingHealth += changeHealthValue;
hp.sinkSpeed += changeSinkSpeedValue;
}
}
显示提示框的帮助信息和错误信息
//当前字段值修改的时候会被调用
private void OnWizardUpdate()
{
errorString = null;
helpString = null;
if (Selection.gameObjects.Length > 0)
{
helpString = "你当前选择了" + Selection.gameObjects.Length + "个敌人";
}
else
{
errorString = "请选择至少一个敌人";
}
}
private void OnSelectionChange()
{
OnWizardUpdate();
}
创建OtherButton按钮并监听按钮点击
[MenuItem("Tools/CreateWizard")]
static void CreateWizard()
{
ScriptableWizard.DisplayWizard<EnemyChange>("统一修改敌人","Change And CLose","Change");
}
private void OnWizardOtherButton()
{
OnWizardCreate();
}
使用ShowNotification显示提示信息
ShowNotification(new GUIContent(Selection.gameObjects.Length + "个游戏物体的值被修改"));
使用EditorPrefs保存数据
const string changeHealthValueKey = "EnemyChange.changeStartHealthValue";
const string changeSinkSpeedValueKey = "EnemyChange.changeSinkSpeedValue";
/// <summary>
/// 当窗口被创建的时候调用
/// </summary>
private void OnEnable()
{
EditorPrefs.GetInt(changeHealthValueKey,changeHealthValue);
EditorPrefs.GetInt(changeSinkSpeedValueKey,changeSinkSpeedValue);
}
//调用的时候
EditorPrefs.SetInt(changeHealthValueKey, changeHealthValue);
EditorPrefs.SetInt(changeSinkSpeedValueKey, changeSinkSpeedValue);
关闭打开之后
显示进度条
//检测create按钮的点击
private void OnWizardCreate()
{
GameObject [] enemyPrefabs = Selection.gameObjects;
EditorUtility.DisplayCancelableProgressBar("进度", "0/" + enemyPrefabs.Length + "完成修改值", 0);
int count = 0;
foreach (GameObject go in enemyPrefabs)
{
CompleteProject.EnemyHealth hp = go.GetComponent<CompleteProject.EnemyHealth>();
Undo.RecordObject(hp, "change health and speed");
hp.startingHealth += changeHealthValue;
hp.sinkSpeed += changeSinkSpeedValue;
count++;
EditorUtility.DisplayCancelableProgressBar("进度", count+"/" + enemyPrefabs.Length + "完成修改值", (float)count/enemyPrefabs.Length);
}
EditorUtility.ClearProgressBar();
ShowNotification(new GUIContent(Selection.gameObjects.Length + "个游戏物体的值被修改"));
}
创建自定义窗口
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class MyWindow : EditorWindow
{
[MenuItem("Window/show my window")]
static void ShowMyWindow()
{
MyWindow window = EditorWindow.GetWindow<MyWindow>();
window.Show();
}
private string name = "";
private void OnGUI()
{
GUILayout.Label("这是我的窗口");
name = GUILayout.TextField(name);
if (GUILayout.Button("创建"))
{
GameObject go = new GameObject(name);
Undo.RegisterCompleteObjectUndo(go, "create gameobject");
}
}
}