简体   繁体   English

停止在每帧C#中调用函数

[英]stop a function from being called every frame c#

I am trying to create a list of buttons using information collected from www forms in my program. 我正在尝试使用从程序中www表单收集的信息来创建按钮列表。 The problem I am having is that when I create the buttons, it infinitely creates them, and thusly unity crashes. 我遇到的问题是,当我创建按钮时,它会无限创建它们,从而导致统一崩溃。 I have two theories as to why this is happening, the first being that the function is being called each frame and is therefore creating too many buttons and the second is that for some reason when I check the length of a multidimensional array it has a length of 33 when it should only have a length of 3 (it should have 3 arrays of arrays). 关于发生这种情况的原因,我有两种理论,一种是在每个框架中调用该函数,因此会创建过多的按钮,第二种是出于某种原因,当我检查多维数组的长度时,它具有一个长度。的长度为33时(长度应为3的数组)。 The whole script is below. 整个脚本如下。

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");
    //}
}

I did try to use a while loop around the section of code however it made no difference to the creation of buttons, they were still created more times than were needed 我确实尝试在代码部分中使用while循环,但是这对创建按钮没有影响,因为创建按钮的次数仍超过所需次数

FullList is continually being populated which will eventually lead to a crash. FullList不断被填充,最终将导致崩溃。

Call SortStudentList in Awake , such as; Awake调用SortStudentList ,例如;

string[,] SortedStudentArray;

void Awake ()
{    
    //Calls the SortStudentArray method
    SortedStudentArray = SortStudentList();
}

Then; 然后;

public void WindowFunction(int windowID)
{
    // Prevent further execution until SortedStudentArray is ready
    if (SortedStudentArray == null) return;

    ...
}

From the documentation : 文档中

OnGUI is called for rendering and handling GUI events. 调用OnGUI来呈现和处理GUI事件。

This means that your OnGUI implementation might be called several times per frame (one call per event). 这意味着您的OnGUI实现可能每帧被调用几次(每个事件一次)。 For more information on GUI events see the Event reference. 有关GUI事件的更多信息,请参见事件参考。 If the MonoBehaviour's enabled property is set to false, OnGUI() will not be called. 如果MonoBehaviour的enabled属性设置为false,则不会调用OnGUI()。

You need to reevaluate how you're doing your GUI. 您需要重新评估GUI的工作方式。 As mentioned in their GUI scripting guide you should probably use their UI system . 如他们的GUI脚本指南中所述,您可能应该使用他们的UI系统

You especially don't want to be making one or more WWW calls per frame, or doing a bunch of sorting every frame. 您尤其不想每帧进行一个或多个WWW调用,或者不想对每帧进行一堆排序。

https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnGUI.html https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnGUI.html

OnGUI is called for rendering and handling GUI events. 调用OnGUI来呈现和处理GUI事件。

This means that your OnGUI implementation might be called several times per frame (one call per event). 这意味着您的OnGUI实现可能每帧被调用几次 (每个事件一次)。 For more information on GUI events see the Event reference. 有关GUI事件的更多信息,请参见事件参考。 If the MonoBehaviour's enabled property is set to false, OnGUI() will not be called. 如果MonoBehaviour的enabled属性设置为false,则不会调用OnGUI()。

You should probably use another way to call your method, or use a boolean value to check whether or not it has already been called. 您可能应该使用另一种方法来调用您的方法,或者使用一个布尔值来检查它是否已经被调用。

Please refer to the image below to better understand the Unity lifecycle methods. 请参考下图以更好地了解Unity生命周期方法。

Unity生命周期

More information about Unity's Lifecycle can be found at: https://docs.unity3d.com/Manual/ExecutionOrder.html 有关Unity生命周期的更多信息, 访问: https//docs.unity3d.com/Manual/ExecutionOrder.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM