代码之家  ›  专栏  ›  技术社区  ›  Oscar

阻止每帧c调用一个函数#

  •  0
  • Oscar  · 技术社区  · 6 年前

    我正在尝试使用程序中从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循环,但是它对按钮的创建没有影响,按钮的创建次数仍然比需要的次数多

    3 回复  |  直到 6 年前
        1
  •  2
  •   Lece    6 年前

    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;
    
        ...
    }
    
        2
  •  1
  •   McAden    6 年前

    documentation :

    OnGUI用于呈现和处理GUI事件。

    这意味着您的OnGUI实现可能被称为 每帧次数(每个事件一次调用)。有关GUI的更多信息 事件请参阅事件参考。如果启用了MonoBehavior 属性设置为false,将不会调用OnGUI()。

    您需要重新评估GUI的工作方式。如他们的 GUI scripting guide 您可能应该使用 UI system

    你尤其不想做一个或多个 WWW 每帧调用,或对每帧进行一系列排序。

        3
  •  0
  •   Community CDub    4 年前

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

    OnGUI用于呈现和处理GUI事件。

    这意味着您的OnGUI实现可能会在每帧中被调用多次 (每个事件一次呼叫)。有关GUI事件的更多信息,请参阅事件参考。如果MonoBehavior的enabled属性设置为false,则不会调用OnGUI()。

    您可能应该使用另一种方法来调用您的方法,或者使用布尔值来检查它是否已被调用。

    请参考下图以更好地理解Unity生命周期方法。

    Unity lifecycle

    有关Unity生命周期的更多信息,请访问: https://docs.unity3d.com/Manual/ExecutionOrder.html