Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Can anyone help pretty please? Seems like a simple toggle question.

Discussion in 'Scripting' started by Richop, Apr 29, 2016.

  1. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    I've made a custom GUILayout option for an array of bools so that they lie horizontal, I now have no function of the toggle button, just turning it on and off. I suspect I've been a fool somewhere and locked it out of use, but I was struggling with this till late last night pulling out my hair!

    The important part I think I'm messing up is:

    Code (CSharp):
    1. public static void ShowButtons (SerializedProperty list, int index, int numberOfSlots) {
    2.  
    3.         bool[] nOff = new bool[numberOfSlots];
    4.  
    5.         for (int i = 0; i < numberOfSlots; i++) {
    6.  
    7.             if (GUILayout.Toggle(nOff[i], buttonContent, miniButtonWidth))
    8.                 {
    9.  
    10.                 if (nOff [i] != true) {
    11.                     nOff[i] = true;
    12.                     Debug.Log (nOff[i]);
    13.                 }
    14.                 else
    15.                 {
    16.                     nOff[i] = false;
    17.                 }
    18.                 Debug.Log(index); // The Row
    19.                 Debug.Log(i); // The Collumn
    20.                 }  
    21.             }
    22.         }
    But I can't actually turn on and off the bools in the inspector, when I debug I see each button knows it's own row and column, it's just forgotten how to turn itself on and off. What am I missing, I'm going slightly crazy tracking this down!

    Here's the whole thing:

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3. using System;
    4.  
    5. [Flags]
    6. public enum EditorListOption {
    7.     None = 0,
    8.     ListSize = 1,
    9.     ListLabel = 2,
    10.     ElementLabels = 4,
    11.     NumSlots = 16,
    12.     Buttons = 16,
    13.     Toggles = 16,
    14.     Default = ListSize | ListLabel | ElementLabels,
    15.     NoElementLabels = ListSize | ListLabel,
    16.     All = Default | Buttons | NumSlots
    17. }
    18.  
    19. public static class EditorList {
    20.  
    21.     private static GUIContent
    22.  
    23.         buttonContent = new GUIContent("+");
    24.  
    25.     private static GUILayoutOption miniButtonWidth = GUILayout.Width(20f);
    26.  
    27.     public static void Show (SerializedProperty list, EditorListOption options = EditorListOption.Default) {
    28.         if (!list.isArray) {
    29.             EditorGUILayout.HelpBox(list.name + " is neither an array nor a list!", MessageType.Error);
    30.             return;
    31.         }
    32.  
    33.         bool
    34.             showListLabel = (options & EditorListOption.ListLabel) != 0,
    35.             showListSize = (options & EditorListOption.ListSize) != 0;
    36.  
    37.         //numSlots =
    38.  
    39.         if (showListLabel) {
    40.             EditorGUILayout.PropertyField(list);
    41.             EditorGUI.indentLevel += 1;
    42.         }
    43.         if (!showListLabel || list.isExpanded) {
    44.             SerializedProperty size = list.FindPropertyRelative("Array.size");
    45.             if (showListSize) {
    46.                 EditorGUILayout.PropertyField(size);
    47.             }
    48.             if (size.hasMultipleDifferentValues) {
    49.                 EditorGUILayout.HelpBox("Not showing lists with different sizes.", MessageType.Info);
    50.             }
    51.             else {
    52.                 ShowElements(list, options);
    53.             }
    54.         }
    55.         if (showListLabel) {
    56.             EditorGUI.indentLevel -= 1;
    57.         }
    58.     }
    59.  
    60.     private static void ShowElements (SerializedProperty list, EditorListOption options) {
    61.         bool
    62.             showElementLabels = (options & EditorListOption.ElementLabels) != 0,
    63.             showButtons = (options & EditorListOption.Buttons) != 0;
    64.  
    65.         for (int i = 0; i < list.arraySize; i++) {
    66.             if (showButtons) {
    67.                 EditorGUILayout.BeginHorizontal();
    68.             }
    69.             if (showButtons) {
    70.                 ShowButtons(list, i, numberOfSlots:16);
    71.                 EditorGUILayout.EndHorizontal();
    72.             }
    73.         }
    74.         if (showButtons && list.arraySize == 0 && GUILayout.Toggle(true, buttonContent, EditorStyles.miniButton)) {
    75.             list.arraySize += 1;
    76.         }
    77.     }
    78.  
    79.     public static void ShowButtons (SerializedProperty list, int index, int numberOfSlots) {
    80.  
    81.         bool[] nOff = new bool[numberOfSlots];
    82.  
    83.         for (int i = 0; i < numberOfSlots; i++) {
    84.  
    85.             if (GUILayout.Toggle(nOff[i], buttonContent, miniButtonWidth))
    86.                 {
    87.  
    88.                 if (nOff [i] != true) {
    89.                     nOff[i] = true;
    90.                     Debug.Log (nOff[i]);
    91.                 }
    92.                 else
    93.                 {
    94.                     nOff[i] = false;
    95.                 }
    96.                 Debug.Log(index); // The Row
    97.                 Debug.Log(i); // The Collumn
    98.                 }  
    99.             }
    100.         }
    101. }
    and

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. [CustomEditor(typeof(ScriptName)), CanEditMultipleObjects]
    5.  
    6. //[CustomEditor(typeof(SamplerLoops))]
    7.  
    8. public class ListTesterInspector : Editor {
    9.  
    10.     public override void OnInspectorGUI () {
    11.         serializedObject.Update();
    12.         EditorList.Show(serializedObject.FindProperty("bools"), EditorListOption.Toggles | EditorListOption.ListSize);
    13.         //EditorList.Show(serializedObject.FindProperty("loops1"), EditorListOption.Toggles | EditorListOption.ListSize);
    14.         serializedObject.ApplyModifiedProperties();
    15.     }
    16. }
    17.  
    If anyone could help I would be insanely grateful.
     
  2. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Damn another thread just talking to myself.

    I'm going slightly mental with this problem please help! It seems so simple from the outside, am I being stupid or is this a specifically difficult task of setting a bool to on or off??

    Code (CSharp):
    1. public static void ShowButtons (SerializedProperty list, int index) {
    2.  
    3.         int numberOfSlots = 16;
    4.  
    5.         bool[ , ] nOff = new bool[numberOfSlots,numberOfSlots];
    6.  
    7.         for (int i = 0; i < numberOfSlots; i++) {
    8.  
    9.             if (GUILayout.Toggle(nOff[i , index], buttonContent, miniButtonWidth))
    10.                 {
    11.                 if (nOff [i, index] != true)
    12.                 {
    13.                     nOff [i, index] = true;
    14.                     GUILayout.Toggle(nOff[i , index], buttonContent, miniButtonWidth); // THIS IS DRIVING ME CRAZY WHY WON'T THIS TOGGLE SET!!
    15.                     Debug.Log (nOff [i, index]);
    16.                 }
    17.  
    18.                 if (nOff [i, index] = true)
    19.                 {
    20.                     nOff [i, index] = false;
    21.                     GUILayout.Toggle(nOff[i , index], buttonContent, miniButtonWidth);
    22.                     Debug.Log("Col =" + i + "Row =" +index);
    23.                 }
    24.              
    25.                 }  
    26.             }
    27.         }
     
  3. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,042
  4. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    I don't think I quite understand, in the reference they assign private bools to each toggle and set them with...

    Code (CSharp):
    1. toggleTxt = GUILayout.Toggle(toggleTxt, "A Toggle text");
    I thought I was doing that with this and the bits that follow:

    Code (CSharp):
    1. bool[ , ] nOff =newbool[numberOfSlots,numberOfSlots];
    I think it's the array I'm getting confused with, as I didn't want to explicitly list everything, I just wanted to wrap it up in for loop.

    I don't want to do anything specific with the buttons in that code. I just wanted to change the appearance/layout of toggles for an array of bools and be able to access/read each container from another script, I just wanted them to work the same as any other bool array does.

    Thank you very much for helping ZombieGorrila, seems like you've seen what the flaw is, I still can't see what is wrong as I'm a giant dum dum. Seems like I'd need to take out the if loop and assign it to itself, would this be it:

    Code (CSharp):
    1. if (GUILayout.Toggle(nOff[i , index], buttonContent, miniButtonWidth))
    2.                 {
    3.                     nOff[i , index] = GUILayout.Toggle(nOff[i , index], buttonContent, miniButtonWidth);
    4.                     Debug.Log (nOff [i, index]);
    5.                 }
     
  5. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    My conceptual problem is I have three scripts, the extension of the editor, the custom options and the final script i'm aiming this at, and I'm not sure how to get the latter two talking together smoothly. I've seen people mention things like an interface would that help in this case?

    I thought this would be relatively simple, it's taking me three days to work out how to turn a switch on.

    For instance make a bool[] array, you can switch the toggles on and off without having to set them to anything, why would I have to set them to read themselves in the editorOptions script? I'm just trying to override the appearance not the functionality, I'm not sure how to wrap my head around this.
     
    Last edited: Apr 30, 2016
  6. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,042
    Sorry meant to post this:
    http://docs.unity3d.com/ScriptReference/EditorGUILayout.Toggle.html
    The editor version.

    Yes, they do just show creating a local bool and using it, but that is just because they are only providing an example of the toogle functionality. But what it illustrates is that Toggle takes an existing bool value (wherever it may originate from and can be used to flip that bool if the widget is clicked.

    Toggle only returns the value of bool that is passed in, if clicked, returns the opposite. It does not set it. In that block you are basically doing things twice by having two toggles.
    So it should be only something like this:
    Code (csharp):
    1.  
    2.                  nOff[i , index] = GUILayout.Toggle(nOff[i , index], buttonContent, miniButtonWidth);
    3.  
    you don't need the if statement wrapper. in fact if this were working properly you would have two toggle at times.

    However, looking at your previous code, there are some other problems as well. You are passing in "list" which is probably supposed to be your list of bools from the script. But you never you use it. You create a new empty array of bools and loop through that. Nothing is being read, or applied. Since a new empty list of bools are all going to default to false, everything will always be false because it is being reset to false every frame.
     
  7. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,042
    You could do it with an interface. But probably unnecessary, that is more useful for broader application of concept/feature. If the goal is just to restyle some controls in the editor, you can just do it with the editor for the class where you set them. Can you explain better what the use is?
     
  8. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Ahh ok, the purpose is complete stupid. I've made a 16 step sequencer for arranging drums and loops in the inspector, when you make a bool array it appears vertically, I would like to have each line of the step sequencer not take up so much space in the inspector, at the moment it's 16 lines when it could be one.

    I've been researching further and I think the main bits I need to get my head around is serialized property, custom property drawer, begin Horizontal and end Horizontal, the OnGUI stuff is slightly baffling it's seems to be written in a slightly unfamiliar way, looks more alien than the C# bits i'm used to looking at.

    I know it should something along these lines:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4.  
    5. [CustomPropertyDrawer(typeof(BooleanArray))]
    6. public class BoolDrawer : PropertyDrawer {
    7.  
    8.     public override void OnGUI (Rect position, SerializedProperty list, GUIContent label)
    9.     {
    10.  
    11.     //    showToggle = true;
    12.         ShowToggle = EditorGUILayout.Toggle("wtf", ShowToggle);
    13.  
    14.         for (int i = 0; i < list.arraySize; i++) {
    15.             if (showToggle) {
    16.                 GUILayout.BeginHorizontal ();
    17.  
    18.             }
    19.             if (showToggle) {
    20.                 (ShowToggle)
    21.                 GUILayout.EndHorizontal ();
    22.             }
    23.         }
    24.     }
    25.         //label = EditorGUI.BeginProperty (position, label, property);
    26.         //Rect contentPosition = EditorGUI.PrefixLabel (position, label);
    27.         //EditorGUI.indentLevel = 0;
    28.         //EditorGUI.PropertyField (contentPosition, property.FindPropertyRelative ("boolean"), GUIContent.none);
    29.         //EditorGUI.EndProperty ();
    30.    
    31. }

    The examples say something like ShwBtn = EditorGUILayout.Toggle("label", ShwBtn); but I haven't been able to get that to work, assigning the variable to itself and confusing even more when there's an array, most of the examples are singular or two toggle cases.

    I think that's the main bit that has been confusing me how to deal with multiple elements and assign their value
     
  9. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Damn I totally didn't see your first message just the second one. Sorry for the thoughtless response earlier.

    Ok I've had another crack and cleaned up the list version of the bool arrays, and still get to the end of the loop scratching my head about assigning the bool array back to itself, I'm glad i'm not going crazy and the answer is something along the lines of nOff = Toggle(nOff) although no joy just yet.

    I've tried taking out of the If statement wrapper like you mentioned, but I put it there to only let something through when something had been happened, otherwise if I take it out it seems like it's just endlessly going for it!

    I wondering if the thing that could be messing me up is not initialising the bool arrays, the examples I've seen set the array like {true, true, true} etc, that's the bit just by looking comparatively at the examples that is different.

    On the last note of the message I missed are you saying I'm looping round things that aren't there? I would prefer to define how large the array from the script I'm directing it at, as opposed to defining the size from show toggles, or pass it a number to define the number of slots. But i'm slightly confused about handling these arrays from script to script.

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3. using System;
    4.  
    5. [Flags]
    6. public enum EditorListOption
    7. {
    8.     ListSize = 16,
    9.     ElementLabels = 2,
    10.     Toggles = 16
    11. }
    12.  
    13. public static class EditorList
    14.  
    15. {
    16.     public static void Show (SerializedProperty list, EditorListOption options)
    17.     {
    18.         bool
    19.         showListSize = (options & EditorListOption.ListSize) != 0,
    20.         showTgls = (options & EditorListOption.Toggles) != 0,
    21.         showElementLabels = (options & EditorListOption.ElementLabels) != 0;
    22.  
    23.         EditorGUILayout.PropertyField (list);
    24.         EditorGUILayout.PropertyField (list.FindPropertyRelative ("Array.size"));
    25.  
    26.         for (int i = 0; i < list.arraySize; i++) {
    27.             if (showTgls) {
    28.                 EditorGUILayout.BeginHorizontal ();
    29.             }
    30.             if (showElementLabels) {
    31.                 EditorGUILayout.PropertyField(list.GetArrayElementAtIndex(i));
    32.             } else {
    33.                 EditorGUILayout.PropertyField (list.GetArrayElementAtIndex(i), GUIContent.none);
    34.             }
    35.             if (showTgls) {
    36.                 ShowToggles(list, i);
    37.                 EditorGUILayout.EndHorizontal();
    38.             }
    39.         }
    40.     }
    41.  
    42.     public static void ShowToggles (SerializedProperty list, int index)
    43.     {
    44.         int r = 16;
    45.  
    46.         bool[ , ]nOff = new bool[r, r];
    47.  
    48.         for (int i = 0; i < 16; i++)
    49.             {
    50.                 //Need to assign to itself, how to do it other than the way below?
    51.                 nOff[i, index] = EditorGUILayout.Toggle(nOff[i, index]);
    52.                 //Debug.Log (index);
    53.             }
    54.    
    55.         }
    56.     }
    57.        
    58.  
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4.  
    5. [CustomEditor(typeof(BoolTester))]
    6. public class BoolDrawer : Editor {
    7.  
    8.     public override void OnInspectorGUI ()
    9.     {
    10.         serializedObject.Update();
    11.         EditorList.Show(serializedObject.FindProperty ("booleans"), EditorListOption.Toggles);
    12.         serializedObject.ApplyModifiedProperties();
    13.    
    14.     }
    15. }
    Code (CSharp):
    1. public class BoolTester : MonoBehaviour {
    2.  
    3.     public bool[] booleans;
    4.  
    5. }
    This really isn't the glamorous part of programming so thank you so much for helping me ZG, your videos on youtube look immense, I got distracted for a while going ooooohhh Ahhhhhh, great work!!
     
  10. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,042
    The inspector/editor scripting is a bit of an odd duck. It takes a while figure out all the little things and the way it does things. I do a lot of editor tools (its about 25% of my job), and it still messes with my head from time to time. Typically, I find the best way to build tools is start as simple as absolutely possible to nail the functionality first, then abstract or break apart and then finally visual appearance. So, if I understand your goal, I would start with something like this:
    Code (CSharp):
    1. // BoolTest.cs
    2.  
    3. using UnityEngine;
    4. using System.Collections;
    5.  
    6. public class BoolTest : MonoBehaviour {
    7.     [SerializeField] public int bool_row_length = 16;
    8.     [SerializeField] public int bool_toggle_width = 12;
    9.     [SerializeField] public bool[] boolList;
    10. }
    11.  
    And then extend it with an editor like this:
    Code (CSharp):
    1. // BoolTestEditor.cs
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Collections;
    5.  
    6.     [CustomEditor(typeof(BoolTest))]
    7.     public class BoolTestEditor : Editor
    8.     {
    9.         private SerializedObject m_Obj;
    10.        
    11.         public void OnEnable()
    12.         {
    13.             m_Obj = new SerializedObject(target);
    14.         }
    15.        
    16.        
    17.         public override void OnInspectorGUI()
    18.         {
    19.             m_Obj.Update();
    20.             int row_length = m_Obj.FindProperty("bool_row_length").intValue;
    21.             int toggle_width = m_Obj.FindProperty("bool_toggle_width").intValue;
    22.             SerializedProperty bool_list = m_Obj.FindProperty("boolList");
    23.            
    24.             EditorGUILayout.BeginVertical(); {
    25.                 EditorGUILayout.BeginHorizontal(); {
    26.            
    27.                 if(bool_list.isArray)
    28.                 {
    29.                     if(bool_list.arraySize>0)
    30.                     {
    31.                         int col_count = 0;
    32.                
    33.                         float block_width = (Screen.width-20)/(bool_list.arraySize+1);
    34.                         for (int i = 0; i < bool_list.arraySize; i++)
    35.                         {
    36.                             SerializedProperty prop = bool_list.GetArrayElementAtIndex(i);
    37.                             prop.boolValue = EditorGUILayout.Toggle(prop.boolValue, GUILayout.Width(toggle_width));
    38.                             col_count++;
    39.                    
    40.                             if(col_count>row_length)
    41.                             {
    42.                                 EditorGUILayout.EndHorizontal();
    43.                                 EditorGUILayout.BeginHorizontal();
    44.                                 col_count=0;
    45.                             }
    46.                         }
    47.                     }
    48.                     else
    49.                     {
    50.                             GUILayout.Label("Array of bools is empty");
    51.                     }
    52.                 }
    53.                 } EditorGUILayout.EndHorizontal();
    54.             } EditorGUILayout.EndVertical();
    55.  
    56.  
    57.             m_Obj.ApplyModifiedProperties();
    58.            
    59.             // draw the raw inspector
    60.             DrawDefaultInspector();
    61.         }
    62.     }
    I did add some variables for spacing and lines, but otherwise it just reads and draws from the array of bools. Hopefully I understood what you are trying to accomplish. Let me know if you have any questions.
     
    Richop likes this.
  11. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Wow! Thank you for so much, it works perfectly! Trust me this inspector GUI scripting is not something I'm going to be diving back into anytime soon, this was bafflingly hard!

    The thing I do notice in your script was the prop.boolValue and when I hover my cursor over it, it says {Get: Set:}
    It seems to be the fundamental part that was confusing me so much...

    SerializedProperty prop=bool_list.GetArrayElementAtIndex(i);

    and then re-assigning it back to itself with prop.boolValue, I didn't know boolValue even existed! I'm gonna have a hack and see if I can get it working in the other list one just for some peace/piece/pies of mind!

    Here's the finished looper with the bells and whistles:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System;
    4.  
    5. public class SamplerLoops : MonoBehaviour {
    6.  
    7.     public float bpm = 120;
    8.     public float beatSegment = 16;
    9.     private double nextEventTime;
    10.     private bool running = false;
    11.  
    12.     public AudioClip[] loop1;
    13.     public AudioClip[] loop2;
    14.     public AudioClip[] loop3;
    15.     public AudioClip[] loop4;
    16.  
    17.     [SerializeField] public bool[] booltests;
    18.     [SerializeField] public int bool_row_length = 15;
    19.     [SerializeField] public int bool_toggle_width = 28;
    20.  
    21.     private AudioSource[] audioSources = new AudioSource[4];
    22.     private AudioHighPassFilter[] audioFilters = new AudioHighPassFilter[4];
    23.     public int counter = 0;
    24.  
    25.     //public bool[] loops1 = new bool[16];
    26.     [Range (0f,1.0f)]
    27.     public float vol1 = 0.5f;
    28.     [Range (20f,22000.0f)]
    29.     public float cut1 = 20f;
    30.     //public bool[] loops2 = new bool[16];
    31.     [Range (0f,1.0f)]
    32.     public float vol2 = 0.5f;
    33.     [Range (20f,22000.0f)]
    34.     public float cut2 = 20f;
    35.     //public bool[] loops3 = new bool[16];
    36.     [Range (0f,1.0f)]
    37.     public float vol3 = 0.5f;
    38.     [Range (20f,22000.0f)]
    39.     public float cut3 = 20f;
    40.     //public bool[] loops4 = new bool[16];
    41.     [Range (0f,1.0f)]
    42.     public float vol4 = 0.5f;
    43.     [Range (20f,22000.0f)]
    44.     public float cut4 = 20f;
    45.     public int numNotes = 4;
    46.  
    47.     // Use this for initialization
    48.     void Start () {
    49.        
    50.             GameObject looper1 = new GameObject ("Loop1");
    51.             looper1.transform.parent = gameObject.transform;
    52.             audioSources[0] = looper1.AddComponent<AudioSource> ();
    53.             audioFilters[0] = looper1.AddComponent<AudioHighPassFilter> ();
    54.  
    55.             GameObject looper2 = new GameObject ("Loop2");
    56.             looper2.transform.parent = gameObject.transform;
    57.             audioSources[1] = looper2.AddComponent<AudioSource> ();
    58.             audioFilters[1] = looper2.AddComponent<AudioHighPassFilter> ();
    59.  
    60.             GameObject looper3 = new GameObject ("Loop3");
    61.             looper3.transform.parent = gameObject.transform;
    62.             audioSources[2] = looper3.AddComponent<AudioSource> ();
    63.             audioFilters[2] = looper3.AddComponent<AudioHighPassFilter> ();
    64.            
    65.             GameObject looper4 = new GameObject ("Loop4");
    66.             looper4.transform.parent = gameObject.transform;
    67.             audioSources[3] = looper4.AddComponent<AudioSource> ();
    68.             audioFilters[3] = looper4.AddComponent<AudioHighPassFilter> ();
    69.             nextEventTime = AudioSettings.dspTime + 2.0f;
    70.             running = true;
    71.     }
    72.    
    73.     // Update is called once per frame
    74.     void Update () {
    75.         if (!running)
    76.             return;
    77.  
    78.         double time = AudioSettings.dspTime;
    79.         if (time + 1.0f > nextEventTime)
    80.         {
    81.         //    audioSources.clip = kick[0];
    82.         //    audioSources.PlayScheduled (nextEventTime);
    83.         //    Debug.Log ("Scheduled source to start at time " + nextEventTime);
    84.             Counter ();
    85.             PlayStuff();
    86.             nextEventTime += (60.0f / bpm) * beatSegment;
    87.         }
    88.         UpdateFX();
    89.     }
    90.  
    91.     void Counter() {
    92.  
    93.  
    94.         if (counter > numNotes) {
    95.             counter = 0;
    96.         } else {
    97.             counter = counter + 1;
    98.         }
    99.     }
    100.        
    101.     void PlayStuff(){
    102.  
    103.         for (int i = 0; i < counter; i++)
    104.         {
    105.             if (booltests[counter-1] == true) {
    106.                 PlayLoop1 (0); // Zero here can take int variable to change the sound/loop being played
    107.                     }
    108.             if (booltests[counter+15] == true) {
    109.                 PlayLoop2(0);
    110.             }
    111.  
    112.             if (booltests[counter+31] == true) {
    113.                 PlayLoop3(0);
    114.             }
    115.  
    116.             if (booltests[counter+47] == true) {
    117.                 PlayLoop4(0);
    118.             }
    119.         }
    120.     }
    121.  
    122.     void PlayLoop1 (int clip)
    123.  
    124.     {
    125.         AudioSource audio1 = audioSources[0];
    126.         audio1.clip = loop1[clip];
    127.         audio1.Play ();
    128.     }
    129.  
    130.     void PlayLoop2 (int clip)
    131.  
    132.     {
    133.         AudioSource audio2 = audioSources[1];
    134.         audio2.clip = loop2[clip];
    135.         audio2.Play ();
    136.     }
    137.  
    138.     void PlayLoop3 (int clip)
    139.  
    140.     {
    141.         AudioSource audio3 = audioSources[2];
    142.         audio3.clip = loop3[clip];
    143.         audio3.Play ();
    144.     }
    145.  
    146.     void PlayLoop4 (int clip)
    147.  
    148.     {
    149.         AudioSource audio4 = audioSources[3];
    150.         //audio4.loop = true;
    151.         audio4.clip = loop4[clip];
    152.         audio4.Play ();
    153.     }
    154.  
    155.     void UpdateFX()
    156.     {
    157.         AudioSource audio1 = audioSources[0];
    158.         audio1.volume = vol1;
    159.         AudioHighPassFilter filter1 = audioFilters[0];
    160.         filter1.cutoffFrequency = cut1;
    161.  
    162.         AudioSource audio2 = audioSources[1];
    163.         AudioHighPassFilter filter2 = audioFilters[1];
    164.         audio2.volume = vol2;
    165.         filter2.cutoffFrequency = cut2;
    166.  
    167.         AudioSource audio3 = audioSources[2];
    168.         AudioHighPassFilter filter3 = audioFilters[2];
    169.         audio3.volume = vol3;
    170.         filter3.cutoffFrequency = cut3;
    171.  
    172.         AudioSource audio4 = audioSources[3];
    173.         AudioHighPassFilter filter4 = audioFilters[3];
    174.         audio4.volume = vol4;
    175.         filter4.cutoffFrequency = cut4;
    176.     }
    177. }
    178.  
    Here's the script for the editor folder courtesy of ZombieGorrilla:

    Code (CSharp):
    1. // StepLoopEditor.cs
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Collections;
    5.  
    6. [CustomEditor(typeof(SamplerLoops))]
    7.  
    8. public class StepLoopEditor : Editor
    9. {
    10.     private SerializedObject m_Obj;
    11.  
    12.     public void OnEnable()
    13.     {
    14.         m_Obj = new SerializedObject(target);
    15.     }
    16.  
    17.  
    18.     public override void OnInspectorGUI()
    19.     {
    20.         m_Obj.Update();
    21.  
    22.  
    23.         int row_length = m_Obj.FindProperty("bool_row_length").intValue; // Find Length
    24.         int toggle_width = m_Obj.FindProperty("bool_toggle_width").intValue; // Find Width
    25.         SerializedProperty bool_list = m_Obj.FindProperty("booltests"); // Find the list
    26.  
    27.         EditorGUILayout.BeginVertical();
    28.  
    29.          {
    30.             EditorGUILayout.BeginHorizontal(); {
    31.  
    32.                 if(bool_list.isArray) // If it's an array
    33.                 {
    34.                     if(bool_list.arraySize>0) // and array is greater than 0
    35.                     {
    36.                         int col_count = 0; // column count is 0
    37.  
    38.                         float block_width = (Screen.width-20)/(bool_list.arraySize+1);
    39.                         for (int i = 0; i < bool_list.arraySize; i++) // For every item in the array do...
    40.                         {
    41.                             SerializedProperty prop = bool_list.GetArrayElementAtIndex(i); // find index
    42.                             prop.boolValue = EditorGUILayout.Toggle(prop.boolValue, GUILayout.Width(toggle_width)); // Assign toggle
    43.                             col_count++; //                                                                         // A bool value
    44.  
    45.                             if(col_count>row_length) // If column is greater than row
    46.                             {
    47.                                 EditorGUILayout.EndHorizontal();
    48.                                 EditorGUILayout.BeginHorizontal();
    49.                                 col_count=0;
    50.                             }
    51.                         }
    52.                     }
    53.                     else
    54.                     {
    55.                         GUILayout.Label("Array of bools is empty, set to multiple of 16");
    56.                     }
    57.                 }
    58.             } EditorGUILayout.EndHorizontal();
    59.         } EditorGUILayout.EndVertical();
    60.  
    61.  
    62.         m_Obj.ApplyModifiedProperties();
    63.  
    64.         // draw the raw inspector
    65.         DrawDefaultInspector();
    66.     }
    67. }
    and here's the 16 step drum sequencer, still needs some work due to the last slot not playing the sound for some reason:

    Code (CSharp):
    1. // Sampler16.cs
    2. using UnityEngine;
    3. using System.Collections;
    4. using System;
    5.  
    6. public class StepSeq16 : MonoBehaviour
    7. {
    8.     public int counter = 0;
    9.     public int numNotes = 15;
    10.     [SerializeField] public bool[] booltests;
    11.     [SerializeField] public int bool_row_length = 15;
    12.     [SerializeField] public int bool_toggle_width = 28;
    13.  
    14.     public float bpm = 120;
    15.     private double nextEventTime;
    16.     private bool running = false;
    17.  
    18.     //public AudioClip[] clips = new AudioClip[2];
    19.     public AudioClip[] kick;
    20.     public AudioClip[] snare;
    21.     public AudioClip[] hiHat;
    22.     public AudioClip[] bassOneShot;
    23.     AudioClip[] openHat;
    24.     AudioClip[] chordOneShot;
    25.     private AudioSource[] audioSources = new AudioSource[4];
    26.  
    27.  
    28.  
    29.     // Use this for initialization
    30.     void Start () {
    31.        
    32.             GameObject child = new GameObject ("Player");
    33.             child.transform.parent = gameObject.transform;
    34.             audioSources[0] = child.AddComponent<AudioSource> ();
    35.             audioSources[1] = child.AddComponent<AudioSource> ();
    36.             audioSources[2] = child.AddComponent<AudioSource> ();
    37.             audioSources[3] = child.AddComponent<AudioSource> ();
    38.             nextEventTime = AudioSettings.dspTime + 2.0f;
    39.             running = true;
    40.     }
    41.    
    42.     // Update is called once per frame
    43.     void Update () {
    44.         if (!running)
    45.             return;
    46.  
    47.         double time = AudioSettings.dspTime;
    48.         if (time + 1.0f > nextEventTime)
    49.         {
    50.         //    audioSources.clip = kick[0];
    51.         //    audioSources.PlayScheduled (nextEventTime);
    52.         //    Debug.Log ("Scheduled source to start at time " + nextEventTime);
    53.             nextEventTime += (60.0f / bpm) * 0.25;
    54.             Counter ();
    55.             PlayStuff();
    56.         }
    57.     }
    58.  
    59.     void Counter()
    60.     {
    61.         if (counter >= numNotes)
    62.         {
    63.             counter = 0;
    64.         } else {
    65.             counter += 1;
    66.         }
    67.     //    Debug.Log (counter);
    68.     }
    69.  
    70.     void PlayStuff()
    71.     {
    72.  
    73.         for (int i = 0; i < counter; i++)
    74.         {
    75.             if (booltests[counter-1] == true) {
    76.                 PlayKick (0);
    77.                     }
    78.             if (booltests[counter+15] == true) {
    79.                 PlaySnare (0);
    80.             }
    81.             if (booltests[counter+31] == true) {
    82.                 PlayHiHat (0);
    83.             }
    84.             if (booltests[counter+47] == true) {
    85.                 PlayBass (0);
    86.             }
    87.         }
    88.     }
    89.  
    90.     void PlayKick (int clip)
    91.  
    92.     {
    93.         AudioSource audio1 = audioSources[0];
    94.         audio1.clip = kick[clip];
    95.         audio1.Play ();
    96.     }
    97.  
    98.     void PlaySnare (int clip)
    99.  
    100.     {
    101.         AudioSource audio2 = audioSources[1];
    102.         audio2.clip = snare[clip];
    103.         audio2.Play ();
    104.     }
    105.  
    106.     void PlayHiHat (int clip)
    107.  
    108.     {
    109.         AudioSource audio3 = audioSources[2];
    110.         audio3.clip = hiHat[clip];
    111.         audio3.Play ();
    112.     }
    113.  
    114.     void PlayBass (int clip)
    115.  
    116.     {
    117.         AudioSource audio4 = audioSources[3];
    118.         audio4.clip = bassOneShot[clip];
    119.         audio4.Play ();
    120.     }
    121.        
    122. }
    123.  
    And the editor script to go along with it:

    Code (CSharp):
    1. // BoolTestEditor.cs
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Collections;
    5.  
    6. [CustomEditor(typeof(StepSeq16))]
    7.  
    8. public class BoolTestEditor : Editor
    9. {
    10.     private SerializedObject m_Obj;
    11.  
    12.     public void OnEnable()
    13.     {
    14.         m_Obj = new SerializedObject(target);
    15.     }
    16.  
    17.  
    18.     public override void OnInspectorGUI()
    19.     {
    20.         m_Obj.Update();
    21.  
    22.  
    23.         int row_length = m_Obj.FindProperty("bool_row_length").intValue; // Find Length
    24.         int toggle_width = m_Obj.FindProperty("bool_toggle_width").intValue; // Find Width
    25.         SerializedProperty bool_list = m_Obj.FindProperty("booltests"); // Find the list
    26.  
    27.         EditorGUILayout.BeginVertical();
    28.  
    29.          {
    30.             EditorGUILayout.BeginHorizontal(); {
    31.  
    32.                 if(bool_list.isArray) // If it's an array
    33.                 {
    34.                     if(bool_list.arraySize>0) // and array is greater than 0
    35.                     {
    36.                         int col_count = 0; // column count is 0
    37.  
    38.                         float block_width = (Screen.width-20)/(bool_list.arraySize+1);
    39.                         for (int i = 0; i < bool_list.arraySize; i++) // For every item in the array do...
    40.                         {
    41.                             SerializedProperty prop = bool_list.GetArrayElementAtIndex(i); // find index
    42.                             prop.boolValue = EditorGUILayout.Toggle(prop.boolValue, GUILayout.Width(toggle_width)); // Assign toggle
    43.                             col_count++; //                                                                         // A bool value
    44.  
    45.                             if(col_count>row_length) // If column is greater than row
    46.                             {
    47.                                 EditorGUILayout.EndHorizontal();
    48.                                 EditorGUILayout.BeginHorizontal();
    49.                                 col_count=0;
    50.                             }
    51.                         }
    52.                     }
    53.                     else
    54.                     {
    55.                         GUILayout.Label("Array of bools is empty");
    56.                     }
    57.                 }
    58.             } EditorGUILayout.EndHorizontal();
    59.         } EditorGUILayout.EndVertical();
    60.  
    61.  
    62.         m_Obj.ApplyModifiedProperties();
    63.  
    64.         // draw the raw inspector
    65.         DrawDefaultInspector();
    66.     }
    67. }
     
  12. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    @zombiegorilla You are a legend thank you so so much! I can finally rest at ease!!
     
  13. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,042
    Glad to help! Like I said, the editor stuff can be a bit odd to deal with, if I can help someone avoid the head bashing I experienced with it, I am happy to do so. ;)