unity如何解锁关卡

下图是一个游戏的关卡界面,在设计关卡时,当前面一关通关后使后一关的关卡解锁该如何设计呢,本章内容将一解锁六个关卡为例

一、理论知识

1、在unity中,如何实现某些按钮可以互动,而其他按钮无法互动呢,这个关键在于button组件上面有一个叫Interactable的布尔值,只要我们把它取消勾选,那么这些按钮就无法互动了,所以在解锁按钮了之后,我们要把这些按钮上的Interactable设成true,没有解锁的关卡设置为false,那么这些按钮就不能产生互动了。

 一般来说,我们使用for循环,先把所有的按钮都设置成不可互动的按钮,代码如下

for(int i=0;i<buttons.length;i++){
buttons[i].interactable=false;   //buttons是用来存储关卡按钮的数组
}

然后再把已经解锁了的关卡设置成可交互的按钮

for(int i=0;i<unlockLevel;i++){
buttons[i].interactable=true;   //unlockLevel是已经解锁的关卡数
}

关卡解锁后更新

if(currentLevelIndex>unlockLevel){
unlockLevel=currentLevelIndex;
PlayerPrefs.SetInt("unlockLevel",unlockLevel);
}

2、本地数据存储,在unity中,本地数据存储可以用PlayerPrefs,存储数据类型有以下几类

public static void SetInt (string key, int value);
// 设置由 key 键确定的整数值
 
public static void SetFloat (string key, float value);
// 设置由 key 键确定的浮点数值
 
public static void SetString (string key, string value);
// 设置由 key 键确定的字符串值
 
public static int GetInt (string key);
public static int GetInt (string key, int defaultValue);
// 获取存储文件中 key 键对应的整数值(不存在则返回 defaultValue)
 
public static float GetFloat (string key);
public static float GetFloat (string key, float defaultValue);
// 获取存储文件中 key 键对应的浮点数值(不存在则返回 defaultValue)
 
public static string GetString (string key);
public static string GetString (string key, string defaultValue);
// 获取存储文件中 key 键对应的字符串值(不存在则返回 defaultValue)
 
public static void Save ();
// 将所有修改的内容写入硬盘(默认情况下,Unity 会在 OnApplicationQuit() 执行过程中自动写入)
 
public static bool HasKey (string key);
// 判断 key 键是否存在(存在则返回 true)
 
public static void DeleteKey (string key);
// 删除 key 键以及其对应的值
 
public static void DeleteAll ();
// 删除所有存储内容(需谨慎使用)

二、实例

1、创建一个空物体,命名为buttonPanel,在此项目下创建六个按钮,分别命名为1-6,创建一个空物体buttonscript,用来存放按钮响应代码,创建六个场景,命名为1-6,用来实现场景跳转, 在六个场景中分别创建一个按钮返回关卡选择界面,为了美观可以自己添加一些内容,本篇文章是在资源商店中下载了UI button,使用了美观一点的panel,并把按钮设置为透明,然后拖拽到与panel相同的位置,这样可以在点击panel的时候响应按钮,然后给按钮贴上了关卡数(这个可以不贴,在代码中会有贴关卡数的操作,但是比较丑,自己贴的会美观一点,为了美观的内容可自行设定)

 整体的布局如下( 没有实现美观的小伙伴可以把1-6当做是六个按钮)

 

2、点击File->build,把需要的场景拖进去,并记住后面的序号,场景跳转的时候需要用到,我这里有一些场景是不需要的,大家按照自己的场景适当变通就好,我这里的总关卡场景是quick,对应序号3,下面的1-6是六个关卡场景,对应序号4-9

3、创建六个脚本用来实现六个场景的跳转,新建六个C#脚本,分别命名为Select1-Select6

六个脚本的代码如下:(这里的4是我的第一关的场景序号,下面几关的一次往后就好)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Select1 : MonoBehaviour
{
    public void OnLoginButtonClick()
    {
        SceneManager.LoadScene(4);
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Select2 : MonoBehaviour
{
    public void OnLoginButtonClick()
    {
        SceneManager.LoadScene(5);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Select3 : MonoBehaviour
{
    public void OnLoginButtonClick()
    {
        SceneManager.LoadScene(6);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Select4 : MonoBehaviour
{
    public void OnLoginButtonClick()
    {
        SceneManager.LoadScene(7);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Select5 : MonoBehaviour
{
    public void OnLoginButtonClick()
    {
        SceneManager.LoadScene(8);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Select6 : MonoBehaviour
{
    public void OnLoginButtonClick()
    {
        SceneManager.LoadScene(9);
    }
}

4、把六个代码赋给buttonscript

5、场景跳转,这里以第一关跳转为例,其余几关的方法相同,选中第一个button,即命名为1的按钮,在右侧Inspector界面中往下滑,看到一个 on click的地方,选择+号,把buttonscript拖到右侧,在左边选择Select1,如下图,其余几个按钮跳转关卡也相同

6、关卡解锁代码,新建C# 命名为LevelSelectManager,相关代码注释如下,把这个代码赋给buttonpanel,然后把buttonpanel赋给levelSelectPanel,这里要注意的是,由于解锁的关卡数使用的是客户端数据存储,所以当运行程序后,即使关闭程序,或者关闭unity,数据都已经发生了改变(如果所有关卡都已经通关,重新运行游戏时关卡仍然是通关状态,要想回到初始状态,则要使用PlayerPrefs.SetInt("unlockedLevelIndex", 0);把数据归零,运行程序后关闭,然后把这行代码注释掉,重新运行程序即可)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class LevelSelectManager : MonoBehaviour
{
    public GameObject levelSelectPanel;
    Button[] levelSelectButtons;
    int unlockedLevelIndex ;
    // Start is called before the first frame update
    void Start()
    {
      //  PlayerPrefs.SetInt("unlockedLevelIndex", 0);
        unlockedLevelIndex = PlayerPrefs.GetInt("unlockedLevelIndex");  //获取解锁过得关卡
        levelSelectButtons = new Button[levelSelectPanel.transform.childCount];//关卡数组初始化
        for(int i = 0; i < levelSelectPanel.transform.childCount; i++)//获取所有的button组件
        {
            //给每个关卡贴上关卡数
            levelSelectPanel.transform.GetChild(i).GetChild(0).GetComponent<Text>().text = (i + 1).ToString();
            levelSelectButtons[i]= levelSelectPanel.transform.GetChild(i).GetComponent<Button>();
        }

       //将所有button组件的iteractable值设置成false
       foreach(var levelSelectButton in levelSelectButtons)
        {
            levelSelectButton.interactable = false;
            //添加事件
            levelSelectButton.onClick.AddListener(delegate ()
            {
                //获取点击按钮上的数字,这个数字就是第几关
                Text text = levelSelectButton.gameObject.GetComponentInChildren<Text>();
                //保存第几关
                PlayerPrefs.SetInt("levelNum", int.Parse(text.text));
                
           
            });
        }
       
       //解锁后关卡的interactable设置成true
       for(int i = 0; i < unlockedLevelIndex +1; i++)
        {
            levelSelectButtons[i].interactable = true;
        }
        CheckLevelNum();
    }

    // Update is called once per frame
    void CheckLevelNum()
    {
        int unlock = PlayerPrefs.GetInt("unlockedLevelIndex");
        int levelNum = PlayerPrefs.GetInt("levelNum");

        //通关条件



        if (levelNum > unlock && levelNum<6)
        {
            PlayerPrefs.SetInt("unlockedLevelIndex", unlock + 1);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/lxy20011125/article/details/129935941