Player.cs error CS1525: Unexpected symbol `public' - c#

Hey guys I am getting this error as i mentioned in the title Ive been trying to debug since last night and finally got down to this one error left i cant seem to beat. here is the code please have a look if you get the chance the error is saying its on line (107,16) and sorry for the link i just joined here don't know how to put it in code.
using UnityEngine;
using System.Collections;
using UnityEngine.UI; //Allows us to use UI.
namespace Completed
{
public class Player
{
public float restartLevelDelay = 1f;
public int pointsPerFood = 10;
public int pointsPerSoda = 20;
public int wallDamage = 1;
public Text foodText;
public AudioClip moveSound1;
public AudioClip moveSound2;
public AudioClip eatSound1;
public AudioClip eatSound2;
public AudioClip drinkSound1;
public AudioClip drinkSound2;
public AudioClip gameOverSound;
private Animator animator;
private int food;
private Vector2 touchOrigin = -Vector2.one;
//Start overrides the Start function of MovingObject
protected override void Start ()
{
//Get a component reference to the Player's animator component
animator = GetComponent<Animator>();
//Get the current food point total stored in GameManager.instance between levels.
food = GameManager.instance.playerFoodPoints;
//Set the foodText to reflect the current player food total.
foodText.text = "Food: " + food;
//Call the Start function of the MovingObject base class.
base.Start ();
}
//This function is called when the behaviour becomes disabled or inactive.
private void OnDisable ()
{
GameManager.instance.playerFoodPoints = food;
}
private void Update ()
{
//If it's not the player's turn, exit the function.
if(!GameManager.instance.playersTurn) return;
int horizontal = 0; //Used to store the horizontal move direction.
int vertical = 0; //Used to store the vertical move direction.
//Check if we have a non-zero value for horizontal or vertical
if(horizontal != 0 || vertical != 0)
{
AttemptMove<Wall> (horizontal, vertical);
}
}
protected override void AttemptMove <T> (int xDir, int yDir)
{
//Every time player moves, subtract from food points total.
food--;
//Update food text display to reflect current score.
foodText.text = "Food: " + food;
//Call the AttemptMove method of the base class, passing in the component T (in this case Wall) and x and y direction to move.
base.AttemptMove <T> (xDir, yDir);
//Hit allows us to reference the result of the Linecast done in Move.
RaycastHit2D hit;
//If Move returns true, meaning Player was able to move into an empty space.
if (Move (xDir, yDir, out hit))
{
//Call RandomizeSfx of SoundManager to play the move sound, passing in two audio clips to choose from.
SoundManager.instance.RandomizeSfx (moveSound1, moveSound2);
}
{
//Since the player has moved and lost food points, check if the game has ended.
CheckIfGameOver ();
//Set the playersTurn boolean of GameManager to false now that players turn is over.
GameManager.instance.playersTurn = false;
}
//OnCantMove overrides the abstract function OnCantMove in MovingObject.
//It takes a generic parameter T which in the case of Player is a Wall which the player can attack and destroy.
public override void OnCantMove <T> (T component)
{
//Set hitWall to equal the component passed in as a parameter.
Wall hitWall = component as Wall;
//Call the DamageWall function of the Wall we are hitting.
hitWall.DamageWall (wallDamage);
//Set the attack trigger of the player's animation controller in order to play the player's attack animation.
animator.SetTrigger ("playerChop");
}
//OnTriggerEnter2D is sent when another object enters a trigger collider attached to this object (2D physics only).
private void OnTriggerEnter2D (Collider2D other)
{
//Check if the tag of the trigger collided with is Exit.
if(other.tag == "Exit")
{
//Invoke the Restart function to start the next level with a delay of restartLevelDelay (default 1 second).
Invoke ("Restart", restartLevelDelay);
//Disable the player object since level is over.
enabled = false;
}
//Check if the tag of the trigger collided with is Food.
else if(other.tag == "Food")
{
//Add pointsPerFood to the players current food total.
food += pointsPerFood;
//Update foodText to represent current total and notify player that they gained points
foodText.text = "+" + pointsPerFood + " Food: " + food; //nothing
//Call the RandomizeSfx function of SoundManager and pass in two eating sounds to choose between to play the eating sound effect.
SoundManager.instance.RandomizeSfx (eatSound1, eatSound2);
//Disable the food object the player collided with.
other.gameObject.SetActive (false);
}
//Check if the tag of the trigger collided with is Soda.
else if(other.tag == "Soda")
{
//Add pointsPerSoda to players food points total
food += pointsPerSoda;
//Update foodText to represent current total and notify player that they gained points
foodText.text = "+" + pointsPerSoda + " Food: " + food;
//Call the RandomizeSfx function of SoundManager and pass in two drinking sounds to choose between to play the drinking sound effect.
SoundManager.instance.RandomizeSfx (drinkSound1, drinkSound2);
//Disable the soda object the player collided with.
other.gameObject.SetActive (false);
}
}
//Restart reloads the scene when called.
private void Restart ()
{
//Load the last scene loaded, in this case Main, the only scene in the game.
Application.LoadLevel (Application.loadedLevel);
}
//LoseFood is called when an enemy attacks the player.
//It takes a parameter loss which specifies how many points to lose.
public void LoseFood (int loss)
{
//Set the trigger for the player animator to transition to the playerHit animation.
animator.SetTrigger ("playerHit");
//Subtract lost food points from the players total.
food -= loss;
//Update the food display with the new total.
foodText.text = "-" + loss + " Food: " + food;
//Check to see if game has ended.
CheckIfGameOver ();
}
//CheckIfGameOver checks if the player is out of food points and if so, ends the game.
private void CheckIfGameOver ()
{
//Check if food point total is less than or equal to zero.
if (food <= 0)
{
//Call the PlaySingle function of SoundManager and pass it the gameOverSound as the audio clip to play.
SoundManager.instance.PlaySingle (gameOverSound);
//Stop the background music.
SoundManager.instance.musicSource.Stop();
//Call the GameOver function of GameManager.
GameManager.instance.GameOver ();
}
}
}
}

In the function protected override void AttemptMove , remove the open {
// ... previous code ...
if (Move (xDir, yDir, out hit))
{
//Call RandomizeSfx of SoundManager to play the move sound, passing in two audio clips to choose from.
SoundManager.instance.RandomizeSfx (moveSound1, moveSound2);
}
// { REMOVE THIS ONE!
//Since the player has moved and lost food points, check if the game has ended.
CheckIfGameOver ();
//Set the playersTurn boolean of GameManager to false now that players turn is over.
GameManager.instance.playersTurn = false;

Related

While working on my Platformer game in Unity, my Update function as it's assigning "true" to a bool even when character is not Grounded

Firstly, the code:
private bool? _hasJumped = false;
private void Update()
{
Debug.Log("Checking the _hasJumped value in Update(): " + _hasJumped);
Debug.Log("Is the player Grounded?: " + IsGrounded());
if (IsGrounded())
{
_extraJumps = _extraJumpCount;
_coyoteTimer = _coyoteTimerVal;
_hasJumped = false; //The Variable that I am having issues with.
Debug.Log("This statement only runs when the player is on ground!");
}
else
{
_coyoteTimer -= Time.deltaTime;
}
}
public bool IsGrounded()
{
return Physics2D.OverlapCircle(_feetpos.position,_feetCheckRadius,_groundLayerMask);
}
public void GetJumpInput(InputAction.CallbackContext context)
{
if (context.started)
{
_jumpBuffer = Time.time;
}
if (_coyoteTimer > 0f && (Time.time - _jumpBuffer >= 0) && context.performed)
{
if(context.interaction is TapInteraction)
{
_myRigidBody.velocity += new Vector2 (0f, _jumpForce);
_whichInteraction = 0;
}
else if (context.interaction is HoldInteraction)
{
_myRigidBody.velocity += new Vector2 (0f, _jumpForce);
_whichInteraction = 1;
}
_jumpBuffer = null;
_hasJumped = true; //_hasJumped set to true when I first jump
Debug.Log("The Player Has Pressed Jump!: " + _hasJumped);
}
else if (_extraJumps > 0 && context.performed && hasJumped) //Double Jump should ONLY work when I have jumped, and not when I fall off a ledge.
{
Debug.Log(_hasJumped);
_extraJumps--;
if(context.interaction is TapInteraction)
{
_myRigidBody.velocity += new Vector2 (0f, _jumpForce*_secondJumpForceMult);
_whichInteraction = 0;
}
}
else
{
_coyoteTimer = 0f;
}
}
Sorry if the the code is confusing, I've tried to add comments to the variable in focus. But the issue that I'm facing is this:
Right now, when a player falls off the edge, the player is able to jump once because of the additional "extra jump" but this should not be happening. The "extra jump" should only come into effect when the player HAS already jumped.
To stop this, I decided to use a bool "_hasJumped" which (in my head works as follows):
As long as the player is touching the ground, it is false.
When the player first jumps, it is set to true.
Only when it is true can player perform the "extra jump".
If it isn't true, the player cannot perform the "extra jump".
However, the issue that I'm facing is that although _hasJumped is set to true when I jump, it is immediately set to false in the next update (even though I'm still in the air!). Video Evidence #1
I've checked that my IsGrounded() function is working completely fine [Video Evidence #2].
The only reason I can deduce is that it may have something to do with Unity's runtime order? I'm a newbie though so I could be wrong.
I am also using the new Input System.
Thank you for taking the time to read it/give advice/help! I really appreciate it!
The problem is how fast the update actually runs in relation to the way you structured your code.
To visualize, this is what happens when the player pressed the jump button:
First frame: Player presses jump button
Second frame: Character is slightly up on the air, but the overlap collision detector is still touching the ground
Solution
Only check for IsGrounded() when the player presses the jump button, not per-update.
This also saves some computing resource as doing Physics calculation per-frame can be demanding.
Use OnCollisionEnter2D or OnTriggerEnter2D to check if the character has just landed to set canExtraJump to false.
Looks something like this:
bool canExtraJump = false;
void Update(){
// Set extrajump when player inputs jump button, and char is grounded
if (Player_Input_Jump) {
if (IsGrounded()){
Jump();
canExtraJump = true;
}
}
}
void TriggerLandedOnGround(){
canExtraJump = false;
}
// ...
/// Ideally this function should be in the character's feet (as another gameObject)
/// As you do not want this to trigger when the side of a character touches the platform.
void OnTriggerEnter2D(Collider2D other){
if (other.CompareTag("platform")){
TriggerLandedOnGround();
}
}

Coin count display display different amount - Unity 2D game

I'm creating a 2D car game using unity. Basic idea is adding coin count when player collect coins and display collected coin in the end-game menu. In my CoinCount script, in OnTriggerEnter2D I add coin value to current collected coins.But when game over some times its shows correct answer and some times it's add 2 or more values to collected values.
//CoinCount script
void OnTriggerEnter2D(Collider2D colInfo)
{
int inc = 0;
if (colInfo.gameObject.CompareTag("Coin"))
{
inc = 5;
coinCount += inc;
print("coinCount" + coinCount);
AudioManager.instance.PlaySound("Coin");
}
currentBalance += inc;
PlayerPrefs.SetInt("CoinCount", currentBalance);
PlayerPrefs.Save();
}
I tried maintain a public class for manage coins but it will give the same result. As an example if I collect 5 coins with the value of 5, it should display 25 as total coin count. sometimes it's 30 and 35.
public class GameScoreManager : MonoBehaviour
{
public static int value;
public Text currentScoreText;
// Start is called before the first frame update
void Start()
{
value = 0;
}
// Update is called once per frame
void Update()
{
currentScoreText.text = "$" + value.ToString();
print("Game coin count" + value);
}
}
This is the CoinCount script after I created the GameScoreManager class.
void OnTriggerEnter2D(Collider2D colInfo)
{
if (colInfo.gameObject.CompareTag("Coin"))
{
GameScoreManager.value += scoreValue;
}
}
I attached this script for each coins for destroy it self after hitting the player
public class DestroyCoin : MonoBehaviour
{
public GameObject effect;
//This script destroy the coin
void OnTriggerEnter2D(Collider2D colInfo)
{
if (colInfo.CompareTag("Player"))
{
Instantiate(effect, transform.position, transform.rotation);
Destroy(gameObject);
}
}
}
Much appreciate your help
I would go about solving such an issue by linking the addition of the coins value to the player's score DIRECTLY to destruction of the coin.
You might think that in the same game frame your coin gets a collision event to self destruct, and your player gets an event to add the coins value to his score.
If you're a guru and you know how the unity engine's internal mechanisms work by heart, be my guest and use that knowledge to write sloppy code that still works. But for a mere mortal like me, good practice can avoid this type of issues... (for example what if the coin's destruction causes no more collision for the player to add a value to the score?)
Use the same collision event to add a value to the player's score and destroy the coin for good, making sure such an event does not occur again. Even set the coin's value to 0 at that moment, just to be doubble-safe.
I manage to solve the problem by identifying the colider. Checked it's attached in the beginning and then disable the collision after the first hit.
void OnTriggerEnter2D(Collider2D colInfo)
{
int inc = 0;
//if (colInfo.CompareTag("Coin"))
if (colInfo.gameObject.CompareTag("Coin") && colInfo.gameObject.GetComponent<CircleCollider2D>().enabled)
{
colInfo.gameObject.GetComponent<CircleCollider2D>().enabled = false;
Destroy(colInfo.gameObject);
inc = 5;
coinCount += inc;
print("coinCount" + coinCount);
// AudioManager.instance.PlaySound("Coin");
currentBalance += inc;
}
PlayerPrefs.SetInt("CoinCount", currentBalance);
PlayerPrefs.Save();
}
Thanks and learnt a lot with this

Is this the right way i should be coding my game to reset the score once the player dies?

Score does not reach 0 once the player dies.
I tried all different kinds of methods and changing values but nothing seemed to work.
{
//when the player's box collider collides with another box collider
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
//scene moves to a game over screen
SceneManager.LoadScene("Player Death");
//Reset score everytime player dies
void resetScore()
{
PlayerPrefs.SetInt ("Score", 0);
}
}
}
// Start is called before the first frame update
void Start()
{ }
// Update is called once per frame
void Update()
{
}
}
It was just building the score up from where it left off and didnt do as i programmed.
You are declaring a new method resetScore() when a player dies, but you're never calling it.
What you should do is declare the method outside of OnTriggerEvent() and call it when a player dies:
//when the player's box collider collides with another box collider
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
//scene moves to a game over screen
SceneManager.LoadScene("Player Death");
//Reset score everytime player dies
resetScore();
}
}
// Start is called before the first frame update
void Start()
{ }
// Update is called once per frame
void Update()
{
}
void resetScore()
{
PlayerPrefs.SetInt("Score", 0);
}
Have you tried to reset the score right when the player dies? I assume you reset it on game start. Try doing it right after the player dies, or use it in a constructor when creating a new game/player. It isn´t clear how you implemented it, it would help if you post more pieces of code.
[EDIT]
Firstly, you are declaring the ResetScore Method, but you don´t call it to execute. So you need to declare it outside the "OnTriggerEnter" method, and then call it inside the method like this :
ResetScore();
Secondly, Why don´t you try to use property instead of SetInt?
public int Score { get; set;}
Then you can change it like this :
if (other.gameObject.tag == "Player")
{
Player.Score = 0;
//scene moves to a game over screen
SceneManager.LoadScene("Player Death");
//Reset score everytime player dies
}

Updating how many enemies are remaining - Unity

I'm pretty new to Unity and I've had a look around for similar problems, but I suck at transferring it over into my program.
Anyway, I basically have a class called Scoring that will keep track of how many enemies there are on the level. I want to pass this value into another class called Bullet_explosive. In this class, it will remove one from that total when an enemy has been hit with the bullet. After it has removed one from the total, I want this value to be passed back into Scoring so that it can be displayed on the screen to the player.
Probably been answered a million times, but I'm sick of not knowing how to implement it into my own program.
Thanks in advance.
Here's the Scoring class:
public class Scoring : MonoBehaviour {
// Create gameobject to store the text object within
public GameObject textObject;
// Holds the text displayed on screen
Text actualText;
// Holds the remaining number of enemies
public static int enemiesRemaining = 12;
// Use this for initialization
void Start ()
{
// Stores the gameobject called EnemiesRemaining
textObject = GameObject.Find ("EnemiesRemaining");
// Gets the text component of that gameobject
actualText = textObject.GetComponent<Text> ();
// Stores what text the display will actually show
actualText.text = "Enemies Remaining: " + enemiesRemaining;
}
// Update is called once per frame
void Update ()
{
// Updates the display
actualText.text = "Enemies Remaining: " + enemiesRemaining;
}
Here's the Bullet_explosive class:
public class Bullet_explosive : MonoBehaviour {
// Lifespan of the bullet
float lifespan = 1.5f;
// Setting up game objects
public GameObject fireEffect;
public GameObject explosion;
public GameObject theGate;
//Passing through the enemies remaining
private static int score;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
score = Scoring.enemiesRemaining;
lifespan -= Time.deltaTime;
// Once the lifespan reaches 0, bullet is destroyed
if (lifespan <= 0)
{
Explode ();
}
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Enemy")
{
// Reduces the remaining enemies
score -= 1;
// Checks for no remaining enemies
if (score <= 0)
{
// Removes the gate
Destroy(GameObject.FindWithTag ("Gate"));
}
// Changes the tag of the target hit
collision.gameObject.tag = "Untagged";
// Applies visual effects at the position and rotation of the target
Instantiate (fireEffect, collision.transform.position, Quaternion.identity);
Instantiate (explosion, collision.transform.position, Quaternion.identity);
// Removes bullet and target
Explode();
Destroy (collision.gameObject);
}
}
void Explode()
{
Destroy (gameObject);
}
I find it to be too much effort to have two static fields that mean exactly the same thing. You should only make one field for that and always refer to that same field in the Scoring class.
public class Bullet_explosive : MonoBehaviour {
// Lifespan of the bullet
float lifespan = 1.5f;
// Setting up game objects
public GameObject fireEffect;
public GameObject explosion;
public GameObject theGate;
// Use this for initialization
void Start () { }
// Update is called once per frame
void Update ()
{
/* no "score" updating needed here in Update() */
lifespan -= Time.deltaTime;
// Once the lifespan reaches 0, bullet is destroyed
if (lifespan <= 0)
{
Explode ();
}
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Enemy")
{
// Reduces the remaining enemies
//Directly modify that one static field
Scoring.enemiesRemaining -= 1;
// Checks for no remaining enemies
if (Scoring.enemiesRemaining <= 0) //here too
{
// Removes the gate
Destroy(GameObject.FindWithTag ("Gate"));
}
// Changes the tag of the target hit
collision.gameObject.tag = "Untagged";
// Applies visual effects at the position and rotation of the target
Instantiate (fireEffect, collision.transform.position, Quaternion.identity);
Instantiate (explosion, collision.transform.position, Quaternion.identity);
// Removes bullet and target
Explode();
Destroy (collision.gameObject);
}
}
void Explode()
{
Destroy (gameObject);
}
And that should be it.

Stealing enemies points in multiplayer game

I have a "Player" gameObject that spawn OnServerInitialized().
It's tag "Enemy" change to "Player" when GetComponent<NetworkView>().isMine.
I'd like to make something like:
void OnTriggerEnter (Collider Enemy){
if (ScoreManager.score > Enemy.Score) {
ScoreManager.score = ScoreManager.score + Enemy.Score;
}
else if (ScoreManager.score < Enemy.Score) {
Destroy (gameObject);
}
}
But I don't know how to access to spawned enemy player's points.
My ScoreManager Script:
public static int score;
Text text;
void Awake () {
text = GetComponent <Text> ();
score = 0;
}
void Update () {
text.text = "Score: " + score;
}
}
It is attached to GUI text gameObject named ScoreText.
1)when you're using GetComponent always check for null.
2)Don't use GetComponent. Serialize the variable (or make it public) by addding [System.Serializable] above Text text; and drag and drop in the inspector, the text component.
3)You don't have to refresh the score every frame, only when it changes. This should be done using events.
In order to access the enemy's points, you can use GameObject.FindWithTag, and use the "Enemy" provided that the enemy has this tag. You can get a reference to the enemy game object that way. Then access its score component.
For example:
ScoreManager enemyScoreManager = null;
GameObject enemyReference = GameObject.FindWithTag("Enemy");
if (enemyReference !=null)
enemyScoreManager = enemyReference.GetComponent<ScoreManager>();
if (enemyScoreManager != null)
{
enemyScoreManager.score -=5; //steal 5 points
myScore.score +=5; //assuming myScore is a reference to your score manager
}
else
Debug.LogError("Enemy not found");

Categories