1. All Unity Pro perpetual license customers: your special offer to subscribe is ready! Click here.
  2. We're running a survey about the usage of our graphics pipeline, help give us your feedback.
  3. Unity 5.6 beta is now available for download.
  4. Unity 5.5 is now released.
  5. Check out all the fixes for 5.5 in patch releases 1 & 2.
  6. Enter the Google Play Indie Games Contest in Europe. Read more about it here.
  7. Get prepared for the Tizen Mobile App Incentive Program! Read more about the upcoming program here.
  8. Enter the Microsoft Developer Challenge for a chance to win prizes. Read more about it here.

2D Roguelike: Q&A

Discussion in 'Community Learning & Teaching' started by Matthew-Schell, Feb 10, 2015.

  1. 8_Stackz

    8_Stackz

    Joined:
    Oct 26, 2015
    Messages:
    1
    -----------------------------------------------------------
    Hey there

    I too had this problem, but I solved it using the following :)

    GameManager:
    Code (csharp):
    1.  
    2.     void Awake () {
    3.         if (instance == null) {
    4.             instance = this;
    5.         } else if (instance != this) {
    6.             Destroy (gameObject);
    7.         }
    8.  
    9.          //For persistance between scenes
    10.          DontDestroyOnLoad (gameObject);
    11.  
    12.          enemies = newList <Enemy> ();
    13.          boardScript = GetComponent <BoardManager> ();
    14.          InitGame ();
    15.     }
    16.  
    17.      private void OnLevelFinishedLoading (Scene scene, LoadSceneMode mode) {
    18.          if (level > 1) {
    19.              InitGame ();
    20.          }
    21.          level++;
    22.      }
    23.  
    24.      private void OnEnable () {
    25.          SceneManager.sceneLoaded += OnLevelFinishedLoading;
    26.      }
    27.  
    28.      privatevoidOnDisable(){
    29.          SceneManager.sceneLoaded-=OnLevelFinishedLoading;
    30.      }
    31.  
    Just add to the level count after the initGame call in OnLevelFinishedLoading, and only call initGame after the first time it has been loaded.
    Hope this helps :)
     
    Matthew-Schell likes this.
  2. AnneSchmidt

    AnneSchmidt

    Joined:
    Aug 8, 2016
    Messages:
    309
    I haven't finished this tutorial yet so, no, no idea. You should take a look at other tutorials having this restart button and see how you can adapt their solution to this project.
     
  3. DatGuyPotato

    DatGuyPotato

    Joined:
    Jul 14, 2016
    Messages:
    8
  4. rmiles55

    rmiles55

    Joined:
    Sep 11, 2016
    Messages:
    1
    Does anyone know of a simple explosion animation I can add to the enemies? I have added code for player weapons, and I destroy the enemies, but it is pretty boring just watching them disappear.
     
  5. CamoClayton

    CamoClayton

    Joined:
    Nov 29, 2016
    Messages:
    3
    I am having an issue. My character just sits at the starting point shaking and I cannot move him at all. I have checked the transform which is 0,0,0 and I have also commented out the "GameManager.instance.playersTurn=false;" but still no joy.
    I keep getting a "NullReferenceException Object reference not set to an instance of an object" Message highlighting "boxCollider.enabled = false; ".

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4.  
    5.    
    6. public abstract class MovingObject : MonoBehaviour
    7. {
    8.     //how fast the objects move
    9.     public float moveTime = 0.1f;
    10.     public LayerMask blockingLayer;
    11.  
    12.     //sets rigidbody and collider also makes calculations run smoother
    13.     private BoxCollider2D boxCollider;
    14.     private Rigidbody2D rb2D;
    15.     private float inverseMoveTime;
    16.  
    17.     // modified start so that they can be overridden by other classes
    18.     protected virtual void Start ()
    19.     {
    20.         boxCollider = GetComponent <BoxCollider2D> ();
    21.         rb2D = GetComponent <Rigidbody2D> ();
    22.         inverseMoveTime = 1f / moveTime; //division is more effecient.
    23.     }
    24.     protected bool Move (int xDir, int yDir, out RaycastHit2D hit)
    25.     {
    26.         Vector2 start = transform.position;             //Store start position to move from
    27.         Vector2 end = start + new Vector2 (xDir, yDir); //calculate end position
    28.  
    29.         boxCollider.enabled = false;                    //disables the boxcollider so that linecast doesnt hit itself
    30.  
    31.         hit = Physics2D.Linecast (start, end, blockingLayer);
    32.  
    33.         boxCollider.enabled = true;                     //turns boxcollider back on
    34.  
    35.         if(hit.transform == null)
    36.         {
    37.                 StartCoroutine (SmoothMovement (end));
    38.                 return true; //move was successful
    39.             }
    40.  
    41.                 return false; //if something was hit, move unsuccessful.
    42.     }
    43.  
    44.     protected IEnumerator SmoothMovement (Vector3 end)
    45.     {
    46.         float sqrRemainingDistance = (transform.position - end).sqrMagnitude;
    47.  
    48.         while (sqrRemainingDistance > float.Epsilon)
    49.         {
    50.             Vector3 newPosition = Vector3.MoveTowards(rb2D.position, end, inverseMoveTime * Time.deltaTime);
    51.             rb2D.MovePosition (newPosition);
    52.             sqrRemainingDistance = (transform.position - end).sqrMagnitude;
    53.             yield return null;
    54.         }
    55.     }
    56.             protected virtual void AttemptMove <T> (int xDir, int yDir)
    57.             where T : Component
    58.             {
    59.                 RaycastHit2D hit;
    60.                 bool canMove = Move (xDir, yDir, out hit);
    61.  
    62.                 if (hit.transform == null)
    63.                     return;
    64.  
    65.             //if something is hit
    66.                 T hitComponent = hit.transform.GetComponent <T> ();
    67.                    
    68.                 if(!canMove && hitComponent != null)
    69.                     OnCantMove(hitComponent);
    70.             }
    71.  
    72.     //protected abstract function that will be overidden by inherent classes.
    73.     protected abstract void OnCantMove <T> (T component)
    74.         where T : Component;
    75.  
    76.         }
    77.  



    Any help would be appreciated and its rather urgent as I chose to do this tutorial for an assignment. Doh!!
     

    Attached Files:

  6. leomuteki

    leomuteki

    Joined:
    Dec 14, 2016
    Messages:
    2
    Hello everybody!

    In the GameManager script, in the singleton algorithm, we use Destroy(gameObject). Can we substitute the gameObject function for "this". It seems to be more descriptive for readability purposes. If so, why is gameObject used instead of this?

    Thank you!!!
     
  7. EthanLac

    EthanLac

    Joined:
    Dec 17, 2016
    Messages:
    1
    Hi everyone, I seem to be having some trouble with my scripts. In the script for destroying walls (Imaginatively called DestroyWall), VisualStudio complains that "instance" is not accepted as a word, despite it working fine in the tutorial. Could someone please help me with this?

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. namespace Completed
    5. {
    6.     using System.Collections.Generic;
    7.  
    8.     public class DestroyWall : MonoBehaviour
    9.     {
    10.         public AudioClip chopSound1;                //1 of 2 audio clips that play when the wall is attacked by the player.
    11.         public AudioClip chopSound2;                //2 of 2 audio clips that play when the wall is attacked by the player.
    12.         public Sprite dmgSprite;                    //Alternate sprite to display after Wall has been attacked by player.
    13.         public int hp = 3;                          //hit points for the wall.
    14.         public GameObject soundManager;
    15.  
    16.  
    17.         private SpriteRenderer spriteRenderer;      //Store a component reference to the attached SpriteRenderer.
    18.  
    19.  
    20.         void Awake()
    21.         {
    22.             //Get a component reference to the SpriteRenderer.
    23.             spriteRenderer = GetComponent<SpriteRenderer>();
    24.         }
    25.  
    26.  
    27.         //DamageWall is called when the player attacks a wall.
    28.         public void DamageWall(int loss)
    29.         {
    30.             //Call the RandomizeSfx function of SoundManager to play one of two chop sounds.
    31.             soundManager.instance.RandomizeSfx(chopSound1, chopSound2);
    32.  
    33.             //Set spriteRenderer to the damaged wall sprite.
    34.             spriteRenderer.sprite = dmgSprite;
    35.  
    36.             //Subtract loss from hit point total.
    37.             hp -= loss;
    38.  
    39.             //If hit points are less than or equal to zero:
    40.             if (hp <= 0)
    41.                 //Disable the gameObject.
    42.                 gameObject.SetActive(false);
    43.         }
    44.     }
    45. }
    Thanks in advance.
     
  8. TheProfessor

    TheProfessor

    Joined:
    Nov 2, 2014
    Messages:
    46
    So in the Enemy and Player scripts I get an error about the GameManager not having certain member variables/functions existing; I don't see where in the Tutorial videos when/where you go and adjust GameManager to match the one in the Completed folder; when does this occur? It's driving me nuts.
     
  9. TheProfessor

    TheProfessor

    Joined:
    Nov 2, 2014
    Messages:
    46
    I found it, so scratch my above post; but now I have a problem: the "Singleton" code doesn't seem to actually work.

    InitGame() is still called in the destroyed instance before it is destroyed, resulting in duplicate assets.

    Additionally ending Day 2 seems to skip to Day 4, and I have zero food.

    Edit: I fixed it by putting enemies = new..., boardScript =... and InitGame() into an else branch so it's skipped if instance != this.


    I also had to put it into "if instance == null)" branch.

    Another problem I had is that when I hit play, even though my GameManager was the only one in my scene and I had not at all loaded the Completed scene, it insisted on attempting to use the Complete.GameManager and I got a null reference exception on loading levels. I figure this is causing my issues.
     
  10. bardan

    bardan

    Joined:
    Sep 12, 2016
    Messages:
    6
    bro, would you mind sharing your codes..
     
  11. TheProfessor

    TheProfessor

    Joined:
    Nov 2, 2014
    Messages:
    46
    Why? I think I was pretty clear I figured it out, it was in Enemy Animator Controller for some strange arbitrary reason.

    The line: "food = GameManager.instance.playerFoodPoints;" doesn't work in the video they originally type it, because GameManager literally doesn't have a public "playerFoodPoints" member variable at the time in the video.
     
  12. doomvad

    doomvad

    Joined:
    Dec 18, 2016
    Messages:
    2
    Hi everyone here!
    I have an issue, I can't hit walls. I was trying to find the reason using debugger and I found out that the problem of my case was an impossibility to get wall component. In MovingObject script we have a clause:

    T hitComponent = hit.transform.GetComponent<T>();

    So if I collide with wall parameter hitComponent is always NULL and then I can’t pass if-clause to invoke OnCantMove function. But with the enemy collisions parameter hitComponent has {Player} value and everything is clear and works correctly. I have no idea what the problem with the walls. What did I made wrong? (my unity version is 5.5 Personal)
     
  13. TheProfessor

    TheProfessor

    Joined:
    Nov 2, 2014
    Messages:
    46
    Do the Walls have a Wall script attached at the root?
     
  14. doomvad

    doomvad

    Joined:
    Dec 18, 2016
    Messages:
    2
    Yes, it does.
     
  15. nekrophile

    nekrophile

    Joined:
    May 12, 2016
    Messages:
    1
    With SoundManager.cs, the pitch randomization seems to be defined globally for all sounds using RandomizeSfx.

    Can you give me some pointers if I wanted to specify a different range of pitch randomization (i.e. 0.75,1.25) for certain sounds (i.e. scavengers_footstep)?

    Similarly, when using RandomizeSfx what would be the best practice for adjusting the volume of an individual audioclip?
     
  16. Skyyofficial7

    Skyyofficial7

    Joined:
    Jun 18, 2014
    Messages:
    1
    Is there a way to remove the short delays between moves? so that its still in turns but when you keep running in one direction you dont stop after every step.
    would be great if someone knows how to do this
     
  17. TheProfessor

    TheProfessor

    Joined:
    Nov 2, 2014
    Messages:
    46
    Did you try setting timeDelay to 0? =/
     
  18. TheProfessor

    TheProfessor

    Joined:
    Nov 2, 2014
    Messages:
    46
    So some thoughts:

    1. Why is it that the completed scripts uploaded online are in the "Completed" namespace? With bad line endings in some cases to boot. This is a minor issue but I think a lot of people who are new to C# aren't going to realize this causes issues to have two scripts sharing a namespace and won't know how to fix it.

    2. Early videos introduce code that isn't implemented until several videos later; essentially rendering the tutorial out of order and in many cases introduces annoying syntax errors regarding undefined functions. If the SoundManager and completed GameManager classes are only going to be shown later; couldn't the early tutorials found a better way to reference them? Again it's going to causes unnecessary issues with people new to C#.

    3. I haven't found any consistent behaviors with dragging selected sprites onto a GameObject to create an animation clip. It seems to create an animation in the same folder as the Sprite Sheet with the Sprite Sheet's name most of the time, and only prompts for save location and file name a minority of the time.

    The most consistent instruction should have been to create an animation controller for the sprite in question; add it to a game object, select the game object, go to the animation window and create a new clip and choose where to save it with a file name.

    4. There is *something* off about the GameManager instance implementation that isn't working correctly in some instances. It appears to result in duplicate tilesets created each time a scene is loaded;

    5. And sometimes it will try to use the GameManager class from the Complete folder instead of the GameManager that is actually on the game object in the scene in question regardless of it's namespace.
     
  19. jannaisop

    jannaisop

    Joined:
    Dec 26, 2016
    Messages:
    2
    Finished the tutorial but a couple of questions

    How might I go about changing the touch screen controls from swiping to tapping in a direction instead?

    And how can I fix the player getting stuck inside an enemy or the enemies getting stuck inside each other?

    Thanks!
     
    Last edited: Dec 26, 2016
  20. LeonardoCoV

    LeonardoCoV

    Joined:
    Dec 28, 2016
    Messages:
    2
    first one of best tutorials

    Hi I have a trouble it's posted but I don't know mine have another thing and I pass the las two day's trying to solve but nothing... it's again I can move my player one time and no more and another stranger thing the player move on diagnal I don't now... my code is equals the compled i show here moving, game manager and player scripts if need some another please say and I'll post thx for all

    [Edited]
    Oh yeah I missing to tell don't have warnings or errors nor VStudio or monodev

    MovingObject.cs

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public abstract class MovingObject : MonoBehaviour
    6. {
    7.  
    8.     public float moveTime = 0.1f;
    9.     public LayerMask blockingLayer;//check collision
    10.  
    11.     private BoxCollider2D boxCollider;
    12.     private Rigidbody2D rb2D;
    13.     private float inverseMoveTime;
    14.  
    15.     // Use this for initialization
    16.     protected virtual void Start ()
    17.     {
    18.         boxCollider = GetComponent<BoxCollider2D>();
    19.         rb2D = GetComponent<Rigidbody2D>();
    20.         inverseMoveTime = 1.0f / moveTime;  
    21.     }
    22.  
    23.     protected bool Move (int xDir, int yDir, out RaycastHit2D hit)
    24.     {
    25.         Vector2 start = transform.position;
    26.         Vector2 end = start + new Vector2(xDir, xDir);
    27.  
    28.         boxCollider.enabled = false;
    29.         hit = Physics2D.Linecast(start, end, blockingLayer);
    30.         boxCollider.enabled = true;
    31.  
    32.         if (hit.transform == null)
    33.         {
    34.             StartCoroutine(SmoothMoviment(end));
    35.             return true;
    36.         }
    37.  
    38.         return false;
    39.     }
    40.  
    41.     protected IEnumerator SmoothMoviment (Vector3 end)
    42.     {
    43.         float sqrRemainingDistance = (transform.position - end).sqrMagnitude;
    44.  
    45.         while(sqrRemainingDistance > float.Epsilon)
    46.         {
    47.             Vector3 newPosition = Vector3.MoveTowards(rb2D.position, end, inverseMoveTime * Time.deltaTime);
    48.             rb2D.MovePosition(newPosition);
    49.             sqrRemainingDistance = (transform.position - end).sqrMagnitude;
    50.             yield return null;
    51.         }
    52.     }
    53.  
    54.     protected virtual void AttemptMove <T> (int xDir, int yDir)
    55.         where T : Component
    56.     {
    57.         RaycastHit2D hit;
    58.         bool canMove = Move(xDir, yDir, out hit);
    59.  
    60.         if (hit.transform == null)
    61.             return;
    62.  
    63.         T hitComponent = hit.transform.GetComponent<T>();
    64.  
    65.         if (!canMove && hitComponent != null)
    66.             OnCantMove(hitComponent);
    67.     }
    68.  
    69.     protected abstract void OnCantMove<T>(T component)
    70.         where T : Component;
    71. }
    Player.cs


    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.SceneManagement;
    6. using UnityEngine.UI;
    7.  
    8. public class Player : MovingObject
    9. {
    10.     public int wallDamage = 1;
    11.     public int pointsPerFood = 10;
    12.     public int pointsPerSoda = 20;
    13.     public float restartLevelDelay = 1.0f;
    14.     public Text foodText;
    15.     public AudioClip moveSound1;
    16.     public AudioClip moveSound2;
    17.     public AudioClip eatSound1;
    18.     public AudioClip eatSound2;
    19.     public AudioClip drinkSound1;
    20.     public AudioClip drinkSound2;
    21.     public AudioClip gameOverSound;
    22.  
    23.  
    24.     private Animator animator;
    25.     private int food;
    26.     private Vector2 touchOrigin = -Vector2.one;
    27.  
    28.     // Use this for initialization
    29.     protected override void Start ()
    30.     {
    31.         animator = GetComponent<Animator>();
    32.         food = GameManager.instance.playerFoodPoints;
    33.         foodText.text = "Food:" + food;
    34.         base.Start();
    35.     }
    36.  
    37.     private void OnDisable()
    38.     {
    39.         GameManager.instance.playerFoodPoints = food;
    40.     }
    41.  
    42.     // Update is called once per frame
    43.     void Update ()
    44.     {
    45.         if (!GameManager.instance.playersTurn) return;
    46.  
    47.         int horizontal = 0;
    48.         int vertical = 0;
    49.  
    50. #if UNITY_EDITOR || UNITY_STANDALONE || UNITY_WEBPLYER
    51.  
    52.         horizontal = (int)(Input.GetAxisRaw("Horizontal"));
    53.         vertical = (int)(Input.GetAxisRaw("Vertical"));
    54.  
    55.         if (horizontal != 0)
    56.             vertical = 0;
    57.  
    58. #else
    59.         if(Input.touchCount > 0)
    60.         {
    61.             Touch myTouch = Input.touches[0];
    62.  
    63.             if(myTouch.phase == TouchPhase.Began)
    64.             {
    65.                 touchOrigin = myTouch.position;
    66.             }
    67.  
    68.             else if(myTouch.phase == TouchPhase.Ended && touchOrigin.x >=0)
    69.             {
    70.                 Vector2 touchEnd = myTouch.position;
    71.                 float x = touchEnd.x - touchOrigin.x;
    72.                 float y = touchEnd.y - touchOrigin.y;
    73.                 touchOrigin.x = -1;
    74.  
    75.                 if (Mathf.Abs(x) > Mathf.Abs(y))
    76.                     horizontal = x > 0 ? 1 : -1;
    77.                 else
    78.                     vertical = y > 0 ? 1 : -1;
    79.             }
    80.         }
    81.  
    82. #endif
    83.  
    84.         if (horizontal != 0 || vertical != 0)
    85.             AttemptMove<Wall>(horizontal, vertical);
    86.     }
    87.  
    88.     protected override void AttemptMove<T>(int xDir, int yDir)
    89.     {
    90.         food--;
    91.         foodText.text = "Food:" + food;
    92.  
    93.         base.AttemptMove<T>(xDir, yDir);
    94.  
    95.         RaycastHit2D hit;
    96.  
    97.         if(Move(xDir, yDir, out hit))
    98.         {
    99.             SoundManager.instance.RandomizeSfx(moveSound1, moveSound2);
    100.         }
    101.  
    102.         CheckIfGameOver();
    103.  
    104.         GameManager.instance.playersTurn = false;
    105.     }
    106.  
    107.     private void OnTriggerEnter2D(Collider2D other)
    108.     {
    109.         if (other.tag == "Exit")
    110.         {
    111.             Invoke("Restat", restartLevelDelay);
    112.             enabled = false;
    113.         }
    114.  
    115.         else if(other.tag == "Food")
    116.         {
    117.             food += pointsPerFood;
    118.             foodText.text = "+ " + pointsPerFood + " Food " + food;
    119.             SoundManager.instance.RandomizeSfx(eatSound1, eatSound2);
    120.             other.gameObject.SetActive(false);
    121.         }
    122.         else if(other.tag == "Soda")
    123.         {
    124.             food += pointsPerSoda;
    125.             foodText.text = "+ " + pointsPerSoda + " Food " + food;
    126.             SoundManager.instance.RandomizeSfx(drinkSound1, drinkSound2);
    127.             other.gameObject.SetActive(false);
    128.         }
    129.     }
    130.  
    131.     protected override void OnCantMove<T>(T component)
    132.     {
    133.         Wall hitWall = component as Wall;
    134.         hitWall.DamageWall(wallDamage);
    135.         animator.SetTrigger("PlayerChop");
    136.     }
    137.  
    138.     private void Restart()
    139.     {
    140.         SceneManager.LoadScene(0);
    141.     }
    142.  
    143.     public void LoseFood(int loss)
    144.     {
    145.         animator.SetTrigger("PlayerHit");
    146.         food -= loss;
    147.         foodText.text = "-" + loss + "Food: " + food;
    148.         CheckIfGameOver();
    149.     }
    150.  
    151.     private void CheckIfGameOver()
    152.     {
    153.         if (food <= 0)
    154.         {
    155.             SoundManager.instance.PlaySingle(gameOverSound);
    156.             SoundManager.instance.musicSource.Stop();
    157.             GameManager.instance.GameOver();
    158.         }
    159.     }
    160. }
    161.  
    GameManager.cs
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5. using UnityEngine.UI;
    6.  
    7. public class GameManager : MonoBehaviour
    8. {
    9.     public float levelStartDelay = 2.0f;
    10.     public float turnDelay = .1f;
    11.     public static GameManager instance = null;//to can be acessed by others scripts on game
    12.     public BoardManager boardScript;
    13.     public int playerFoodPoints = 100;
    14.     [HideInInspector]
    15.     public bool playersTurn = true;
    16.  
    17.     private Text levelText;
    18.     private GameObject levelImage;
    19.     private int level = 1;
    20.     private List<Enemy> enemies;
    21.     private bool enemiesMoving;
    22.     private bool doingSetup;
    23.  
    24.  
    25.  
    26.     //This is called each time a scene is loaded.
    27.     void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode)
    28.     {
    29.         //add one to our lvl number
    30.         level++;
    31.         //call Initgma to initialize our level.
    32.         InitGame();
    33.     }
    34.  
    35.     /*private void OnEnable()
    36.     {
    37.         SceneManager.sceneLoaded += OnLevelFinishedLoading;
    38.     }
    39.  
    40.     private void OnDisable()
    41.     {
    42.         SceneManager.sceneLoaded -= OnLevelFinishedLoading;
    43.     }*/
    44.  
    45.     void Awake()
    46.     {
    47.         if (instance == null)
    48.             instance = this;//we play here
    49.         else if (instance != this)
    50.             Destroy(gameObject);//destroy the map(or instance) duplicated
    51.  
    52.         DontDestroyOnLoad(gameObject);
    53.         enemies = new List<Enemy>();  
    54.         boardScript = GetComponent<BoardManager>();
    55.         InitGame();
    56.     }
    57.  
    58.     void InitGame()
    59.     {
    60.         doingSetup = true;
    61.         levelImage = GameObject.Find("LevelImage");
    62.         levelText = GameObject.Find("LevelText").GetComponent<Text>();
    63.         levelText.text = "Day" + level;
    64.         levelImage.SetActive(true);
    65.         Invoke("HideLevelImage", levelStartDelay);
    66.         enemies.Clear();//reset enemies to next lvl
    67.         boardScript.SetupLevel(level);
    68.     }
    69.  
    70.     private void HideLevelImage()
    71.     {
    72.         levelImage.SetActive(false);
    73.         doingSetup = false;
    74.     }
    75.  
    76.     public void GameOver()
    77.     {
    78.         levelText.text = "After " + level + " days, you starved";
    79.         levelImage.SetActive(true);
    80.         enabled = false;
    81.     }
    82.  
    83.     // Update is called once per frame
    84.     void Update()
    85.     {
    86.             if (playersTurn || enemiesMoving || doingSetup)
    87.             return;
    88.  
    89.         StartCoroutine(MoveEnemies());
    90.     }
    91.  
    92.     public void AddEnemyToList(Enemy script)
    93.     {
    94.         enemies.Add(script);
    95.     }
    96.  
    97.     IEnumerator MoveEnemies()
    98.     {
    99.         enemiesMoving = true;
    100.         yield return new WaitForSeconds(turnDelay);
    101.  
    102.         if(enemies.Count == 0)
    103.         {
    104.             yield return new WaitForSeconds(turnDelay);
    105.         }
    106.  
    107.         for(int i = 0; i < enemies.Count; i++)
    108.         {
    109.             enemies[i].MoveEnemy();
    110.             yield return new WaitForSeconds(enemies[i].moveTime);
    111.         }
    112.  
    113.         playersTurn = true;
    114.         enemiesMoving = false;
    115.     }
    116. }
    117.  
    plaese help me thx.
     
    Last edited: Dec 29, 2016
  21. LeonardoCoV

    LeonardoCoV

    Joined:
    Dec 28, 2016
    Messages:
    2
    oooo I FOUND! is the rigid body 2d not seted to kinematic y.y and on wrong walk on second line of function move on MovingObjects I pass wrong the reference like this xD
    Code (CSharp):
    1. Vector2 end = start + new Vector2(xDir, xDir);//is solved yet
    and I found (and fixed) anothers two errors, and I see is have some people have this problem too and I hope it's can be helpfull well the problem... when begin the game is like all good except for the first day is 2 and I can walk arround on sickness and eat fruits and drinking bad health things to cure to try survivor, when I reach exit and go next day the day is 3 or 4 and when you do the first move you die instant, it's simple the board is created two time and you can see on Hierarchy painel, if you delete the second your game bug and if you delete the first your game runs ok but the day count 4 6 8 ... or 3 5 7 9 ... to solve this is simple, on GameManager.cs the function InitGame() is called two times it's because the function OnLevelFinishedLoading(Scene, LoadSceneMode) and Awake() is used initialized game duplicate the board on same scene and put the player on the second map "Day 2" what can do is simple have two options
    1 alterntive- take off the call of InitGame() function from awake because is used 1 time when the game begin the game call GameManager script and no more, with this the gama initilize the "Day 1" with OnLevelFinishedLoading() and all take normal again when you pass to next day and all other this same function will be called calling InitGame in the end (I make this to not change the code so much consuming more process and more 1 memory slot with a count)
    2 alterntive- you can make a other function or put it on awake calling the kernel it's the first time we are run game (it's a new game) well we don't need this function running now, but make rigth your function will be needed on all others next time
     
    Last edited: Dec 29, 2016
  22. dacoursey

    dacoursey

    Joined:
    Dec 17, 2016
    Messages:
    2
    I'm trying to do part 5 of the tutorial where the last steps are to add the Loader script to the Main Camera, and then add the GameManager prefab to the Loader script.

    Why don't I have the option like in the video to drag anything into the GameManager field? I'm working in 5.5.0f3

    Thanks
     

    Attached Files:

  23. XerxesIhen

    XerxesIhen

    Joined:
    Jan 4, 2017
    Messages:
    1
    Question01.jpg I have done all the Part 4 tutorial about coding Board Manager, but I can't spawn Floor correctly.
    Please help me!



    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System;
    4. //可用Serializable的功能在Unity裡面的Inspector面板裡面修改變數
    5. using System.Collections.Generic;
    6. //可用List功能
    7. using Random = UnityEngine.Random;
    8. //class Random的功能呼叫
    9.  
    10. public class BoardManager : MonoBehaviour {
    11.  
    12.     [Serializable]
    13.     //利用Serializable功能來讀取及時變數並可在Inspector面板裡面修改參數
    14.     public class Count
    15.     //此為可修改之參數功能Count
    16.     {
    17.         public int Minimum;
    18.         public int Maximun;
    19.  
    20.         public Count(int min, int max)
    21.         //此為即時傳送以及修改參數的功能
    22.         {
    23.             Minimum = min;
    24.             Maximun = max;
    25.         }
    26.     }
    27.     public int colums = 8;
    28.     public int rows = 8;
    29.     //上兩句程式為決定遊戲版面大小的參數
    30.     public Count wallCount = new Count(5, 9);
    31.     //此為決定牆壁生產值最小為5,最大為9
    32.     public Count foodCount = new Count(1, 5);
    33.     //此為決定Food生產數量
    34.     public GameObject Exit;
    35.     //此為決定Exit物品的拖放處
    36.     public GameObject[] WallTiles;
    37.     //此為決定Wall物品陣列的拖放處
    38.     public GameObject[] FloorTiles;
    39.     //此為決定Floor物陣列品的拖放處
    40.     public GameObject[] FoodTiles;
    41.     //此為決定Food物品陣列的拖放處
    42.     public GameObject[] EnemyTiles;
    43.     //此為決定Enemy物品陣列的拖放處
    44.     public GameObject[] OuterWallTiles;
    45.     //此為決定OuterWallTiles物品陣列的拖放處
    46.  
    47.     private Transform BoardHolder;
    48.     //將所有生產出的Objects全部歸類為BoardHolder
    49.     private List<Vector3> GridPosition = new List<Vector3>();
    50.     //產生一個List來追蹤所有隨機生產的Objects是否有正常生產
    51.  
    52.     void InitialiseList()
    53.     {
    54.         GridPosition.Clear();
    55.         //清除所有GridPosition裡面所紀錄的Objects
    56.           for( int x =1; x< colums-1; x++)
    57.           //生產的Objects不超出Colums的範圍
    58.         {
    59.             for(int y =1; y< rows-1; y++)
    60.             //生產的Objects不超出Rows的範圍
    61.             {
    62.                 GridPosition.Add(new Vector3(x, y, 0f));
    63.                 //用GridPosition來記錄所有的已生產的Objects
    64.             }
    65.         }
    66.     }
    67.  
    68.     void BoardSetup()
    69.     //製造牆壁
    70.     {
    71.         BoardHolder = new GameObject("Board").transform;
    72.         //將所有的牆壁都歸名為Board的Object
    73.         for( int x= -1; x <colums+1; x++)
    74.         {
    75.             for( int y= -1; y <rows+1; y++)
    76.             {
    77.                 GameObject toInstantiate = FloorTiles[Random.Range(0,FloorTiles.Length)];
    78.                 //用FloorTiles來製造Floor,並用Random來隨機取得座標
    79.                 if (x == -1 || x == colums || y == -1 || y == rows)
    80.                 //一但碰到邊界之後
    81.                 {
    82.                     toInstantiate = OuterWallTiles[Random.Range(0, OuterWallTiles.Length)];
    83.                     //用OuterWallTiles來製造邊界,並用Random來隨機取得座標
    84.                     GameObject instance =
    85.                         Instantiate(toInstantiate, new Vector3(x, y, 0f), Quaternion.identity) as GameObject;
    86.                     //創造一個GameObject instance來複製GameObject toInstantiate並且會對準X及Y並不會任意旋轉
    87.                     instance.transform.SetParent(BoardHolder);
    88.                     //GameObject instance將會收在BoardHolder之中,是整理Hirachy的方法
    89.                 }
    90.             }
    91.         }
    92.     }
    93.  
    94.     Vector3 RandomPosition()
    95.     //隨機座標取得
    96.     {
    97.         int randomIndex = Random.Range(0, GridPosition.Count);
    98.         //隨機座標變數為0至已經生成的數量之間
    99.         Vector3 randomPosition = GridPosition[randomIndex];
    100.         //將Vector3的randomPosistion設成 radomIndex
    101.         GridPosition.RemoveAt(randomIndex);
    102.         //之後將其刪除
    103.         return randomPosition;
    104.     }
    105.  
    106.     void LayoutObjectAtRandom(GameObject[] tileArray, int Minimum, int Maximun)
    107.     {
    108.         int ObjectCount = Random.Range(Minimum, Maximun + 1);
    109.         //隨機產生Object數
    110.         for( int i=0; i< ObjectCount; i++)
    111.         {
    112.             Vector3 randomPosition = RandomPosition();
    113.             //取得隨機RandomPosition
    114.             GameObject TileChoice = tileArray[Random.Range(0, tileArray.Length)];
    115.             //隨機產生TileChoice根據TileArray的分布
    116.             Instantiate(TileChoice, randomPosition, Quaternion.identity);
    117.             //所生成的Copies的位置是根據(TileChoice, randomPosition, Quaternion.identity)而定
    118.         }
    119.  
    120.     }
    121.  
    122.     public void SetupScene(int Level)
    123.     {
    124.         BoardSetup();
    125.         InitialiseList();
    126.         LayoutObjectAtRandom(WallTiles, wallCount.Minimum, wallCount.Maximun);
    127.         LayoutObjectAtRandom(FoodTiles, foodCount.Minimum, foodCount.Maximun);
    128.         int enemyCount = (int)Mathf.Log(Level, 2f);
    129.         LayoutObjectAtRandom(EnemyTiles, enemyCount, enemyCount);
    130.         Instantiate(Exit,new Vector3(colums - 1, rows - 1, 0f), Quaternion.identity);
    131.     }
    132.  
    133.  
    134. }
    135.  
     
  24. Disane

    Disane

    Joined:
    Sep 6, 2016
    Messages:
    2
    I just gone through the video tutorials. There's one thing that desperately needs fixing:
    The player spawining logic and code needs some rethinking. In the video the commentator simply places the player prefab in the game hierarchy (yeah, just like that). Which places the player to a default location which is mostly outside the bounds of the board. There are player spawn related issues regarding the player throughout videos 11 up to 14 because of this.

    My solution would be: modifying the BoardManager and adding the player prefab to the list of spawnable objects and modifying the board creation algorithm in a way that allows the player to be spawned in its own "safe" location where no enemies or obsticles can be spawned. Also, foodText needs to be dyniamically looked up in Start() of the Player's C# script to enable everything that has been said above. If I have time I might post my modifications later today.

    In the meantime could anyone explain to me why Vector3, Quaternions are needed to build the game board, when Vector2 was already available? It's unlikely that you need the Z coordinate being explicitly set, when objects are placed on Z=0 by default. Well, according to my experience.
     
    Last edited: Jan 7, 2017
  25. edwardchuajh

    edwardchuajh

    Joined:
    Jan 8, 2017
    Messages:
    2
    Thanks!! This helped!!
     
  26. TheProfessor

    TheProfessor

    Joined:
    Nov 2, 2014
    Messages:
    46

    Vector3 is probably used because of habit. There isn't really a need for Vector2 unless you're trying really hard not to confuse students new to Unity and 3D games development.

    The player is placed at 0,0,0 and the board is spawned from there; the player isn't outside of bounds if it's perfectly 0,0,0. I think the probability of Monsters spawning within this space next to the player is low enough that it isn't a huge priority if your goal is to be instructional.

    Because at that point you're delving more and more into algorithms.

    The bigger issue I wanna see addressed though that breaks the entire thing is when BoardManager/GameManager is appeared to be called twice in Init().
     
  27. TheProfessor

    TheProfessor

    Joined:
    Nov 2, 2014
    Messages:
    46
    Hrm, for some reason the Awake() in GameManager isn't being called on the subsequent levels with this.
     
  28. Prometheus121

    Prometheus121

    Joined:
    Apr 6, 2016
    Messages:
    9
    So. I've been working on the level generation, and for some reason the top row of outer walls never spawns, and if I change the number of rows and columns, weird things start happening like if I change the rows down, a second outer wall spawns halfway through the map and when I change the columns down, the exit and enemies don't spawn. I'm not sure what it is. Here's my code:

    Board Manager:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System;
    5. using Random = UnityEngine.Random;
    6.  
    7. public class BoardManager : MonoBehaviour {
    8.  
    9.     [Serializable]
    10.     public class Count {
    11.         public int minimum;
    12.         public int maximum;
    13.  
    14.         public Count (int min, int max) {
    15.  
    16.             minimum = min;
    17.             maximum = max;
    18.         }
    19.     }
    20.  
    21.     public int columns = 8;
    22.     public int rows = 8;
    23.     public Count wallCount = new Count (5, 9);
    24.     public Count foodCount = new Count (5, 9);
    25.     public GameObject exit;
    26.     public GameObject[] floorTiles;
    27.     public GameObject[] wallTiles;
    28.     public GameObject[] foodTiles;
    29.     public GameObject[] enemyTiles;
    30.     public GameObject[] outerWallTiles;
    31.  
    32.     private Transform boardHolder;
    33.     private List <Vector3> gridPositions = new List<Vector3>();
    34.  
    35.     void InitializeList() {
    36.         gridPositions.Clear ();
    37.  
    38.         for (int x = 1; x < columns - 1; x++) {
    39.             for (int y = 1; y < rows - 1; y++) {
    40.                 gridPositions.Add (new Vector3 (x, y, 0f));
    41.             }
    42.         }
    43.     }
    44.  
    45.     void boardSetUp() {
    46.         boardHolder = new GameObject ("Board").transform;
    47.  
    48.         for (int x = -1; x < columns + 1; x++) {
    49.             for (int y = -1; y < rows + 1; y++) {
    50.                 GameObject toInstantiate = floorTiles[Random.Range (0, floorTiles.Length)];
    51.                 if (x == -1 || x == columns || y == -1 || x == rows) {
    52.                     toInstantiate = outerWallTiles [Random.Range (0, outerWallTiles.Length)];
    53.                 }
    54.                 GameObject instance = Instantiate(toInstantiate, new Vector3 (x, y, 0f), Quaternion.identity) as GameObject;
    55.  
    56.                 instance.transform.SetParent(boardHolder);
    57.             }
    58.         }
    59.     }
    60.  
    61.  
    62.     Vector3 RandomPosition() {
    63.         int randomIndex = Random.Range (0, gridPositions.Count);
    64.         Vector3 randomPosition = gridPositions [randomIndex];
    65.         gridPositions.RemoveAt (randomIndex);
    66.         return randomPosition;
    67.     }
    68.  
    69.     void layoutObjectAtRandom(GameObject[] tileArray, int minimum, int maximum) {
    70.         int objectCount = Random.Range (minimum, maximum + 1);
    71.  
    72.         for (int i = 0; i < objectCount; i++) {
    73.             Vector3 randomPosition = RandomPosition ();
    74.             GameObject tileChoice = tileArray[Random.Range (0, tileArray.Length)];
    75.             Instantiate (tileChoice, randomPosition, Quaternion.identity);
    76.         }
    77.     }
    78.  
    79.     public void SetupScene (int level) {
    80.         boardSetUp();
    81.         InitializeList ();
    82.         layoutObjectAtRandom (wallTiles, wallCount.minimum, wallCount.maximum);
    83.         layoutObjectAtRandom (foodTiles, foodCount.minimum, foodCount.maximum);
    84.         int enemyCount = (int)Mathf.Log (level, 2f);
    85.         layoutObjectAtRandom (enemyTiles, enemyCount, enemyCount);
    86.         Instantiate (exit, new Vector3 (columns - 1, rows - 1, 0f), Quaternion.identity);
    87.     }
    88.        
    89. }
    90.  
    and here's my game manager just in case:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class GameManager : MonoBehaviour {
    6.  
    7.     public BoardManager boardScript;
    8.  
    9.     private int level = 3;
    10.  
    11.     // Use this for initialization
    12.     void Awake () {
    13.         boardScript = GetComponent<BoardManager> ();
    14.         initGame ();
    15.     }
    16.  
    17.     // Update is called once per frame
    18.     void initGame () {
    19.         boardScript.SetupScene (level);
    20.     }
    21. }
    22.  
    Thanks for any help you can give, guys.
     
  29. breadtop

    breadtop

    Joined:
    Jan 12, 2017
    Messages:
    2
    Hi,

    I'm using this tutorial to build a game but I want to add a start screen to it, with buttons for Level 1, Level 2, Level 3 and Level 4. I want the buttons, once pressed on, to go straight to that level and if the player passes it, to continue on with the next randomly generated levels.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.SceneManagement; // Allows SceneManager to be used.
    4.  
    5. public class LoadSceneOnClick : MonoBehaviour
    6. {
    7.  
    8.     public void LoadByIndex(int sceneIndex) // Passes in what scene will be loaded.
    9.     {
    10.         SceneManager.LoadScene(sceneIndex); // SceneManager loads scene.
    11.     }
    12. }
    This is my code for my LoadSceneOnClick script that I am using for each of my main menu buttons. I got this from the Creating A Main Menu tutorial. However it is not working because it assumes that each level is a different scene. This game contains all its levels in a single scene so I'm not sure how to make this work. I've tried passing in the variable for level instead of sceneIndex but it did not work, so maybe I was not doing it right.

    Any help would be appreciated!!

    Thanks :)
     
  30. edwardchuajh

    edwardchuajh

    Joined:
    Jan 8, 2017
    Messages:
    2
    Hi,

    Just helping here, it's in Line 51 of your Board Manager.

    You have a x instead of y.

    if(x ==-1|| x == columns || y ==-1|| x == rows){
     
    Matthew-Schell likes this.
  31. Prometheus121

    Prometheus121

    Joined:
    Apr 6, 2016
    Messages:
    9
    Oh... I have a top wall... Thanks a bunch! I actually used the completed script and it still didnt work so... that's weird. Idk. It works now so. Thanks!
     
    Matthew-Schell likes this.
  32. Matthew-Schell

    Matthew-Schell

    Unity Technologies

    Joined:
    Oct 1, 2014
    Messages:
    209
    This issue is caused because you have copied and pasted the scripts directly from the learn website instead of typing them. Previously those scripts were in the Completed namespace (like those in the Completed folder). If you're not familiar with this concept of namespace, see here: https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx

    I have actually edited the Learn pages to remove the wrapping of these scripts in that namespace since so many people were having issues with it. Generally my recommendation is that people should type the scripts since they will learn better than simply copying and pasting but enough people were getting stuck on this that I decided to change it.
     
  33. Matthew-Schell

    Matthew-Schell

    Unity Technologies

    Joined:
    Oct 1, 2014
    Messages:
    209
    It sounds like you might not have a BoxCollider2D component attached? The error is telling you that the script cannot find one, therefore it is 'null'.
     
  34. Matthew-Schell

    Matthew-Schell

    Unity Technologies

    Joined:
    Oct 1, 2014
    Messages:
    209
    Yes you can.
     
  35. Matthew-Schell

    Matthew-Schell

    Unity Technologies

    Joined:
    Oct 1, 2014
    Messages:
    209
    Re 1) I have actually gone and removed the scripts from the Completed namespace on the site as I agree it's confusing. At the time my thinking was 'people should type the scripts in instead of copying' but in retrospect that was a mistake. The tutorial is intended for intermediate students who would hopefully know what a namespace was, but this being the internet there is no way to control for that.

    Re 2) It's been a while since I made this but I believe that in the sequence shown you should not get errors if you follow the tutorial correctly and do things in that order. That said I made this tutorial a while ago now and looking back on it see many ways I would now do it differently. Hopefully at some point I'll get a chance to do a new version or make an update, but making these things takes many, many months and a ton of labor, so it won't be any time soon. In the mean time hopefully folks can learn some intermediate ideas from it in it's current state. Thanks for your feedback.

    Re 3) This is due to changes in the editor since this was made, I made an annotation on the video on YouTube which appears when you watch it at 1:16. This series was recorded when 5.0 first came out.

    Re 4 and 5) This is new to me, I don't see how it would interact across namespaces... I have however in the past noticed strange behavior with scripts called GameManager in Unity (like the component disappearing when added). You could try refactoring the name and seeing if that helps.
     
  36. Matthew-Schell

    Matthew-Schell

    Unity Technologies

    Joined:
    Oct 1, 2014
    Messages:
    209
    I'm guessing you failed to add a public GameManager variable to your script.
     
  37. NPSao

    NPSao

    Joined:
    Jan 14, 2017
    Messages:
    1
    Hello, one of the later videos tells me to look into the PDF file, provided by the package. This file is also listed in the package contents, but when I add the 2D Rogue Like Asset Package to my project, the pdf file is nowhere to be found!
     
  38. breadtop

    breadtop

    Joined:
    Jan 12, 2017
    Messages:
    2
    Hi,

    Just want to say this is an awesome, easy to understand tutorial with great music!
    My question is, for some reason my game does not progress to the next level when the first is completed. Like it shows level one then once the player reaches the end it does not go any further. Could someone please tell me how to fix this?

    Here's my GameManager code.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. namespace Completed
    5. {
    6.     using System.Collections.Generic;       //Allows us to use Lists.
    7.     using UnityEngine.UI;                   //Allows us to use UI.
    8.     using UnityEngine.SceneManagement;
    9.  
    10.     public class GameManager : MonoBehaviour {
    11.  
    12.         public float levelStartDelay = 2f;                      //Time to wait before starting level, in seconds.
    13.         public float turnDelay = 0.1f;                          //Delay between each Player turn.
    14.         public int playerPoints = 100;                          //Starting value for Player points.
    15.         public static GameManager instance = null;              //Static instance of GameManager which allows it to be accessed by any other script.
    16.         [HideInInspector]
    17.         public bool playersTurn = true;                         //Boolean to check if it's the players turn, hidden in inspector but public.
    18.         public float lineSpacing;                               //Float to store line spacing of text.
    19.  
    20.         private int level = PlayerPrefs.GetInt("initialLevel");
    21.         // To get initial level from button clicked
    22.  
    23.         private Button backButton;                              //Button to allow user to return to the main menu.
    24.         private Text levelText;                                 //Text to display current level number.
    25.         private GameObject levelImage;                          //Image to block out level as levels are being set up, background for levelText.
    26.         private BoardManager boardScript;                       //Store a reference to our BoardManager which will set up the level.
    27.         // private int level = 1;                                  //Current level number, expressed in game as "Level 2".
    28.         private List<Enemy> enemies;                            //List of all Enemy units, used to issue them move commands.
    29.         private bool enemiesMoving;                             //Boolean to check if enemies are moving.
    30.         private bool doingSetup = true;                         //Boolean to check if we're setting up board, prevent Player from moving during setup.
    31.  
    32.  
    33.  
    34.         //Awake is always called before any Start functions
    35.         void Awake()
    36.         {
    37.             //Check if instance already exists
    38.             if (instance == null)
    39.  
    40.                 //if not, set instance to this
    41.                 instance = this;
    42.  
    43.             //If instance already exists and it's not this:
    44.             else if (instance != this)
    45.  
    46.                 //Then destroy this. This enforces our singleton pattern, meaning there can only ever be one instance of a GameManager.
    47.                 Destroy(gameObject);
    48.  
    49.             //Sets this to not be destroyed when reloading scene
    50.             DontDestroyOnLoad(gameObject);
    51.  
    52.             //Assign enemies to a new List of Enemy objects.
    53.             enemies = new List<Enemy>();
    54.  
    55.             //Get a component reference to the attached BoardManager script
    56.             boardScript = GetComponent<BoardManager>();
    57.  
    58.             //Call the InitGame function to initialize the first level
    59.             InitGame();
    60.         }
    61.  
    62.         //This is called each time a scene is loaded.
    63.         void OnLevelWasLoaded(int index)
    64.         {
    65.             //Add one to our level number.
    66.             level++;
    67.             //Call InitGame to initialize our level.
    68.             InitGame();
    69.         }
    70.  
    71.         //Initializes the game for each level.
    72.         void InitGame()
    73.         {
    74.  
    75.             //While doingSetup is true the player can't move, prevent player from moving while title card is up.
    76.             doingSetup = true;
    77.  
    78.             //Get a reference to our image LevelImage by finding it by name.
    79.             levelImage = GameObject.Find("LevelImage");
    80.  
    81.             //Get a reference to our text LevelText's text component by finding it by name and calling GetComponent.
    82.             levelText = GameObject.Find("LevelText").GetComponent<Text>();
    83.  
    84.             //Get a reference to Back button component by finding it by name.
    85.             backButton = GameObject.Find("BackButton").GetComponent<Button>();
    86.  
    87.             //Set the text of levelText to the string "Level" and append the current level number.
    88.             levelText.text = "Level " + level;
    89.  
    90.             //Set levelImage to active blocking player's view of the game board during setup.
    91.             levelImage.SetActive(true);
    92.  
    93.             //Set Back button to false during the level title cards.
    94.             backButton.gameObject.SetActive(false);
    95.  
    96.             //Call the HideLevelImage function with a delay in seconds of levelStartDelay.
    97.             Invoke("HideLevelImage", levelStartDelay);
    98.  
    99.             //Clear any Enemy objects in our List to prepare for next level.
    100.             enemies.Clear();
    101.  
    102.             //Call the SetupScene function of the BoardManager script, pass it current level number.
    103.             boardScript.SetupScene(level);
    104.  
    105.         }
    106.  
    107.         //Hides black image used between levels
    108.         void HideLevelImage()
    109.         {
    110.             //Disable the levelImage gameObject.
    111.             levelImage.SetActive(false);
    112.            
    113.             //Set doingSetup to false allowing player to move again.
    114.             doingSetup = false;
    115.         }
    116.  
    117.         //Update is called every frame.
    118.         void Update()
    119.         {
    120.             //Check that playersTurn or enemiesMoving or doingSetup are not currently true.
    121.             if (playersTurn || enemiesMoving)
    122.  
    123.                 //If any of these are true, return and do not start MoveEnemies.
    124.                 return;
    125.  
    126.             //Start moving enemies.
    127.             StartCoroutine(MoveEnemies());
    128.         }
    129.  
    130.         //Call this to add the passed in Enemy to the List of Enemy objects.
    131.         public void AddEnemyToList(Enemy script)
    132.         {
    133.             //Add Enemy to List enemies.
    134.             enemies.Add(script);
    135.         }
    136.  
    137.         //Disables GameManager at the end of the game.
    138.         public void GameOver ()
    139.         {
    140.             //Set levelText to display number of levels passed and game over message
    141.             levelText.text = "Game over! \n \n After " + level + " levels, you died. \n \n Better luck next time. \n \n";
    142.  
    143.             //Sets line spacing to 1.3 to increase legibility of text.
    144.             lineSpacing = 1.3f;
    145.  
    146.             //Enable black background image gameObject.
    147.             levelImage.SetActive(true);
    148.  
    149.             //Enable Back button in Game Results screen.
    150.             backButton.gameObject.SetActive(true);
    151.  
    152.             //Disable this GameManager.
    153.             enabled = false;
    154.         }
    155.  
    156.         //Coroutine to move enemies in sequence.
    157.         IEnumerator MoveEnemies()
    158.         {
    159.             //While enemiesMoving is true player is unable to move.
    160.             enemiesMoving = true;
    161.  
    162.             //Wait for turnDelay seconds, defaults to .1 (100 ms).
    163.             yield return new WaitForSeconds(turnDelay);
    164.  
    165.             //If there are no enemies spawned (IE in first level):
    166.             if (enemies.Count == 0)
    167.             {
    168.                 //Wait for turnDelay seconds between moves, replaces delay caused by enemies moving when there are none.
    169.                 yield return new WaitForSeconds(turnDelay);
    170.             }
    171.  
    172.             //Loop through List of Enemy objects.
    173.             for (int i = 0; i < enemies.Count; i++)
    174.             {
    175.                 //Call the MoveEnemy function of Enemy at index i in the enemies List.
    176.                 enemies[i].MoveEnemy();
    177.  
    178.                 //Wait for Enemy's moveTime before moving next Enemy,
    179.                 yield return new WaitForSeconds(enemies[i].moveTime);
    180.             }
    181.             //Once Enemies are done moving, set playersTurn to true so player can move.
    182.             playersTurn = true;
    183.  
    184.             //Enemies are done moving, set enemiesMoving to false.
    185.             enemiesMoving = false;
    186.         }
    187.     }
    188. }
    189.  
    Would appreciate any help you can give!! Thanks :)
     
  39. Cobalt313

    Cobalt313

    Joined:
    Sep 14, 2016
    Messages:
    2
    I'm on the third-to-last video where you add the UI elements, and suddenly I'm getting a "NullReferenceException: Object reference not set to an instance of an object" error for Gamemanager apparently refusing to acknowledge that the BoardManager script I tell it to use not only exists, but is also affixed to the same prefab object as the GameManager script itself. Has anyone else encountered this problem and/or have a solution?

    For what it's worth I have just updated my Unity to 5.5 before this step of the project so I suspect some work may have been lost in translation so to speak.
     
  40. Cobalt313

    Cobalt313

    Joined:
    Sep 14, 2016
    Messages:
    2
    Ok so I think I resolved the issue in my previous post but now I'm getting an error from DontDestroyOnLoad(gameObject) and the game increments days and enemies wrong. I compared my work to that of the example and all of it matches save for the parts I was told to substitute in the PDF. Anyone else had a similar issue?