In my Unity Project, I have list of 4 signals. In the code, when CheckPress()
is called, a random index, what I call the firststimIndex
is selected from a list of signals and that index is sent to MAX/MSP via UDP to play some audio. When PlaySignal()
is called, the audio associated with this index is played. This works fine. Then, when LoadNextSignal()
is called, this previous index is removed and a new random index is loaded and played and is removed. LoadNextSignal()
needs to be called 3 times as the remaining number of signals are three. This process will continue until all signals from the list are removed.
My problem lies when LoadNextSignal()
is executed when called second time. How do I fix this part of my code? Also, The variable stimIndex is required as in my project when I write the data, it is written as signals[stimIndex]
.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Text;
using System.Net;
using System.Net.Sockets;
public class CheckButtonBehaviour : MonoBehaviour
{
public Button Check;
public Button Play;
public Button NextSignal;
public List<string> signals = new List<string> {"Speech1", "Speech2", "Speech3", "Speech4"};
public int stimIndex;
public int index = 1;
public int counter = 3;
public int remainingSignals;
private static int localPort;
private string IP;
public int port = 8050;
IPEndPoint remoteEndPoint;
UdpClient client;
void Start()
{
IP = "127.0.0.1";
port = 8050;
remoteEndPoint = new IPEndPoint(IPAddress.Parse(IP), port);
client = new UdpClient();
Play.gameObject.SetActive(false);
NextSignal.gameObject.SetActive(false);
}
public void CheckPress()
{
var random = new System.Random();
int firststimIndex = random.Next(signals.Count);
///Sends to MAX MSP
string text = firststimIndex.ToString();
byte[] data5 = Encoding.ASCII.GetBytes(text);
client.Send(data5, data5.Length, remoteEndPoint);
Debug.Log("<color=red>First signal is : </color>"+ signals[firststimIndex]);
stimIndex = firststimIndex;
Check.gameObject.SetActive(true);
Check.interactable = false;
Check.enabled = false;
Play.gameObject.SetActive(true);
NextSignal.gameObject.SetActive(true);
}
public void LoadNextSignal()
{
if(signals.Count == 0)
return;
signals.RemoveAt(stimIndex); //Removes the previous signal
remainingSignals = signals.Count;
Debug.Log("<color=red>Remaining Signals are : </color>" + remainingSignals);
int randomIndex = UnityEngine.Random.Range(0, remainingSignals);
string text1 = randomIndex.ToString();
byte[] data6 = Encoding.ASCII.GetBytes(text1);
stimIndex = randomIndex;
client.Send(data6, data6.Length, remoteEndPoint);
Debug.Log("Loaded Signal" + stimIndex + "; remaining signals before removal equals" + remainingSignals);
index++;
if (counter >= index)
{
Debug.Log("<color=orange>Yay! Keep Listening!</color>");
}
else
{
Debug.Log("<color=green>All Trials finished</color>");
Play.gameObject.SetActive(false);
NextSignal.gameObject.SetActive(false);
}
}
void PlaySignal()
{
byte[] data2 = Encoding.ASCII.GetBytes("A"); //B
client.Send(data2, data2.Length, remoteEndPoint);
Debug.Log("<color=red>Signal is Played</color>");
}
}
There are several "problems" with the code, but they can be fixed:
UnityEngine.Random.Range(0, remainingSignals)
for Int value.This function always return float as stated on Unity page for this function . You want to have result as
int
and I would follow thatnew System.Random().Next(signals.Count)
only.In development such program/functions, which are called from different places, developer is usually trying to prevent any problems & exceptions when it is possible. As an example we can take your method
public void LoadNextSignal()
and add following lines at the beginning:This will prevent stepping out of the index & casting this exception. Main idea behind is that you can never be sure, how many times it was executed.