Trying to customize NGUI - UIButton in the Inspector - unity3d

When I try to customize a class of "NGUI - UIButton",
I got a problem that's not working serialize variables in Unity editor inspector view.
public class MyButton : UIButton // inherited NGUIButton class
{
public bool _isChecked;
public int _count;
}
I can't see the variables in the inspector of Unity editor.
How can I see the variables in inspector?
I was trying it with [serializeField] script too.
But it's also not working
Is there something special about NGUI?

Related

Serializable object is looking weird in the inspector

So I have this small class called StoryTrigger:
namespace VisualNovelScripting
{
[System.Serializable]
public class StoryTrigger
{
[SerializeField] public string triggerName;
public bool value;
public StoryTrigger(string name, bool value = false)
{
this.triggerName = name;
this.value = value;
}
}
}
And I want to make a ScriptableObject with a list of StoryTrigger objects that could add, remove and edit elements right on the unity inspector.
I assumed that if the StoryTrigger had the [System.Serializable] modified it should work. And It kind of works but looks like this on the inspector:
I want to know if there's something I am doing wrong or something I could do better so it doesn't look this weird on the inspector or if this is an issue on the unity editor.
I saw that when I add only 1 element to the StoryTriggers list it does look weird on the inspector like shown in the question.
But when I add multiple elements it stops looking weird. So I can work with it.
I assume this is a bug on the Unity Editor since the condition to the weird behavior is on the amount of elements on the list.

How to set a button component's transition option to "none" via C# in Unity?

I need to setup my button components in Unity to look like this via C# (i.e. with "Transition" and "Navigation" set to "None").
For the Navigation, it was a little unintuitive but I eventually found that this worked:
Navigation customNav = new Navigation();
customNav.mode = Navigation.Mode.None;
myButton.navigation = customNav;
But I can't for the life of me find a equivalent for "Transition". If it's in the documentation, it must be buried under a heading I can't find. Does anyone have any idea how it can be done?
You can change the transition value by assigning a Selectable.Transition type enum value to the .transition property.
Example
using UnityEngine;
using UnityEngine.UI;
public class TestScript : MonoBehaviour
{
[SerializeField]
private Button target = null;
private void Start()
{
target.transition = Selectable.Transition.None;
}
}
Reference
https://docs.unity3d.com/2017.3/Documentation/ScriptReference/UI.Selectable-transition.html

Saving string variables in a custom EditorWindow while formatted like a TextArea

Basically, I want to figure out how I can:
Save string (or any) variables in a custom editor window (inheriting
from EditorWindow) when they are changed in that window.
Display strings in a format like a TextArea while still allowing
saving changes as mentioned above.
Display strings from a string array by index, rather than individually defined strings (I've had trouble with this before)
If you know how to do the above in a custom inspector too
(inheriting from Editor, not EditorWindow), that'd be great too.
I've run into this issue a few times with different classes inheriting from Editor, and previously solved by using a PropertyField rather than a TextArea/TextField, but that gets rid of the TextArea-style formatting that I want.
Also, classes inheriting from EditorWindow don't seem to allow it in the same way (t = (script type)target; doesn't work, and PropertyField needs it)..?
I'm pretty new to custom inspectors and this stuff, so code examples would be super helpful if possible.
Thanks!
Before starting a general note because you mentioned it in your question:
Whenever possible I strongly recommend to avoid using target at all! In particular do not set any fields directly. this makes things like marking your scene direty and thus saving changes and also Undo/Redo functionality pretty complicated as you will have to implement it by yourself!
Rather always go through SerializedProperty combined with SerializedObject.Update and SerializedObject.ApplyModifiedProperties (examples will be below). This handles all this stuff like marking dirty and thus saving the scene changes and Undo/Redo automatically for you!
Then to the TextArea.
Lets say you have a class like
public class Example : MonoBehaviour
{
[SerializeField] private string _exampleString;
public string AnotherExampleString;
}
Basically there are three main options. I will do the Editor (custom Inspector) script first since there you are a bit more flexible.
The EditorWindow will be below.
Editor Attribute [TextArea]
Actually you wouldn't even need an Editor script at all! Simply tag the according field(s) as [TextArea] like this:
public class Example : MonoBehaviour
{
[SerializeField] [TextArea] private string _exampleString;
// You can also directly configure the min and max line count here as well
// By default it is 3 lines
[TextAre(3,7)] public string AnotherExampleString;
}
This already looks like this
EditorGUILayout.PropertyField
Then if you still need the Editor script the good thing about a EditorGUILayout.PropertyField is it automatically uses the correct drawer for the according type ... and it also applies all editor attributes! Isn't this great?
So simply having and Editor like
[CustomEditor(typeof(Example))]
public class ExampleEditor : Editor
{
private SerializedProperty _exampleString;
private SerializedProperty AnotherExampleString;
private void OnEnable()
{
// Link in the serialized properties to their according fields
_exampleString = serializedObject.FindProperty("_exampleString");
AnotherExampleString = serializedObject.FindProperty("AnotherExampleString");
}
public override void OnInspectorGUI()
{
DrawScriptField();
// load the real target values into the serialized properties
serializedObject.Update();
EditorGUILayout.PropertyField(_exampleString);
EditorGUILayout.PropertyField(AnotherExampleString);
// write back the changed properties into the real target
serializedObject.ApplyModifiedProperties();
}
// Little bonus from my side so you have the script field on top
private void DrawScriptField()
{
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.ObjectField("Script", MonoScript.FromMonoBehaviour((Example)target), typeof(Example), false);
EditorGUILayout.Space();
EditorGUI.EndDisabledGroup();
}
}
The result looks basically exactly the same:
EditorGUILayout.TextField
Using a EditorGUILayout.TextArea you can display any string as a multi-line text area. This also applies to an EditorWindow.
Lets say again we didn't tag our string fields
public class Example : MonoBehaviour
{
[SerializeField] private string _exampleString;
public string AnotherExampleString;
}
But we can make them appear just as before using this Editor script:
[CustomEditor(typeof(Example))]
public class ExampleEditor : Editor
{
private SerializedProperty _exampleString;
private SerializedProperty AnotherExampleString;
private Vector2 scroll1;
private Vector2 scroll2;
private void OnEnable()
{
// Link in the serialized properties to their according fields
_exampleString = serializedObject.FindProperty("_exampleString");
AnotherExampleString = serializedObject.FindProperty("AnotherExampleString");
}
public override void OnInspectorGUI()
{
DrawScriptField();
// load the real target values into the serialized properties
serializedObject.Update();
EditorGUILayout.PrefixLabel(_exampleString.displayName);
scroll1 = EditorGUILayout.BeginScrollView(scroll1,GUILayout.MaxHeight(3 * EditorGUIUtility.singleLineHeight));
_exampleString.stringValue = EditorGUILayout.TextArea(_exampleString.stringValue, EditorStyles.textArea);
EditorGUILayout.EndScrollView();
EditorGUILayout.PrefixLabel(AnotherExampleString.displayName);
scroll2 = EditorGUILayout.BeginScrollView(scroll2, GUILayout.MaxHeight(7 * EditorGUIUtility.singleLineHeight));
AnotherExampleString.stringValue = EditorGUILayout.TextArea(AnotherExampleString.stringValue);
EditorGUILayout.EndScrollView();
// write back the changed properties into the real target
serializedObject.ApplyModifiedProperties();
}
// Little bonus from my side so you have the script field on top
private void DrawScriptField()
{
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.ObjectField("Script", MonoScript.FromMonoBehaviour((Example)target), typeof(Example), false);
EditorGUILayout.Space();
EditorGUI.EndDisabledGroup();
}
}
Though you can see we already had to fake it a bit using the additional EditorGUILayout.BeginScrollView
This same thing you can also do in an EditorWindow. Most of the times it makes not much sense to go through SerializedProperty for EditorWindow
public class ExampleWindow : EditorWindow
{
private string exampleString;
private Vector2 scroll;
[MenuItem("Example/Show ExampleWindow")]
private static void Initialize()
{
var window = GetWindow<ExampleWindow>();
window.Show();
}
private void OnGUI()
{
EditorGUILayout.PrefixLabel("Example String");
scroll = EditorGUILayout.BeginScrollView(scroll,GUILayout.MaxHeight(3 * EditorGUIUtility.singleLineHeight));
exampleString = EditorGUILayout.TextArea(exampleString, EditorStyles.textArea);
EditorGUILayout.EndScrollView();
}
}
which results in

Auto-Draggable Variables

I want to be able to drag & drop variables (such as floats, integers, maybe even classes) in the Inspector view. So that if I have FirstScript and SecondScript I could easily drag & drop variables between them so that they can change each others' data. I need this to create more modular workflow.
I know that ScriptableObjects allow similar functionality but I need to create them manually through Create button in Inspector. Instead I want this to happen automatically.
This should look something like scripts below. So that I could drag the original_float to float_to_change field right in the Inspector.
// First Component
public class FirstScript : MonoBehaviour
{
public DraggableFloat original_float = 5.0f;
}
// SecondComponent
public class SecondScript: MonoBehaviour
{
public DraggableFloat float_to_change;
public void ChangeFloat()
{
// The value of original_float is changed through reference
float_to_change += 10.0f;
}
}

Extending UnityEngine.UI.Image and add extra field available in Inspector

I am trying to extend UnityEngine.UI.Image like that
public class MyImage : Image {
public string Comment;
}
But I do not see extra text field Comment in inspector. Is it possible to add extra field that would be available in inspector?
PS It triggered as duplicated for Extending Unity UI components with custom Inspector but it is not dupe. I do not ask anything about custom Inspector. It is just regular field with default Inspector. The problem is that field is not appearing in inspector at all.
Unfortunately, the Inspector GUI cannot inherit from base class automatically. You need to write that yourself, just like what is described in Extending Unity UI components with custom Inspector.
MyImage.cs
using UnityEngine;
using UnityEngine.UI;
[ExecuteInEditMode]
public class MyImage : Image
{
public string Comment;
}
MyImageEditor.cs
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(MyImage))]
public class MyImageEditor : UnityEditor.UI.ImageEditor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();//Draw inspector UI of ImageEditor
MyImage image = (MyImage)target;
image.Comment = EditorGUILayout.TextField("Comment", image.Comment);
}
}
Result: