I was about to answer too with too much haste! Didn’t see that you were looking to use Arrays. I have an example of mine. But I used a list… Since it doesn’t require you to set the array size…
In my class that I was editing I had this
Part of the Edited Class looks like.
[SerializeField]
pubic List<bool> foldout = new List<bool>();
[SerializeField]
public List<QuestDialog> DialogList = new List<QuestDialog>(); //Dialog
Where QuestDialog is nothing more then a custom data type I made, Which holds a 3 different strings.
The Editor
//Add Dialog and User Options to Quest
self.Counter = EditorGUILayout.IntSlider(self.Counter, 0, 10); //Slider Counter
if(self.Counter > self.foldout.Count) //If the counter is greater then foldout count
{
var temp = (self.Counter - self.foldout.Count);
for(int j = 0; j < temp ; j++)
self.foldout.Add(true);
}
if(self.Counter > self.DialogList.Count) //If the Slider is higher add more elements.
{
var temp = self.Counter - self.DialogList.Count;
for(int j = 0; j < temp ; j++)
{
self.DialogList.Add(new QuestDialog() );
}
}
if(self.DialogList.Count > self.Counter)
{
self.DialogList.RemoveRange( (self.Counter), self.DialogList.Count - (self.Counter)); // If the list is longer then the set size
self.foldout.RemoveRange( (self.Counter), self.foldout.Count-(self.Counter));
}
for(int i = 0; i < self.Counter; i++)
{
if(self.foldout[i] = EditorGUILayout.Foldout(self.foldout[i],"Dialog "+ i ) )
{
EditorGUILayout.LabelField("Dialog", ":smile:ialog By NPC");
self.DialogList[i].Dialog = EditorGUILayout.TextArea(self.DialogList[i].Dialog, GUILayout.Width(300) );
EditorGUILayout.LabelField("Accept",":User Accepting to NPC Dialog", GUILayout.Width(300) );
self.DialogList[i].InputAccept = EditorGUILayout.TextArea(self.DialogList[i].InputAccept, GUILayout.Width(300));
EditorGUILayout.LabelField("Decline:",":User Declining to NPC Dialog", GUILayout.Width(300) );
self.DialogList[i].InputDecline = EditorGUILayout.TextArea(self.DialogList[i].InputDecline,GUILayout.Width(300));
GUILayout.Space(10.0f);
}
}
Edit Heres a picture :
I made a List of bools so I each added quest dialog could be independantly foldedout or in. I wrote this quite some time ago. But it did the trick. Probably go back to it eventually and fix it up… Anyways I hope this helped you out in someway.
Still has to be in C# because I don’t know how js uses lists and such if its different and I don’t really want to go and google it.
self.Counter = EditorGUILayout.IntSlider(self.Counter, 0, 10); // Must use some way of inputing a number for the array size or list size.
if(self.Counter > self.DialogList.Count) //If the Slider is higher add more elements.
{
var temp = self.Counter - self.DialogList.Count; //Forgot that I used a counter to keep track of the slider, Since all
//Information stored from Editors isn't kept.
for(int j = 0; j < temp ; j++) //For a list we add as many elements we need
{
self.DialogList.Add(new QuestDialog() );
}
//If you wanted to use arrays
target.someAnimation = new String[target.Counter]; //C# also when I use self.. its merly the target script being referenced.
target.sound = new AudioClip[target.Counter]; //C#
//Now the problem with arrays is when you change the size you lose all data.. Lists you can keep update your min slider point.. If you use my above method to only remove the range that your missing.
}
//After you figure out what you want to do there simply loop through your new created objects.. to there count value.
for(int i = 0; i < self.Counter; i++)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Animation String");
target.someAnimation[i] = EditorGUILayout.TextField(target.someAnimation[i] );
EditorGUILayout.EndHorizontal();
//same thing for your AudioClips
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Animation String");
target.sound[i] = (AudioClip) EditorGUILayout.ObjectField(target.sound[i], typeof(AudioClip), true );
EditorGUILayout.EndHorizontal();
}
I typed this all in this window so it may look hidious… If you can’t figure it out based on this then I can’t help you ;P…
To respond to your initial question… None of this is “Editor” material. This is all GameObject stuff. And your stuck on it because you are not referencing the first class correctly:
class PlaySound{
public var sound : AudioClip[];
public var someAnimation : String[];
public function Play(obj : GameObject)
{
if(obj.audio){
obj.audio.clip = sound[Random.Range(0, sound.length)];
obj.audio.Play();
}
if(obj.animation)
obj.animation.CrossFadeQueued(someAnimation[Random.Range(0, someAnimation.Length)], 0.15, QueueMode.PlayNow);
}
}
var playSound : PlaySound;
function Start(){
print(playSound.sound.Length);
}
and this must be editor script for PlaySound script?
you are confusing me more and more… I need only find the way how to add arrays(like variable var sound : AudioClip[ ];) to my editor script. I can’t find the right way how to do that.
No, none of this has to be an Editor script. Add the code I gave you to an object. In the inspector for that object, click the arrow beside Play Sound. This will open up two arrays. Set the length of the array, drag sounds to the sound, fill the strings with animation names and let her rip.
An editor script should only be created when you are trying to fulfill these obligations without directly dragging them. So in script, you would fulfill the string array like this:
someAnimation = [“this”, “is”, “a”, “test”];
clips would be a bit different as you would have to have them in the system and generate a list.
Sounds and animations are just for example of my question.
all i want is to add arrays [ ] to my editor script , but i don’t know how. Everything else i know how to add.
The easiest way I’ve found so far to deal with situations like this is to just use DrawDefaultInspector() in your editor script(which does what the name implies) to get the array editor functionality, and then just draw your own inspector after that. It is possible to duplicate the built in editor functionality on your own, but it’s quite a bit simpler to just let the default code do it.
I wrote a quick class and editor. Again I don’t understand JS enough to write stuff well enough in there so I did it in c# but I’m including the files I wrote in a handy zip file…
You can load it into your project and see that it works the same as the picture. 661673–23676–$__eTest.zip (1.16 KB)
im getting two errors:
Assets/Editor/HolderClassEditor.cs(51,61): error CS1502: The best overloaded method match for UnityEditor.EditorGUILayout.ObjectField(string, UnityEngine.Object, System.Type, params UnityEngine.GUILayoutOption[ ])' has some invalid arguments Assets/Editor/HolderClassEditor.cs(51,61): error CS1503: Argument #4’ cannot convert bool' expression to type UnityEngine.GUILayoutOption[ ]’
The true added at the end is so Unity will stop complaining and giving some warning. The code in the Zip folder works. That’s exactly how I took the SS of that. What Version of Unity are you running? I think that his true at the end is new.
I’m using Lists to Store the data for sound and strings. Your using array. I don’t think its going to work the same for you…
I’m positive js has lists… But I don’t know how to write them.
The “self” that I reference is the same as your “target”.
visually all works fine and i don’t get any errors, but for some reasons i can’t add sounds
@CustomEditor(HolderClass)
class HolderClassEditor extends Editor{
override function OnInspectorGUI (){
var sk : HolderClass = target as HolderClass;
EditorGUILayout.BeginVertical ();
sk.size = EditorGUILayout.IntField("Size", sk.size);
sk.sounds = new AudioClip[sk.size];
for( var i : int = 0; i < sk.sounds.length; i++){
sk.sounds[i] = EditorGUILayout.ObjectField("Clip_" + i + ":" , sk.sounds[i], AudioClip, true) as AudioClip;
GUILayout.Space(10);
}
EditorGUILayout.EndVertical ();
}
}
class HolderClass extends MonoBehaviour {
var size : int = 0;
var sounds : AudioClip[];
}