I have a Button array. I am trying to check if a Button in the array is clicked/pressed and then execute code (play a sound effect) on that frame.
I tried 4 different ways of using Button.onClick.AddListener(), but they all resulted in the last Button being effectively pressed. In the Buttons() function in my code below, I commented out each of my 4 attempts and explained how they cause only the last button effect to occur regardless of which button is pressed. There is also an issue with code running hundreds of times when it shouldn’t run at all. It seems to me that Button.onClick.AddListener() runs at the end of the frame no matter where it is written in the code, and it runs hundreds of times per click.
Could someone please show me what I’m doing wrong here?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ButtonSFXScript : MonoBehaviour
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public AudioClip[] sfx_AudioClipArray; // Set in editor
public Transform buttonSlider_Transform; // Set in editor
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public int setIndex_int = -1;
public bool setPlayIndex_bool;
public bool limitSet_bool;
public Button[] clickable_ButtonArray;
public Button current_Button;
public int buttonCount_int;
public AudioSource this_audioSource;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Start()
{
this_audioSource = GetComponent<AudioSource>();
buttonCount_int = buttonSlider_Transform.childCount;
clickable_ButtonArray = new Button[buttonCount_int];
for (int i_int = 0; i_int < clickable_ButtonArray.Length; i_int++)
{
clickable_ButtonArray[i_int] = buttonSlider_Transform.GetChild(i_int).GetComponent<Button>();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private void Update()
{
Buttons();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private void Buttons()
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
///Attempt 0:
limitSet_bool = false;
for (int i_int = 0; i_int < clickable_ButtonArray.Length; i_int++)
{
if (limitSet_bool)
{
i_int = clickable_ButtonArray.Length;
Debug.Log("Breaking from for loop...");
}
else
{
setIndex_int = i_int;
clickable_ButtonArray[setIndex_int].onClick.AddListener(delegate { PlaySFXNow(setIndex_int); });
}
}
///Problem: No Matter which Button is clicked, the last clip in sfx_AudioClipArray is played.
Also the message "Why is this code executing? [PlaySFXNow]" is logged hundres of times.
*/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
///Attempt 1:
limitSet_bool = false;
for (int i_int = 0; i_int < clickable_ButtonArray.Length; i_int++)
{
if (limitSet_bool)
{
i_int = clickable_ButtonArray.Length;
Debug.Log("Breaking from for loop...");
}
else
{
setIndex_int = i_int;
current_Button = clickable_ButtonArray[setIndex_int];
current_Button.onClick.AddListener(delegate { PlaySFXNow(setIndex_int); });
}
}
///Problem: Same as Attempt 0: No Matter which Button is clicked, the last clip in sfx_AudioClipArray is played.
Also the message "Why is this code executing? [PlaySFXNow]" is logged hundres of times.
*/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
///Attempt 2:
limitSet_bool = false;
for (int i_int = 0; i_int < clickable_ButtonArray.Length; i_int++)
{
if (!setPlayIndex_bool)
{
setIndex_int = i_int;
current_Button = clickable_ButtonArray[setIndex_int];
current_Button.onClick.AddListener(delegate { SetPlayIndex(setIndex_int); });
}
else
{
i_int = clickable_ButtonArray.Length;
Debug.Log("Breaking from for loop...");
}
}
if (setPlayIndex_bool)
{
PlaySFX(setIndex_int);
}
///Problem: Same as Attempt 0: No Matter which Button is clicked, the last clip in sfx_AudioClipArray is played.
Also the message "Why is this code executing [SetPlayIndex]" is logged hundres of times.
*/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
///Attempt 3:
limitSet_bool = false;
for (int i_int = 0; i_int < clickable_ButtonArray.Length; i_int++)
{
if (!setPlayIndex_bool)
{
setIndex_int = i_int;
current_Button = clickable_ButtonArray[setIndex_int];
current_Button.onClick.AddListener(SetPlayIndex);
}
else
{
i_int = clickable_ButtonArray.Length;
Debug.Log("Breaking from for loop...");
}
}
if (setPlayIndex_bool)
{
PlaySFX(setIndex_int);
}
///Problem: Same as Attempt 0: No Matter which Button is clicked, the last clip in sfx_AudioClipArray is played.
Also the message "Why is this code executing [SetPlayIndex]" is logged hundres of times.
*/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void PlaySFXNow(int clipIndex_int)
{
if (!limitSet_bool)
{
limitSet_bool = true;
Debug.Log("clipIndex_int: " + clipIndex_int);
if (clipIndex_int < sfx_AudioClipArray.Length)
{
this_audioSource.clip = sfx_AudioClipArray[clipIndex_int];
this_audioSource.Play();
Debug.Log("Play: " + this_audioSource.clip.name);
}
}
else
{
Debug.Log("Why is this code executing? [PlaySFXNow]");
}
}
public void PlaySFX(int audioClipIndex_int)
{
if (!limitSet_bool)
{
setPlayIndex_bool = false;
PlaySFXNow(audioClipIndex_int);
}
else
{
Debug.Log("Why is this code executing? [PlaySFX]");
}
}
public void PlaySFX()
{
PlaySFX(setIndex_int);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void SetPlayIndex(int index_int)
{
if (!setPlayIndex_bool)
{
Debug.Log("setPlayIndex_bool set to true when setIndex_int: " + setIndex_int);
setPlayIndex_bool = true;
}
else
{
Debug.Log("Why is this code executing [SetPlayIndex]?");
}
}
public void SetPlayIndex()
{
SetPlayIndex(setIndex_int);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}