Well, I’m doing the Roguelike2D tutorial and I’ve found an error on the parameters of the character’s food points. Here is the code:
protected override void Start ()
{
animator = GetComponent ();
food = GameManager.instance.playerFoodPoints;
base.Start ();
}
And the GameManager code for the playerFoodPoints variable:
public int playerFoodPoints = 100;
So, the problem is, when I start game, the food variable should get the playerFoodPoints value from another class (the first code is from the Player class and the second from GameManager class), but it didn’t. When I walk for the first time, the game tests if food is less than or equal to 0, if true, it calls the GameOver function.
I haven’t found why the value isn’t passing to food. Anyone can help me, please?
ADNCG
August 28, 2017, 6:57pm
2
Are you getting a null ref? How is the static instance of GameManager defined out of curiosity?
1 Like
public static GameManager instance = null;
public BoardManager boardScript;
public int playerFoodPoints = 100;
And I have this on the Awake function:
if (instance == null)
instance = this;
else if (instance != this)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
enemies = new List();
boardScript = GetComponent();
InitGame();
ADNCG
August 28, 2017, 7:15pm
4
Can you post the class your character is inheriting from! With code tags for bonus style points
1 Like
Are you getting an error? What is happening? food should get the value from the gamemanager once in Start, so the value should be 100, but I’m not sure what else you are doing with that value since you didn’t mention what was going wrong or if you get an error.
1 Like
Here it goes, sorry, I didn’t know how to use code tags before.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class MovingObject : MonoBehaviour {
public float moveTime = .1f;
public LayerMask blockingLayer;
private BoxCollider2D boxCollider;
private Rigidbody2D rb2D;
private float inverseMoveTime;
// Use this for initialization
protected virtual void Start ()
{
boxCollider = GetComponent<BoxCollider2D> ();
rb2D = GetComponent<Rigidbody2D> ();
inverseMoveTime = 1f / moveTime;
}
protected bool Move (int xDir, int yDir, out RaycastHit2D hit)
{
Vector2 start = transform.position;
Vector2 end = start + new Vector2 (xDir, yDir);
boxCollider.enabled = false;
hit = Physics2D.Linecast (start, end, blockingLayer);
boxCollider.enabled = true;
if (hit.transform == null)
{
StartCoroutine (SmoothMovement (end));
return true;
}
return false;
}
protected IEnumerator SmoothMovement (Vector3 end)
{
float sqrRemainingDistance = (transform.position - end).sqrMagnitude;
while (sqrRemainingDistance > float.Epsilon)
{
Vector3 newPosition = Vector3.MoveTowards (rb2D.position, end, inverseMoveTime * Time.deltaTime);
rb2D.MovePosition (newPosition);
sqrRemainingDistance = (transform.position - end).sqrMagnitude;
yield return null;
}
}
protected virtual void AttemptMove <T> (int xDir, int yDir)
where T : Component
{
RaycastHit2D hit;
bool canMove = Move(xDir, yDir, out hit);
if (hit.transform == null)
return;
T hitComponent = hit.transform.GetComponent<T> ();
if (!canMove && hitComponent != null)
OnCantMove (hitComponent);
}
protected abstract void OnCantMove <T> (T component)
where T : Component;
}
Brathnann:
Are you getting an error? What is happening? food should get the value from the gamemanager once in Start, so the value should be 100, but I’m not sure what else you are doing with that value since you didn’t mention what was going wrong or if you get an error.
Nops, the value 100 don’t pass, when I hit Play Game, food just stays as 0.
Here is the Player code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Player : MovingObject {
public int wallDamage = 1;
public int pointsPerFood = 10;
public int pointsPerSoda = 20;
public float restartLevelDelay = 1f;
private Animator animator;
private int food; // PRIVATE
// Use this for initialization
protected override void Start ()
{
animator = GetComponent<Animator> ();
food = GameManager.instance.playerFoodPoints;
base.Start ();
}
private void OnDisable()
{
GameManager.instance.playerFoodPoints = food;
}
// Update is called once per frame
void Update ()
{
if (!GameManager.instance.playersTurn)
return;
int horizontal = 0;
int vertical = 0;
horizontal = (int)Input.GetAxisRaw ("Horizontal");
vertical = (int)Input.GetAxisRaw ("Vertical");
if (horizontal != 0)
vertical = 0;
if (horizontal != 0 || vertical != 0)
AttemptMove<Wall> (horizontal, vertical);
}
protected override void AttemptMove <T> (int xDir, int yDir)
{
food--;
base.AttemptMove <T> (xDir, yDir);
RaycastHit2D hit;
CheckIfGameOver ();
GameManager.instance.playersTurn = false;
}
protected void OnTriggerEnter2D (Collider2D other)
{
if (other.tag == "Exit") {
Invoke ("Restart", restartLevelDelay);
enabled = false;
} else if (other.tag == "Food") {
food += pointsPerFood;
other.gameObject.SetActive (false);
} else if (other.tag == "Soda") {
food += pointsPerSoda;
other.gameObject.SetActive (false);
}
}
protected override void OnCantMove <T> (T component)
{
Wall hitWall = component as Wall;
hitWall.DamageWall (wallDamage);
animator.SetTrigger ("playerChop");
}
private void Restart()
{
SceneManager.LoadScene (0);
//Application.LoadLevel(Application.loadedLevel);
}
public void LoseFood (int loss)
{
animator.SetTrigger ("playerHit");
food -= loss;
CheckIfGameOver ();
}
private void CheckIfGameOver() {
if (food <= 0)
GameManager.instance.GameOver ();
}
}
And the GameManager code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour {
public float turnDelay = .1f;
public static GameManager instance = null;
public BoardManager boardScript;
public int playerFoodPoints = 100;
[HideInInspector] public bool playersTurn = true;
private int level = 3;
private List<Enemy> enemies;
private bool enemiesMoving;
private void Awake()
{
if (instance == null)
instance = this;
else if (instance != this)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
enemies = new List<Enemy>();
boardScript = GetComponent<BoardManager>();
InitGame();
// SceneManager.sceneLoaded += OnSceneLoaded; //------------------------- QUANDO LINHA ATIVA, NÃO SALVA O PERSONAGEM PARA A PROXIMA FASE.
// ----------------------- QUANDO LINHA INATIVA, NÃO CARREGA O MAPA NA PROXIMA FASE.
SceneManager.LoadScene(0);
}
/* // Não Funfa
static private void OnSceneLoaded(Scene arg0, LoadSceneMode arg1)
{
instance.level++;
instance.InitGame();
}
*/
void OnLevelWasLoaded(int index)
{
instance.level++;
instance.InitGame ();
}
void InitGame()
{
enemies.Clear ();
boardScript.SetupScene (level);
}
public void GameOver()
{
enabled = false;
Debug.Log("Game Over");
}
// Update is called once per frame
void Update () {
if (playersTurn || enemiesMoving)
return;
StartCoroutine (MoveEnemies ());
}
public void AddEnemyToList(Enemy script)
{
enemies.Add (script);
}
IEnumerator MoveEnemies()
{
enemiesMoving = true;
yield return new WaitForSeconds (turnDelay);
if (enemies.Count == 0) {
yield return new WaitForSeconds (turnDelay);
}
for (int i = 0; i < enemies.Count; i++) {
enemies [i].MoveEnemy ();
yield return new WaitForSeconds (enemies [i].moveTime);
}
playersTurn = true;
enemiesMoving = false;
}
}
ADNCG
August 28, 2017, 7:32pm
9
Like @Brathnann suggested, if you get any error messages, help us help you by sharing them.
If you don’t, it can be many things! The value you set in the inspector will have priority over the one declared in your class. Make sure that you haven’t changed the “playerFoodPoints” value in the inspector.
If you haven’t, possibly you could put a Debug.Log (food); right after your “food=GameManager.Instance.playerFoodPoints;” line, in your player code, to make sure that this is indeed where the code is breaking.
1 Like
ADNCG:
Like @Brathnann suggested, if you get any error messages, help us help you by sharing them.
If you don’t, it can be many things! The value you set in the inspector will have priority over the one declared in your class. Make sure that you haven’t changed the “playerFoodPoints” value in the inspector.
If you haven’t, possibly you could put a Debug.Log (food); right after your “food=GameManager.Instance.playerFoodPoints;” line, in your player code, to make sure that this is indeed where the code is breaking.
Both “playerFoodPoints” and “food” are private, I can’t change it from inspector.
I put a Debug.Log(food) right after the execution of that line and it returned 0, the value isn’t passing.
It didn’t returned any error message, the game just started normally, but food stayed with 0.
ADNCG
August 28, 2017, 7:42pm
11
Just asking to make sure, but are you certain playerFoodPoints is private? Because in the script you posted, playerFoodPoints it is public.
Edit : Add Debug.Log (playerFoodPoints); in the awake of your game controller class and see what that returns
1 Like
ADNCG:
Just asking to make sure, but are you certain playerFoodPoints is private? Because in the script you posted, playerFoodPoints it is public.
Edit : Add Debug.Log (playerFoodPoints); in the awake of your game controller class and see what that returns
Sorry, it’s public, but I have a function calling GameManager, so I don’t have any way to change it on the inspector, I guess.
ADNCG
August 28, 2017, 7:54pm
13
How about debug.log’ing the playerFoodPoints in your game controller’s awake?
1 Like
felipedelta0:
Sorry, it’s public, but I have a function calling GameManager, so I don’t have any way to change it on the inspector, I guess.
Your GameManager script isn’t in your scene? That wouldn’t be possible as Awake couldn’t run unless it is in your scene somewhere. Which means you need to see where it is.
1 Like
felipedelta0:
Sorry, it’s public, but I have a function calling GameManager, so I don’t have any way to change it on the inspector, I guess.
The GameManager must be in the scene somewhere, otherwise you’d be getting a null ref error. Check all the objects in your scene and find the one that has the GameManager attached to it, and make sure the playerFoodPoints is set to 100 there.
1 Like
On my scene, in the Main Camera, has a script called Loader, it’s triggered when the game starts and call the function BoardManager to procedurally create the map and the GameManager function.
felipedelta0:
On my scene, in the Main Camera, has a script called Loader, it’s triggered when the game starts and call the function BoardManager to procedurally create the map and the GameManager function.
And just to verify, once this script is added, what value is the playerFoodPoints showing in the inspector? You can still get access to it after it’s added in play mode.
1 Like
Hey everyone, thank you for the help, I’ve found the problem. I have a line on Player code with a function called OnDisable, and as I looked for, that function doesn’t work properly on the unity new version. I changed for a new fuction I don’t record the name cause I’m working now, but anyway, thanks everybody, I’ll post the solution here.