How do I write the code to deduct one hit point? - c#

Working on a Basketball Shooter on a unit. I am doing the part that is responsible for subtracting the cells of life. The part of the code that is responsible for adding points is triggered when you touch the "Bonus" component and adds points, but the next part of the code that is responsible for reducing health does not work. By design, this should happen after the ball does not hit the "Bonus" object and comes into contact with the "Terraine" object. How to write a code so that if there is no touch with the "Bonus" object and then there is a touch with the "Terraine" object, one life point is subtracted?
public GameObject hp3;
public GameObject hp2;
public GameObject hp1;
int score = 0;
int best = 0;
void Awake()
{
rb = GetComponent<Rigidbody>();
col = GetComponent<Collider>();
//instance = this;
}
private void Start()
{
best = PlayerPrefs.GetInt("best", 0);
scoreText.text = "Score: " + score.ToString();
bestScoreText.text = "Best: " + best.ToString();
}
public void Push(Vector2 force)
{
rb.AddForce(force, ForceMode.Impulse);
}
public void ActivateRb()
{
rb.isKinematic = false;
}
public void DesactivateRb()
{
rb.velocity = Vector3.zero;
//rb.angularVelocity = 0f;
rb.isKinematic = true;
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.name == "Terraine")
{
transform.position = new Vector3(Random.Range(-4f, 8f), Random.Range(2f, 7f), -0.2f);
DesactivateRb();
}
}
public void OnTriggerExit(Collider other)
{
if (other.gameObject.name == "Bonus")
{
score += 2;
scoreText.text = "Score: " + score.ToString();
if (best < score)
PlayerPrefs.SetInt("best", score);
}
if (other.gameObject.name != "Bonus")
{
health = health - 1;
}
}
void Update()
{
if (health == 3)
{
hp3.SetActive(true);
hp2.SetActive(false);
hp1.SetActive(false);
}
if (health == 2)
{
hp3.SetActive(false);
hp2.SetActive(true);
hp1.SetActive(false);
}
if (health == 1)
{
hp3.SetActive(false);
hp2.SetActive(false);
hp1.SetActive(true);
}
}

Don't know c#, but would something as simple as this work?
Hard to know without the logic.
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.name == "Terraine")
{
transform.position = new Vector3(Random.Range(-4f, 8f), Random.Range(2f, 7f), -0.2f);
DesactivateRb();
if (flag != 1)
{
health = health - 1;
}
else
{
flag = 0; //reset flag if 1
}
}
}
public void OnTriggerExit(Collider other)
{
if (other.gameObject.name == "Bonus")
{
score += 2;
flag = 1;
scoreText.text = "Score: " + score.ToString();
if (best < score)
PlayerPrefs.SetInt("best", score);
}
}

Related

Why is the highscore reset when the game starts again?

I'm trying to make a 2D game in Unity. I'm stuck on the high score part. When the game starts, the score and the high score go together, but when the game ends and I press play again, the high score is reset. what is the reason of this?
Thank you from now.
public Text scoreText;
public Text highscoreText;
private float score = 0;
private float highScore = 0;
public Transform cam;
public GameObject panel;
private bool moveLeft;
private bool moveRight;
private float horizontalMove;
void Update()
{
if (rb.velocity.y > 0 && transform.position.y > score)
{
score = transform.position.y;
}
scoreText.text = Mathf.Round(score).ToString();
if (cam.position.y > transform.position.y + 7f)
{
Time.timeScale = 0;
panel.SetActive(true);
}
if (score > highScore)
{
PlayerPrefs.SetFloat("highScore", highScore);
highscoreText.text = "HIGHSCORE: " + Mathf.Round(score).ToString();
PlayerPrefs.Save();
}
MovementPlayer();
}
public void PlayAgain()
{
PlayerPrefs.GetFloat("highScore");
highscoreText.text = "HIGHSCORE: " + Mathf.Round(highScore).ToString();
SceneManager.LoadScene(0);
}
private void Start()
{
rb = GetComponent<Rigidbody2D>();
moveLeft = false;
moveRight = false;
Time.timeScale = 1;
PlayerPrefs.GetFloat("highScore");
highscoreText.text = highScore.ToString();
}
isn't problem here? You are not update your player prefs with actual score but with old highscore?
if (score > highScore)
{
PlayerPrefs.SetFloat("highScore", highScore);
it should be
PlayerPrefs.SetFloat("highScore", score);

Unity C# Input.GetMouseDown(1) only happening once in update function

so i've been working on some code for a game in Unity and i am using the Input.GetMouseButtonDown(1) function. However, it only works the first time i press the left click in the game and no other times after that. The code for the player controller where it's used is below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour {
public float speed;
public Transform enemy;
public Transform shot;
public GameObject shotObj;
public Text scoreT;
public Text timeT;
public Text roundT;
public float health;
public float damageTaken;
public Vector3 lookPoint;
public float shotSpeed;
private Camera mainCamera;
private int round = 1;
private int tempRound = 0;
private float time = 300;
private bool win = false;
private bool allowShoot;
private EnemyController enemyScript;
private ShotController shotScript;
private bool tempImune = false;
private int targetTime;
private int score = 0;
private int defeatedEnemy = 0;
private GameObject enemyObj;
//coroutine
IEnumerator Pause(float timE)
{
allowShoot = false;
//time since the object was created
float start = Time.realtimeSinceStartup;
//sets the game to slow down to 0 movement
Time.timeScale = 0.0f;
//loops until start up time is less than start time + pause time
while (Time.realtimeSinceStartup < start + timE)
{
//returns null from the subroutine and restarts the subroutine at this point after null (0) time has passed
yield return null;
}
//sets the gamne to be running at normal speed
Time.timeScale = 1.0f;
allowShoot = true;
if (timE == 5.0f)
{
roundT.gameObject.SetActive(false);
}
}
void Start () {
//center mouse
Cursor.lockState = CursorLockMode.Locked;
Cursor.lockState = CursorLockMode.None;
//set camera to be the camera in the scene (should only ever be one camera in the scene)
mainCamera = FindObjectOfType<Camera>();
//set default text values
scoreT.text = "Score: 000000";
timeT.text = "Time Left: 600";
roundT.text = "Round: " + round;
//pause game before first round begins
StartCoroutine(Pause(5.0f));
}
void Update () {
//looka at mouse script
Ray cameraRay = mainCamera.ScreenPointToRay(Input.mousePosition);
Plane ground = new Plane(Vector3.up, Vector3.zero);
float rayLength;
if (ground.Raycast(cameraRay, out rayLength))
{
lookPoint = cameraRay.GetPoint(rayLength);
transform.LookAt(new Vector3(lookPoint.x, transform.position.y, lookPoint.z));
}
//enemy spawner check and win criteria check
if (defeatedEnemy != 45)
{
if (round != tempRound)
{
spawnEnemy();
roundT.gameObject.SetActive(true);
if (round == 5)
{
roundT.text = "Round: " + round + "(Final Round)";
}
else
{
roundT.text = "Round: " + round;
}
StartCoroutine(Pause(5.0f));
}
}
else
{
win = true;
}
//timer and win check
if (health == 0f)
{
win = true;
}
if (!win)
{
time -= Time.deltaTime;
timeT.text = "Time Left: " + time;
}
else
{
if (health == 0f)
{
roundT.gameObject.SetActive(true);
int finalScore = Mathf.RoundToInt(score * ((time / 2) / 10));
roundT.text = "To Bad, You Loose! Score = " + finalScore;
Debug.Log(finalScore);
StartCoroutine(Pause(99999f));
}
else
{
roundT.gameObject.SetActive(true);
int finalScore = Mathf.RoundToInt(score * ((time / 2) / 10));
roundT.text = "Congratulations! Score = " + finalScore;
Debug.Log(finalScore);
}
}
//movement controlls
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
{
transform.Translate(new Vector3(0.0f, 0.0f, speed * Time.deltaTime));
}
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
{
transform.Translate(new Vector3(-speed * Time.deltaTime, 0.0f, 0.0f));
}
if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
{
transform.Translate(new Vector3(0.0f, 0.0f, -speed * Time.deltaTime));
}
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
{
transform.Translate(new Vector3(speed * Time.deltaTime, 0.0f, 0.0f));
}
//shoot controll
if (allowShoot)
{
Debug.Log("shot allowed");
if (Input.GetMouseButtonDown(0))
{
//var spawnShot = Instantiate(shot, this.transform.position + new Vector3(0.0f, 0.0f, 0.5f), this.transform.rotation);
//shotScript = shotObj.GetComponent<ShotController>();
//if (shotScript.enemy)
//{
// Debug.Log("enemy found");
// enemyScript = shotScript.enemy.GetComponent<EnemyController>();
// if(enemyScript.health <= 0.0f)
// {
// score += 20;
// defeatedEnemy += 1;
// scoreT.text = "Score: " + score;
// Debug.Log("enemy killed : " + defeatedEnemy);
// }
//}
Debug.Log("mouseDown");
int layermask = 1 << 8;
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity, layermask))
{
enemyObj = hit.transform.gameObject;
enemyScript = enemyObj.GetComponent<EnemyController>();
Debug.Log("hit");
//hit.transform.SendMessage("HitByRay");
if (enemyScript.health == 0f)
{
Destroy(hit.transform.gameObject);
score += 20;
defeatedEnemy += 1;
scoreT.text = "Score: " + score;
Debug.Log("enemy killed : " + defeatedEnemy);
}
}
}
}
//enemy existance check
if (GameObject.Find("Enemy(Clone)") == null)
{
round = round + 1;
}
if (tempImune)
{
if (Mathf.RoundToInt(time) == targetTime)
{
tempImune = false;
}
}
}
void spawnEnemy()
{
tempRound = round;
for (int i = 1; i <= round * 3; i++)
{
var spawnEnemy = Instantiate(enemy, new Vector3(Random.Range(-14.5f, 14.5f), 0.25f, Random.Range(-6f, 6f)), Quaternion.identity);
}
}
void OnCollisionEnter(Collision col)
{
if (col.gameObject.tag == "Enemy")
{
if (!tempImune)
{
health = health - damageTaken;
Debug.Log(health);
tempImune = true;
targetTime = Mathf.RoundToInt(time) - 1;
}
}
}
}
Any help with this would be greatly appreciated as it's for a school project. Thanks.
You need to call this function from the Update function, since the state gets reset each frame. It will not return true until the user has released the mouse button and pressed it again. button values are 0 for the primary button (often the left button), 1 for secondary button, and 2 for the middle button
using UnityEngine;
using System.Collections;
public class ClassName : MonoBehaviour
{
void Update()
{
if (Input.GetMouseButtonDown(0))
Debug.Log("Pressed primary button.");
if (Input.GetMouseButtonDown(1))
Debug.Log("Pressed secondary button.");
if (Input.GetMouseButtonDown(2))
Debug.Log("Pressed middle click.");
}
}

Unity Multiplayer sending position and update to partner, socket.io

I'm trying to make a 2D multiplayer game and I encountered the next problem: animation and movement are not displayed correctely to partner. They have a small delay and the character looks judder. My annimation has 3 states: (IDLE, MOVE AND JUMP).Both objects have rigidbody component - player1,player 2. My code looks like this:
Sending position from player 1 to player 2: GameController.cs
public PlayerManager player1;
public PartenerManager player2;
void Update () // CODE TO SEND POSITION
{
if (player1.transform.position.x!=position.x || player1.transform.position.y!=position.y || player1.transform.position.z !=position.z)
{
int state = player1.getState();
position = new Vector3(player1.transform.position.x, player1.transform.position.y, player1.transform.position.z);
Dictionary<string, string> data = new Dictionary<string, string>();
data["position"] = position.x + ";" + position.y + ";" + position.z;
data["state"] = state.ToString(); // this is for the state of the annimation
socket.Emit("MOVE", new JSONObject(data));
}
}
// RECEIVING POSITION
void Start () {
socket.On("MOVED", onUserMove);
}
void onUserMove(SocketIOEvent obj)
{
string stare = obj.data.GetField("state").ToString();
stare = stare.Substring(1);
stare = stare.Substring(0, stare.Length - 1);
player2.setPositionState(JsonToVector3(JsonToString(obj.data.GetField("position").ToString(),"\"")),int.Parse(stare));
}
Recieveing and displaying the position at player 2: PartnerManager.cs
public class PartenerManager : MonoBehaviour {
public bool gotmove=false;
public float speedX = 6;
private string playerName;
public Text username;
Animator anim;
Rigidbody2D rb;
bool facingRight;
float speed;
Vector3 vec3;
int stare;
void Start () {
rb = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
facingRight = true;
}
void Flip()
{
if ((speed> 0 && !facingRight) || (speed < 0 && facingRight))
{
facingRight = !facingRight;
Vector3 temp = transform.localScale;
temp.x *= -1;
transform.localScale = temp;
}
}
public void setPositionState(Vector3 ve,int st)
{
gotmove = true;
vec3 = ve;
stare = st;
}
void FixedUpdate ()
{
if (gotmove==true)
{
if (transform.position.x < vec3.x)
{
Debug.Log("RIGHT");
speed = speedX;
}
if (transform.position.x > vec3.x)
{
Debug.Log("Left");
speed= -speedX;
}
if (transform.position.x == vec3.x)
{
speed = 0;
}
transform.position = vec3;
Flip();
anim.SetInteger("State", stare);
gotmove = false;
}
}
}
Player 1 code: PlayerManager.cs
public class PlayerManager : MonoBehaviour {
public float speedX=6;
public float jumpSpeedY=300;
private string playerName;
public Text username;
Animator anim;
Rigidbody2D rb;
bool facingRight;
bool jumping;
bool grounded;
float speed;
int numJumps = 0;
void Start ()
{
anim = GetComponent<Animator>();
rb = GetComponent<Rigidbody2D>();
facingRight = true;
grounded = false;
}
public int getState()
{
return anim.GetInteger("State");
}
void Update ()
{
MovePlayer(speed);
Flip();
}
void MovePlayer(float playerSpeed)
{
if ((playerSpeed < 0 && !jumping) || (playerSpeed>0 && !jumping))
{
anim.SetInteger("State", 1);
}
if(playerSpeed==0 && !jumping)
{
anim.SetInteger("State", 0);
}
rb.velocity = new Vector3(speed, rb.velocity.y, 0);
}
void Flip()
{
if((speed>0 && !facingRight) || (speed<0 && facingRight))
{
facingRight = !facingRight;
Vector3 temp = transform.localScale;
temp.x *= -1;
transform.localScale = temp;
}
}
void OnCollisionEnter2D(Collision2D other)
{
if(other.gameObject.tag=="ground")
{
jumping = false;
numJumps = 0;
grounded = true;
anim.SetInteger("State", 0);
}
}
public void WalkLeft()
{
speed = -speedX;
}
public void WalkRight()
{
speed = speedX;
}
public void StopMoving()
{
speed = 0;
}
public void Jump()
{
grounded = false;
if (grounded == true && numJumps >= 2)
{
numJumps = 0;
}
if (numJumps < 2 )
{
jumping = true;
if (numJumps == 0)
{
rb.AddForce(new Vector2(rb.velocity.x, jumpSpeedY));
}
else
{
rb.AddForce(new Vector2(rb.velocity.x, jumpSpeedY-100));
}
anim.SetInteger("State", 2);
numJumps++;
}
}
}
I resolved the problem. When you send the position you have also to send the rotation - quaternion . Here is my solution:
IMPORTANT: in the rigidbodycomponent, the z ax rotation must be checked
PartnerManager.cs - partner. The object that have to be sync
public class PartenerManager : MonoBehaviour
public Text username;
Vector3 targetPosition;
Quaternion targetRotation;
Animator anim;
bool facingRight;
int state;
void Start()
{
anim = GetComponent<Animator>();
facingRight = true;
anim.SetInteger("State", 0);
}
void Flip()
{
facingRight = !facingRight;
Vector3 temp = transform.localScale;
temp.x *= -1;
transform.localScale = temp;
}
public void setPositionState(Vector3 pozitie, Quaternion rotatie, int stare)
{
targetPosition = pozitie;
targetRotation = rotatie;
state = stare;
}
void ApplyMovement()
{
Debug.Log("pozitie actuala:" + transform.position.x + " pozitie mutata: " + targetPosition.x);
if (transform.position.x < targetPosition.x)
{
if (facingRight != true)
{
Flip();
facingRight = true;
}
}
if (transform.position.x > targetPosition.x)
{
if (facingRight == true)
{
Flip();
facingRight = false;
}
}
transform.position = Vector3.Lerp(transform.position, targetPosition, 0.5f);
transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, 0.5f);
anim.SetInteger("State", state);
}
void FixedUpdate()
{
ApplyMovement();
}
GameController.cs - the controlloer. Here i send and receive the message with the position
if (player1.transform.position.x != position.x || player1.transform.position.y != position.y || player1.transform.position.z != position.z)
{
int state = player1.getState();
position = new Vector3(player1.transform.position.x, player1.transform.position.y, player1.transform.position.z);
Dictionary<string, string> data = new Dictionary<string, string>();
data["position"] = position.x + ";" + position.y + ";" + position.z;
data["state"] = state.ToString();
data["rotation"] = player1.transform.rotation.x + ";" + player1.transform.rotation.y + ";" + player1.transform.rotation.z + ";" + player1.transform.rotation.w;
socket.Emit("MOVE", new JSONObject(data));
}
Quaternion JsonToQuaternion(string target)
{
Quaternion newVector;
string[] newString = Regex.Split(target, ";");
newVector = new Quaternion(float.Parse(newString[0]), float.Parse(newString[1]), float.Parse(newString[2]),float.Parse(newString[3]));
return newVector;
}
void onUserMove(SocketIOEvent obj)
{
string stare = obj.data.GetField("state").ToString();
stare = stare.Substring(1);
stare = stare.Substring(0, stare.Length - 1);
Vector3 pozitie = JsonToVector3(JsonToString(obj.data.GetField("position").ToString(), "\""));
Quaternion rotatie= JsonToQuaternion(JsonToString(obj.data.GetField("rotation").ToString(), "\""));
int state = int.Parse(stare);
//Debug.Log("Partener: pozitie: " + pozitie + " rotatie " + rotatie + " stare: " + stare);
player2.setPositionState(pozitie,rotatie,state);
//player2.setPositionState(JsonToVector3(JsonToString(obj.data.GetField("position").ToString(),"\"")),int.Parse(stare));
}

Unity navmesh ai stuck

I am trying to develop an AI that works with photon networking system, in unity engine. It should be fairly simple: it runs to a random player till it reaches 5 units distance between him and player, then it walk at a slightly slower speed till it reaches the front of the player. Then he attacks. So far so good, but sometimes, the AI get stuck right when it reaches 5 units distance between him and the player. I tried several fixes from the internet, but nothing worked.
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(NavMeshAgent))]
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(PhotonView))]
[RequireComponent(typeof(PhotonTransformView))]
public class EnemyAI : Photon.MonoBehaviour {
NavMeshAgent agent;
Animator anim;
PlayerController target;
[Header("Base settings")]
[SerializeField]
float health = 100f, damage, timeBetweenAttacks = 5f;
[Space]
[Header("Enemy Ragdoll")]
[SerializeField]
GameObject ragdoll;
AudioSource emotAud, stepAud;
[Space]
[SerializeField]
[Header("Audio")]
List<AudioClip> attackingAuds;
[Space]
[Header("Sunete pasi")]
[SerializeField]
List<AudioClip> stepAuds;
[Space]
[Header("Alte optiuni")]
[SerializeField]
float distantaLaCareIncepeSaMearga = 5f, walkSpeed = .5f, runSpeed = 3.5f;
bool dead, walking;
PhotonView killer;
float nextAttackTime;
// Use this for initialization
void Start () {
emotAud = gameObject.AddComponent<AudioSource>();
stepAud = gameObject.AddComponent<AudioSource>();
emotAud.spatialBlend = 1;
emotAud.maxDistance = 7;
stepAud.spatialBlend = 1;
stepAud.maxDistance = 7;
emotAud.playOnAwake = false;
stepAud.playOnAwake = false;
dead = false;
target = null;
agent = GetComponent<NavMeshAgent>();
anim = GetComponent<Animator>();
killer = null;
}
// Update is called once per frame
void Update () {
if (photonView.isMine)
{
if (walking)
{
agent.speed = walkSpeed;
}
else
{
agent.speed = runSpeed;
}
if (health <= 0)
{
if (!dead)
{
dead = true;
photonView.RPC("die", PhotonTargets.AllBuffered);
}
}
if (!target)
{
if (!PhotonNetwork.offlineMode)
{
nextAttackTime = (float)PhotonNetwork.room.CustomProperties["remainTime"];
}
else
{
nextAttackTime = 0f;
}
PlayerController[] controllers = FindObjectsOfType<PlayerController>();
int randCh = Random.Range(0, controllers.Length);
if (controllers.Length > 0)
{
target = controllers[randCh];
}
anim.SetFloat("move", 0);
}
else
{
if (Vector3.Distance(transform.position, target.gameObject.transform.position) > 1.8f)
{
if (Vector3.Distance(transform.position, target.gameObject.transform.position) > distantaLaCareIncepeSaMearga)
{
walking = false;
}
else
{
walking = true;
}
anim.SetBool("walking", walking);
anim.SetFloat("move", 1);
//print("Active: " + agent.isActiveAndEnabled + " Pend: " + agent.pathPending + " Has path: " + agent.hasPath);
if (agent.isActiveAndEnabled)
{
if (!agent.pathPending)
{
agent.SetDestination(target.gameObject.transform.position - transform.forward * 1.2f);
}
}
}
else
{
if (!PhotonNetwork.offlineMode)
{
if (nextAttackTime >= (float)PhotonNetwork.room.CustomProperties["remainTime"])
{
anim.SetTrigger("attack");
nextAttackTime -= timeBetweenAttacks;
}
else
{
anim.SetFloat("move", 0);
}
}
else
{
if (nextAttackTime <= 0f)
{
anim.SetTrigger("attack");
nextAttackTime += timeBetweenAttacks;
}
else
{
nextAttackTime -= Time.deltaTime;
anim.SetFloat("move", 0);
}
}
}
}
}
}
void OnDrawGizmosSelected()
{
if (target)
{
Gizmos.color = Color.blue;
Gizmos.DrawSphere(agent.destination, 1);
}
}
[PunRPC]
void die()
{
if (killer)
{
killer.gameObject.GetComponent<PlayerController>().kill();
}
if (attackingAuds.Count > 0)
{
emotAud.clip = attackingAuds[Random.Range(0, attackingAuds.Count - 1)];
emotAud.Play();
}
gameObject.GetComponent<CapsuleCollider>().enabled = false;
Instantiate(ragdoll, transform.position, transform.rotation);
Destroy(this.gameObject);
}
public void attack()
{
if (target && target.health >= 0)
{
if (Vector3.Distance(target.gameObject.transform.position, transform.position) <= 2f)
{
target.doDamage(damage);
if (target.health <= 0)
{
target.photonView.RPC("die", PhotonTargets.All, true);
}
}
}
}
void OnCollisionEnter(Collision col)
{
if (col.gameObject.tag.Contains("Bullet"))
{
killer = col.gameObject.GetComponent<Magic_Bullet>().owner;
target = killer.gameObject.GetComponent<PlayerController>();
photonView.RPC("takeDamage", PhotonTargets.AllBuffered, col.gameObject.GetComponent<Magic_Bullet>().damage);
PhotonNetwork.Destroy(col.gameObject);
}
}
[PunRPC]
void takeDamage(float dmg)
{
health -= dmg;
}
public void step()
{
stepAud.clip = stepAuds[Random.Range(0, stepAuds.Count - 1)];
stepAud.Play();
}
}
What am I doing wrong?
Well there's a hell of if else in your update function which just gives a headache to all of us,
Instead, try implementing a simple FSM using scriptableobject (as unity official tutorials ) or Coroutines which requires hard coding and is not recommended.
https://unity3d.com/learn/tutorials/topics/navigation/finite-state-ai-delegate-pattern

How to save high score?

I am trying to save high score in my game. The high score is updated with the score during play. However, after level restarts, both (current score and high score) becomes zero.
How can I do this? What mistake I am doing?
Here is my code:
Generate
public class Generate : MonoBehaviour
{
private static int score;
public GameObject birds;
private string Textscore;
public GUIText TextObject;
private int highScore = 0;
private int newhighScore;
private string highscorestring;
public GUIText highstringgui;
// Use this for initialization
void Start()
{
PlayerPrefs.GetInt ("highscore", newhighScore);
highscorestring= "High Score: " + newhighScore.ToString();
highstringgui.text = (highscorestring);
InvokeRepeating("CreateObstacle", 1f, 3f);
}
void Update()
{
score = Bird.playerScore;
Textscore = "Score: " + score.ToString();
TextObject.text = (Textscore);
if (score > highScore)
{
newhighScore=score;
PlayerPrefs.SetInt ("highscore", newhighScore);
highscorestring = "High Score: " + newhighScore.ToString ();
highstringgui.text = (highscorestring);
}
else
{
PlayerPrefs.SetInt("highscore",highScore);
highscorestring="High Score: " + highScore.ToString();
highstringgui.text= (highscorestring);
}
}
void CreateObstacle()
{
Instantiate(birds);
}
}
Bird
public class Bird : MonoBehaviour {
public GameObject deathparticales;
public Vector2 velocity = new Vector2(-10, 0);
public float range = 5;
public static int playerScore = 0;
// Use this for initialization
void Start()
{
rigidbody2D.velocity = velocity;
transform.position = new Vector3(transform.position.x, transform.position.y - range * Random.value, transform.position.z);
}
// Update is called once per frame
void Update () {
Vector2 screenPosition = Camera.main.WorldToScreenPoint(transform.position);
if (screenPosition.x < -10)
{
Die();
}
}
// Die by collision
void OnCollisionEnter2D(Collision2D death)
{
if(death.transform.tag == "Playercollision")
{
playerScore++;
Destroy(gameObject);
Instantiate(deathparticales,transform.position,Quaternion.identity);
}
}
void Die()
{
playerScore =0;
Application.LoadLevel(Application.loadedLevel);
}
}
The problem is your variable highScore. It is always 0. In the game you ask
if (score > highScore)
And because you set highScore = 0 while declaring that variable, score is always greater.
My suggestion is that you should declare it without value:
private int highScore;
In Start() you should give it value of saved high-score if it exists, and if it doesn't, give it 0 value:
highScore = PlayerPrefs.GetInt("highscore", 0);
That should work for you.
This line in Start(), won't actually do anything.
PlayerPrefs.GetInt ("highscore", newhighScore);
The second parameter is the default return value, if the given key doesn't exist.
But you're not using the return value for anything.
I think what you meant to do is:
newhighScore = PlayerPrefs.GetInt("highscore");
The default value will be 0, when not set explicitly.

Categories