plyaerjava中使用framemakerr中PlayerPrefs怎么用

Unity本身有PlayerPrefs来做一些数据的保存和读取,也可以通过循环来做批量的读取或者保存,下面这个脚本可以方便的调用用来做上面批量的工作,比如读取一组文本数组数据和保存一组文本数组数据.
建议把这个脚本放在Standard Assets(或者Plugins)目录下,这样可以按照下面的方法方便的调用它.现在包含了下面这些命令:
&&&&&PlayerPrefsX.SetVector3
&&&&& PlayerPrefsX.GetVector3
&&&&& PlayerPrefsX.SetIntArray
&&&&& PlayerPrefsX.GetIntArray
&&&&& PlayerPrefsX.SetFloatArray
&&&&& PlayerPrefsX.GetFloatArray
&&&&& PlayerPrefsX.SetStringArray
&&&&& PlayerPrefsX.GetStringArray
保存一个向量
&&&static function SetVector3 (key : string, value : Vector3) : boolean
//尝试保存一个物体位置&&&&&var player : GameO
if (!PlayerPrefsX.SetVector3(&PlayerPosition&,player.transform.position))//成功返回真,否则假(例如用Webplayer保存超过1M数据的时候)。
print(&不能保存物体位置!&);
获得一个向量
varplayer : GameO
player.transform.position = PlayerPrefsX.GetVector3(&PlayerPosition&);//如果读取的向量存在的话将会返回这个向量值。
保存一组整型数据:
//当保存Scores命名的分数时候创建一个10成员数组
var myScores = new int[10];
for (i = 0; i & myScores.L i++)
&&& myScores[i] = i+1;
if (!PlayerPrefsX.SetIntArray(&Scores&, myScores))
&print(&不能保存分数!&);
&&& 获得一组整型数据
staticfunction GetIntArray (key : string) : int[]
如果存在将返回这组数据,否则将返回int[0];
varscores = PlayerPrefsX.GetIntArray(&Scores&);
staticfunction GetIntArray (key : string, defaultValue : int, defaultSize : int) :int[]
如果不存在这组数据,将返回指定长度的数组以及每个成员都会赋予默认值.
其他函数的使用方法:
staticfunction SetFloatArray (key : string, value : float[]) : boolean
static function GetFloatArray (key : string) : float[]
static function GetFloatArray (key : string, defaultValue : float, defaultSize: int) : float[]
static function SetStringArray (key : string, value : String[]) : boolean
static function SetStringArray (key : string, value : String[], separator :char) : boolean
static function GetStringArray (key : string) : string[]
static function GetStringArray (key : string, separator : char) : string[]
static function GetStringArray (key : string, defaultValue : String,defaultSize : int) : string[]
static function GetStringArray (key : string, separator : char, defaultValue :String, defaultSize : int) : string[]
自己写的测试脚本如下:
using UnityE
using System.C
public classTest :MonoBehaviour {
&&& publicint[]scores =new
&&&&&&&& //Use this for initialization
&&&&&&&& voidStart ()
&&&&&&& for(inti = 0; i & 10; i++)//先定义一个数组,赋值为
1 2 3 4 5 6 7 8 9 10
&&&&&&&&&&&scores[i] = i + 1;
&&&&&&&&&&& Debug.Log(&分数: &+scores[i]);
&&&&&&&&&&&
&&&&&&& PlayerPrefsX.SetIntArray(&SCORES&,scores);//保存整型数组到SCORES的名字存储空间中;
&&&&&&& for(inti = 0; i & 10; i++)//然后重新为数组赋值为10 11 12 13
14 15 16 17 18 19
&&&&&&&&&&&scores[i] = i + 10;
&&&&&&&&&&& Debug.Log(&分数: & +scores[i]);
&&&&&&&Invoke(&Printf&,5);//5s以后再把保存到SCORES变量下的存储的数组的信息重新写到scores的数组中;此处要注意,接受信息的是最初的数组名scores,而不是scores[]数组;再使用数组的知识,就可以获得每个元素的值了!
&&&&&&&& }
&&& voidPrintf()
&&&&&&&scores = PlayerPrefsX.GetIntArray(&SCORES&);
&&&&&&& for(inti = 0; i & 10; i++)
&&&&&&&&&&& Debug.LogError(i+&id: &+scores[i]);
}最后运行的结果是:1 2 3 4 5 6 7 8 9 10& 10 11 12 13 14 15 16 17 18 19&
最后是12 3 4 5 6 7 8 9 10下面两图为输出信息截图:
同理,其他几种类型的数据的批量存取用法与PlayerPrefsX.SetIntArray用法类似;
该脚本的C#版
本文已收录于以下专栏:
相关文章推荐
孙广东  
之前有网友询问这个问题, 当时我只是 提供了一个思路, 使用json序列化、反序列化。 下面就写出两种(都是只能变成字符串)1、json的序列化、反序列化方式JsonF...
因为做的项目是移动平台上的小游戏,所以用不到数据库什么比较大型的存储,所以就选择unity自带的存储PlayerPrefs。
PlayerPrefs自带的函数:
      PlayerP...
Unity本身有PlayerPrefs来做一些数据的保存和读取,也可以通过循环来做批量的读取或者保存,下面这个脚本可以方便的调用用来做上面批量的工作,比如读取一组文本数组数据和保存一组文本数组数据.
...
他的最新文章
讲师:姜飞俊
讲师:汪木铃
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)unity(9)
分享使用Unity 3D免费版本编写游戏的教程(二)
发布时间: 17:31:09&Tags:,,,
作者:John Boardman
欢迎继续阅读本文第二部分内容。(请点击此处阅读本文,)
*使用PlayerPrefs执行高分排行榜
*如何用文本域来执行搜集用户数据的对话框
*如何在Unity中执行作弊码
这些代码现在就在。 本文代码可能会比第1部分更多,现在载入Unity,点击一个脚本,开始吧!
使用PlayerPrefs执行高分排行榜
PlayerPrefs API乍一看可能相当有限。它有10个方法,其中包括DeleteAll(), DeleteKey(), GetFloat(), GetInt(), GetString(), HasKey(), Save(),SetFloat(), SetInt()和SetString()。
有一个显眼的遗漏是取回所有key的方法。对我来说,这就好比去银行存钱,之后回来取款时就要报出票据的序列号。
所以如果找不到PlayerPrefs中的东西,我们如何存储高分?我们事先并不知道用户名称……光有分数根本没用啊。有一个线索就是HasKey()方法。我们可以询问对象它是否含有一个key。所以,如果我们遇到了自己已知的key,我们就可以用来保存和载入高分。让我们看看如何执行。
我决定使用PlayerData这个前缀作为key的已知部分,然后为其附加一个索引以便创造一个独特的key。在scriptSceneManager,我定义了在PlayerPrefs中访问key时的静态字符串。这可以避免程序员因输入错误的key名称而抓狂,并将所有的key置于同一地点,以便追踪被存储的内容。
当30秒过去之后,或者玩家已经没有命值时,就会调用 saveHighScores()。让我们浏览一下该代码中的重要部分。无论是C#还是Unity类、方法还是属性,我都将把它链接到各自的文档中。如果没有链接,这意味着它是我自己的方法之一。
首先发生的一个情况就是调用MakePlayerKey(),它会连接到用户进入CSV格式的数据,并将其以字符串形式返回。你可能会问,这难道不是PlayerData外加索引的key?是这样的,这款游戏的一个条件就是任何独特的玩家数据只会在用户玩游戏时存储一次。这是因为游戏是用来让玩家参与竞赛。所以,PlayerIndex()方法会使用“real”key)“PlayerData”外加一个索引)进行检索,试图找到用户进入的信息。如果找到了,用户仍可继续玩游戏,系统会忽略分数。因为索引0并不用于存储玩家数据,如果找到玩家,0就会返回到KeyIndex。如果没找到玩家,经过上一名玩家的索引就会返回,并创建托管高分的列表。此时就会创建一个KeyValuePair列表,以便将分数从其余数据中隔离出来,更便于排序。
// this data is how we form the key to search for the player
string playerData = MakePlayerKey();
int keyIndex = PlayerIndex(playerData);
if (keyIndex & 0) {
int maxPlayerIndex = MaxPlayerIndex();
List&KeyValuePair& highScores = new List&KeyValuePair&();
现在我们不只要载入前10名,尽管列表能显示的就是这10个名次。另一个条件就是存储所有玩过游戏的用户数据。要知道,这可是一种营销机会!别担心,keyhole并不打算出卖用户数据。所以,我们不但要载入前10名,还要载入1-maxPLayerIndex. 并将其置于列表之上。因为分数是居于每段数据末尾的值,因此我们可以在KeyValuePair.中抓取和单独使用。你可能会说,这里看不到排序。那是因为列表是以排序方式存储,所以不会出现完整的排序。
// read in scores & names
for (int i = 1; i &= maxPlayerI i++) {
string currentData = PlayerPrefs.GetString(PREF_PLAYER_DATA + i);
if (currentData.Length & 0) { int currentScore =
int.Parse(currentData.Substring(currentData.LastIndexOf(“,”) + 1));
KeyValuePair highScore = new KeyValuePair(currentScore, currentData);
highScores.Add(highScore);
分数已经显示在列表,但还是要添加新的分数。这只需在列表上进行简单的线性检索,将当前分数与列表上的分数进行对比即可。首个获得某个分数的玩家排名应该高于列表上其他获得相同分数的玩家,排名只选取更高分数。这样我们就能按顺序存储了相同的分数,如果列表上的分数太低,就将其添加到列表末尾。
// add current score in sorted position
playerData += “,” + KeyValuePair newScore = new
KeyValuePair(score, playerData);
bool playerInserted =
for (int i = 0; i & highScores.C i++) {
if (score & highScores[i].Key) {
highScores.Insert(i, newScore);
playerInserted =
if (!playerInserted) {
highScores.Add(newScore);
现在已经创建了新列表,列表可用新数据(包括新分数)进行重写。这会转变为在列表进行标准的0-Count重复循环。如果列表变化了,首选项仍会保持。因为Unity支持许多平台,它会关注每个平台所谓的“持续” 标准。我们所需知道的是它是否可行。如果初始检索找到了玩家,就要设置另一个临时首选项指出这一事实。这可以用于显示高分之时。最后,要载入关卡以显示高分。
// write out new scores including new player
for (int i = 0; i & highScores.C i++) {
PlayerPrefs.SetString(PREF_PLAYER_DATA + (i + 1), highScores[i].Value);
PlayerPrefs.Save();
PlayerPrefs.SetString(PREF_DOES_PLAYER_EXIST, “TRUE”);
Application.LoadLevel(“sceneScreenWin”);
我们可以在sceneScreenWin脚本中看到显示的高分。这里我要简单陈述下这个画面的设置。
首先,我们要检索标志以便查看是否存在该用户。无论结果如何,我们都要一直使用PREF_SCORE临时首选项来呈现分数。我们可以从scriptScreenGetPlayerInfo脚本中得知这些首选项是临时性的,每次游戏开始时都会删除key。我们会在之后的部分讲到这个画面。如果玩家已经存在,显示他们刚获得分数的画面并不会影响到高分。
bool doesPlayerExist = layerPrefs.HasKey(scriptSceneManager.PREF_DOES_PLAYER_EXIST);
float y = 0;
GUI.Label(new Rect(60.0f, y, 290.0f, 50.0f), “Score: ” + PlayerPrefs.GetInt(scriptSceneManager.PREF_SCORE));
if (doesPlayerExist) {
y += 30.0f;
GUI.Label(new Rect(60.0f, y, 290.0f, 50.0f), “Player found! Score not recorded!”);
现在让我们跳到分数环节。前10名的每个数据都会被复原。因为10名玩家可能还没有玩过游戏,因此查看数据是否存在是避免执行时间脚本错误的一个关键。如果数据存在,被存储的CSV数据就会被解析成各个不同部分,然后以一个格式化的列表呈现。我没有时间去想如何使用等宽字体或其他很棒的效果来呈现数据,有这些基本的可行元素就可以了。
for (int i = 1; i &= 10; i++) {
y += 20.0f;
string currentData = PlayerPrefs.GetString(scriptSceneManager.PREF_PLAYER_DATA + i);
int score = 0;
string firstName = “”;
string lastName = “”;
if (currentData.Length & 0) {
score = int.Parse(currentData.Substring(currentData.LastIndexOf(“,”) + 1));
int index = currentData.IndexOf(“,”);
firstName = currentData.Substring(0, index);
int index2 =currentData.IndexOf(“,”, index + 1);
lastName = currentData.Substring(index + 1, index2 – index – 1);
GUI.Label(new Rect(60.0f, y, 290.0f, y + 20.0f), string.Format(“{0,2}. {1,10} : {2}”, i, score, firstName + ” ” + lastName)); }
KeyShotHighScores(from gamasutra)
另一个显示玩家数据的画面是scriptScreenShowData,这可以通过使用我们之后将描述的代码来实现。
如何用文本域来执行搜集用户数据的对话框
我们已经说过了高分列表,那么这些数据是如何进入的呢?答案就是Unity有一个丰富的用户界面控制集合。我只使用了一些,没有进行验证,因为这只是一款用于一个会议的简单游戏。如果我是为发行一款游戏而编 码,一定会进行完整的检验。
MonoBehavior是一个Unity类,是每个Unity脚本的基本类。它提供了丰富的功能,并且易于扩展。在JavaScript,C#类会从MonoBehavior自动生成扩展——但在C#编码时,程序员必须明确从中扩展。
OnGUI()这个Unity方法会在每一帧调用。只要在这个方法中添加一个print语句然后运行画面即可证明这一点。这也正是firstName, lastName, phone和email fields在类级中而非在方法中定义的原因,因为我们希望它们进行更新,而不是在每一帧中重新初始化。
public class scriptScreenGetPlayerInfo : MonoBehaviour {
public float buttonWidth = 90.0f;
public float buttonHeight = 40.0f;
string firstName = “”;
string lastName = “”;
string phone = “”;
string email = “”;
正如之前所言,调用Start() 时会移除临时首选项。每次加载一个画面时Unity都会调用Start()。
现在,要使用GUI.TextField() API来搜集用户数据。要定义一个Rect给屏幕一个域尺寸,将临近呈现的数据,以及屏幕能够接受的最大字符数。由用户输入的数据将被返回。以下是一个域定义,以及在其左边呈 现的标签:
float y = 30.0f;
GUI.Label(new Rect(10.0f, y, 80.0f, 40.0f), “First Name”); firstName =
GUI.TextField(new Rect(90.0f, y, 200.0f, 30.0f), firstName, 40);
呈现数据域之后,现在要做的就是进行收集。用户点击“Save Info”按钮时即可执行。当用户点击按钮时,GUI.Button() 返回为真。此时域会在首选项中保存,并加载下一个画面。
if (GUI.Button(new Rect(90.0f, y, buttonWidth, buttonHeight), “Save Info”)) {
// here is where you would validate data if it is required PlayerPrefs.SetString(scriptSceneManager.PREF_PLAYER_FIRST_NAME, firstName); PlayerPrefs.SetString
(scriptSceneManager.PREF_PLAYER_LAST_NAME, lastName); PlayerPrefs.SetString(scriptSceneManager.PREF_PLAYER_PHONE, phone); PlayerPrefs.SetString(scriptSceneManager.PREF_PLAYER_EMAIL,
email); Application.LoadLevel(“sceneScreenLoad”);
KeyShot_GatherInfo(from gamasutra)
游戏结束时,字段会在临时首选项域中等待。
如何在Unity中执行作弊码
这对我来说很棘手。我希望用一种方法找开管理函数,以免用户在玩游戏时用很短的时间就想出方法。《KeyShot》有两个管理条件:
1.要在玩家进入游戏之前重置高分,以便在“真正”的游戏开始之前进行检测。
2.在会议结束之后,要能够呈现所有由用户输入的数据。另一个方法就是执行一个远程调用向一个服务器发送数据,但我没有时间来设置这个操作。因为数据是独立于游戏进行存储,我可以在游戏结束后一直添加数据。
执行作弊码的关键在于Unity UI classInput中的inputString域。这个域会托管施加于当前帧的key,即使屏幕上没有任何输入域。这个API的文档尚不明确这一点,并且看似会让用户输入的任何文本处于该域,但事实并非如此。该域会在每一帧重置。所以,如果一个作弊码超过1个字符,那就需要执行更多操作以令其可用。
每次调用Update() ,inputString中的值都会进行检查。如果这个值存在,它就会串连到隐藏域(游戏邦注:这是一个类变量),这样它就会存在于到达Update()的调用之间。现在可以检查隐藏域,看看是否已输入字符串“Key”。 要使用Contains()方法,这样就可以在作弊码之前输入key令其仍然可行。如果超过10个字符在没有key的情况下输入,隐藏域就会重置以免它变得过长。注意,如果k或者e是11个字符,这可以在一开始就避免作 弊码生效。这种情况发生的概率很低,但还是有可能发生。通过检查其他字符串,任何数量的作弊码都可以用这种方法来检查。
如果存在key,numberOfButtons域增加到6,就表明管理画面目前处于活跃状态。
// Update is called once per frame
void Update ()
{ string input = Input.inputS
if (input.Length & 0) {
hidden += }
if (hidden.Contains(“key”))
{ numberOfButtons = 6;
} else if (hidden.Length & 10) {
hidden = “”;
如果numberOfButtons是6,那么“Show Data”和“Clear Data”按钮也会显示并且处于可用状态。
if (numberOfButtons == 6) {
y += buttonHeight + 10.0f;
if (GUI.Button(Rect(10.0f, y, buttonWidth, buttonHeight), “Show Data”)) { Application.LoadLevel(“sceneScreenShowData”);
y += buttonHeight + 10.0f;
if (GUI.Button(Rect(10.0f, y, buttonWidth, buttonHeight), “Clear Data”)) { PlayerPrefs.DeleteAll();
KeyShotAllData(from gamasutra)
以下是带有一个分数的“Show Data”画面。虽然只有基础元素,但已经满足条件了。(本文为游戏邦/编译,拒绝任何不保留版权的转载,如需转载请联系:游戏邦)
Writing Games With Unity 3D in JavaScript and C# – Part 2
by John Boardman
The following blog was, unless otherwise noted, independently written by a member of Gamasutra’s game development community. The thoughts and opinions expressed here are not necessarily those of Gamasutra or its parent company.
Want to write your own blog post on Gamasutra? It’s easy! Click here to get started. Your post could be featured on Gamasutra’s home page, right alongside our award-winning articles and news stories.
Welcome back for Part 2! We covered the following topics in Part 1 of this Unity 3D tutorial:
Introduction to Unity
Introduction to KeyShot
Using multiple cameras to implement a background logo
JavaScript and C# Implementations (including how to use nested generics in JavaScript and how to call C# scripts from JavaScript)
How to use 3D models with axes that don’t line up with normal “Y-up” Unity standards
So if you missed it, be sure to skip over and read it first!
For part 2, we’ll cover the following items:
Implementing a high score table using PlayerPrefs
How to implement a dialog with text fields to collect user data
How to implement cheat codes in Unity
The code is now on GitHub. This will be much more code-intensive than Part 1, so load Unity, click a script, and follow along!
Implementing a high score table using PlayerPrefs
PlayerPrefs can seem fairly limited when you first look at the API. It has 10 methods including DeleteAll(), DeleteKey(), GetFloat(), GetInt(), GetString(), HasKey(), Save(),SetFloat(), SetInt(), and SetString().
One glaring omission is a method that retrieves all keys. To me, that’s like going to a bank, depositing money, and then coming back later to make a withdrawal and being asked what the serial numbers of the bills were.
So, if there is no way to find out what is in PlayerPrefs, how do we save the high scores? We don’t know the user names ahead of time…the scores themselves are no help…hmmmm. Ah, a clue is the HasKey() method. We can ask the object if it has a key. So, if we
come up with our own known keys we can use these to save and load the high scores. Let’s look at how that is done.
I decided to use the prefix “playerData” as the key’s known part, and then append an index to that to create a unique key. In scriptSceneManager I defined static strings to use when accessing keys in PlayerPrefs. This keeps the programmer from frustrations
caused by mistyping key names, and locates all of the keys in one place so it is easy to keep track of what is being stored.
When 30 seconds have passed or the player has no more lives, saveHighScores()is called. Let’s work through the important bits of that code. Whenever there is a C# or Unity class, method, or property throughout the code, I’ll link it to the respective documentation.
If there is no link, that means it is one of my methods.
One of the first things to happen is a call to MakePlayerKey(), which concatenates the data that the user entered in CSV format and returns it as a string. Wait…wasn’t the key “playerData” plus an index? Well…one of this game’s requirements is that any unique
player’s data is only saved the first time the game is played (user exercise: remove this limitation).
This is because the game was used to enter players in a contest (this was the “shroud of secrecy” mentioned in part 1). So, the PlayerIndex() method searches using the “real” keys (“playerData” plus an index) to try to find the information the user entered.
If it is found, the user can still play the game…the score will just be ignored. Since index 0 is not used to store player data, 0 is returned for the keyIndex if the player is found. If the player is not found, the index just past the last player is returned
and a List is created to hold the high scores that are about to be read. A List of KeyValuePair is used so the score can be separated from the rest of the data to make sorting easier.
// this data is how we form the key to search for the player
string playerData = MakePlayerKey();
int keyIndex = PlayerIndex(playerData);
if (keyIndex & 0) {
int maxPlayerIndex = MaxPlayerIndex();
List&KeyValuePair& highScores = new List&KeyValuePair&();
Now we don’t just read-in the top 10, although that is all that is displayed. Another requirement was to save all users that played the game. Hey, this is marketing! Don’t worry, Keyhole has no nefarious plans to sell user data – your data is safe with us.
So anyway, instead of loading 1-10, we load 1 – maxPLayerIndex. and place them into the list. Since score is the value on the end of each piece of data, it can be grabbed and used separately in the KeyValuePair. Hmm you say…I don’t see any sorting in here.
That’s because the list is saved in sorted order, so no full sort ever has to occur
// read in scores & names
for (int i = 1; i &= maxPlayerI i++) {
string currentData = PlayerPrefs.GetString(PREF_PLAYER_DATA + i);
if (currentData.Length & 0) { int currentScore =
int.Parse(currentData.Substring(currentData.LastIndexOf(“,”) + 1));
KeyValuePair highScore = new KeyValuePair(currentScore, currentData);
highScores.Add(highScore);
Now that the scores are in the list, the new one needs to be added. This is a simple linear search through the list, comparing the current score with the score in the list. Since the first player to make a score should be higher in the list than any other player
with the same score, only greater is used instead of greater or equal. In this way we store equal scores in the order that they were made. If the score was too low to be found, it is added to the end of the list.
// add current score in sorted position
playerData += “,” + KeyValuePair newScore = new
KeyValuePair(score, playerData);
bool playerInserted =
for (int i = 0; i & highScores.C i++) {
if (score & highScores[i].Key) {
highScores.Insert(i, newScore);
playerInserted =
if (!playerInserted) {
highScores.Add(newScore);
Now that the new list has been created, the list can be overwritten with the new data, including the new score. The loop switches to a normal 0-Count iteration over the list. If the list was changed, the prefs are persisted. Since Unity supports so many platforms,
it takes care of what “persisted” means for each platform. All we have to know is that it worked. If the player was found by the initial search, another temporary pref is set to indicate that fact. This will be used later when the high scores are displayed.
Finally, the level is loaded to display the high scores.
// write out new scores including new player
for (int i = 0; i & highScores.C i++) {
PlayerPrefs.SetString(PREF_PLAYER_DATA + (i + 1), highScores[i].Value);
PlayerPrefs.Save();
PlayerPrefs.SetString(PREF_DOES_PLAYER_EXIST, “TRUE”);
Application.LoadLevel(“sceneScreenWin”);
Displaying the high scores can be found in the sceneScreenWin script. I’ll briefly cover that screen.
First, we retrieve the flag to tell if the user exists. Regardless of that fact, we always display the score using the PREF_SCORE temporary pref. The way to tell these prefs are temporary is to look at the scriptScreenGetPlayerInfo script, where the keys are
deleted each time the game starts. That screen will be covered in a later section. If the player already existed, the screen shows that the score they just achieved won’t effect the high scores.
bool doesPlayerExist = layerPrefs.HasKey(scriptSceneManager.PREF_DOES_PLAYER_EXIST);
float y = 0;
GUI.Label(new Rect(60.0f, y, 290.0f, 50.0f), “Score: ” + PlayerPrefs.GetInt(scriptSceneManager.PREF_SCORE));
if (doesPlayerExist) {
y += 30.0f;
GUI.Label(new Rect(60.0f, y, 290.0f, 50.0f), “Player found! Score not recorded!”);
Now let’s skip down to the scores. For each of the top 10, the data is retrieved. Because 10 players may not have yet played, checking to see if data is present is crucial to prevent runtime scripting errors. If data is present, the stored CSV data is parsed
into its respective parts, and then displayed in a formatted list. I didn’t have time to figure out how to display the data using a monospaced font or other cool stuff, but the basics are here and they work.
for (int i = 1; i &= 10; i++) {
y += 20.0f;
string currentData = PlayerPrefs.GetString(scriptSceneManager.PREF_PLAYER_DATA + i);
int score = 0;
string firstName = “”;
string lastName = “”;
if (currentData.Length & 0) {
score = int.Parse(currentData.Substring(currentData.LastIndexOf(“,”) + 1));
int index = currentData.IndexOf(“,”);
firstName = currentData.Substring(0, index);
int index2 =currentData.IndexOf(“,”, index + 1);
lastName = currentData.Substring(index + 1, index2 – index – 1);
GUI.Label(new Rect(60.0f, y, 290.0f, y + 20.0f), string.Format(“{0,2}. {1,10} : {2}”, i, score, firstName + ” ” + lastName)); }
KeyShotHighScores
The other screen that shows player data is scriptScreenShowData, which is reached by using the cheat code that we’ll cover later. The code there is fairly obvious so I won’t cover it here.
How to implement a dialog with text fields to collect user data
Now that high scores have been covered, how did the data get there? The answer is that Unity has a rich set of user interface controls built in. I only used a few, with no validations, because this was a quick ‘n dirty game for a conference. When I code a game
for publication it will have full validation, and I might do a Part 3 to cover that functionality if anyone is interested.
MonoBehavior is a Unity class that is the base class for every Unity script. It provides a wealth of functionality and is easy to extend. In JavaScript, the C# class generated automatically extends from MonoBehavior – but when coding in C#, the programmer must
explicitly extend from it.
The OnGUI() Unity method is called on every frame. It is easy to prove this by adding a print statement to the method and then running the scene. This is why the firstName, lastName, phone, and email fields are defined at the class level instead of inside the
method, because we want them to update instead of being re-initialized with each frame.
public class scriptScreenGetPlayerInfo : MonoBehaviour {
public float buttonWidth = 90.0f;
public float buttonHeight = 40.0f;
string firstName = “”;
string lastName = “”;
string phone = “”;
string email = “”;
As discussed earlier, when Start() is called the temporary pref keys are removed.Start() is called by Unity once each time a screen is loaded.
Now, to collect user data the GUI.TextField() API is used. A Rect is defined to give the field dimensions on the screen, the data to display is next, and the maximum number of characters to accept is the last parameter. The data entered by the user is returned.
Here is one of the field definitions, along with a label to display to the left of it:
float y = 30.0f;
GUI.Label(new Rect(10.0f, y, 80.0f, 40.0f), “First Name”); firstName =
GUI.TextField(new Rect(90.0f, y, 200.0f, 30.0f), firstName, 40);
With the data fields displayed, the only thing left is to harvest it. To do this the user clicks on the “Save Info” button. When the button is clicked, GUI.Button() returns true. At that point the fields are saved in prefs and the next screen is loaded.
if (GUI.Button(new Rect(90.0f, y, buttonWidth, buttonHeight), “Save Info”)) {
// here is where you would validate data if it is required PlayerPrefs.SetString(scriptSceneManager.PREF_PLAYER_FIRST_NAME, firstName); PlayerPrefs.SetString(scriptSceneManager.PREF_PLAYER_LAST_NAME, lastName); PlayerPrefs.SetString(scriptSceneManager.PREF_PLAYER_PHONE,
phone); PlayerPrefs.SetString(scriptSceneManager.PREF_PLAYER_EMAIL, email); Application.LoadLevel(“sceneScreenLoad”);
When the game ends, the fields will be waiting in the temporary pref fields.
How to implement cheat codes in Unity
This was tricky for me because the documentation for the API was very light. I wanted a way to turn on the admin functions that the user would be unlikely to figure out during the short time they were playing the game. Two admin requirements were present for
The high scores needed to be reset just before the game was made available to players so the game could be tested before “real” play began.
The data that had been entered by all users needed to be able to be displayed after the conference was over so it could be harvested. Another way to do this would be to implement a remote call to send the data to a server, but I didn’t have time to set that
up. Since the data is stored separately from the game, I can always add that after the conference is over if it is necessary.
The key to implementing cheat codes is the field inputString in the Unity UI classInput. This field holds the key (if any) that was pressed on the current frame, even if there are no input fields on the screen. The documentation for this API is unclear about
that and makes it seem like any text that the user types will be held in the field, but this is not the case. The field resets for each frame. So, if a cheat code longer than 1 character is needed (most are…) a little more work needs to be done to make that
available for use.
Each time Update() is called, the value in inputString is examined. If a value is present, it is concatenated to the hidden field, which is a class variable so it exists between calls to Update(). Now hidden can be checked to see if the string “key” has been
typed. The Contains() method is used so keys can be typed before the cheat code and it will still work. If more than 10 characters have been typed without “key” being present, the hidden field is reset so it doesn’t become too long. Note that if k or e is
the 11 character this can prevent the cheat code from working the first time. There is a low chance of that happening, but it certainly can happen. By checking for other strings, any number of cheat codes can be checked for in this manner.
If “key” is present, the numberOfButtons field is increased to 6, indicating that the admin screen is now active.
public class scriptScreenMainMenu : MonoBehaviour {
string hidden = “”; int numberOfButtons = 4;
// Update is called once per frame
void Update ()
{ string input = Input.inputS
if (input.Length & 0) {
hidden += }
if (hidden.Contains(“key”))
{ numberOfButtons = 6;
} else if (hidden.Length & 10) {
hidden = “”;
If the numberOfButtons is 6, then the “Show Data” and “Clear Data” buttons are shown and usable.
if (numberOfButtons == 6) {
y += buttonHeight + 10.0f;
if (GUI.Button(Rect(10.0f, y, buttonWidth, buttonHeight), “Show Data”)) { Application.LoadLevel(“sceneScreenShowData”);
y += buttonHeight + 10.0f;
if (GUI.Button(Rect(10.0f, y, buttonWidth, buttonHeight), “Clear Data”)) { PlayerPrefs.DeleteAll();
Here’s the “Show Data” screen, with one score. Basic stuff, but fills the requirement.
KeyShotAllData
So, that wraps it up for Part 2! Make sure to check the code out on GitHub. I truly appreciate your time and interest, and I hope it helps you develop using Unity!(source:)
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:6745次
排名:千里之外
(1)(2)(9)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'}

我要回帖

更多关于 r中laply 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信