Unity基础和Unity Editor基础

一、MonoBehaviour

       所有需要挂载到GameObject上面的脚本,都需要继承自MonoBehaviour,MonoBehaviour是Unity中所有脚本驱动的基类。MonoBehaviour有一些事件函数会在特定的时间被调用,Unity的MonoBehaviour脚本的生命周期示意图如下:

1、FixedUpdate与Update的不同在于,Update在每帧被调用,但是调用时间不确定,所以我们要实现一个物体匀速运动是,是无法通过Update准确实现的,但是我们可以在FixedUpdate中实现,因为它在确定的时间间隔中被调用。FixedUpdate有可能在Update之前调用多次。FixedUpdate除了用来处理物理逻辑之外并不适合处理其他模块的逻辑。

2、LateUpdate它会在所有update被调用后调用,这个函数可以在我们编写ai时被使用,因为我们要当所有物体和怪物移动过后再判断物体的一些策略,比如开枪等,这个时候就可以在LateUpdate中编写,因为LateUpdate基本可以保证所有物体在本帧的移动等操作均已经完成。

3、Coroutine,协程,参考https://blog.csdn.net/blues1021/article/details/40959915

二、Editor

       unity editor是一个通用的编辑器,提供了unity内部对象的创建,预览,编辑的功能及可视化界面。​ 用于扩展editor的类需要放到名字为“Editor"的文件夹中,这个文件夹可以直接放到”Assets“文件夹下,也可以是项目目录任何文件夹下的子文件夹,比如”Assets/BigWorld/Editor"。

       1.使用MenuItem特性扩展工具栏菜单。

        eg:

        using UnityEditor;

        [MenuItem("Tools/离线处理")]

         public void OfflineData()

          {    

                  ......

          }

          这时菜单栏里会多出T“ools/离线处理”项。

          2.扩展ScriptableWizard类

        使用方法:

        1>继承ScriptableWizard

        2>调用ScriptableWizard.DisplayWizard函数可以快速创建这个向导窗口。这个向导窗口只支持小于或等于两个按钮的定制(即提供的消息响应函数只有两个按钮的)。显示的按钮名字通过ScriptableWizard.DisplayWizard函数传入。

        eg: ScriptableWizard.DisplayWizard("Click info to know the distance between the objects", typeof(ScriptableWizardButton), "Finish!", "Info");

        ScriptableWizard的API中的消息响应函数:(当满足某些条件下执行这些函数)

        OnWizardCreate :两个按钮事件中的一个,当传入ScriptableWizard.DisplayWizard函数中"createButtonName"参数对应的按钮被点击时调用。

       OnWizardOtherButton:两个按钮事件中的一个,当传入ScriptableWizard.DisplayWizard函数中"otherButtonName"参数对应的按钮被点击时调用。

       OnWizardUpdate:当向导窗口打开时或者用户改变窗口内容时都会被调用。一般会在这里显示帮助文字和进行内容有效性验证。也可以动态改变按钮状态。

代码:

using UnityEngine;
using UnityEditor;
using System.Collections;

public class ScriptableWizardButton : ScriptableWizard
{
    public Transform firstObject = null;
    public Transform secondObject = null;

    [MenuItem("Example/Show OnWizardOtherButton Usage")]
    static void CreateWindow()
    {
        ScriptableWizard.DisplayWizard("Click info to know the distance between the objects", typeof(ScriptableWizardButton), "Finish!", "Info");
    }

    void OnWizardUpdate()
    {
        if (firstObject == null || secondObject == null)
        {
            isValid = false;
            errorString = "Select the objects you want to measure";
        }
        else
        {
            isValid = true;
            errorString = "";
        }
    }
    // Called when you press the "Info" button.
    void OnWizardOtherButton()
    {
        float distanceObjs = Vector3.Distance(firstObject.position, secondObject.position);
        EditorUtility.DisplayDialog(
            "The distance between the objects is: " + distanceObjs + " Units",
            "",
            "Ok");
    }
    // Called when you press the "Finish!" button.
    void OnWizardCreate()
    {
        EditorUtility.DisplayDialog("OnWizardCreate ", "", "Ok");
    }
}

效果:

可以自己拖物体在右面的编辑器,然后点info,会显示下图。

         3.继承EditorWindow,重写“OnGUI”函数。代码比较简单,应该都可以看懂。

代码:

using UnityEngine;
using UnityEditor;

public class MyEditorWnd : EditorWindow
{
    string myString = "Hello World";
    bool groupEnabled;
    bool myBool = true;
    float myFloat = 1.23f;

    // Add menu named "My Window" to the Window menu
    [MenuItem("Window/MyEditorWnd")]
    static void Init()
    {
        // Get existing open window or if none, make a new one:
        MyEditorWnd window = (MyEditorWnd)EditorWindow.GetWindow(typeof(MyEditorWnd));
        window.Show();
    }

    void OnGUI()
    {
        GUILayout.Label("Base Settings", EditorStyles.boldLabel);
        myString = EditorGUILayout.TextField("Text Field", myString);
        groupEnabled = EditorGUILayout.BeginToggleGroup("Optional Settings", groupEnabled);
        myBool = EditorGUILayout.Toggle("Toggle", myBool);
        myFloat = EditorGUILayout.Slider("Slider", myFloat, -3, 3);
        EditorGUILayout.EndToggleGroup();
    }
}

效果:

         4.扩展自定义组件,继承Editor类,并重写"OnInspectorGUI"函数,对自己扩展的组件的编辑界面进行定制。和第3种比较类似,可以自定义,很方便。

代码:

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(MyDefineEvent))]//当挂MyDefineEvent脚本时就会显示这个编辑器,用来让编辑器和脚本互通
public class MyDefineEditor : Editor
{
    protected MyDefineEvent m_Event;
    public Vector3 m_Des;
    void OnEnable()
    {

    }
    public override void OnInspectorGUI()
    {
        Rect rect = EditorGUILayout.BeginHorizontal(GUILayout.Height(100));
        {
            GUI.Box(rect, "");
            m_Des = EditorGUILayout.Vector3Field("目标位置m_Vec", m_Des);
        }
        EditorGUILayout.EndHorizontal();
        rect = GUILayoutUtility.GetRect(18, 18, "TextField");
        EditorGUI.ProgressBar(rect, 0.5f , "TestBar");
        EditorGUILayout.Space();
    }
}
效果:

       注:效果图只是用来展示原理,用精简的语言教会大家,自己可以扩展。

       使用CustomEditor特性把继承于Editor的类绑定到自己定义的组件类上,并重写"OnInspectorGUI"函数。如果需要在"Scene"视图中显示相应内容,需要重写OnSceneGUI。

在编辑器扩展过程中经常会用到的一些其他类,有兴趣可以自己搜一下用法,后续也会扩展,持续更新

1.Undo

​       我们在做编辑器时常用到"Undo"和"Redo"功能。Undo类提供了给特定对象注册"undo"操作。

2.ShaderGUI

​       unity中的shader都有自己的默认显示界面,如果想自定义shader的显示界面,可以继承ShaderGUI并重写"OnGUI"函数。

3.PrefabUtility

      ​ Prefab是unity中经常用到的资源,用PrefabUtility可以方便的对其进行创建,修改及其他常用操作。

4.EditorSceneManager

​       编辑器中也常对场景进行操作,EditorSceneManager提供了常用的打开,关闭,保存,设置成未保存状态,合并场景等一系列对场景的操作。

5.Selection

​         当想获得当前选中对象时可以用Selection

猜你喜欢

转载自blog.csdn.net/jfy307596479/article/details/84972848