Before you read this tutorial, you need to have some basic understanding of unity's operational processes, and it is best to understand how the built-in GUI system is used.
How to get the editor to run your code
Unity3d can execute your editor code through event triggering, but we need some compiler parameters to tell the compiler when it needs to trigger the code.
[MenuItem (XXX)] declares above a function, tells the compiler to add a menu item to the Unity3d editor, and calls the function when it clicks the menu item. Trigger function can write any legitimate code, can be a resource batch program, you can also pop up an editor window. The code can access the currently selected content (through the selection Class) and determine the display view accordingly. Similarly, [ContextMenu ("XXX")] can add a menu item to your context menu.
When you write some component script, when it is attached to a gameobject and you want to see the effect in scene view in Edit view, you can write [Executeineditmode] above the class to inform the compiler. Functions such as Ongui and update of this class are also called in edit mode. We can also use [Addcomponentmenu ("xxx/xxx")] to associate the script with the Component menu and click on the menu item to add the component script for Gameobject.
start writing an editor
To avoid unnecessary inclusions, the Unity3d Runtime and editor classes are stored in different assemblies (Unityengine and Unityeditor). Before you start writing the editor, you need a using Unityeditor to import the editor's namespace.
Some of the code might be executed by both the runtime and the editor, and if you want to differentiate between them, you can use the # if Unity_editor ... #endif宏来对编辑器代码做特殊处理.
Before you start to actually write the code, I think you need to know that all the scripts placed in the directory named editor will be compiled after the other scripts, which makes it easier for you to use those runtime content. The scripts in those directories are not accessible to the contents of the editor directory. So, you'd better write your editor script in the editor directory.
How to create a custom editor window
Create your own window
If you want to customize an editable panel, then you need to write a class that inherits from Editorwindow. Typically, you also need to write a [MenuItem] to tell the compiler when to open the Panel. The callback for this event should be a static method and return an instance of a window.
Now, when you click on the corresponding menu item, a blank window pops up. And you can drag and dock as you like the Unity3d Editor's prefabricated window. Let's see how we can implement the features we want in the window.
Expand Your Window
As with the runtime GUI, if you need to add interactive controls to the window, you must override the Ongui method. As with the runtime GUI, you can even use any plug-ins that extend from native GUI systems (such as Igui and Guix) to simplify your plug-in development process (only initial testing, deeper usability is yet to be verified). At the same time, the editorguilayout under the Unityeditor namespace provides some more convenient interfaces and controls on the native GUI, allowing you to easily use some of the editor-specific UI controls.
In addition to Ongui, you may also need some of the following callbacks to trigger specific logic (see the official documentation for a complete list):
L Onselectionchange, but when you click on an item, it triggers.
L Onfocus/onlostfocus, trigger when acquiring and losing focus
Extend your window further
Custom Controls
As with the run-time GUI, if you are going to customize your own control, the simplest way is to implement a static method (or not static), and provide some optional parameters to complete the layout of the control within the method based on these parameters (as you did in Ongui).
If you're going to implement a custom control inside a window class, you can use the partial class to better manage your code.
Draw 2D Content
Drawing Pictures
You can use Gui.drawtexture to finish drawing a picture resource.
To draw an underlying primitive
The GUI itself does not provide a way to draw the underlying primitives, but these methods can be encapsulated in a number of ways.
L Draw segment: the mapping resource of a pixel with gui.drawtexture and matrix rotation to complete the line segment.
L Draw rectangles: Gui.box and style settings to encapsulate rectangles and rectangles
Fill the box.
Resource Selector
The Editorlayout.objectfield control provides a resource selection logic that you need to specify when generating a resource type. You can then drag that kind of resource to the control or click the small circle next to the control to make a list selection.
how to store edits
You may need to create a class that inherits from Serializedobject to save the edited data. Objects that inherit from Serializedobject can be used to store data without participating in rendering, and can eventually be packaged into Assetbundle.
For storage of content such as the current editing options, another Serializedobject class (related to the specific system design) may be required.
Wizard-style editing window
In many cases you may need an edit panel with a lot of parameters, and then a button to confirm it after the edit is complete. You don't have to do this yourself, Unityeditor provides scriptablewizard to help you develop quickly.
He is inherited from the Editorwindow, so their use is very similar. Note, however, that onwizardcreate () is called when you click the Confirm button. In addition, Scriptablewizard.displaywizard can help you build and display the window.
How to extend the Inspector panel
When you select an object in Unity3d, the Inspector panel displays the properties of the object. We can extend the panel for a type of object, which is useful when developing plug-ins for Unity3d.
define when inspector is triggered
The custom Inspector panel needs to inherit the editor class. Because the functionality is relatively specific, you do not need to define when the code is triggered, and the corresponding code executes automatically when you click on the object it corresponds to.
So how do you define the type it corresponds to? This can only be done by using the compiler's command [Customeditor (typeof (XXX)]) before your class definition.
accessing the object being edited
In the Inspector view, we often need to access the object being edited. This association is provided by the member variable target of the editor class.
However, it is important to note that target is an object of type objects, which may require type conversions (you can use generics in C # to avoid duplicate type conversions).
implement your own Inspector interface
The only difference between extension editor and extended Editorwindow is that you need to rewrite Oninspectorgui instead of Ongui. Also, if you want to draw the default editable items, simply call Drawdefaultinspector.
defining an edit handle in the scene interface
When an object is selected, we may want to define some edits or displays in the scene view as well. This work can be done through the Onscenegui and handle classes. Onscenegui is used to handle events from the scene view, while the handle class is used to implement some 3D GUI controls in the scene view (for example, a position controller that controls the location of objects).
Refer to the official reference documentation for specific usage.
Some common feature descriptions
L Assetdatabase.createasset can help you create a resource instance from the resource directory.
L Selection.activeobject Returns the currently selected object.
L Editorguiutility.pingobject is used to implement an action that clicks on an item in the Project window.
L Editor.repaint is used to redraw all the controls on the interface.
L Xxximporter is used to set specific import settings for a resource (for example, in some cases you need to set the imported map to be readable).
L Editorutility.unloadunusedassets is used to release unused resources and prevent your plug-in from generating a memory leak.
L Event.use is used to mark the event has been processed to the end.
L Editorutility.setdirty is used to inform the editor that the data has been modified so that the next time the data is saved will be stored.
The convenience of Unity3d is that it is easy to extend the editor suite. Each game has different requirements for processing, which can be quickly and fully integrated to build these content and greatly increase the speed of development.
There are a number of complex packages that provide complex tools based on the basic Unity feature suite, from the Visual Script Editor to the navigation grid in the editor. However, there are few procedural instructions on how to build such things yourself. I'll list some of the editor customizations that I've summarized in my work.
Unity-window (from Gamasutra)
How to build editor scripts
Because you don't want to include all of the editor customizations in the game, and you don't want the game to be dependent on something in some unity editor, Unity places the runtime and editor code in a separate compilation.
In the edit command, the run time code is executed before the editor code so that the editor type can be reliably contacted by the runtime component (game state Note: Otherwise it becomes difficult to edit), but your runtime component does not involve any editor code.
You must maintain a strict level. This aspect of the Unity 3.4 release is more specific, and now the resulting project file corresponds to the 4 editing stages it provides, so that it does not confuse the build time of the file.
The program description at a point is somewhat unclear. When I first started using it, I thought I needed to create a single "editor" folder on my project and put all the editor types in it. In fact, the system is more flexible, and you can create any number of "editor" folders in your project and bury them anywhere in the assets folder, all of which can hold editor code.
So now I usually use the function (game state Note: for example, named "AI") to create a folder, then include all of the feature-related components, and then put the editor folder next to it (game State Note: for example, named "Ai/editor"), install all the editor extensions that run these components.
As long as Unity's intrinsic type works, the runtime type will exist in the Unityengine namespace, and all editor types will exist in the Unityeditor namespace.
Unity-projectlist (from Gamasutra)
Unityeditor.editor class
So far, the most common customization I have set up is a custom checker. Unity's Inspector Panel provides a window that sees the state of the component, but this basic setting only understands a limited type and can only show public areas.
The custom inspector gives you complete control over how users view and edit your components. For example, they can allow you to present read-only assets, compulsive value restrictions, or only change the way options are presented.
Inspector in Unity is a subcategory of the editor class, so you should start here. However, I don't like the way the editor class handles styles. There's a "Target" in it that mentions the object the inspector is editing, but it's just the basic "object" style, so you're going to keep turning it into a more useful style. To avoid this problem, I used a very simple category, specifically as follows:
- public class Inspectorbase:editor where t:unityengine.object
- {
- Protected T Target {get {return (T) target;}}
- }
Copy Code
Now, if I want to create an inspector for Mycustomcomponent, I can get the checker from Inspectorbase and then use "Target" so I don't have to change it all the time.
It should be noted that you also need to attach the Customeditor attribute to the Inspector class for unity to be able to actually use them.
Editor GUI
Once you've created your custom checker, the way you usually want to do it is Oninspectorgui (). Oninspectorgui () can be used to specify everything that is shown in the inspector, using Unity's GUI system.
Because this is the editor code, we can use the type in the Unityeditor namespace, which includes Editorguilayout. The editorguilayout allows for a lot of simple controls that can be used in the editor, better than the unity Common runtime GUI system. For example, if I want to show the user a field that goes into a 3D position, I can use
- Editorguilayout.vector3field ():
- Target.someposition = Editorguilayout.vector3field ("Some position", target.someposition).
Copy Code
The resulting effect in the Inspector is as follows:
Unity-vec3field (from Gamasutra)
Because the GUI system works, if I change the value in the UI, Vector3field will return the new value and the Target.someposition will be updated. Before assigning it to a target, you can freely change the value (game state Note: For example, define a value in a range), and you can completely ignore the value returned.
The value does not necessarily come from the domain, you can expose the asset in the inspector, you can call a feature to get the current value and use another feature to save it.
Of course, unity will handle this by default. If you just want to build on the basis that unity has shown, you don't have to re-execute all those domains. The editor has a Drawdefaultinspector () method that tells Unity to invoke all the normally called controls, but after the process is complete, you still have the opportunity to add additional fields and keystrokes.
When it comes to keystrokes, Editorguilayout's use is quite extensive, but you may have noticed a loophole. For example, what if I wanted to add a recalculate button to the navigation grid component? The trick is that Editorguilayout is still built on the regular run time guilayout, so you can still use everything in guilayout.
When you make a change to a field in the inspector and assign a new value to the domain of the target object, unity perceives that you are changing the object, so the next time you save the screen or item, it will be written to disk. This perception is limited, and it can only identify the direct assignment of public assets. If you modify the target object by means of an asset or call method, you may need to call editorutility.setdirty yourself.
Extended Component Background Menu
Sometimes it is useful to manually raise certain behaviors while testing. You can trigger the behavior by placing a button on the custom Inspector: if (Guilayout.button ("Explode now!")) Target.explodenow ().
But there is a simpler way, and this method does not require a custom checker at all. You can use the Unityengine.contextmenu property:
/* In the target class ... */
[ContextMenu ("Explode now!")]
public void Explodenow () {...}
Right-click on the component's Inspector (game State Note: Whether or not customized), you will see the background menu, which has additional features. can be tested quickly.
Extended Main Menu
So far, everything I've said is a custom centered around a particular component. What about other kinds of extensions?
In my game, the animation system stores its assets in the folder schema so that each folder corresponds to an entry for the enum. When I change the enum, if I can synchronize the folder structure will play a big role, add any missing folders and delete
Any extra folders. So I used the following simple method:
- public class animationsystem{
- public static void Syncfolderstructure () {...}
- }
Copy Code
But when and how do I call it? My approach is to use the MenuItem property along with the menu item in the Assets menu:
- [MenuItem ("Assets/sync folder Structure")]
- public static void Syncfolderstructure () {...}
Copy Code
Click on the menu item to invoke the function. It should be noted that the function needs to be static, but the classes can be of many types.
Wizards
Editor GUI elements are not necessarily in inspector. It can also create a subjective editor window that moves like any unity built-in window, and can use GUI commands as in the inspector. The simplest way is to use Scriptablewizard, which is much like a dialog box. You set certain values after rendering, then click the button to display the "magic".
Unity-ragdollwizard (from Gamasutra)
By default, Scriptablewizard works much like the inspector: any public domain in a class is automatically rendered in the wizard window. Your wizard will be as simple as a bunch of public domains, and there is a onwizardcreate () method that unity calls when the user taps the "Create" button. And, you can change the text on the button, "Apply" or "OK" and the like will appear more intuitive.
Another aspect of the wizard is to determine how the user can open it, and the common approach is to use a menu option with static functionality, as shown in:
- [MenuItem ("Gameobject/create other/explosion")]
- public static void Createexplosion ()
- {
- Scriptablewizard.displaywizard ("Create explosion");
- }
Copy Code
( This article for the game state/gamerboom.com compiled, if necessary reprint please contact: Game State )
Original link http://www.j2megame.com/html/xwzx/ty/3842.html
If it involves the infringement of the original author, please contact me, I will immediately delete, thank you!
"Reprint" Unity3d unityeditor editor customization and development plugin