LeaderBoard in C# UNITY3D? - c#

I Needed To Develop LeaderBoard For Storing Details(means Scores) of Players in Games.Just Displaying players Scores on LeaderBoard in UNITY3D.so plz help me i dont have any idea. in below code Social Platforms NameSpace is there but i dont know how start and how to implement LeaderBoard in unity3d.
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.SocialPlatforms;
public class LBoard : MonoBehaviour
{
ILeaderboard leaderBoard;
// Use this for initialization
void Start ()
{
leaderBoard = Social.CreateLeaderboard();
}
// Update is called once per frame
void Update ()
{
}
}

You need to create an IComparable class and add details like name and score , compare by score.
public class PlayerScore : IComparable<PlayerScore>
public string name;
public int score;
public int CompareTo(PlayerScore other)
{
return this.score.CompareTo(other.score);
}
You also need a list
public static List<PlayerScore> scoreIndex = new List<PlayerScore>(5);
You need some way of getting input from user to add name.
When adding score, create object of iComparer class and set name, score etc.
PlayerScore a = new PlayerScore();//create instance
a.name = PlayerStats.playerName;//set name
a.score = PlayerStats.score;//and score
scoreIndex.Add(a);
Then add new object to List and sort list, List.Sort();. if you want reversed then add reverse().
scoreIndex.Sort ();
scoreIndex.Reverse ();
Save list to player prefs e.g.
PlayerPrefs.SetString("name0" , scoreIndex[0].name);
PlayerPrefs.SetInt("score0" , scoreIndex[0].score);
PlayerPrefs.SetString("name1" , scoreIndex[1].name);
PlayerPrefs.SetInt("score1" , scoreIndex[1].score);
To display names and scores, create 3dText objects for names/scores and place a script like
public class PlayerNameHS : MonoBehaviour
public int pos;
void Start ()
{
renderer.material.color = Color.black;
TextMesh t = (TextMesh)gameObject.GetComponent(typeof(TextMesh));
t.text = PlayerPrefs.GetString("name" + pos);
}
void Update ()
{
}
}
Set Pos for each object.Do the same for scores with score script.
At the start of the game add player prefs into list or you will get an error when trying to retrieve names/scores. needs to be same amount as list size.
PlayerScore a = new PlayerScore();
a.name = PlayerPrefs.GetString("name0");
a.score = PlayerPrefs.GetInt("score0");
yourScript.scoreIndex.Add(a);
PlayerScore b = new PlayerScore();
b.name = PlayerPrefs.GetString("name1");
b.score = PlayerPrefs.GetInt("score1");
yourScript.scoreIndex.Add(b);
Don't know if I'm explaining this well, but you basically need to add playerprefs to list, add comparable scores to list, sort the list, save the list, display the saved list. I'm new to this so take it easy with criticism ;)

If you mean leaderboard like a local high scores table, you would need two functions: AddScore and a function that gets the high scores. (note this example is in C#)
function AddScore(string name, int score){
int newScore;
string newName;
int oldScore;
string oldName;
newScore = score;
newName = name;
for(int i=0;i<10;i++){
if(PlayerPrefs.HasKey(i+"HScore")){
if(PlayerPrefs.GetInt(i+"HScore")<newScore){
// new score is higher than the stored score
oldScore = PlayerPrefs.GetInt(i+"HScore");
oldName = PlayerPrefs.GetString(i+"HScoreName");
PlayerPrefs.SetInt(i+"HScore",newScore);
PlayerPrefs.SetString(i+"HScoreName",newName);
newScore = oldScore;
newName = oldName;
}
}else{
PlayerPrefs.SetInt(i+"HScore",newScore);
PlayerPrefs.SetString(i+"HScoreName",newName);
newScore = 0;
newName = "";
}
}
}
And then to get the highscores:
void GetHighScores()
{
for(int i = 0; i < 10; i++)
{
Debug.Log(PlayerPrefs.GetString(i + "HScoreName") + " has a score of: " + PlayerPrefs.GetInt(i + "HScore"));
}
}
If you want to create a networked/online leaderboard, you need to use something like GameFly (take a look at that example).

Related

Printing list with additional text

Edit:
So currently I am creating a struct:
struct Coordinate
{
public string Name;
public int HP;
public int EXP;
public Coordinate(string name, int hp, int exp)
{
this.Name = name;
this.HP = hp;
this.EXP = exp;
}
}
}
I have also created this list:
var myList = new List<Coordinate>();
And this is a code i have been working on:
{Console.Write("name:");
string name = Console.ReadLine();
Console.Write("hp:");
int hp = Convert.ToInt32(Console.ReadLine());
Console.Write("exp:");
int exp = Convert.ToInt32(Console.ReadLine());
Coordinate point = new Coordinate(name, hp, exp);
Console.WriteLine("Pokemon's name: "+point.Name);
Console.WriteLine(point.HP); //output: hp inputed
Console.WriteLine(point.EXP); //output: 20
myList.Add(point);
}
else if (menu == '6'){ //need help here, want to print list
}
How to I add the list so that when I input 6, I want to write this:
Pokemon's name = Charmander
Pokemon's HP = 20
Pokemon's EXP = 40
This is probably incorrect:
if (myDictionary.Count <= 0)
{
myDictionary.Add("Pokemon's Name", name);
myDictionary.Add("Pokemon's HP", hp.ToString());
myDictionary.Add("Pokemon's EXP", exp.ToString());
myDictionary.Add("Pokemon's Skill", name);
Console.WriteLine("Pokemon has been added!");
}
First of all, it will only run the code if the dictionary is empty, so trying to add another pokemon will not do anything.
Secondly, it adds the pokemons properties as separate values in the dictionary. So if you remove the Count <= 0 check it will fail since keys are constants and have already been added. Regular dictionaries can only have a single value for a specific key.
You probably want to do the following:
Introduce a Pokemon-class with name, hp, exp and skill properties.
Replace myDictionary with a regular list of pokemons.
Remove the Count <= 0 check
If you only want to allow a single pokemon with a specific name you can keep the dictionary and change it to myDictionary[myPokemonName] = myPokemonObject. This will add a new pokemon, or overwrite any existing pokemon with the same name.

Need my C# JSON.text file to have Default HighScores if it gets deleted or values are changed (UNITY)

How can I add default int and string name values to a JSON.txt though C#?
I would first create the default collection of HighScore with all of those fake players:
private List<Score> scores = null;
void Start()
{
this.scores = new List<Score>()
{
new Score("Adam", 10000), new Score("Eve",7500); // ...
};
Score[]scores = GetJsonFileWithScore(); // This is where you get the real players score
this.scores.AddRange(scores);
this.scores.OrderBy (s => s.score); // Order it by score
int index = 4;
this.scores.RemoveRange(index, list.Count - index); // keep only the best 5
}

how to get C# code to read XML file in a basic game

I am creating a basic text based rpg and am trying to use xml to save games. This is the code that calls the players data from an xml:
public class SuperAdventure() {
private Player _player;
private Monster _currentMonster;
private const string PLAYER_DATA_FILE_NAME = "PlayerData.xml";
public SuperAdventure()
{
InitializeComponent();
if (File.Exists(PLAYER_DATA_FILE_NAME))
{
_player = Player.CreatePlayerFromXmlString(File.ReadAllText(PLAYER_DATA_FILE_NAME));
}
else
{
_player = Player.CreateDefaultPlayer();
}
MoveTo(_player.CurrentLocation);
UpdatePlayerStats();
}
}
I also know for sure that the xml is being created correctly. When I close the game, I can manually find the xml. All the stats are saved but when the game is reopened the player is reset to the default stats and items. I'm not sure if the order of the function calling would matter or if the creation of the xml would affect the games use of the xml.
Here's the CreatePlayerFromXmlString() function:
public static Player CreatePlayerFromXmlString(string xmlPlayerData)
{
try
{
XmlDocument playerData = new XmlDocument();
playerData.LoadXml(xmlPlayerData);
int currentHitPoints = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/CurrentHItPoints").InnerText);
int maximumHitPoints = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/MaximumHitPoints").InnerText);
int gold = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/Gold").InnerText);
int experiencePoints = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/ExperiencePoints").InnerText);
Player player = new Player(currentHitPoints, maximumHitPoints, gold, experiencePoints);
int currentLocationID = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/CurrentLocation").InnerText);
player.CurrentLocation = World.LocationByID(currentLocationID);
foreach (XmlNode node in playerData.SelectNodes("/Player/InventoryItems/InventoryItem"))
{
int id = Convert.ToInt32(node.Attributes["ID"].Value);
int quantity = Convert.ToInt32(node.Attributes["Quantity"].Value);
for (int i = 0; i < quantity; i++)
{
player.AddItemToInventory(World.ItemByID(id));
}
}
foreach (XmlNode node in playerData.SelectNodes("/Player/PlayerQuests/PlayerQuest"))
{
int id = Convert.ToInt32(node.Attributes["ID"].Value);
bool isCompleted = Convert.ToBoolean(node.Attributes["IsCompleted"].Value);
PlayerQuest playerQuest = new PlayerQuest(World.QuestByID(id));
playerQuest.IsCompleted = isCompleted;
player.Quests.Add(playerQuest);
}
return player;
}
catch
{
//If there was an error with the XML data, return a default player object
return Player.CreateDefaultPlayer();
}
}
The problem is when the game went through the try block of code there was an error. This caused it to move to the catch block and create a default player instead. The string in the line of code searching for the currentHitPoints is misspelled-visual studio didn't see it as an error because it was a string passed into an XML function.
int currentHitPoints = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/CurrentHItPoints").InnerText);
The "/Player/Stats/CurrentHItPoints" should be "/Player/Stats/CurrentHitPoints"

C# Replace String.Split [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have a string with this format "10,2/20,5/50,3"
Those are wins of every player.
"roomPrize,wins/nextRoomPrize,wins" etc
I figured out how to read it but I want to change the amount of wins for some roomPrize. I've come this far.
winsRawData = getStatW.text; //That is the wins string formated as explained above
string[] winSplits = winsRawData.Split('/');
for(int i = 0; i < winSplits.Length; i++)
{
if(winSplits[i].Split(',')[0] == room.ToString()) //room is the roomPrize that i want to affect
{
//newWins is the new win count that I want to update with
//winSplits[i].Split(',')[1] == newWins; <-- I just need to do that
}
}
Thanks
If I understood your question well, you would like to do the following:
winSplits[i].Split(',')[1] = newWins;
In order to achieve this, you would need to split the value, then re-create it (e.g. Join) and put it back in the original array.
The following should do the trick:
winsRawData = getStatW.text; //That is the wins string formated as explained above
string[] winSplits = winsRawData.Split('/');
for (int i = 0; i < winSplits.Length; i++)
{
var dataArray = winSplits[i].Split(',');
if (dataArray[0] == room.ToString()) //room is the roomPrize that i want to affect
{
// sets the new value.
dataArray[0] = newWins;
}
// finalize by recreating the string and push it back to the original array
winSplits[i] = String.Join(",", dataArray);
}
Edit Using the following values:
var winsRawData = "10,2/20,5/50,3";
int room = 10;
int newWins = 100;
And by adding the var output = String.Join("/", winSplits); at the end of the above code, you will get a string output:
"100,2/20,5/50,3"
See the code below for a complete example:
string[] winSplits = winsRawData.Split('/');
for (int i = 0; i < winSplits.Length; i++)
{
var dataArray = winSplits[i].Split(',');
if (dataArray[0] == room.ToString()) //room is the roomPrize that i want to affect
{
// sets the new value.
dataArray[0] = newWins.ToString();
}
// finalize by recreating the string and push it back to the original array
winSplits[i] = String.Join(",", dataArray);
}
var output = String.Join("/", winSplits); // = "100,2/20,5/50,3"
you should first refactor to deserialize the data into some Player objects, change it's wins count and then serialize it back:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// Raw data
string rawData = "10,2/20,5/50,3";
// First split
string[] playersRaw = rawData.Split('/');
// Initialize a collection for the player objects
var players = new List<Player>();
// Iterates over the splitted players data
foreach (var playerRaw in playersRaw)
{
// Deserialize each player
var playerDeserialized = Player.Deserialize(playerRaw);
// Store the player data into the players collection
if (playerDeserialized != null)
players.Add(playerDeserialized);
}
// Seeks for player with room prize 10
foreach (var player in players)
{
if (player.RoomPrize == 10)
// Increments players data wins count
player.Wins += 1;
}
// Updates the raw data serializing all players back again
rawData = string.Join("/", Array.ConvertAll(players.ToArray(), (p) => p.Serialize()));
Console.WriteLine(rawData);
Console.ReadLine();
}
}
class Player
{
public int RoomPrize { get; set; }
public int Wins { get; set; }
public static Player Deserialize(string data, char separator = ',')
{
Player player = null;
string[] splittedData = new string[] { };
if (!string.IsNullOrEmpty(data) && (splittedData = data.Split(separator)).Length == 2)
{
int roomPrize = 0, wins = 0;
if (int.TryParse(splittedData[0], out roomPrize) && int.TryParse(splittedData[1], out wins))
{
player = new Player();
player.RoomPrize = roomPrize;
player.Wins = wins;
}
}
return player;
}
public string Serialize()
{
return string.Format("{0},{1}", this.RoomPrize, this.Wins);
}
}
}
It's much more code, but is easier to maintain.

C# - Making classes in a for loop

I have this class:
class player
{
public string name;
public int rating;
{
The number of these classes made is dependant on a user specified amount numberOfPlayers. So my first reaction was to create a for loop to do this. i.e:
for (int i = 0; i< numberOfPlayers; i++)
{
//create class here
}
However, I need to be able to access these classes individually when later using their individual data - almost like they've been put into an array. How would I go about making a number of classes of which can be accessed individually?
You use a List<T> variable where T is your class
List<Player> players = new List<Player>();
for (int i = 0; i< numberOfPlayers; i++)
{
Player p = new Player();
p.Name = GetName();
p.rating = GetRating();
players.Add(p);
}
Of course GetName and GetRating should be substituded by your code that retrieves these informations and add them to the single player.
Getting data out of a List<T> is in no way very different from reading from an array
if(players.Count > 0)
{
Player pAtIndex0 = players[0];
....
}
You can read more info at MSDN page on List class
List<Player> players = new List<Player>();
for (int i = 0; i< numberOfPlayers; i++)
{
Player p = new Player();
p.Name = "";
p.rating = "";
players.Add(p);
}
to access it individually you can use...
foreach(Player p in players )
{
}
You've got the right idea. Make a player class that can be re-used over and over, a loop in which to create these players and now we need to store them somewhere. This will probably divide opinion if you get more than one answer but I like dictionaries for this kind of thing as you can access values by unique keys.
// Your player class. I've added 'id' so we can identify them by this later.
class Player
{
public int id;
public string name;
public int rating;
}
// The dictionary. They work like this dictionary<key, value> where key is a unique identifier used to access the stored value.
// Useful since you wanted array type accessibility
// So in our case int represents the player ID, the value is the player themselves
Dictionary<int, Player> players = new Dictionary<int, Player>();
// Create your players
for (int i = 0; i < numberOfPlayers; i++)
{
Player p = new Player()
{
id = i + 1,
name = $"Player{i}",
rating = 5
};
// Add them to dictionary
players.Add(p.id, p);
}
// Now you can access them by the ID:
if (players.ContainsKey(1))
{
Console.WriteLine(players[1].name);
}
The dictionary key can be anything you like so long as it's unique. You could identify them by name if you like.

Categories