[Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(四)----使用PlayerPrefs存储数据到本地

来源:互联网 发布:mysql 临时表空间不足 编辑:程序博客网 时间:2024/05/21 07:57

关于PlayerPrefs的使用与说明请参照这篇文章:

[Unity3D]手机3D游戏开发:场景切换与数据存储(PlayerPrefs 类的介绍与使用)


为了进一步完善上次做的Demo,首先制作一个首页用来跳转到目标页。

在首页的GameStateObj中添加SetPlayerPrefs脚本:

function Update () {}function Start() {PlayerPrefs.SetString("Player Name", "Bob");//存入字符串}
再添加一个LoadLevelButton脚本创建跳转按钮和相关操作:

var levelToLoad:String;var graphic = TextureGUI(); //(28,23);var startPoint = Location();var GUIColor:Color = Color.white;var noGuiStyle : GUIStyle;function Start() {graphic.setAnchor();}function Update() {if (graphic.texture){startPoint.updateLocation();}}function OnGUI() {GUI.color = GUIColor;if (GUI.Button(Rect(graphic.offset.x+startPoint.offset.x,graphic.offset.y+startPoint.offset.y,            graphic.texture.width,graphic.texture.height),graphic.texture,noGuiStyle)) {PlayerPrefs.Save();Application.LoadLevel(levelToLoad);}}

运行效果如下:


在上次的HighScoreDisplay脚本中作如下修改即可(Start方法中读取数据):

var boxStartLocation:Vector2; // offset of main GUI elementvar center = Location(); // handy class for calculating the center of the screenfunction Start() {Debug.Log(PlayerPrefs.GetString("Player Name"));}function Update() {center.updateLocation(); // every frame, check if the screen has changed and re-calculate the screen center value.}// draw a text string to the screenvar textGUIStyle : GUIStyle; // to control the display of textvar roundsGUIStyle : GUIStyle; // to control the display of text for killsvar score = new Highscore[10]; // array of names for the highscorescore[0].name = "www.DigitalTutors.com"; // Highscore #1score[1].name = "Papa";score[2].name = "Kyle";score[3].name = "Tanya";score[4].name = "Delano";score[5].name = "Justin";score[6].name = "Eddie";score[7].name = "Josh";score[8].name = "Chris";score[9].name = "Steve";score[0].rounds = 999;score[0].kills = 999;var heightOffset: float = 10; // how much space to place between each highscore levelvar roundsOffset:float; // horizontal offset for rounds columnvar killsOffset:float; // horizontal offset for kills columnvar numberHighscores:int = 8; // controls how many loops to run to displayfunction OnGUI() {for( var i:int = 0 ; i < numberHighscores ; i++ ) { // for the number of highscores to displayGUI.Box(Rect(center.offset.x + boxStartLocation.x, // draw a box with the namecenter.offset.y + boxStartLocation.y + i * heightOffset,222,34),score[i].name,textGUIStyle); // using textGUIStyleGUI.Box(Rect(center.offset.x + boxStartLocation.x + roundsOffset, // draw a box with the roundscenter.offset.y + boxStartLocation.y + i * heightOffset,222,34),score[i].rounds.ToString(),roundsGUIStyle); // using roundsGUIStyleGUI.Box(Rect(center.offset.x + boxStartLocation.x + killsOffset, // draw a box with the killscenter.offset.y + boxStartLocation.y + i * heightOffset,222,34),score[i].kills.ToString(),roundsGUIStyle); // using roundsGUIStyle}}
当然这样只能将数据读取并显示在Console面板上:

在主页的场景创建一个脚本GameState_simple.js来处理相关数据:

import PreviewLabs.PlayerPrefs;var timer:float = 10;private var origTimer:float;var maxTimer:float;var roundsWon:int = 1;var enemyKills:int = 0;var totalEnemyKills:int = 0;var transitionDelay:float = 0;function OnGUI() {if (GUI.Button(Rect(10,70,50,30),"Click")) {// Highscore naming scheme// key starts : "highscore"// past that, whatever the setting needs to bePreviewLabs.PlayerPrefs.SetInt("highscoreCurrentRounds", roundsWon);PreviewLabs.PlayerPrefs.SetInt("highscoreCurrentKills", totalEnemyKills);PreviewLabs.PlayerPrefs.Flush();}}function Awake() {origTimer = timer;}function Start() {maxTimer = timer;// if there is a GameID, we want to get it and add onevar gameID:int;if (PreviewLabs.PlayerPrefs.HasKey("highscoreCurrentGameID")) {gameID = PreviewLabs.PlayerPrefs.GetInt("highscoreCurrentGameID");PreviewLabs.PlayerPrefs.SetInt("highscoreCurrentGameID",++gameID);} else { PreviewLabs.PlayerPrefs.SetInt("highscoreCurrentGameID",1);}}function EnemyKilled () {enemyKills += 1;enemyKills = Mathf.Clamp(enemyKills,0,999999);totalEnemyKills += 1;totalEnemyKills = Mathf.Clamp(totalEnemyKills,0,999999);}function WonRound() {roundsWon++;}var isGameOver:boolean = false;function GameOver() {if (!isGameOver) {NotificationCenter.DefaultCenter().PostNotification(this, "GameOver");isGameOver = true;}// wait for death to play, something else?Application.LoadLevel("highscore");}

这样在初始化的时候点击按钮便会将数据写入本地。

再在后面的脚本中将原脚本的Start方法:

function Start() {Debug.Log(PlayerPrefs.GetString("Player Name"));}
做如下修改即可:

function Start() {Debug.Log("The value of key 'highscoreCurrentRounds' is: " + PlayerPrefs.GetInt("highscoreCurrentRounds"));Debug.Log("The value of key 'highscoreCurrentKills' is: " + PlayerPrefs.GetInt("highscoreCurrentKills"));}

此时再运行项目就会发现,欢迎界面对数据进行修改后点击按钮即可存之本地,并且再次运行依旧有效:

接下来就是实现PlayerPrefs和本地数据的同步。

我们添加一个SyncPlayerPrefs函数用来实现同步数据:

function SyncPlayerPrefs() {// our assumption is that the data in player prefs should over-ride the local data// need this to see if we have player prefs keys and if we do, copy into our local// if the key does not exist, we need to populate it with the local datafor( var i:int = 0 ; i < numberHighscores ; i++ ) { // for the number of highscoresif (PlayerPrefs.HasKey("highscore" + i + "name" )) {//copy Player preferences value to local highscore class arrayscore[i].name = PlayerPrefs.GetString("highscore" + i + "name");} else {//set that player prefs to local dataPlayerPrefs.SetString("highscore" + i + "name" , score[i].name);}}}

然后再在Update方法中刷新数据并调用Start函数来打印数据:

function Start() {    Debug.Log("The value of key 'highscore4name' is: " + PlayerPrefs.GetString("highscore4name"));    Debug.Log("The value of key 'highscore8name' is: " + PlayerPrefs.GetString("highscore8name"));}function Update() {center.updateLocation(); // every frame, check if the screen has changed and re-calculate the screen center value.SyncPlayerPrefs();Start();}

此时运行项目便会发现本来是脚本中的数据已经可以写入到本地了

可以使用相同的方法写入Rounds好Kills等数据:

function SyncPlayerPrefs() {// our assumption is that the data in player prefs should over-ride the local data// need this to see if we have player prefs keys and if we do, copy into our local// if the key does not exist, we need to populate it with the local datafor( var i:int = 0 ; i < numberHighscores ; i++ ) { // for the number of highscoresif (PlayerPrefs.HasKey("highscore" + i + "name" )) {//copy Player preferences value to local highscore class arrayscore[i].name = PlayerPrefs.GetString("highscore" + i + "name");} else {//set that player prefs to local dataPlayerPrefs.SetString("highscore" + i + "name" , score[i].name);}if (PlayerPrefs.HasKey("highscore" + i + "rounds" )) {//copy Player preferences value to local highscore class arrayscore[i].rounds = PlayerPrefs.GetInt("highscore" + i + "rounds");} else {//set that player prefs to local dataPlayerPrefs.SetInt("highscore" + i + "rounds" , score[i].rounds);}if (PlayerPrefs.HasKey("highscore" + i + "kills" )) {//copy Player preferences value to local highscore class arrayscore[i].kills = PlayerPrefs.GetInt("highscore" + i + "kills");} else {//set that player prefs to local dataPlayerPrefs.SetInt("highscore" + i + "kills" , score[i].kills);}}}

但是这样的简单存储一般来说是难以满足需要的。所以我们需要添加一个函数AddNewHighScore:

function AddNewHighscore() {var curRounds = PlayerPrefs.GetInt("highscoreCurrentRounds");var curKills = PlayerPrefs.GetInt("highscoreCurrentKills");var newHighscorePosition: int;// check if the current score are good / above the highscores in the playersPrefs// are we assuming the local and playerprefs data is the same? - Yesfor( var i:int = 0 ; i < numberHighscores ; i++ ) { // for the number of highscoresif (curRounds > score[i].rounds) {// new score is higher!newHighscorePosition = i;break;} else if (curRounds == score[i].rounds && curKills > score[i].kills) {// new score is equal in rounds and kills are greaternewHighscorePosition = i;break;} // if the rounds are equal and kills are less} // if the rounds are lessDebug.Log (newHighscorePosition);//if it is calculate what the # of the new houigschore would be// add it into our data and save it.}
脚本的目的就是将当前的最高分与排行榜进行比较并且如果高于榜中的任意一个元素立即跳出并添加进去。

当然现在还只能在控制台输出数据。比如原始数据是1,12:

跳转到前端后修改数值:

在跳转回排行榜就会发现数据发生了改变

完整的脚本HighScoreDisplay.js代码如下:

// this is called after a player dies OR from the main menu// Display the highscore// track the follow: Player Name, highscore number of the rounds survived and kills //Upon entering the High Score menu, test if we have a high score and if we do, ask the// player to enter a name and add it to the High Score save data.var boxStartLocation:Vector2; // offset of main GUI elementvar center = Location(); // handy class for calculating the center of the screenfunction Start() {Debug.Log("The value of key 'highscoreCurrentRounds' is: " + PlayerPrefs.GetInt("highscoreCurrentRounds"));Debug.Log("The value of key 'highscoreCurrentKills' is: " + PlayerPrefs.GetInt("highscoreCurrentKills"));AddNewHighscore();}function Update() {center.updateLocation(); // every frame, check if the screen has changed and re-calculate the screen center value.//SyncPlayerPrefs();//Start();}// draw a text string to the screenvar textGUIStyle : GUIStyle; // to control the display of textvar roundsGUIStyle : GUIStyle; // to control the display of text for killsvar score = new Highscore[10]; // array of names for the highscorescore[0].name = "www.DigitalTutors.com"; // Highscore #1score[1].name = "Papa";score[2].name = "Kyle";score[3].name = "Tanya";score[4].name = "Delano";score[5].name = "Justin";score[6].name = "Eddie";score[7].name = "Josh";score[8].name = "Chris";score[9].name = "Steve";score[0].rounds = 99;score[0].kills = 999;score[1].rounds = 1;score[1].kills = 9;var heightOffset: float = 10; // how much space to place between each highscore levelvar roundsOffset:float; // horizontal offset for rounds columnvar killsOffset:float; // horizontal offset for kills columnvar numberHighscores:int = 8; // controls how many loops to run to displayfunction OnGUI() {for( var i:int = 0 ; i < numberHighscores ; i++ ) { // for the number of highscores to displayGUI.Box(Rect(center.offset.x + boxStartLocation.x, // draw a box with the namecenter.offset.y + boxStartLocation.y + i * heightOffset,222,34),score[i].name,textGUIStyle); // using textGUIStyleGUI.Box(Rect(center.offset.x + boxStartLocation.x + roundsOffset, // draw a box with the roundscenter.offset.y + boxStartLocation.y + i * heightOffset,222,34),score[i].rounds.ToString(),roundsGUIStyle); // using roundsGUIStyleGUI.Box(Rect(center.offset.x + boxStartLocation.x + killsOffset, // draw a box with the killscenter.offset.y + boxStartLocation.y + i * heightOffset,222,34),score[i].kills.ToString(),roundsGUIStyle); // using roundsGUIStyle}}// Highscore naming scheme// key starts : "highscore"// past that, whatever the setting needs to be// a specific high score would look like this:// highscore4namefunction AddNewHighscore() {var curRounds = PlayerPrefs.GetInt("highscoreCurrentRounds");var curKills = PlayerPrefs.GetInt("highscoreCurrentKills");var newHighscorePosition: int;// check if the current score are good / above the highscores in the playersPrefs// are we assuming the local and playerprefs data is the same? - Yesfor( var i:int = 0 ; i < numberHighscores ; i++ ) { // for the number of highscoresif (curRounds > score[i].rounds) {// new score is higher!newHighscorePosition = i;break;} else if (curRounds == score[i].rounds && curKills > score[i].kills) {// new score is equal in rounds and kills are greaternewHighscorePosition = i;break;} // if the rounds are equal and kills are less} // if the rounds are lessDebug.Log (newHighscorePosition);//if it is calculate what the # of the new houigschore would be// add it into our data and save it.}function SyncPlayerPrefs() {// our assumption is that the data in player prefs should over-ride the local data// need this to see if we have player prefs keys and if we do, copy into our local// if the key does not exist, we need to populate it with the local datafor( var i:int = 0 ; i < numberHighscores ; i++ ) { // for the number of highscoresif (PlayerPrefs.HasKey("highscore" + i + "name" )) {//copy Player preferences value to local highscore class arrayscore[i].name = PlayerPrefs.GetString("highscore" + i + "name");} else {//set that player prefs to local dataPlayerPrefs.SetString("highscore" + i + "name" , score[i].name);}if (PlayerPrefs.HasKey("highscore" + i + "rounds" )) {//copy Player preferences value to local highscore class arrayscore[i].rounds = PlayerPrefs.GetInt("highscore" + i + "rounds");} else {//set that player prefs to local dataPlayerPrefs.SetInt("highscore" + i + "rounds" , score[i].rounds);}if (PlayerPrefs.HasKey("highscore" + i + "kills" )) {//copy Player preferences value to local highscore class arrayscore[i].kills = PlayerPrefs.GetInt("highscore" + i + "kills");} else {//set that player prefs to local dataPlayerPrefs.SetInt("highscore" + i + "kills" , score[i].kills);}}}


原创粉丝点击