Search Unity

Issues with 2DRoguelike tutorial

Discussion in '2D' started by BlackBat023, Feb 11, 2016.

  1. BlackBat023

    BlackBat023

    Joined:
    Feb 9, 2016
    Posts:
    14
    Hi all. I am very new to game development and C# coding. I do have, however, experience in Python and some other languages. I have followed the 2DRogueLike tutorial up to point 4.2 and upon testing the game I encountered the following 5 errors:

    1.
    NullReferenceException: Object reference not set to an instance of an object
    Player.AttemptMove[Wall] (Int32 xDir, Int32 yDir) (at Assets/Scripts/Player.cs:68)
    Player.Update () (at Assets/Scripts/Player.cs:55)

    2.
    NullReferenceException: Object reference not set to an instance of an object
    Player.OnTriggerEnter2D (UnityEngine.Collider2D other) (at Assets/Scripts/Player.cs:94)

    3.
    NullReferenceException: Object reference not set to an instance of an object
    Wall.DamageWall (Int32 loss) (at Assets/Scripts/Wall.cs:21)
    Player.OnCantMove[Wall] (.Wall Component) (at Assets/Scripts/Player.cs:102)
    MovingObject.AttemptMove[Wall] (Int32 xDir, Int32 yDir) (at Assets/Scripts/MovingObject.cs:66)
    Player.AttemptMove[Wall] (Int32 xDir, Int32 yDir) (at Assets/Scripts/Player.cs:63)
    Player.Update () (at Assets/Scripts/Player.cs:55)

    4.
    NullReferenceException: Object reference not set to an instance of an object
    Player.AttemptMove[Wall] (Int32 xDir, Int32 yDir) (at Assets/Scripts/Player.cs:68)
    Player.Update () (at Assets/Scripts/Player.cs:55)

    5.
    NullReferenceException: Object reference not set to an instance of an object
    Enemy.OnCantMove[Player] (.Player component) (at Assets/Scripts/Enemy.cs:58)
    MovingObject.AttemptMove[Player] (Int32 xDir, Int32 yDir) (at Assets/Scripts/MovingObject.cs:66)
    Enemy.AttemptMove[Player] (Int32 xDir, Int32 yDir) (at Assets/Scripts/Enemy.cs:32)
    Enemy.MoveEnemy () (at Assets/Scripts/Enemy.cs:47)
    GameManager+<MoveEnemies>c__Iterator3.MoveNext () (at Assets/Scripts/GameManager.cs:96)

    What happens when I fire up the game is that the Player moves more than one block sometimes. I also get no movement sounds. Upon colliding with either food or soda the gameObject does not get de-activated and stays active and no eatSound or drinkSound is played. Upon colliding with either enemy1 or enemy2 the player hit animation isn't activated, the enemyAttack1 or enemyAttack2 sound is not played. Also if the food counter reaches 0 the game does not terminate. It simply sends the food count into a - and carry on with the came.

    If anyone could help me out with some solutions I will be very grateful as I have now scrutinized the code with a fine tooth comb and I see no discrepancies between my code and the examples given.

    Thanks,
    BlackBat
     
  2. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Would you mind posting your code here? If so, use the ["code] your code here ["/code] tags, without quotes.
     
  3. BlackBat023

    BlackBat023

    Joined:
    Feb 9, 2016
    Posts:
    14
    The errors refer to following code:

    The player code:
    Code (csharp):
    1.  
    2.         if (Move (xDir, yDir, out hit))
    3.         {
    4.             SoundManager.instance.RandomizeSfx (moveSound1, moveSound2);
    5.         }
    6.  
    The wall code:
    Code (csharp):
    1.  
    2.     public void DamageWall (int loss)
    3.     {
    4.         SoundManager.instance.RandomizeSfx(chopSound1, chopSound2);
    5.         spriteRenderer.sprite = dmgSprite;
    6.         hp -= loss;
    7.         if (hp <= 0)
    8.             gameObject.SetActive (false);
    9.     }
    10.  
    The food & soda code:
    Code (csharp):
    1.  
    2.     private void OnTriggerEnter2D (Collider2D other)
    3.     {
    4.         if(other.tag == "Exit")
    5.         {
    6.             Invoke ("Restart", restartLevelDelay);
    7.             enabled = false;
    8.         }
    9.         else if (other.tag == "Food")
    10.         {
    11.             food += pointsPerFood;
    12.             foodText.text = "+" + pointsPerFood + " Food: " + food;
    13.             SoundManager.instance.RandomizeSfx (eatSound1, eatSound2);
    14.             other.gameObject.SetActive(false);
    15.         }
    16.         else if (other.tag == "Soda")
    17.         {
    18.             food += pointsPerSoda;
    19.             foodText.text = "+" + pointsPerSoda + " Food: " + food;
    20.             SoundManager.instance.RandomizeSfx (drinkSound1, drinkSound2);
    21.             other.gameObject.SetActive(false);
    22.         }
    23.     }
    24.  
    The enemy code:
    Code (csharp):
    1.  
    2.     protected override void OnCantMove <T> (T component)
    3.     {
    4.         Player hitPlayer = component as Player;
    5.  
    6.         hitPlayer.LoseFood (playerDamage);
    7.  
    8.         animator.SetTrigger ("enemyAttack");
    9.  
    10.         SoundManager.instance.RandomizeSfx (enemyAttack1, enemyAttack2);
    11.  
    12.     }
    13.  
    hope you can help me out ...

    Thanks,
    BlackBat
     
  4. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Before I try to speculate on what's happening, I will mention that you have a SoundManager being referenced in every snippet you have there.

    Are you certain that SoundManager.instance is not null? Make sure you have a SoundManager instance in your scene.
     
  5. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I think that's a good possibility. Your project is basically composed of two parts: the code, and the scene. If there's no problem with the code, then the problem is probably in the scene.

    Also, the fact that you've gotten to the "end" of your project and now have a long list of problems suggests you're going about it the wrong way. Don't write (or follow a tutorial to write) a whole bunch of code and test it all at once. Instead, write a little, then test a little. Make sure the bit you just wrote works as it should. Then write a little more, and test again. Repeat this write-a-little, test-a-little cycle many many times each day. You should have a project that is always in a correct working state, except possibly for the one little bit you're currently working on.
     
    jtsmith1287 and LiterallyJeff like this.
  6. BlackBat023

    BlackBat023

    Joined:
    Feb 9, 2016
    Posts:
    14
    I do have the SoundManager attached to the Hierarchy with 2 Audio sources attached to it... one for Music and one for the Sfx. Funny thing is the music source is the only one actually working. Joe: I did test each piece of section as I finished it and kept testing it until all the bugs were sorted out. These last bugs are the only ones that are stumping me... and it only occurred once I wrote in the sfx code. Testing the game with only the music worked perfectly beginning to end. Jeff: I do assign the SoundManager to null as a variable in the SoundManager file :
    Code (csharp):
    1.  public static SoundManager instance = null;
     
  7. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Make sure that the instance isn't null when you're calling SoundManager.instance.RandomizeSfx, and make sure that the sound clips you're passing in aren't null also.
     
  8. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Yep, that public SoundManager instance is almost certainly null. Can you post the SoundManager code, or at least the part of that that should be setting instance to something other than null (probably the Awake method)?
     
  9. BlackBat023

    BlackBat023

    Joined:
    Feb 9, 2016
    Posts:
    14
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class SoundManager : MonoBehaviour
    6. {
    7.     public AudioSource efxSource;
    8.     public AudioSource musicSource;
    9.     public static SoundManager instance = null;
    10.     public float lowPitchRange = .95f;
    11.     public float highPitchRange = 1.05f;
    12.  
    13.  
    14.     // Use this for initialization
    15.     void Awake ()
    16.     {
    17.         if (instance == null)
    18.             instance = this;
    19.         else if (instance != this)
    20.             Destroy (gameObject);
    21.  
    22.         DontDestroyOnLoad (gameObject);
    23.     }
    24.  
    25.     public void PlaySingle (AudioClip clip)
    26.     {
    27.         efxSource.clip = clip;
    28.         efxSource.Play ();
    29.     }
    30.  
    31.     public void RandomizeSfx (params AudioClip[] clips)
    32.     {
    33.         int randomIndex = Random.Range (0, clips.Length);
    34.         float randomPitch = Random.Range (lowPitchRange, highPitchRange);
    35.  
    36.         efxSource.pitch = randomPitch;
    37.         efxSource.clip = clips [randomIndex];
    38.         efxSource.Play ();
    39.     }
    40.    
    41.    
    42. }
    43.  
     
  10. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Well, that certainly looks reasonable... and yet you're getting null reference exceptions. So something's wrong. I still suspect you don't actually have SoundManager attached to a script in your scene. Or, somehow it's getting destroyed later.

    Let's add some debug logs to see what's going on. At the bottom of the SoundManager.Awake function, let's add:
    Code (CSharp):
    1. Debug.Log("SoundManager.instance initialized to " + instance, instance);
    And then, wherever you are getting your first null reference exception, right before the line where it occurs, add one of these:
    Code (CSharp):
    1. Debug.Log("About to use SoundManager.instance, which is " + SoundManager.instance, SoundManager.instance);
    Note that the second parameter to Debug.Log specifies a context object which, when you select that log line in the Console, will be selected in the Hierarchy so you can inspect it yourself.

    This should provide more insight into what's going on.
     
  11. BlackBat023

    BlackBat023

    Joined:
    Feb 9, 2016
    Posts:
    14
    This is the result:
    About to use SoundManager.instance, which is
    UnityEngine.Debug:Log(Object, Object)
    Player:AttemptMove(Int32, Int32) (at Assets/Scripts/Player.cs:68)
    Player:Update() (at Assets/Scripts/Player.cs:55)

    and:
    NullReferenceException: Object reference not set to an instance of an object
    Player.AttemptMove[Wall] (Int32 xDir, Int32 yDir) (at Assets/Scripts/Player.cs:69)
    Player.Update () (at Assets/Scripts/Player.cs:55)
     
  12. BlackBat023

    BlackBat023

    Joined:
    Feb 9, 2016
    Posts:
    14
    This is the full section of code attached to that:

    Code (csharp):
    1.  
    2.     protected override void AttemptMove <T> (int xDir, int yDir)
    3.     {
    4.         food--;
    5.         foodText.text = "Food: " + food;
    6.  
    7.         base.AttemptMove <T> (xDir, yDir);
    8.  
    9.         RaycastHit2D hit;
    10.         if (Move (xDir, yDir, out hit))
    11.         {
    12.             Debug.Log("About to use SoundManager.instance, which is " + SoundManager.instance, SoundManager.instance);
    13.             SoundManager.instance.RandomizeSfx (moveSound1, moveSound2);
    14.         }
    15.  
    16.         CheckIfGameOver ();
    17.  
    18.         GameManager.instance.playersTurn = false;
    19.     }
    20.  
     
  13. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Yep, so, as I suspected — the SoundManager instance is never being set. I think you need to double-check where you have that (SoundManager) script attached to an object in the scene.
     
  14. BlackBat023

    BlackBat023

    Joined:
    Feb 9, 2016
    Posts:
    14
    I have the "SoundManager" script attached to the "SoundManager" Object in the Hierarchy.
     
  15. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    So you say... but the debug logs prove that its Awake method is never firing, right? So, something there is not what you think it is. Maybe you have an empty SoundManger script that is actually attached instead. Maybe the object is inactive. Maybe the script is disabled. I can only guess, but that's where you should be focusing your attention.
     
  16. BlackBat023

    BlackBat023

    Joined:
    Feb 9, 2016
    Posts:
    14
    Ok I deleted the Whole SoundManager from the Hierarchy and set it up again from scratch. Presto it's working... Thank you so much Joe and Jeff, you guys have helped me a lot... I can only guess that I had the wrong script attached somehow without realizing it. But thanks a lot guys you've also taught me a lot about debugging here. I really do appreciate it! ;):D
     
    JoeStrout likes this.
  17. Deleted User

    Deleted User

    Guest

    For whom who have yet this trouble. The issues was with namespace Completed. You had copied script SoundManager from Completed project and it was with namespace Completed. You must delete it.