持久化数据PlayerPrefs其实说白了,就是Android里面的bundle《【Android】多个Activity之间利用bundle传递数值》(点击打开链接),其实说得更直白些,就是一个超级全局变量,这个全局变量贯穿于整个游戏之中,所有的场景都可以对其操作,相当于一个文件似得的。在《【Unity3D】同场景物体传值与Vector》(点击打开链接)我曾经写了Unity3D中,同一个场景的各个组件怎么传递数据,本文将论述如何在场景中传值。同时,继《【Unity3D】场景切换、UGUI组件事件、开始游戏与关闭游戏》(点击打开链接)继续补存UGUI的使用,讲述下按钮组ToggleGroup如何使用。
下面将用一个程序讲述这个问题,如图所示,其实也不用怎么解释,类似与《【php】基本语法与页面之间数值传递》(点击打开链接):
具体制作过程如下:
一、场景布置
1、两个场景一个Input,另一个Output。Input场景布置如下图,3个Text分别是姓名、性别与国籍这个没什么好说,下拉列表DropDownList在《【Unity3D】Unity3D 4.x利用原生UGUI完成下拉列表DropDownList》(点击打开链接)已经说过。InputField输入框其实也没什么好说的,直接在GameObject->UI->InputField可以创建。
下面重点说说按钮组ToggleGroup的制作:
(1)先在Canvas下创建一个Create Empty改名为ToggleGroup,部分版本默认的话,空物体会直接创建到Canvas以外,需要再自己手动拖到这个Canvas以内,不然之后附着于这个空物体的Toggle看不到。
(2)之后在这个ToggleGroup创建Toggle,只有一个Toggle的Is On是打开的。
(3)最关键的是这里,在空物体ToggleGroup添加组件UI->Toggle Group
(4)之后,对于各个Toggle,Toggle0~ToggleN,都设置为这个组的成语,如图所示:
至此一个按钮组ToggleGroup制作完毕,在这个组下的Toggle只有一个可以被选择。
2、下面Output场景的布置简单得不能再简单,就一个Canvas、一个Button和一个用于接受输出结果的Text,还有一个用于接受脚本的空物体GameObject。
二、脚本编写
1、Input场景的脚本核心,在于最下方的确定按钮,给予一个Ensure.cs,如下所示:
using UnityEngine;
using UnityEngine.UI;//用到了多个UI
using System.Collections;
using System.Collections.Generic;//按钮组将会用到C#的集合
public class Ensure : MonoBehaviour
{
public void Onclick()
{
string name = GameObject.Find("Canvas/InputField/Text").GetComponent().text;//这样就能直接获取输入框的输入内容
//当然接下来你还可以做些判空检测之类的
//接下来将展示按钮组的使用
string sex = "";
IEnumerable toggleGroup = GameObject.Find("Canvas/ToggleGroup").GetComponent().ActiveToggles();//用于获取按钮组中哪个Toggle被选择
foreach (Toggle t in toggleGroup)
{//遍历这个存放Toggle的按钮组IEnumerable,此乃C#的一个枚举集合,一般直接用foreach遍历
if (t.isOn)//遍历到一个被选择的Toggle
{
switch (t.name)//根据这个Toggle的name,我们给string sex赋予不同的值
{
case "Toggle0":
sex = "男";
break;
case "Toggle1":
sex = "女";
break;
}
break;//就没必要遍历下去了,后面已经可以预见到,都是没被选择的Toggle。
}
}
//最后是下拉菜单的获取
string nation = GameObject.Find("Canvas/DropDownList/Button0/Text").GetComponent().text;
//用持久化数据PlayerPrefs来存储数据
//Unity3D对中文支持不好,必须按照擦写一下,才能保存到这个PlayerPrefs里面
//实质上,PlayerPrefs是一个key-value的键值对,也就是Java中的Map,Python中的Dict,Javascript的Json……就是一个数据字典
PlayerPrefs.SetString("name", WWW.EscapeURL(name));
PlayerPrefs.SetString("sex", WWW.EscapeURL(sex));
PlayerPrefs.SetString("nation", WWW.EscapeURL(nation));
Application.LoadLevel("Output");//切换到场景Output
}
}
上述脚本同时展示了UGUI用户输入组件中,对用户输入数据的获取。其中按钮组ToggleGroup遍历的思想,与《【mfc】标签页》( 点击打开链接)中是一模一样的。对存放在数组的Toggle直接进行遍历得了!
最后这里的持久化数据PlayerPrefs,大家权当一个数据字典来操作就好,HashMap这东西在各个语言都有,也就是所谓的容器类,估计对其研究得更加透彻的,大有人在,大部分的程序猿的面试题一考再考……这里需要小吐槽一个,人家Android什么的全局变量是支持setObject的,它这个Unity3d作为这么高级的游戏引擎,居然只让setString、setInt和setFloat简直药丸,毕竟扔个数组什么的,估计他让你走文件了,又或者自己弄成json字符串压进去吧……存个东西还要像Javascript害怕乱码一样转个码-_-!
而Unity3D的切换场景在《【Unity3D】场景切换、UGUI组件事件、开始游戏与关闭游戏》(点击打开链接)说过了,这里不再赘述了。
2、至于Output场景赋予其空物体GameObject的脚本Result.cs更是简单了:
using UnityEngine;
using UnityEngine.UI;//用到Text这头文件还是需要的
using System.Collections;
public class Result : MonoBehaviour
{
void Start()
{
//将持久化数据PlayerPrefs的结果输出到Text
GameObject.Find("Canvas/Text").GetComponent().text =
WWW.UnEscapeURL(PlayerPrefs.GetString("name")) + "," +
WWW.UnEscapeURL(PlayerPrefs.GetString("sex")) + "," +
WWW.UnEscapeURL(PlayerPrefs.GetString("nation"));
}
public void Onclick()
{
Application.LoadLevel("Input");//切换回Input场景
}
}
只是记得在输出持久化数据PlayerPrefs的时候注意,刚才是Input是转码压入PlayerPrefs的,你输出自然转回来。
如果不经历这个转码解码的过程,亲测,对于中文,就是一堆坑爹Bug!