Unity Editor Small Tutorial __unity3d

Source: Internet
Author: User
It 's written in front .

One of the most powerful places in unity is its highly extensible editor. Unite Europe 2016 has a video devoted to editor programming: Https://www.youtube.com/watch?v=9bHzTDIJX_Q

Here is a general record of the key points inside. Scene One

concerns : Draw important areas, gizmos.drawxxx Ondrawgizmos and ondrawgizmosselected callback functions click the Gizmos button to see the wireframe in the game view

    Ondrawgizmos () is invoked when the editor's scene view is refreshed
    //We can draw some data
    void Ondrawgizmos () for debug here ()
    {
        Gizmos.color = new Color (1f, 0f, 0f, 1f);
        Gizmos.drawwirecube (transform.position + boxcollider.center, boxcollider.size);

        Gizmos.color = new Color (1f, 0f, 0f, 0.3f);
        Gizmos.drawcube (transform.position + boxcollider.center, boxcollider.size);
    }

    Ondrawgizmosselect () is similar to Ondrawgizmos (), which is invoked when the object to which the component belongs is selected
    void ondrawgizmosselected ()
    {
        Gizmos.color = new Color (1f, 1f, 0f, 1f);
        Gizmos.drawwirecube (transform.position + boxcollider.center, boxcollider.size);

        Gizmos.color = new Color (1f, 1f, 0f, 0.3f);
        Gizmos.drawcube (transform.position + boxcollider.center, boxcollider.size);
    }
Scene Two

concerns : Parameters on the organization panel, adding sliders, headers, blanks, and more

    [Space (Ten)]
    public float maximumheight;
    public float minimumheight;

    [Header ("Safe Frame")]
    [Range (0f, 1f)]
    public float safeframetop;
    [Range (0f, 1f)]
    public float Safeframebottom;

Notice that the minimum surface of the upper panel has a camera height, which can be adjusted to change the height of the camera. This change can occur in editor mode and does not require a script to add Executeineditor. This is accomplished by implementing a custom editor script:

Using Unityengine;
Using Unityeditor;

Using System.Collections;
We can customize the drawing interface of the class by defining its editor type [Customeditor] for a class//This requires placing the file in the editor directory [Customeditor (typeof (Gamecamera))]

    public class Gamecameraeditor:editor {Gamecamera m_target;
        Overload Oninspectorgui () to draw its own editor public override void Oninspectorgui () {//target allows us to get the currently drawn Component object

        M_target = (Gamecamera) Target;
        Drawdefaultinspector told Unity to draw the Panel in the default way, which is useful when we just want to customize a few properties Drawdefaultinspector ();  
    Drawcameraheightpreviewslider ();

        } void Drawcameraheightpreviewslider () {guilayout.space (10);
        Vector3 cameraposition = m_Target.transform.position; CAMERAPOSITION.Y = Editorguilayout.slider ("Camera Height", CAMERAPOSITION.Y, M_target.minimumheight, m_

        Target.maximumheight); if (cameraposition.y!= m_target.transform.position.y) {//change state, use this method to record the operation so that the undo Und O.recordobject (M_targET, "Change Camera Height");
        M_Target.transform.position = cameraposition; }
    }
}
scene Three

concerns : Custom Draw list objects use Serializedobject to modify parameters unity will automatically have various help functions, such as automatically add Undo function if you modify the parameters directly, Need to use editorutility.setdirty to tell unity to need to save the data Beginchangecheck () and Endchangecheck () will detect the GUI between them has been modified, if modified can modify the parameters accordingly Undo.recordobject can add Undo/redo for next modification editorutility.displaydialog can open a built-in dialog box

First hides the default list drawing method on the panel, using Hideininspector to hide the attributes:

public class Pistone03:monobehaviour 
{public
    float Speed;
    Public Vector3 Addforcewhenhittingplayer;

    We are hiding this in the inspector because we want to draw we own custom
    //inspector for it.
    [Hideininspector]
    Public list<pistonstate> States = new list<pistonstate> ();
    ......

To allow Pistonstate to appear on the panel, you need to serialize Pistonstate:

[System.serializable] tells Unity to serialize this class if 
//it ' s used in a public array or as a public variable i n a component
[system.serializable] public
class Pistonstate 
{public
    string Name;
    Public Vector3 Position;
}

To implement a custom drawing equation:

[Customeditor (typeof (PistonE03))]
public class Pistone03editor:editor 
{
    PistonE03 m_target;

    public override void Oninspectorgui ()
    {
        m_target = (PistonE03) Target;

        Drawdefaultinspector ();
        Drawstatesinspector ();        
    }

    Draw a beautiful and useful custom inspector for our states array
    void Drawstatesinspector ()
    {
        guilayout . Space (5);
        Guilayout.label ("States", Editorstyles.boldlabel);

        for (int i = 0; i < M_Target.States.Count ++i)
        {
            drawstate (i);
        }

        Drawaddstatebutton ();
    }
Drawdefaultinspector: First draw the default, Drawstatesinspector: Custom draw panel function.

Drawstate function:

 void drawstate (int index) {if (Index < 0 | | | | | index >= m_Target.States.Count) {return; ///states variable//Serializedobject in our serializedobject allows us to easily access and modify parameters, unity will provide a series of help functions. For example, we can modify component values by serializedobject instead of directly modifying them, and unity automatically creates undo and redo functions Serializedproperty listiterator =

    Serializedobject.findproperty ("States");
    Guilayout.beginhorizontal (); {//If the parameter is modified on the instantiated prefab, we can imitate the unity default way to show the modified and not apply values to bold if (Listiterator.isinstantiatedprefab = = T 
            Rue) {//the setbolddefaultfont functionality is usually hidden-us but we can use some tricks to Access the method anyways. Implementation of our own Editorguihelper.setbolddefaultfont//for more info editorguihelp Er.
        Setbolddefaultfont (Listiterator.getarrayelementatindex (index). prefaboverride);

        } guilayout.label ("Name", Editorstyles.label, Guilayout.width (50)); BeginchangeCheck () and Endchangecheck () detect whether the GUI between them has been modified editorgui.beginchangecheck (); String newName = Guilayout.textfield (m_target.states[index).
        Name, Guilayout.width (120)); Vector3 newposition = Editorguilayout.vector3field ("", m_target.states[Index).

        Position); If modified, Endchangecheck () returns True, at which point we can do some action such as storing the changed value if (Editorgui.endchangecheck ()) {/

            /create an Undo/redo step for this modification Undo.recordobject (m_target, "Modify State"); m_target.states[index].
            Name = NewName; m_target.states[index].

            Position = newposition; If we modify the attributes directly without passing the serializedobject, unity does not save the data, unity will save only those attributes that are identified as Dirty Editorutility.setdirty (M_target)
        ;

        } Editorguihelper.setbolddefaultfont (FALSE);

            if (Guilayout.button ("Remove")) {editorapplication.beep (); It is convenient to display a dialog box that contains a specific button, such as whether to agree to delete the IF (EditorutIlity. Displaydialog ("Really?", "Do your really want to remove" "+ m_target.states[Index].
                Name + "'?", "Yes", "No") = = True) {Undo.recordobject (M_target, "Delete State");
                M_Target.States.RemoveAt (index);
            Editorutility.setdirty (M_target); }} guilayout.endhorizontal ();
scene Four

attention points : Sortable array panel, implemented by using Reorderablelist, and its various callback functions

Using Unityengine;
Using Unityeditor; Unityeditorinternal is an internal use of unity, not yet open to users of some libraries, there may be some interesting classes, such as reorderablelist, but note that the new version may be changed using
unityeditorinternal;

Using System.Collections; Caneditmultipleobjects tells Unity that when we select multiple components of the same type, our custom panel is capable of supporting all the selected components at the same time, if we are using Serializedobject to modify the parameters, Then this unity will be automatically completed//But if we are using "target" to access and modify parameters, this variable can only access the selected first component//At this time we can use "targets" to get all the same selected components [ Caneditmultipleobjects] [Customeditor (typeof (Pistone04pattern))] public class Pistone04patterneditor:editor {/
    /Unityeditorinternal provides a sort of sortable list panel display class Reorderablelist m_list;

    PistonE03 M_piston;
        Onenable will be invoked when the custom panel is opened, for example, when a gameobject with Pistone04pattern is selected, void Onenable () {if (target = null)
        {return;
        } findpistoncomponent ();
        Createreorderablelist ();
        Setupreoirderablelistheaderdrawer ();
        Setupreorderablelistelementdrawer ();
    Setupreorderablelistonadddropdowncallback (); } void FIndpistoncomponent () {M_piston = (target as Pistone04pattern).
    Getcomponent<pistone03> (); } void Createreorderablelist () {//Reorderablelist is a great implementation class for viewing array type variables. It is located in unityeditorinternal, which means unity does not feel that the class is good enough to be open to the public//More about reorderablelists content can refer to://Http://va.lent.in/un Ity-make-your-lists-functional-with-reorderablelist/m_list = new Reorderablelist (Seriali Zedobject, Serializedobject.findproperty ("pattern"), True, True, true, t
    Rue); } void Setupreoirderablelistheaderdrawer () {//Reorderablelist has a series of callback functions to let us overload the drawing of these arrays//here we use draw Headercallback to draw the table's head headers//each callback will accept a RECT variable that contains the position of the element drawn//So we can use this variable to determine where we are drawing the current element M_lis T.drawheadercallback = (Rect Rect) => {Editorgui.labelfield (new R 
 ECT (Rect.x, Rect.y, rect.width-60, Rect.height),               "State"); Editorgui.labelfield (New Rect (Rect.x + rect.width-60, Rect.y, Rect.height), "Dela
        Y ");
    }; } void Setupreorderablelistelementdrawer () {//Drawelementcallback defines how each element in the list is drawn//same, ensuring that we draw  The elements are drawn relative to the Rect parameter M_list.drawelementcallback = (Rect Rect, int index, BOOL isactive, BOOL isfocused)
            => {var element = M_List.serializedProperty.GetArrayElementAtIndex (index);

            Rect.y + 2;
            float delaywidth = 60;

            float namewidth = rect.width-delaywidth;
                Editorgui.propertyfield (New Rect (Rect.x, Rect.y, nameWidth-5, Editorguiutility.singlelineheight), Element.

            Findpropertyrelative ("Name"), Guicontent.none); Editorgui.propertyfield (new Rect rect.x + namewidth, Rect.y, Delaywidth, Editorguiutility.singlelineheig
         HT),       Element.
        Findpropertyrelative ("Delayafterwards"), Guicontent.none);
    };
        } void Setupreorderablelistonadddropdowncallback () {//Onadddropdowncallback defines the event that occurs when we click the [+] button below the list In this case, we want to display a drop-down menu to give some predefined states M_list.onadddropdowncallback = (Rect buttonrect, reorderable
                List L) => {if (m_piston.states = null | | m_Piston.States.Count = 0) {
                Editorapplication.beep ();
                Editorutility.displaydialog ("Error", "You don ' t have any states defined in the PistonE03 component", "OK");
            Return

            var menu = new Genericmenu (); foreach (pistonstate state in m_piston.states) {menu. AddItem New Guicontent (state.
                              Name), False, Onreorderablelistadddropdownclick,
            State); } mEnu.
        Showascontext ();
    }; }//This callback function calls void Onreorderablelistadddropdownclick (object target) {Pistonst After the user selects an item in the [+] drop-down Menu

        Ate state = (pistonstate) target;
        int index = m_List.serializedProperty.arraySize;
        m_list.serializedproperty.arraysize++;

        M_list.index = index;
        Serializedproperty element = M_List.serializedProperty.GetArrayElementAtIndex (index); Element. Findpropertyrelative ("Name"). StringValue = state.
        Name; Element.

        Findpropertyrelative ("Delayafterwards"). Floatvalue = 0f;
    Serializedobject.applymodifiedproperties ();

        public override void Oninspectorgui () {guilayout.space (5);

        Editorguilayout.propertyfield (Serializedobject.findproperty ("delaypatternatbeginning"));
        Serializedobject.applymodifiedproperties ();

        Serializedobject.update ();
        M_list.dolayoutlist ();
    Serializedobject.applymodifiedproperties (); }
}
Scene Five

Focus : Implements an editor window that can preview effects in the editor state

Using Unityengine;
To implement a custom window you need to include the unityeditor using Unityeditor;

Using System.Collections; Editorwindow is another very useful editor class. We can rely on it to define our own Windows public class Previewplaybackwindow:editorwindow {//MenuItem can let us Open this window in the menu bar [MenuItem ("Window /preview Playback window ")] static void Openpreviewplaybackwindow () {EDITORWINDOW.GETWINDOW&LT;PREVIEWPL
        Aybackwindow> (False, "Playback"); Another useful writing is the following//allows us to access the properties of the window, such as defining the minimum size//editorwindow window = Editorwindow.getwindow<previewplayb
        Ackwindow> (False, "Playback");
    Window.minsize = new Vector2 (100.0f, 100.0f);
    float M_playbackmodifier;

    float M_lasttime; The void onenable () {//Update function is invoked 30 times per second to refresh the editor interface//We can register our editor update function accordingly EDITORAPPLICATION.UPD
        ate-= OnUpdate;
    Editorapplication.update + = OnUpdate;
    } void Ondisable () {editorapplication.update-= OnUpdate;
       } void OnUpdate () { if (m_playbackmodifier!= 0f) {//Previewtime is a custom class://public class Previewtime        {//public static float time//{//Get//                {//if (application.isplaying = = true)//{//
            return UnityEngine.Time.timeSinceLevelLoad; ////Editorprefsle is similar to playerprefs but works only in editor/////We can deposit it accordingly
            Storage variables, basically we close the editor the variable can also be saved long//return Editorprefs.getfloat ("Previewtime", 0f); }//Set//{//Editorprefs.setfloat ("Previewtime
            ", value); }///////M_playbackmodifier is a variable used to control the preview playback rate//When it is not 0, say Ming needs to refresh the interface, update time previewtime.time + = (Time.realtimesincestartup- m_lasttime) * M_playbackmodifier; When the preview time changes, we need to make sure that we redraw the window so that we can immediately see its update//and unity will redraw only when it thinks that the window needs to be redrawn (for example, when we move the window)//So we can call the repaint function

            To force the immediate redrawing of the Repaint ();
        Since the preview time has changed, we also want to be able to redraw the scene View Interface Sceneview.repaintall () immediately;
    } m_lasttime = Time.realtimesincestartup;
        void Ongui () {//Draw individual buttons to control preview time float seconds = mathf.floor (previewtime.time% 60);

        Float minutes = Mathf.floor (PREVIEWTIME.TIME/60); Guilayout.label ("Preview time:" + minutes + ":" + seconds.
        ToString ("00"));

        Guilayout.label ("Playback Speed:" + m_playbackmodifier);
        Guilayout.beginhorizontal (); {if (Guilayout.button ("|<", Guilayout.height ()) {previewtime.time = 0
                F
            Sceneview.repaintall ();
    } if (Guilayout.button ("<<", Guilayout.height (30)) {            M_playbackmodifier = -5f;  } if (Guilayout.button ("<", guilayout.height) {m_playbackmodifier =
            -1f; } if (Guilayout.button ("| |", guilayout.height ()) {m_playbackmodifier = 0
            F  } if (Guilayout.button (">", guilayout.height) {m_playbackmodifier =
            1f; } if (Guilayout.button (">>", Guilayout.height) {M_playbackmodifi
            ER = 5f;
    } guilayout.endhorizontal (); }
}

In order to see the motion of the Cube in the editor state, we also need to implement Ondrawgizmos to draw some wireframe representation motion. The principle is to use previewtime.time to control movement. Scene Six

Focus : In Scene view, the mouse position draws a specific handle

Using Unityengine;
Using Unityeditor;

Using System.Collections; [Initializeonload] ensures that the constructor of this class is invoked on the editor load [Initializeonload] public class Leveleditore06cubehandle:editor {Publi
    c static Vector3 currenthandleposition = Vector3.zero;

    public static bool Ismouseinvalidarea = FALSE;

    static Vector3 m_oldhandleposition = Vector3.zero; Static Leveleditore06cubehandle () {//the Onscenegui delegate is called every time the Sceneview was redrawn an D allows you//to draw GUI elements into the Sceneview to create in Editor functionality//Onscenegui delegate in S
        The Cene view is invoked each time it is redrawn//This allows us to draw a custom GUI element sceneview.onsceneguidelegate-= Onscenegui in the scene view;
    Sceneview.onsceneguidelegate + = Onscenegui;
    } void OnDestroy () {sceneview.onsceneguidelegate-= Onscenegui;
            } static void Onscenegui (Sceneview sceneview) {if (isincorrectlevel () = = False) {
        Return } bool isleveleditorenabled = Editorprefs.getbool ("isleveleditorenabled", True 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.