我正在尝试使用从我的程序中的www表单收集的信息创建一个按钮列表。我遇到的问题是,当我创建按钮时,它无限地创建它们,因此统一崩溃。我有两个理论为什么会发生这种情况,第一个是每个帧都调用函数,因此创建了太多的按钮,第二个是因为某些原因,当我检查多维数组的长度时,它有一个长度33当它应该只有3的长度(它应该有3个数组阵列)。整个脚本如下。
using Boo.Lang;
using System.Collections;
using SCG = System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using System;
public class MeetingRequestViewer : MonoBehaviour
{
//This script contains the code on how to display information about the students to the staff
//it displays each student in a different row
private Rect windowRect = new Rect(0, 0, Screen.width, Screen.height);
public Vector2 scrollPosition = Vector2.zero;
private int BSpace;
public string[,] SortedStudentArray;
private int j;
private string[][] MeetRequests;
private string[] temp;
private SCG.List<string> H_Priority = new SCG.List<string>();
private SCG.List<string> M_Priority = new SCG.List<string>();
private SCG.List<string> L_Priority = new SCG.List<string>();
private SCG.List<string> FullList = new SCG.List<string>();
private SCG.List<string> UAList;
private SCG.List<object> StudentButtonList = new SCG.List<object>();
private string[] Holding = new string[5];
private string[] SearchTerms;
public int ButtonSpacing = 10;
public int ButtonWidth = 80;
public int ButtonHeight = 30;
public void OnGUI()
{
//create a window
GUI.Window(0, windowRect, WindowFunction, "Meeting Request Viewer");
}
public void WindowFunction(int windowID)
{
//Fetches all user Data
string[][] userArray = GetComponent<Userdata>().CallDetail();
string[][] StudentArray = GetComponent<Userdata>().UserSorting(userArray);
//Calls the SortStudentArray method
string[,] SortedStudentArray = SortStudentList();
//Creates a box with a scrolling bar to taverse the y axis
scrollPosition = GUI.BeginScrollView(new Rect(Screen.width / 6, Screen.height / 6, 350, 250), scrollPosition, new Rect(0, 0, 300, 40 * SortedStudentArray.Length));
//for each row in the sorted student array
for (int x = 0; x < SortedStudentArray.Length - 1; x++)
{
//This keeps the gap between each button consistent
var y = ButtonSpacing + ButtonHeight;
//Regular Meeting Request
if (SortedStudentArray[x, 7] == "1")
{
//Urgent Meeting Request
if (SortedStudentArray[x, 8] == "1")
{
Debug.Log("Even Here");
//Create Button coloured red
GUI.backgroundColor = Color.red;
}
//Regular Meeting Request
else
{
//Create Button coloured yellow
GUI.backgroundColor = Color.yellow;
}
}
//No Meeting Request
else
{
//Create Button coloured green
GUI.backgroundColor = Color.green;
}
GUI.Button(new Rect(ButtonSpacing, ButtonSpacing + x * y, ButtonWidth, ButtonHeight), SortedStudentArray[x, 6]);
}
GUI.EndScrollView();
ButtonsCreated = true;
}
private string[,] SortStudentList()
{
//This method is used to fetch the meeting request data, split it into a jagged array and then again so that each
//row is a new user and each item in the row is a different peice of information relating to the user
//The Jagged array is then sorted using the bubble sort algorithm so that the students that require urgent meetings
//appear at the topo of the request table
//call website with the data store
WWW MeetReqData = new WWW("http://localhost/Wellbeing/meetingrequest.php");
//until WWW is finished do nothing
while (MeetReqData.isDone == false)
{
}
//convert the returned value into a string
string MeetReqString = MeetReqData.text;
//split the text into a string list
string[] mrq = MeetReqString.Split(';');
//convert the string list into a jagged array
MeetRequests = new string[mrq.Length][];
int i = 0;
//for each item in the list
foreach (string s in mrq)
{
//split it into its individual peice of information
string[] g = s.Split('|');
//store the information about a user on a new line
MeetRequests[i] = g;
++i;
}
for (int n = 0; n < MeetRequests.Length - 1; n++)
{
if (MeetRequests[n][1] == "1" && MeetRequests[n][2] == "1")
{
H_Priority.Add(MeetRequests[n][0]);
}
else if (MeetRequests[n][1] == "1" && MeetRequests[n][2] == "0")
{
M_Priority.Add(MeetRequests[n][0]);
}
else
{
L_Priority.Add(MeetRequests[n][0]);
}
}
//Combines all lists into a larger list of priorities
FullList.AddRange(H_Priority);
FullList.AddRange(M_Priority);
FullList.AddRange(L_Priority);
//convertFullList into an array for easier mainpulation and comparisons
string[][] feelingsArray = GetComponent<Userdata>().CallFeelings();
//FullList only contains 3 values
Debug.Log(FullList.Count);
//Info array about each user
string[,] SortedStudentArray = new string[FullList.Count, 11];
//SortedStudentArray contains 33 rows
Debug.Log("This thing Here");
Debug.Log(SortedStudentArray.Length);
//Line Counter
int SSAPos = 0;
// For every element in FullList
foreach (var item in FullList)
{
Debug.Log(FullList.Count);
//For each user in userArray
for (int y = 0; y < Userdata.userArray.Length; y++)
{
if (Userdata.userArray[y][0] == item)
{
for (int n = 0; n < Userdata.userArray; n++)
SortedStudentArray[SSAPos, n] = Userdata.userArray[y][n];
break;
}
}
Debug.Log(SortedStudentArray.Length);
//For each user in userArray
for (int y = 0; y < MeetRequests.Length; y++)
{
if (MeetRequests[y][0] == item)
{
SortedStudentArray[SSAPos, 7] = MeetRequests[y][1];
SortedStudentArray[SSAPos, 8] = MeetRequests[y][2];
break;
}
}
Debug.Log(SortedStudentArray.Length);
SSAPos += 1;
}
return SortedStudentArray;
}
// Update is called once per frame
void Update ()
{
//if (GUI.Button(new Rect(Screen.width / 4, Screen.height / 7, Screen.width / 2, Screen.height / 8), "Log Out"))
//{
// Debug.Log("Logged Out");
// SceneManager.LoadScene("Login");
//}
}
我确实尝试在代码段周围使用while循环但是它对按钮的创建没有任何影响,它们仍然创建的次数超过了所需的次数
答案 0 :(得分:2)
FullList
不断被填充,最终会导致崩溃。
在SortStudentList
中致电Awake
,例如;
string[,] SortedStudentArray;
void Awake ()
{
//Calls the SortStudentArray method
SortedStudentArray = SortStudentList();
}
然后;
public void WindowFunction(int windowID)
{
// Prevent further execution until SortedStudentArray is ready
if (SortedStudentArray == null) return;
...
}
答案 1 :(得分:1)
调用OnGUI来渲染和处理GUI事件。
这意味着您的OnGUI实现可能会被调用多个 每帧时间(每个事件一次)。有关GUI的更多信息 事件参见事件参考。如果启用了MonoBehaviour property设置为false,不会调用OnGUI()。
您需要重新评估自己的GUI使用方式。正如他们GUI scripting guide中提到的那样,您应该使用他们的UI system。
您特别不希望每帧进行一次或多次WWW
次呼叫,或者每帧都进行一系列排序。
答案 2 :(得分:0)
https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnGUI.html
调用OnGUI来渲染和处理GUI事件。
这意味着您的OnGUI实现可能每帧调用几次(每个事件一次调用)。有关GUI事件的更多信息,请参阅事件参考。如果MonoBehaviour的enabled属性设置为false,则不会调用OnGUI()。
您应该使用其他方法来调用您的方法,或使用布尔值来检查它是否已被调用。
请参阅下图以更好地了解Unity生命周期方法。
有关Unity生命周期的更多信息,请访问:https://docs.unity3d.com/Manual/ExecutionOrder.html