2013-05-19 40 views
1

我對我製作的遊戲有個奇怪的問題。出於某種原因,每當我從菜單中切換到另一個場景時,菜單都可以在後臺看到,並且其按鈕處於活動狀態。所以玩家可以點擊一個菜單按鈕的空間(實際上並不在菜單屏幕上),並獲得意外的響應。它只發生在這一場景中;所有其他場景正常工作。這是有問題的腳本。即使我不想要它,場景仍然存在於背景中

using UnityEngine; 
    using System.Collections; 



public class Menu : MonoBehaviour 
{ 
    //public Texture2D background; 
    public GUITexture backgroundCopy; 
    public GUITexture background; 
    float bgPos, bgCopyPos; 
    public GUISkin buttonSkin; 
    public GUISkin recordSkin; 
    public GUIText guiRecordLabel; 
    public GUIText guiTime; 
    public GUIText guiComplete; 
    public GUIText guiTurns; 
    public GUIText guiLosses; 
    public GUIText guiQuits; 

    Records records = new Records(); 

    //public static Menu instance = null; 
    private bool onMenuScreen;    //this prevents the menu buttons from being pressed when I'm not on the menu. weird issue. 

    void Awake() 
    { 
     //ScreenFader.fadeToBlack = false; 
     //create a singleton so that there's only one instance of a menu at any time. 
     //if (instance != null) 
     // DestroyObject(this); //destroys the new instance 
     //else 
     // instance = this; 

     //menu needs to persist for the duration of the game because I want the music to keep playing across multiple screens. -THIS IS NO LONGER THE CASE 
     //DontDestroyOnLoad(this); 

     //load records 
     records.LoadRecords(); 

    } 
    // Use this for initialization 
    void Start() 
    { 
     bgPos = 0;     //initial x Position of the background 
     bgCopyPos = -Screen.width; //this is placed before the original background. 
     onMenuScreen = true;  //I SHOULDN'T NEED THIS 

    } 





    // Update is called once per frame 
    void Update() 
    { 
     if (!onMenuScreen) //I need to do this check because the menu persists and remains on screen. 
     { 
      guiRecordLabel.enabled = false; 
      guiTime.enabled = false; 
      guiComplete.enabled = false;  //I shouldn't need any of this 
      guiTurns.enabled = false; 
      guiLosses.enabled = false; 
      guiQuits.enabled = false; 
     } 
     else 
     { 
      guiRecordLabel.enabled = true; 
      guiTime.enabled = true; 
      guiComplete.enabled = true; 
      guiTurns.enabled = true; 
      guiLosses.enabled = true; 
      guiQuits.enabled = true; 
     } 

     //show records 
     guiRecordLabel.material.color = Color.red; 
     guiTime.text = "Total Time: " + records.TotalTime; 
     guiComplete.text = "Completion: " + records.CompletionRate + "%"; 
     guiTurns.text = "Turn Total: " + records.TurnTotal; 
     guiLosses.text = "Total Losses: " + records.LossCount; 
     guiQuits.text = "Rage Quits: " + records.RageCount; 



     //scroll the background. TODO: provide different backgrounds 
     bgPos = (bgPos > Screen.width) ? -Screen.width + 2 : bgPos += 1; 
     bgCopyPos = (bgCopyPos > Screen.width) ? -Screen.width + 2 : bgCopyPos += 1; 

     background.pixelInset = new Rect(bgPos, background.transform.position.y, Screen.width, Screen.height); 
     backgroundCopy.pixelInset = new Rect(bgCopyPos, background.transform.position.y, Screen.width, Screen.height); 


    } 

    void OnGUI() 
    { 


     //buttons 
     GUI.skin = buttonSkin; 
     if (onMenuScreen && GUI.Button(new Rect(60 * Title.scale.x, 400 * Title.scale.y, 130 * Title.scale.x, 33 * Title.scale.y), "Level Select")) 
     {   
      Application.LoadLevel("LevelSelectScreen"); 
      onMenuScreen = false; 
     } 

     if (onMenuScreen && GUI.Button(new Rect(300 * Title.scale.x, 400 * Title.scale.y, 130 * Title.scale.x, 33 * Title.scale.y), "Help & Options")) 
     {   
      Application.LoadLevel("HelpScreen"); 
      onMenuScreen = false; 
     } 

     if (onMenuScreen && GUI.Button(new Rect(540 * Title.scale.x, 400 * Title.scale.y, 130 * Title.scale.x, 33 * Title.scale.y), "Back to Title")) 
     { 
      //DestroyObject(this); //Kill the menu whenever I return to title screen.   
      Application.LoadLevel("TitleScreen"); 
      onMenuScreen = false; 
     } 
    } 
} 

我認爲這個問題可能是我在場景中的第二個腳本,但我禁用了它,並且我遇到了同樣的問題。這是另一個腳本。

/* This script is used to allow music to persist between screens. It uses a singleton to prevent more than once instance 
* from being created. This script must be placed in MenuScreen scene. */ 

using UnityEngine; 
using System.Collections; 
using System.IO; 
using System; 

public class MusicPlayer : MonoBehaviour 
{ 

    public static MusicPlayer instance = null; 
    AudioClip track;  //copy of the music currently playing. 
    public AudioClip[] musicTracks; 
    AudioSource source; 
    private bool musicPlaying; 
    private short trackNumber; 

    void Awake() 
    { 
     //create a singleton so that there's only one instance of a music track at any time. 
     if (instance != null) 
      DestroyObject(this); //destroys the new instance 
     else 
      instance = this; 


     DontDestroyOnLoad(this); 
    } 
    // Use this for initialization 
    void Start() 
    { 
     source = GetComponent<AudioSource>(); 
     LoadTrackFile(); 
    } 

    public string TrackName 
    { 
     get { return musicTracks[trackNumber].name; } 
    } 

    public short TrackNumber 
    { 
     get { return trackNumber; } 
     set { trackNumber = value; } 
    } 

    public bool MusicPlaying 
    { 
     get { return musicPlaying; } 
     set { musicPlaying = value; } 
    } 

    /* Create/update a file to save track number. */ 
    public void UpdateTrackFile() 
    { 
     string directory = Application.persistentDataPath + "/Tile Crusher/Data/"; 
     string fileName = "trackfile.savefile"; 

     //initialize track number if file doesn't exist. 
     if (!File.Exists(directory + fileName)) 
     { 
      trackNumber = 0; 
     } 

     FileStream fs = new FileStream(directory + fileName, FileMode.OpenOrCreate); 
     StreamWriter writer = new StreamWriter(fs); 

     //write track number to file 
     writer.WriteLine(trackNumber); 

     writer.Close(); 
     fs.Close(); 
    } 

    void LoadTrackFile() 
    { 

     //start searching and reading files 
     string directory = Application.persistentDataPath + "/Tile Crusher/Data/"; 
     string fileName = "trackfile.savefile"; 


     //locate the file. If it doesn't exist, it will be created. 
     if (!File.Exists(directory + fileName)) 
     { 
      UpdateTrackFile(); 
     } 

     //read data. The file is read in a specific order. 
     FileStream fs = new FileStream(directory + fileName, FileMode.Open); 
     StreamReader fileRead = new StreamReader(fs); 

     //load track number 
     string track = fileRead.ReadLine(); 
     trackNumber = Int16.Parse(track); 

     //done 
     fileRead.Close(); 
     fs.Close(); 


    } 

    // Update is called once per frame 
    void Update() 
    { 

     if (!musicPlaying && trackNumber >= 0) 
     { 
      //play music 
      source.clip = musicTracks[trackNumber]; 
      source.Play(); 
      musicPlaying = true; 
     } 
     else if (trackNumber < 0) 
      source.Stop(); 


} 

什麼在擾亂我是這個問題只發生在這一個場景。我所有的其他場景都很好。我使用了一種解決方法,但我認爲我不需要爲這一個場景做這樣的事情。有人能幫忙嗎?

回答

0

我會重構菜單類,以便您可以禁用它時,沒有必要有兩個原因AA全:

  1. 只有當你實際上是在菜單中的場景
  2. 需要在Update代碼OnGui是相當昂貴的,因爲它被稱爲每幀多次

您可以創建一個空的遊戲對象MenuManager甚至更​​好SceneManager持續使用Object.DontDestroyOnLoad。所以啓用和禁用Menu對象可以在這個類中完成。

也許Unity singleton manager classes可以給你一些啓發。我使用這種方法來保持層次小而乾淨。我的所有場景都包含來自預製件的遊戲對象_ApplicationStartup,其中包含初始引導代碼和一些開發增強功能。當您的項目不斷壯大並且有幾個場景時,我強烈建議您設計場景,以便您可以直接測試場景。當你在場景Level-5上工作時,如果你不得不切換回主場景進行測試,這是完全令人討厭的。

+0

是的,我知道OnGUI的性能問題。當我問我的問題時,我正在離開它。誰知道,也許它會解決我遇到的問題。 – King

+0

我曾經使用Unity的內置GUI系統,但後來切換到NGUI - 我最好的決定之一。也許他們會做類似的事情,NGUI的人現在在Unity工作。 – Kay

+0

因此,在消除OnGUI和切換到GUITextures之後,出現了一些改進。切換屏幕時,按鈕在後臺不再處於活動狀態。所以看起來OnGUI對這個問題的一部分負責。不過,我仍然不確定問題的原因。我想我會按照建議製作SceneManager腳本。 – King