一起来玩U3D之场景转换+关卡选择

场景转换

在游戏中我们经常会有场景转换的使用,比如传送阵等
那么U3D中如何实现场景转换呢?
假设我们现在有两个如下场景:
在这里插入图片描述
那么如何在这两个场景中切换呢?
首先,打开下面的界面
在这里插入图片描述

然后再打开的界面中拖入我们的场景

在这里插入图片描述
最后我们要在两个场景中分别创建一个脚本
注意脚本中首先引入命名空间

using UnityEngine.SceneManagement;

public void OnClickLoadScene()
	{
		SceneManager.LoadScene("Complete");
	}

然后随便绑定一个按钮,就可以跳转到想去的场景了。

关卡选择

最终效果如下面几张图所示:
刚进入关卡界面:
在这里插入图片描述
点击第一关并确定后(直接就开始算分了,得几个星星自己挑):在这里插入图片描述
这边我选2颗星后确定:可以看到,第一关得了2颗星,第二关解锁了
在这里插入图片描述

UI的搭建我就不演示了,直接贴出最终搭建好的UI层次

在这里插入图片描述
在这里插入图片描述
下面对上述UI做出解释:
canvas:就是画布
BackGround:整个大背景
windowBG:背景框(无所谓)
windowHead:上面的标题(无所谓)

接下来的很重要

levels:一个空对象,里面添加一个grid网格组件用来排列关卡按钮,levels里面我写了10个子对象,就是我们的关卡
level01:按钮
Select:一张图片,注意只在这一个关卡中创建这个,后面的不要(或者你干脆不要,不影响功能,只是为了看着舒服)
Text:用来显示关卡编号
stars:星星背景框
star1–star3–star2:三个星星图片
lock:小锁图片
AcceptButton:进入关卡场景按钮

好啦,接下来开始写脚本

首先,我们在levels里面添加一个脚本CheckPointCotroller(选择关卡控制器)
代码如下:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class LevelsController : MonoBehaviour {

	[Header("最高可挑战的关卡")]
	private int challengingLevel;

	/// <summary>
	/// 选择框
	/// </summary>
	private Transform select;

	private int currentLevelNum;

	void Awake()
	{
		//找到选择框
		select = GameObject.FindWithTag("Select").transform;
	}

	void Start()
	{
		challengingLevel = Singleton.GetInstance().levelAndStars.Count + 1;

		InitUI();
	}


	public void InitUI()
	{
		//初始化UI
		for (int i = 0; i < transform.childCount; i++)
		{
			//找到第i个子对象(关卡)
			Transform child = transform.GetChild(i);

			Transform stars = child.Find("stars");

			//更改子对象关卡编号
			child.Find("Text").GetComponent<Text>().text = (i+1).ToString();

			//如果当前关卡编号小于最高可挑战关卡编号,就解锁
			if (i < challengingLevel)
			{
				//把小锁图片设为非激活
				child.Find("lockImage").gameObject.SetActive(false);
				//让关卡按钮可以点击
				child.GetComponent<Button>().interactable = true;
				//将解锁后的关卡编号文字颜色变亮
				child.Find("Text").GetComponent<Text>().color = new Color32(255, 234, 149,255);
				//最新解锁的关卡就解锁以上内容直接continue
				if (i + 1 == challengingLevel)
				{
					continue;
				}
				
				//将星星背景框激活
				stars.gameObject.SetActive(true);
				//根据各个关卡获得的星星数激活指定数量的星星
				switch (Singleton.GetInstance().levelAndStars[i + 1])
				{
					case 1:
						stars.GetChild(0).gameObject.SetActive(true);
						break;

					case 2:
						stars.GetChild(0).gameObject.SetActive(true);
						stars.GetChild(2).gameObject.SetActive(true);
						break;

					case 3:
						for (int j = 0; j < 3; j++)
						{
							stars.GetChild(j).gameObject.SetActive(true);
						}
						break;

					default:
						break;
				}


			}
		}
	}

	//点击关卡按钮时响应此方法(传入的是关卡编号)
	public void CheckLevelByClick(int levelNum)
	{
		//获取当前选择的关卡
		Transform currentLevel = transform.GetChild(levelNum - 1);

		//选择框的父对象变更为当前选中的关卡
		select.SetParent(currentLevel);

		//选择框放到最底层
		select.SetSiblingIndex(0);

		//选择框位置变更到当前选择的关卡
		select.localPosition = Vector3.zero;

		//保存当前选中的关卡编号(这里也可以直接用单例对象接收)
		currentLevelNum = levelNum;
	}

	//点击对号按钮时执行此方法
	public void OnClickLoadScene()
	{
		//将当前关卡编号保存在单例中
		Singleton.GetInstance().levelNum = currentLevelNum;
		//跳转场景
		SceneManager.LoadScene("LevelComplete");
	}

}

好,接下来我们把单例类写好

using System.Collections.Generic;

public class Singleton {

	//当前进入的关卡
	public int levelNum;

	//当前关卡中获得的星星数量
	public int getStars;

	//定义字典用来存储所有关卡信息
	public Dictionary<int, int> levelAndStars;
	//定义单例对象
	private static Singleton instance;
	//在构造中初始化字典
	private Singleton()
	{
		levelAndStars = new Dictionary<int, int>();
	}
	//获取单例
	public static Singleton GetInstance()
	{
		if (instance == null)
		{
			instance = new Singleton();
		}
		return instance;
	}
	//更新关卡信息方法(在complete场景中调用)
	public void UpdateLevelStars()
	{
		if (levelAndStars.ContainsKey(levelNum))
		{
			if (levelAndStars[levelNum] < getStars)
			{
				levelAndStars[levelNum] = getStars;
			}
		}
		else
		{
			levelAndStars.Add(levelNum, getStars);
		}

		
	}

}

接下来,另一个场景的UI如下

在这里插入图片描述
在这里插入图片描述

读者可以不搭建那些花里胡哨的东西,只看红框中的就行

我们在每一个star中都添加一个脚本LevelComplete

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class LevelComplete : MonoBehaviour,IPointerEnterHandler{

	[Header("第几颗星")]
	public int starIndex;
	//获取全部星星的此脚本
	public LevelComplete[] stars;
	//定义一个图片组件用来修改透明度
	private Image image;
	//接收MouseX的返回值
	private float mhor;

	void Awake()
	{
		//初始化image
		image = transform.GetComponent<Image>();
	}
	
	//当鼠标进入当前图片
	public void OnPointerEnter(PointerEventData eventData)
	{
		//获取鼠标移动方向
		mhor = Input.GetAxis("Mouse X");
		//若大于0表示鼠标是自左向右划,我们就点亮星星
		if (mhor > 0)
		{
			ShowStars();
		}
		else
		{
			HideStars();
		}
	}
	//根据点亮的是哪颗星星以决定要点亮几颗星
	public void ShowStars()
	{
		for (int i = 0; i < starIndex; i++)
		{
			stars[i].ChangeStarColorA(1);
		}
		//用单例保存获得的星星数量
		Singleton.GetInstance().getStars = starIndex;

	}
	//根据要熄灭哪个星以决定熄灭哪几颗星
	public void HideStars()
	{
		for (int i = 2; i >= starIndex - 1; i--)
		{
			stars[i].ChangeStarColorA(0);
		}
		//用单例保存获得的星星数量
		Singleton.GetInstance().getStars = starIndex - 1;

	}
	//改变星星图片的透明度
	public void ChangeStarColorA(int A)
	{
		image.color = new Color(image.color.r, image.color.g, image.color.b, A);
	}


}

最后我们在complete场景里的按钮上添加以下脚本

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class CompleteAcceptButton : MonoBehaviour {
	//定义按钮
	private Button btn;

	void Awake()
	{	//初始化按钮
		btn = transform.GetComponent<Button>();
	}

	void Start()
	{	//在按钮上绑定OnClickLoadScene事件
		btn.onClick.AddListener(OnClickLoadScene);
	}

	//单击按钮的响应事件
	private void OnClickLoadScene()
	{
		//执行单例的更新关卡信息方法
		Singleton.GetInstance().UpdateLevelStars();

		//切换场景
		SceneManager.LoadScene("Checkpoint");
	}


}

好了,关卡的UI就简单的介绍到这里。

点个关注,给个赞呗!

猜你喜欢

转载自blog.csdn.net/maybe_ice/article/details/104849300