With this code I get always current score while I want to save high score I try everything to solve it but find nothing.
I want to save hgscr which is highscore , when I call with loadPlayer() I want to compare with topScore which is current score. After all that I call current score and highscore data to my score page.
Player page
if (isStarted == true)
{
if (rb2d.velocity.y > 0 && transform.position.y > topScore)
{
topScore = transform.position.y; // Current Score
}
scoreText.text = "Score: " + Mathf.Round(topScore).ToString();
}
PlayerData data = SaveSystem.LoadPlayer();
if (topScore > data.hgscrp) // current score > where I get highscore data from save page
{
hgscr = topScore; // save highs score for display on score page and compare current score after game restart
scsc = Mathf.Round(topScore).ToString(); // save current score for display on score page
SaveSystem.SavePlayer(this);
}
else
{
scsc = Mathf.Round(topScore).ToString();
SaveSystem.SavePlayer(this);
}
}
Save Page
public string cscore;
public float hgscrp;
public PlayerData (Controller player)
{
cscore = player.scsc;
hgscrp = player.hgscr;
}
Instead of using save/load, try this:
unity has a PlayerPrefs class which allows you to save variables which stay the same through restarting the game or switching scenes so if you used :
PlayerPrefs.SetFloat("VARIABLE NAME", number);
If you want to save a highs core this is perfect and to access the saved variable use:
PlayerPrefs.GetFloat("VARIABLE NAME");
I hope this works, it did for me :)
Related
I made a simple multiplayer quiz game. At the end of the quiz I want to display the scores of both players. Is it possible to get PlayerPrefs value from another player?
I use Photon PUN.
Well yes sure it is!
You could send a simple request RPC like e.g.
// Pass in the actor number of the player you want to get the score from
public void GetScore(int playerId)
{
// Get the Player by ActorNumber
var targetPlayer = Player.Get(playerId);
// Get your own ID so the receiver of the request knows who to answer to
var ownId = PhotonNetwork.LocalPlayer.ActorNumber;
// Call the GetScoreRpc on the target player
// passing in your own ID so the target player knows who to answer to
photonView.RPC(nameof(GetScoreRpc), targetPlayer, ownId);
}
[PunRpc]
private void GetScoreRpc(int requesterId)
{
// Get the requester player via the ActorNumber
var requester = Player.Get(requesterId);
// Fetch your score from the player prefab
// -1 indicates that there was an error e.g. no score exists so far
// up to you how you deal with that case
var ownScore = PlayerPrefs.GetInt("Score", -1);
// Get your own ID so the receiver knows who answered him
var ownId = PhotonNetwork.LocalPlayer.ActorNumber;
// Call the OnReceivedPlayerScore on the player who originally sent the request
photonView.RPC(nameof(OnReceivedPlayerScore), ownId, ownScore);
}
[PunRpc]
private void OnReceivedPlayerScore(int playerId, int score)
{
// Get the answering player by ActorNumber
var player = Player.Get(playerId);
// Do whatever you want with the information you received e.g.
if(score < 0)
{
Debug.LogError($"Could not get score from player \"{player.NickName}\"!");
}
else
{
Debug.Log($"Player \"{player.NickName}\" has a score of {score}!");
}
}
While recording user voice, i want to know when he/she stopped talking to end the recording and send the audio file to google speech recognition API.
I found this thread here and tried to use it's solution but i am always getting the same value from the average of spectrum data which is 5.004574E-08:
Unity - Microphone check if silent
This is the code i am using for getting the GetSpectrumData value:
public void StartRecordingSpeech()
{
//If there is a microphone
if (micConnected)
{
if (!Microphone.IsRecording(null))
{
goAudioSource.clip = Microphone.Start(null, true, 10, 44100); //Currently set for a 10 second clip max
goAudioSource.Play();
StartCoroutine(StartRecordingSpeechCo());
}
}
else
{
Debug.LogError("No microphone is available");
}
}
IEnumerator StartRecordingSpeechCo()
{
while (Microphone.IsRecording(null))
{
float[] clipSampleData = new float[128];
goAudioSource.GetSpectrumData(clipSampleData, 0, FFTWindow.Rectangular);
Debug.Log(clipSampleData.Average());
yield return null;
}
}
PS: I am able to record the users voice, save it and get the right response from the voice recognition api.
The following method is what worked for me. it detect the volume of the microphone, turn it into decibels. It does not need to play the recorded audio or anything. (credit goes to this old thread in the unity answers: https://forum.unity.com/threads/check-current-microphone-input-volume.133501/).
public float LevelMax()
{
float levelMax = 0;
float[] waveData = new float[_sampleWindow];
int micPosition = Microphone.GetPosition(null) - (_sampleWindow + 1); // null means the first microphone
if (micPosition < 0) return 0;
goAudioSource.clip.GetData(waveData, micPosition);
// Getting a peak on the last 128 samples
for (int i = 0; i < _sampleWindow; i++)
{
float wavePeak = waveData[i] * waveData[i];
if (levelMax < wavePeak)
{
levelMax = wavePeak;
}
}
float db = 20 * Mathf.Log10(Mathf.Abs(levelMax));
return db;
}
In my case, if the value is bigger then -40 then the user is talking!if its 0 or bigger then there is a loud noise, other then that, its silence!
If you are interested in a volume then GetSpectrumData is actually not really what you want. This is used for frequency analysis and returns - as the name says - a frequency spectrum so how laud is which frequency in a given frequency range.
What you rather want to use is GetOutputData which afaik returns an array with amplitudes from -1 to 1. So you have to square all values, get the average and take the square root of this result (source)
float[] clipSampleData = new float[128];
goAudioSource.GetOutputData(clipSampleData, 0);
Debug.Log(Mathf.Sqrt(clipSampleData.Select(f => f*f).Average()));
I'm new to unity and i'm trying to load scenes based on items collected.
Problem is that the counter is not counting my acquired items.
I'm using OnTriggerEnter2D() to trigger the event; Below is the snippet:
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Player"))
{
collectionNumber += 1;
Destroy(gameObject);
if (collectionNumber == 1)
{
collision.gameObject.transform.Find("Acquired_Items").GetChild(0).gameObject.SetActive(true);
qiCollector.gameObject.transform.GetChild(0).gameObject.SetActive(true);
}
else if (collectionNumber == 2)
{
collision.gameObject.transform.Find("Acquired_Items").GetChild(1).gameObject.SetActive(true);
qiCollector.gameObject.transform.GetChild(1).gameObject.SetActive(true);
}
else if (collectionNumber == 3)
{
collision.gameObject.transform.Find("Acquired_Items").GetChild(2).gameObject.SetActive(true);
qiCollector.gameObject.transform.GetChild(2).gameObject.SetActive(true);
}
else
{
Debug.LogWarning("All Items Collected !!");
}
cN.text = "Collection Number " + collectionNumber.ToString();
}
}
Whenever a new scene is loaded this script is loaded because it is on my quest item. And for every scene there is a quest item. So what I want to do is basically keep track of my collectionNumber, but it resets to 0.
Any help is much appreciated :)
First method:
Don't allow your object to be destroyed on scene load
https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html
public static void DontDestroyOnLoad(Object target);
Above code will prevent destroying your GameObject and its components from getting destroyed when loading a new scene, thus your script values
Second Method:
Write out your only value into a player pref
https://docs.unity3d.com/ScriptReference/PlayerPrefs.html
// How to save the value
PlayerPrefs.SetInt("CollectionNumber", collectionNumber);
// How to get that value
collectionNumber = PlayerPrefs.GetInt("CollectionNumber", 0);
Third method:
Implement a saving mechanism:
In your case i would not suggest this
I've created a fairly basic 2d scrolling game in Unity, and one of the game modes is survival. When you die, this screen will load and allow you to input your high score, which will be saved into a high scores table once the button is pressed.
However, while I can replace the score it is higher than, I cannot for the life of me think of the logic that would instead put the score that was replaced into the position below it, then that score would drop by one, then the next score etc.
The stage I'm at is below, with the code that simply replaces all of the high scores lower than the current store deleted, because it isn't what needs to be done. I currently have five generic scores saved to the playerprefsX int array so i know all of the below code is working, its just the dropping all the scores down one and deleting the final score that is proving problematic for me
public class high_score_input : Game_Over {
private string name = "highscores";
private int score;
public int[] highscores = new int[5];
// Use this for initialization
void Start () {
GameObject levelcontroller = GameObject.Find ("levelcontroller");
survival_mode survival = levelcontroller.GetComponent<survival_mode> ();
score = survival.setScore();
highscores = PlayerPrefsX.GetIntArray(name);}
void OnGUI()
{
base.OnGUI ();
if (GUI.Button (new Rect (Screen.width/10, 250, 120, 30), "Save High Score"))
{
for(int i = 0;i<highscores.Length;i++)
{
if(score>highscores[i])
{
}
}
PlayerPrefsX.SetIntArray(name, highscores);
}
}
Given that it's a small array and this isn't performance-critical code, I'd go for something that's simple and avoids errors:
Make sure that your score array is sorted.
Does the new score beat the score in the last slot? If so, replace it.
Make sure that your score array is sorted.
Given helper functions such as Array.Sort, this should be pretty quick.
this will be my first question so go on easy on me please ;)
I'm building my first game in Unity using my limited knowledge, tutorials and troubleshooting on google but i can't seem to fix this issue
i have a script that counts score(with a GUIText) and another one to pause the game(using timescale) and you probably guessed it already but when i pause the game it doesn't pause the score.
Script for Pausing:
var isPaused : boolean = false;
function Update()
{
if(Input.GetKeyDown("p"))
{
Pause();
}
}
function Pause()
{
if (isPaused == true)
{
Time.timeScale = 1;
isPaused = false;
}
else
{
Time.timeScale = 0;
isPaused = true;
}
}
Script for Score:
var Counter : int = 100000;
var Substractor : int = 0;
var Score : int = Counter - Substractor;
function Update (
) {
Score--;
guiText.text = "Score: "+Score;
}
the score script is attached to a gameobject with a gui text and the script for pausing the game is attached to the player
another issue is that when i'm moving(using the arrow keys) then press pause and then unpause the player moves faster and unpredictable for a splitsecond but this is only when i press pause while pressing the arrow buttons when i only press pause there is no issue, this is a small bugg that i'l try to fix myself, just thought i'd add it here for those that have an easy answer to this issue aswell
I only know this problem from other game frameworks and I've got no experiance with unity. But it should work the same way for unity as it does in other frameworks. You have two options:
Update is called after every rendering frame! So your timescale doesn'T influence how often update is called. Instead you have to find some dt or deltaT (don't know how it is called in unity and how to get it, but I mean the time, since unities the last call to update, please tell me in the comments, so I can edit this answer).
Then don't calculate your score like:
Score--;
but use something like:
Score -= 1 * dt
or
Score -= 1 * dt * Time.timeScale
(depending how exactly unity works)
alternatively you can sourround your update-block with some if-statement:
in Score:
function Update (
) {
if (! isPaused()) { // not sure how this function / property is called in unity
Score--;
guiText.text = "Score: "+Score;
}
}