原文:http://blog.teotigraphix.com/2011/06/10/unity3d-scriptablewizard-tutorial-1/
In this blog post we talk about the Unity3D ScriptableWizard
class. I am really enjoying the API adventure intoUnity3D but, the API Scripting reference is to be desired. An example of this is theScriptableWizard
description;
"Derive from this class to create an editor wizard. Editor wizards are typically opened using a menu item."
If this description doesn’t leave you scratching your head, then can you please tell me what I’m missing? After messing around, I finally realized that the wizard base class must use reflection on the public properties to create the wizard fields. Why couldn’t they just write one more sentence and add a detail like that. Aside from giving you two button options like the classic wizard, automatic control generation is in the realm of majik as well.
Another problem I had minus the above misunderstanding is the WizardCreateLight
example they give is really mixing a wizard with an inspector. For me, this example was really confusing. Most of the wizard classes I have dealt with or written are usually called, filled out and dismissed. The WizardCreateLight
example gives you an option to create a lightOR apply a new color to the current transform. Applying values to existing instances is in the realm of an inspector. Anyway, that is just my point of view.
Tutorial version; Unity 3.3
In the class below the following can be observed;
MenuItem
attribute will create the menu item "My Scriptable Wizard" underGameObject/Wizards
CreateWizard()
to it’s command action.ScriptableWizard
class adds four messages;
OnDrawGizmo()
– Called every frame, updates a custom gizmo in the Scene view.OnWizardUpdate()
– Called when opened and when user interaction events are fired within the wizard.OnWizardCreate()
– Called when the user clicks the first wizard button.OnWizardOtherButton()
- Called when the user clicks the second wizard button.using UnityEngine;
using UnityEditor;
using System.Collections;
// A Wizard class that generates it's fields from public properties
public MyScriptableWizard : ScriptableWizard
{
//---------------------------------
// Reflection Fields
//---------------------------------
// An auto generated field
public string myGeneratedField;
//---------------------------------
// Static Methods
//---------------------------------
// Create the wizard
[MenuItem ("GameObject/Wizards/My Scriptable Wizard")]
static void CreateWizard ()
{
MyScriptableWizard wizard = DisplayWizard(
"My Scriptable Wizard", "Wizard Create", "Wizard Other Button");
}
//==================================
// Messages
//==================================
// Called every frame when the wizard is visible.
void OnDrawGizmos()
{
}
// This is called when the user clicks on the Create button.
void OnWizardCreate()
{
}
// This is called when the wizard is opened or whenever the user
// changes something in the wizard.
void OnWizardUpdate()
{
}
// Allows you to provide an action when the user clicks on the
// other button.
void onWizardOtherButton()
{
}
}
In the class below shows a pretty close approximation of all the different UserInterface controls that can be created through the wizard’s reflection mechanism.
The example also shows the use of the isValid
, errorString
andhelpString
class properties. If the intField
has not had it’s value changed from 500 and thetextField
has not had a string entered, the wizard will be in it’s disabled state. Once those two conditions are met, the wizard’sCreate and Apply button will be enabled, allowing the user to click the either button.
using UnityEngine;
using UnityEditor;
using System.Collections;
/**
* Shows the following;
*
* - ScriptableWizard.errorString
* - ScriptableWizard.helpString
* - ScriptableWizard.isValid
* - ScriptableWizard.OnDrawGizmos()
* - ScriptableWizard.OnWizardCreate()
* - ScriptableWizard.OnWizardUpdate()
* - ScriptableWizard.OnWizardOtherButton()
*
* @author Michael Schmalle
*/
public enum TestEnum {
ONE,
TWO,
THREE
}
public class MyScriptableWizard : ScriptableWizard
{
// Note: All public properties that are created as fields will have
// their names split
//----------------------------------
// Primitive Fields
//----------------------------------
// FloatField()
public float floatField = 500;
// IntField()
public int intField = 500;
// Toggle()
public bool toggle = true;
// TextField()
public string textField;
//----------------------------------
// Struct Fields
//----------------------------------
// Vector2Field()
public Vector2 vector2Field;
// Vector3Field()
public Vector3 vector3Field;
// Vector4Field()
public Vector4 vector4Field;
// RectField()
public Rect rectField;
//----------------------------------
// Enum(lists) Fields
//----------------------------------
// EnumPopup()
public LightType enumPopup1;
// EnumPopup()
public TestEnum enumPopup2;
//----------------------------------
// Custom Fields
//----------------------------------
// ColorField()
public Color colorField;
// CurveField()
public AnimationCurve curveField;
//----------------------------------
// Object Fields
//----------------------------------
// ObjectField()
public Light objectField1;
// ObjectField()
public Font objectField2;
//----------------------------------
// Static Creation
//----------------------------------
// Create the wizard
[MenuItem ("GameObject/Create My Scriptable Wizard")]
static void CreateWizard()
{
MyScriptableWizard wizard = DisplayWizard(
"My Scriptable Wizard", "Create", "Apply");
wizard.isValid = false;
}
//----------------------------------
// Messages
//----------------------------------
// Called every frame when the wizard is visible.
void OnDrawGizmos()
{
// Currently on Windows 7, I cannot get this to run
// has anybody else had this problem?
Gizmos.color = Color.green;
Gizmos.DrawWireCube(Vector3.zero, new Vector3(1,1,1));
Debug.Log("ODG()");
}
// This is called when the wizard is opened or whenever the user
// changes something in the wizard.
void OnWizardUpdate()
{
if (textField == "")
{
errorString = "Please fill in textField string";
}
else if (intField == 500)
{
errorString = "Please change the value of intField";
}
else
{
helpString = "All fields correct, Create enabled";
errorString = "";
isValid = true;
}
}
// This is called when the user clicks on the Create button.
void OnWizardCreate()
{
Debug.Log("OnWizardCreate()");
}
// Allows you to provide an action when the user clicks on the
// other button "Apply".
void OnWizardOtherButton()
{
Debug.Log("OnWizardOtherButton(Apply was pressed)");
Close();
}
}