【问题标题】:Unity3D : Retry Menu (Scene Management)Unity3D:重试菜单(场景管理)
【发布时间】:2014-07-07 14:29:44
【问题描述】:

我正在使用 Unity3D 游戏引擎为 Android 制作一个简单的 2D 游戏。我创建了所有关卡和所有内容,但我坚持制作游戏结束/重试菜单。到目前为止,我一直在使用新场景作为游戏结束菜单。我使用了这个简单的脚本:

#pragma strict

var level = Application.LoadLevel;

function OnCollisionEnter(Collision : Collision)
{
    if(Collision.collider.tag == "Player")
    {
        Application.LoadLevel("GameOver");
    }
}

这是一个“菜单”:

#pragma strict

var myGUISkin : GUISkin;

var btnTexture : Texture;

function OnGUI() {
GUI.skin = myGUISkin;


if (GUI.Button(Rect(Screen.width/2-60,Screen.height/2+30,100,40),"Retry"))
    Application.LoadLevel("Easy1");

if (GUI.Button(Rect(Screen.width/2-90,Screen.height/2+100,170,40),"Main Menu"))
    Application.LoadLevel("MainMenu");
}

问题在于我必须创建超过 200 个游戏的场景、障碍物(杀死玩家的对象)并为每个级别重新创建超过 200 次相同的脚本。有没有其他方法可以让这个过程更快更轻松?

编辑:如果可能的话,请在您提出您的想法时,仅使用 javascript,我不懂 C#,甚至一点都不懂。我知道我问的太多了,但这真的让我很困惑。 谢谢。

【问题讨论】:

  • 不清楚。为什么你需要创建超过 200 个游戏场景和超过 200 次编辑脚本?
  • 因为这个Application.LoadLevel("Easy1");?
  • 我在这个游戏中有超过 200 个关卡,我必须/不得不复制/粘贴它们并编辑每个关卡以打开特定关卡。

标签: menu unity3d


【解决方案1】:

有几种不同的解决方案,但我建议使用 PlayerPrefs。这有一个额外的好处,即即使应用程序关闭然后重新打开,也能保持不变。

在 Main Menu 类的 Awake() 函数中,您可以获取当前级别并将其存储在 Main Menu 类的静态字符串中。如果是第 1 次,请使用 1 级的名称。

类似这样的:

static string currentLevelName;
void Awake()
{
    currentLevelName = PlayerPrefs.GetString("CurrentLevel");
    if (currentLevelName == defaultValue)
    {
       currentLevelName = "Level1"
    }
}

然后,修改您的按钮以执行此操作:

if (GUI.Button(Rect(Screen.width/2-60,Screen.height/2+30,100,40),"Retry"))
    Application.LoadLevel(currentLevelName);

每当玩家进入下一个关卡时,将 PlayerPrefs 中的字符串设置为新关卡名称:

PlayerPrefs.SetString("CurrentLevel", Application.loadedLevelName);

【讨论】:

    【解决方案2】:

    您可以创建具有静态属性的类。例如(在 c# 中)

    public class GameOverInput
    {
        public static string name;
        public static string retryLevel;
        //all the info you need
    }
    

    然后您可以轻松读取游戏结束场景中的输入(只需要一个)

    public class GameOverMenu : MonoBehavior
    {
        void Start()
        {
            Debug.Log("You were killed by " + GameOverInput.name);
            Application.LoadLevel(GameOverInput.retryLevel);
        }
    }
    

    你在加载游戏之前设置了这个信息

    if (Collision.collider.tag == "Player")
    {
        GameOverInput.name = "Baddie";
        Application.LoadLevel("GameOver");
    }
    

    【讨论】:

    • @SergeyKrusch 这只是一个例子。这些语言并没有那么不同,希望 OP 可以管理。
    • @LVBen 这就是为什么输入类不是 MonoBehavior :)
    【解决方案3】:

    另一种选择是制作类似于单例 LevelManager MonoBehavior 的东西并将其添加到名为“Level Manager”的对象中。使用 DontDestroyOnLoad 函数使对象即使在您加载另一个关卡时仍然存在。

    class LevelManager : MonoBehavior
    {
        static LevelManager _instance;
        public string currentLevelName;
        public string killedBy;
    
        function Awake ()
        {
           if (_instance == null)
           {
              _instance = this;
               DontDestroyOnLoad(gameObject);
           }
           else
           {
              Destroy(gameObject); // Make sure we never have more than 1 Level Manager.
           }
        }
    
        LevelManager Instance
        {
           get
           {
              if (_instance == null)
              {
                 GameObject levelManagerObject = GameObject.Find("Level Manager");
                 _instance = levelManagerObject.GetComponent<LevelManager>();
              }
              return _instance
           }
        }
    }
    

    然后,您可以从主菜单类中随时访问关卡管理器,如下所示:

    Debug.Log("Killed by " + LevelManager.Instance.killedBy);
    

    LevelManager.Instance.currentLevelName = Application.loadedLevelName;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多