1

在我的 Unity 项目中,我列出了 4 个信号。在代码中,当CheckPress()被调用时,一个随机索引,我称之为firststimIndex从信号列表中选择,并且该索引通过 UDP 发送到 MAX/MSP 以播放一些音频。调用时PlaySignal(),播放与该索引关联的音频。这工作正常。然后,当LoadNextSignal()被调用时,这个先前的索引被删除,并且一个新的随机索引被加载并播放并被删除。LoadNextSignal()需要调用 3 次,因为剩余的信号数为 3。此过程将继续,直到列表中的所有信号都被删除。

我的问题在于LoadNextSignal()第二次调用时何时执行。如何修复这部分代码?此外,变量 stimIndex 是必需的,因为在我编写数据时在我的项目中,它被写为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>");
}
}
4

1 回答 1

1

代码有几个“问题”,但可以修复:

  1. 用于IntUnityEngine.Random.Range(0, remainingSignals)值。

此函数始终返回该函数的Unity 页面上所述的浮点数。你想得到结果int,我只会遵循那个new System.Random().Next(signals.Count)


  1. 访问那些可以为空的列表项

在开发此类从不同位置调用的程序/功能时,开发人员通常会尽可能避免出现任何问题和异常。作为示例,我们可以采用您的方法public void LoadNextSignal()并在开头添加以下行:

public void LoadNextSignal()
{
   if(signals.Count == 0) return;

   //... the rest of the code
}

这将防止跳出索引并抛出此异常。背后的主要思想是你永远无法确定它被执行了多少次。

于 2020-11-24T11:46:40.230 回答