Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Official 2D Roguelike: Q&A

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

Thread Status:
Not open for further replies.
  1. Sartoris

    Sartoris

    Joined:
    Dec 8, 2013
    Posts:
    21
    Hi everyone,
    I'm trying to extend the tutorial using the dungeon generation script available here: https://unity3d.com/learn/tutorials/topics/scripting/basic-2d-dungeon-generation

    However, Unity slows down a lot when a large number of walls is instantiated. I was wondering how one would go about spawning only those walls that are bordering the rooms and corridors, while leaving empty space in other locations. Or if that's difficult, how would you cut down on the number of walls being spawned in all that empty space "out there", i.e. in areas of the map that do not contain rooms or corridors?

    I'd be grateful for any ideas :)
     
  2. robert-sherwood

    robert-sherwood

    Joined:
    Jan 7, 2018
    Posts:
    14
    I have a question on the following code in lesson 6:

    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;
    }
    }



    Why do we switch between transform.position and rb2d.position in our calculations? Are these positions different? Is there a specific reason why we use them both in the same function for very similar looking calculations?

    Thanks!
     
  3. FlamingVorpalCow

    FlamingVorpalCow

    Joined:
    Oct 29, 2014
    Posts:
    6
    Hi, i'm trying to extend on this project, but i'm encountering an issue, from what i saw in youtube comments is common...

    I created a Main Menu screen, from where i'm trying to launch the game, if I click play and go into this scene, it will start on Day 2, and after completing the map, the next day will be Day 4 and as soon as i touch and try to move, I die and have -1 food and the game stays there.

    This doesn't happen if i normally launch from finished tutorial scene, only if i try to go into it from somewhere else...

    Any Ideas on how to work around this?

    Tried debugging but i don't see why this is happening...
     
  4. marivs

    marivs

    Joined:
    Dec 2, 2017
    Posts:
    2
    Hello! I am following the tutorials to this game but after finishing the 12th part my game has 2 problems. One is that the level text does not show the correct number (it shows day 2, day 4, day 6 and so on) and if I set the value of level to 0 initially I get day 1, day 3, day 5 and so on. I have not yet realised where it jumps by 1. Another problem is that I lose the food after the 1st level. It displays 0 and after I move the game over message appears. Another issue is that sometimes there are tiles over another tiles (food on the same tile as wall and sometimes even 2 walls in the same place).I am using Unity 2017.3.
     
  5. robert-sherwood

    robert-sherwood

    Joined:
    Jan 7, 2018
    Posts:
    14
    Check out the top comment on the video explaining UI and Levels. It tells you what you need to do.
     
    marivs likes this.
  6. robert-sherwood

    robert-sherwood

    Joined:
    Jan 7, 2018
    Posts:
    14
    Check out the top comment on the video explaining UI and Levels. It tells you what you need to do.
     
  7. marivs

    marivs

    Joined:
    Dec 2, 2017
    Posts:
    2
    Thanks man! I was really struggling.You are the best!
     
  8. prent2cookies

    prent2cookies

    Joined:
    Jan 15, 2018
    Posts:
    4
    Hi everyone! So I am really new to Unity and I started having problems with my game only after I tried adding sound. The game will load up just fine, but the second I attempt to move my player it immediately goes to the game over screen and the program ends. I am really confused because my game worked just fine before I attempted to add sound. If anyone has ideas as to what happened, I would appreciate the help!
     
  9. atraska

    atraska

    Joined:
    Jan 10, 2018
    Posts:
    1
    Has anybody else been having difficulty with the Player only moving one spot, then getting stuck there? I just finished video 11 and tried my level out and he won't move more than one space before freezing.
     
  10. ArSplln

    ArSplln

    Joined:
    Jan 17, 2018
    Posts:
    7
    Hi Guys !

    I'm at the end of video 11.
    My player is moving correctly, i can chop walls. But i can't pick up food or soda, enemies don't attack but move, and I can walk throught them. I can walk on the "Exit" Tiles, but it's not ending the current level. There is no error message in Unity's console.

    Enemies are tagged "Enemy" and on the "Blocking Layer". Food and soda are tagged "Food" and "Soda"

    Someone have any idea of where the problem is ?

    Here is the code :

    Code (CSharp):
    1. //player.cs
    2.  
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6. using UnityEngine.SceneManagement;
    7.  
    8. public class Player : MovingObjects
    9. {
    10.  
    11.     public int wallDamage = 1;
    12.     public int pointsPerFood = 10;
    13.     public int pointsPerSoda = 20;
    14.     public float restartLevelDelay = 1f;
    15.  
    16.     private Animator animator;
    17.     private int food;
    18.  
    19.  
    20.     protected override void Start()
    21.     {
    22.         animator = GetComponent<Animator>();
    23.  
    24.         food = GameManager.instance.playerFoodPoints;
    25.  
    26.         base.Start();
    27.     }
    28.  
    29.     private void OnDisable()
    30.     {
    31.         GameManager.instance.playerFoodPoints = food;
    32.     }
    33.  
    34.     void Update()
    35.     {
    36.         if (!GameManager.instance.playersTurn) return;
    37.  
    38.         int horizontal = 0;
    39.         int vertical = 0;
    40.  
    41.         horizontal = (int)Input.GetAxisRaw("Horizontal");
    42.         vertical = (int)Input.GetAxisRaw("Vertical");
    43.  
    44.         if (horizontal != 0)
    45.             vertical = 0;
    46.  
    47.         if (horizontal != 0 || vertical != 0)
    48.             AttemptMove<Wall>(horizontal, vertical);
    49.     }
    50.  
    51.     protected override void AttemptMove<T>(int xDir, int yDir)
    52.     {
    53.         food--;
    54.  
    55.         base.AttemptMove<T>(xDir, yDir);
    56.  
    57.         RaycastHit2D hit;
    58.  
    59.         CheckIfGameOver();
    60.  
    61.         GameManager.instance.playersTurn = false;
    62.     }
    63.  
    64.     private void OnTriggerEnter2D(Collider other)
    65.     {
    66.         if (other.tag == "Exit")
    67.         {
    68.             Invoke("Restart", restartLevelDelay);
    69.             enabled = false;
    70.         }
    71.         else if (other.tag == "Food")
    72.         {
    73.             food += pointsPerFood;
    74.             other.gameObject.SetActive(false);
    75.         }
    76.         else if (other.tag == "Soda")
    77.         {
    78.             food += pointsPerSoda;
    79.             other.gameObject.SetActive(false);
    80.         }
    81.  
    82.     }
    83.  
    84.     protected override void OnCantMove <T> (T component)
    85.     {
    86.         Wall hitWall = component as Wall;
    87.         hitWall.DamageWall(wallDamage);
    88.         animator.SetTrigger("playerChop");
    89.     }
    90.  
    91.     private void Restart()
    92.     {
    93.         SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    94.     }
    95.  
    96.     public void LoseFood(int loss)
    97.     {
    98.         animator.SetTrigger("playerHit");
    99.         food -= loss;
    100.         CheckIfGameOver();
    101.     }
    102.  
    103.     private void CheckIfGameOver()
    104.     {
    105.         if (food <= 0)
    106.             GameManager.instance.GameOver();
    107.     }
    108. }
    109.  
    Code (CSharp):
    1. //enemy.cs
    2.  
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6.  
    7. public class Enemy : MovingObjects {
    8.  
    9.     public int playerDamage;
    10.  
    11.     private Animator animator;
    12.     private Transform target;
    13.     private bool skipMove;
    14.  
    15.  
    16.    
    17.     protected override void Start ()
    18.     {
    19.         GameManager.instance.AddEnemyToList(this);
    20.         animator = GetComponent<Animator>();
    21.         target = GameObject.FindGameObjectWithTag("Player").transform;
    22.         base.Start();
    23.     }
    24.    
    25.     protected override void AttemptMove<T>(int xDir, int yDir)
    26.     {
    27.         if (skipMove)
    28.         {
    29.             skipMove = false;
    30.             return;
    31.         }
    32.  
    33.         base.AttemptMove <T> (xDir, yDir);
    34.  
    35.         skipMove = true;
    36.     }
    37.  
    38.     public void MoveEnemy ()
    39.     {
    40.         int xDir = 0;
    41.         int yDir = 0;
    42.  
    43.         if (Mathf.Abs(target.position.x - transform.position.x) < float.Epsilon)
    44.             yDir = target.position.y > transform.position.y ? 1 : -1;
    45.         else
    46.             xDir = target.position.x > transform.position.x ? 1 : -11;
    47.  
    48.         AttemptMove<Player>(xDir, yDir);
    49.     }
    50.  
    51.     protected override void OnCantMove <T> (T component)
    52.     {
    53.         Player hitPlayer = component as Player;
    54.  
    55.         animator.SetTrigger("enemyAttack");
    56.  
    57.         hitPlayer.LoseFood(playerDamage);
    58.     }
    59. }
    60.  
    Code (CSharp):
    1. //gameManager.cs
    2.  
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6.  
    7. public class GameManager : MonoBehaviour
    8. {
    9.     public float turnDelay = .1f;
    10.     public static GameManager instance = null;
    11.     public BoardManager boardScript;
    12.     public int playerFoodPoints = 100;
    13.     [HideInInspector] public bool playersTurn = true;
    14.  
    15.     private int level = 3;
    16.     private List<Enemy> enemies;
    17.     private bool enemiesMoving;
    18.  
    19.    
    20.     void Awake ()
    21.     {
    22.         if (instance == null)
    23.             instance = this;
    24.         else if (instance != this)
    25.             Destroy(gameObject);
    26.  
    27.         DontDestroyOnLoad(gameObject);
    28.         enemies = new List<Enemy>();
    29.         boardScript = GetComponent<BoardManager>();
    30.         InitGame();
    31.     }
    32.    
    33.     void InitGame ()
    34.     {
    35.         enemies.Clear();
    36.         boardScript.SetupScene(level);
    37.     }
    38.  
    39.     public void GameOver()
    40.     {
    41.         enabled = false;
    42.     }
    43.    
    44.     void Update ()
    45.     {
    46.         if (playersTurn || enemiesMoving)
    47.             return;
    48.  
    49.         StartCoroutine(MoveEnemies());
    50.     }
    51.  
    52.     public void AddEnemyToList(Enemy script)
    53.     {
    54.         enemies.Add(script);
    55.     }
    56.  
    57.     IEnumerator MoveEnemies()
    58.     {
    59.         enemiesMoving = true;
    60.         yield return new WaitForSeconds(turnDelay);
    61.         if (enemies.Count == 0)
    62.         {
    63.             yield return new WaitForSeconds(turnDelay);
    64.         }
    65.  
    66.         for (int i = 0; i < enemies.Count; i++)
    67.         {
    68.             enemies[i].MoveEnemy();
    69.             yield return new WaitForSeconds(enemies[i].moveTime);
    70.         }
    71.  
    72.         playersTurn = true;
    73.         enemiesMoving = false;
    74.     }
    75. }
     
  11. gwnguy

    gwnguy

    Joined:
    Apr 25, 2017
    Posts:
    144
    Are you getting a console error message regarding line 64 of player.cs?
    on line 64 of player.cs, please try
    private void OnTriggerEnter2D(Collider2D other)
    instead of
    private void OnTriggerEnter2D(Collider other)

    and see if it makes any difference

    BTW, inspector on the player:
    upload_2018-1-17_13-21-48.png
     
    Last edited: Jan 17, 2018
  12. ArSplln

    ArSplln

    Joined:
    Jan 17, 2018
    Posts:
    7
    Thanks for the reply.

    Writting private void OnTriggerEnter2D(Collider2D other) , is not making any changes.
    Here's my items in the Inspector.

    Capture1.JPG Capture2.JPG Capture3.JPG Capture4.JPG
     
  13. gwnguy

    gwnguy

    Joined:
    Apr 25, 2017
    Posts:
    144
    Darn, I really thought that was the problem.


    1) Exit your Unity session and restart it. Some people have found this clears up their problems,
    and it is an easy thing to do. It will force any changes to be committed or dropped.

    2) Confirm there are no compile/build errors in your scripts, or runtime errors upon execution.
    If there are, then read them, they may help you pinpoint where the problem is.
    Check that the console log is not reporting ANY errors.

    3) Confirm you have attached your working script (not the script from the "_Completed_Game" directory) to your game objects
    in your inspector and the code you are modifying is in your working directory (not the "_Completed_Game" directory)
    Personally, I think the "Completed Game" directory is a double edged sword,
    since scripts from it may be confused with scripts from the working hierarchy.
    *** Move or Delete the "_Completed_Game" directory to make sure there is no accidental confusion. ***

    4) Check the spelling on your methods, they should all start with a capital letter.
    (void Start() , NOT void start ())

    5) Check that spelling on the tags on the game object in the inspector with the tags in the C# script.
    Same spelling, capitalization and punctuation. (tag name "pick up", PickUp", "pickUp", "Pick Up" are all different)

    6) a simple sanity check debug statement to the player.cs script
    Code (csharp):
    1.  
    2. void Start ()
    3. {
    4.    Debug.Log("Player.Start: we have entered the start method");
    5.    // ... other code ...
    6. }
    7.  
    and confirm it prints to the console.
     
    Last edited: Jan 19, 2018
  14. ArSplln

    ArSplln

    Joined:
    Jan 17, 2018
    Posts:
    7

    Hey, thanks for the reply.

    No error compile in the console, before or after running the game.
    No spelling error in my methods neither. I'm using my own sccripts, not ones from the Completed_Game file.

    I have nothing called Pick Up or pickUp. Did I miss something ?

    If I change Collider2D to Collider, it gets an error on the console, so you were right for that.

    Debug.Log("Player.Start: we have entered the start method"); is working, it prints to the console.

    SeNd HaLp !

    Thank you guys !
     
  15. gwnguy

    gwnguy

    Joined:
    Apr 25, 2017
    Posts:
    144
    Sorry, the "6 items to check" is a fairly generic checklist tailored to Roll-a-ball.
    In this case, the tags to check for spelling would "Player", "Food" and "Soda"


    I copied and pasted your player code into my project’s Player.cs
    I got this message:
    upload_2018-1-19_18-9-5.png

    I corrected the code to be:
    private void OnTriggerEnter2D(Collider2D other)
    And the game worked. I picked up food/soda, changed levels, the enemies attack and I can’t walk through them. BUT, the enemies DON’T follow me




    I copied/pasted the enemy.cs code into my enemy.cs
    I saw what you report. The enemy doesn’t move nor attack (but I don’t walk through them).
    I had this error:
    upload_2018-1-19_18-9-40.png

    So, my animator.SetTrigger("enemyAttack"); from my working code had a capital E:
    animator.SetTrigger("EnemyAttack");
    That fixed the problem, the enemy attacked, but, doesn’t move.
    I modified line 46
    From
    xDir = target.position.x > transform.position.x ? 1 : -11;
    To

    xDir = target.position.x > transform.position.x ? 1 : -1;
    (-1, not -11) and everything worked, the enemies follow me



    I haven’t tried the gameManager.cs.
     
    Last edited: Jan 20, 2018
  16. unity_P_E6_wAQcwWw2g

    unity_P_E6_wAQcwWw2g

    Joined:
    Dec 15, 2017
    Posts:
    2
    error1.JPG Hi, i have a problem since i completed lesson Adding UI & level transitions, error code is here:

    NullReferenceException: Object reference not set to an instance of an object
    UnityEditor.Graphs.Edge.WakeUp () (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Edge.cs:114)
    UnityEditor.Graphs.Graph.DoWakeUpEdges (System.Collections.Generic.List`1 inEdges, System.Collections.Generic.List`1 ok, System.Collections.Generic.List`1 error, Boolean inEdgesUsedToBeValid) (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:387)
    UnityEditor.Graphs.Graph.WakeUpEdges (Boolean clearSlotEdges) (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:286)
    UnityEditor.Graphs.Graph.WakeUp (Boolean force) (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:272)
    UnityEditor.Graphs.Graph.WakeUp () (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:250)
    UnityEditor.Graphs.Graph.OnEnable () (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:245)

    NullReferenceException: Object reference not set to an instance of an object
    GameManager.InitGame () (at Assets/Scripts/GameManager.cs:56)
    GameManager.Awake () (at Assets/Scripts/GameManager.cs:32)
    UnityEngine.Object:Instantiate(GameObject)
    Loader:Awake() (at Assets/Scripts/Loader.cs:12)

    NullReferenceException: Object reference not set to an instance of an object
    UnityEditor.Graphs.Edge.WakeUp () (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Edge.cs:114)
    UnityEditor.Graphs.Graph.DoWakeUpEdges (System.Collections.Generic.List`1 inEdges, System.Collections.Generic.List`1 ok, System.Collections.Generic.List`1 error, Boolean inEdgesUsedToBeValid) (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:387)
    UnityEditor.Graphs.Graph.WakeUpEdges (Boolean clearSlotEdges) (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:286)
    UnityEditor.Graphs.Graph.WakeUp (Boolean force) (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:272)
    UnityEditor.Graphs.Graph.WakeUp () (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:250)
    UnityEditor.Graphs.Graph.OnEnable () (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:245)

    NullReferenceException: Object reference not set to an instance of an object
    UnityEditor.Graphs.Edge.WakeUp () (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Edge.cs:114)
    UnityEditor.Graphs.Graph.DoWakeUpEdges (System.Collections.Generic.List`1 inEdges, System.Collections.Generic.List`1 ok, System.Collections.Generic.List`1 error, Boolean inEdgesUsedToBeValid) (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:387)
    UnityEditor.Graphs.Graph.WakeUpEdges (Boolean clearSlotEdges) (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:286)
    UnityEditor.Graphs.Graph.WakeUp (Boolean force) (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:272)
    UnityEditor.Graphs.Graph.WakeUp () (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:250)
    UnityEditor.Graphs.Graph.OnEnable () (at C:/buildslave/unity/build/Editor/Graphs/UnityEditor.Graphs/Graph.cs:245)

    NullReferenceException: Object reference not set to an instance of an object
    GameManager.InitGame () (at Assets/Scripts/GameManager.cs:56)
    GameManager.Awake () (at Assets/Scripts/GameManager.cs:32)
    UnityEngine.Object:Instantiate(GameObject)
    Loader:Awake() (at Assets/Scripts/Loader.cs:12)

    Game Manager Script:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.SceneManagement;

    public class GameManager : MonoBehaviour {

    public BoardManager boardScript;
    public static GameManager instance = null;
    public int playerFoodPoints = 100;
    [HideInInspector] public bool playersTurn = true;
    public float turnDelay = .1f;
    public float levelStartDelay = 2f;

    private int level = 1;
    private List<Enemy> enemies;
    private bool enemiesMoving;
    private Text levelText;
    private GameObject levelImage;
    private bool doingSetup;

    void Awake ()
    {
    if (instance == null)
    instance = this;
    else if (instance != this)
    Destroy (gameObject);
    DontDestroyOnLoad (gameObject);
    enemies = new List<Enemy> ();
    boardScript = GetComponent<BoardManager> ();
    InitGame ();

    }

    void OnLevelFinishedLoading (Scene scene, LoadSceneMode mode)
    {
    level++;
    InitGame ();
    }

    void OnEnable()
    {
    SceneManager.sceneLoaded += OnLevelFinishedLoading;
    }

    void OnDisable()
    {
    SceneManager.sceneLoaded -= OnLevelFinishedLoading;
    }

    void InitGame()
    {
    doingSetup = true;
    levelImage = GameObject.Find ("LevelImage");
    levelText = GameObject.Find ("LevelText").GetComponent<Text> ();
    levelText.text = "Day " + level;
    levelImage.SetActive (true);
    Invoke ("HideLevelImage", levelStartDelay);

    enemies.Clear ();
    boardScript.SetupScene (level);
    }

    void HideLevelImage()
    {
    levelImage.SetActive (false);
    doingSetup = false;
    }

    void Update ()
    {
    if (playersTurn || enemiesMoving || doingSetup)
    return;
    StartCoroutine (MoveEnemies());
    }

    public void AddEnemyToList (Enemy script)
    {
    enemies.Add (script);
    }

    public void GameOver()
    {
    levelText.text = "After " + level + "days, you starved.";
    levelImage.SetActive (true);
    enabled = false;
    }

    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.MoveEnemy ();
    yield return new WaitForSeconds (enemies.moveTime);
    }
    playersTurn = true;
    enemiesMoving = false;
    }
    }

    Player script:


    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.SceneManagement;

    public class Player : MovingObjects {

    public int wallDamage=1;
    public int pointsPerFood=10;
    public int pointsPerSoda=20;
    public float restartLevelDelay = 1f;
    public Text foodText;

    private Animator animator;
    private int food;

    // Use this for initialization
    protected override void Start ()
    {
    animator = GetComponent <Animator> ();
    food = GameManager.instance.playerFoodPoints;
    foodText.text = "Food: " + food;
    base.Start ();
    }

    // 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);
    }

    private void OnDisable ()
    {
    GameManager.instance.playerFoodPoints = food;
    }

    protected override void AttemptMove <T> (int xDir, int yDir)
    {
    food--;
    foodText.text = "Food: " + food;
    base.AttemptMove <T> (xDir, yDir);
    RaycastHit2D hit;
    CheckIfGameOver();
    }

    private void CheckIfGameOver()
    {
    if (food <= 0)
    GameManager.instance.GameOver();

    }

    private void OnTriggerEnter2D (Collider2D other)
    {
    if (other.tag == "Exit")
    {
    Invoke ("Restart", restartLevelDelay);
    enabled = false;
    }
    else if (other.tag == "Food")
    {
    food += pointsPerFood;
    foodText.text = "+" + pointsPerFood + " Food: " + food;
    other.gameObject.SetActive (false);
    }
    else if (other.tag == "Soda")
    {
    food += pointsPerSoda;
    foodText.text = "+" + pointsPerSoda + " Food: " + food;
    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);
    }

    public void LoseFood (int loss)
    {
    animator.SetTrigger ("plaherHit");
    food -= loss;
    foodText.text = "-" + loss + " Food: " + food;
    CheckIfGameOver ();
    }

    }

    Before that, the game was perfect, i can move player, pick up food and soda
     
  17. archteck

    archteck

    Joined:
    Jan 29, 2018
    Posts:
    2
    Hello,
    I'm making this post because maybe it could help someone that is in trouble because if you do all the steps in tutorial even with the new suggestions it will not be working, you still have to "tune" the scripts, i keep it very simple, similar with the result expected from the tutorial.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;       //Allows us to use Lists.
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5. using UnityEngine.UI;
    6.  
    7. public class GameManager : MonoBehaviour
    8. {
    9.     public float levelStartDelay = 2f;                      //Time to wait before starting level, in seconds.
    10.     public float turnDelay = 0.1f;                          //Delay between each Player turn.
    11.     public int playerFoodPoints = 100;                      //Starting value for Player food points.
    12.     public static GameManager instance;              //Static instance of GameManager which allows it to be accessed by any other script.
    13.     [HideInInspector] public bool playersTurn = true;       //Boolean to check if it's players turn, hidden in inspector but public.
    14.  
    15.     private Text levelText;                                 //Text to display current level number.
    16.     private GameObject levelImage;                          //Image to block out level as levels are being set up, background for levelText.
    17.     private BoardManager boardScript;                       //Store a reference to our BoardManager which will set up the level.
    18.     private int level;                                  //Current level number, expressed in game as "Day 0".
    19.     private List<Enemy> enemies;                          //List of all Enemy units, used to issue them move commands.
    20.     private bool enemiesMoving;                             //Boolean to check if enemies are moving.
    21.     private bool doingSetup;                         //Boolean to check if we're setting up board, prevent Player from moving during setup.
    22.  
    23.     //Awake is always called before any Start functions
    24.     private void Awake()
    25.     {
    26.         //Check if instance already exists
    27.         if (instance == null)
    28.  
    29.             //if not, set instance to this
    30.             instance = this;
    31.  
    32.         //If instance already exists and it's not this:
    33.         else if (instance != this)
    34.  
    35.             //Then destroy this. This enforces our singleton pattern, meaning there can only ever be one instance of a GameManager.
    36.             Destroy(gameObject);
    37.  
    38.         //Sets this to not be destroyed when reloading scene
    39.         DontDestroyOnLoad(gameObject);
    40.  
    41.         //Assign enemies to a new List of Enemy objects.
    42.         enemies = new List<Enemy>();
    43.  
    44.         //Get a component reference to the attached BoardManager script
    45.         boardScript = GetComponent<BoardManager>();
    46.     }
    47.  
    48.     //This is called each time a scene is loaded.
    49.     private void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode)
    50.     {
    51.         //Add one to our level number.
    52.         level++;
    53.         //Call InitGame to initialize our level.
    54.         InitGame();
    55.     }
    56.  
    57.     private void OnEnable()
    58.     {
    59.         //Tell our ‘OnLevelFinishedLoading’ function to start listening for a scene change event as soon as this script is enabled.
    60.         SceneManager.sceneLoaded += OnLevelFinishedLoading;
    61.     }
    62.  
    63.     private void OnDisable()
    64.     {
    65.         //Tell our ‘OnLevelFinishedLoading’ function to stop listening for a scene change event as soon as this script is disabled.
    66.         //Remember to always have an unsubscription for every delegate you subscribe to!
    67.         SceneManager.sceneLoaded -= OnLevelFinishedLoading;
    68.     }
    69.  
    70.     //Initializes the game for each level.
    71.     private void InitGame()
    72.     {
    73.         //While doingSetup is true the player can't move, prevent player from moving while title card is up.
    74.         doingSetup = true;
    75.  
    76.         //Get a reference to our image LevelImage by finding it by name.
    77.         levelImage = GameObject.Find("LevelImage");
    78.  
    79.         //Get a reference to our text LevelText's text component by finding it by name and calling GetComponent.
    80.         levelText = GameObject.Find("LevelText").GetComponent<Text>();
    81.  
    82.         //Set the text of levelText to the string "Day" and append the current level number.
    83.         levelText.text = string.Format("Day {0}", level);
    84.  
    85.         //Set levelImage to active blocking player's view of the game board during setup.
    86.         levelImage.SetActive(true);
    87.  
    88.         //Call the HideLevelImage function with a delay in seconds of levelStartDelay.
    89.         Invoke("HideLevelImage", levelStartDelay);
    90.  
    91.         //Clear any Enemy objects in our List to prepare for next level.
    92.         enemies.Clear();
    93.  
    94.         //Call the SetupScene function of the BoardManager script, pass it current level number.
    95.         boardScript.SetupScene(level);
    96.     }
    97.  
    98.     //Hides black image used between levels
    99.     private void HideLevelImage()
    100.     {
    101.         //Disable the levelImage gameObject.
    102.         levelImage.SetActive(false);
    103.  
    104.         //Set doingSetup to false allowing player to move again.
    105.         doingSetup = false;
    106.     }
    107.  
    108.     //Update is called every frame.
    109.     private void Update()
    110.     {
    111.         //Check that playersTurn or enemiesMoving or doingSetup are not currently true.
    112.         if (playersTurn || enemiesMoving || doingSetup)
    113.  
    114.             //If any of these are true, return and do not start MoveEnemies.
    115.             return;
    116.  
    117.         //Start moving enemies.
    118.         StartCoroutine(MoveEnemies());
    119.     }
    120.  
    121.     //Call this to add the passed in Enemy to the List of Enemy objects.
    122.     public void AddEnemyToList(Enemy script)
    123.     {
    124.         //Add Enemy to List enemies.
    125.         enemies.Add(script);
    126.     }
    127.  
    128.     //GameOver is called when the player reaches 0 food points
    129.     public void GameOver()
    130.     {
    131.         //Set levelText to display number of levels passed and game over message
    132.         levelText.text = string.Format("After {0} days,{1}you starved.", level, System.Environment.NewLine);
    133.  
    134.         //Enable black background image gameObject.
    135.         levelImage.SetActive(true);
    136.  
    137.         //Disable this GameManager.
    138.         enabled = false;
    139.     }
    140.  
    141.     //Coroutine to move enemies in sequence.
    142.     private IEnumerator MoveEnemies()
    143.     {
    144.         //While enemiesMoving is true player is unable to move.
    145.         enemiesMoving = true;
    146.  
    147.         //Wait for turnDelay seconds, defaults to .1 (100 ms).
    148.         yield return new WaitForSeconds(turnDelay);
    149.  
    150.         //If there are no enemies spawned (IE in first level):
    151.         if (enemies.Count == 0)
    152.         {
    153.             //Wait for turnDelay seconds between moves, replaces delay caused by enemies moving when there are none.
    154.             yield return new WaitForSeconds(turnDelay);
    155.         }
    156.  
    157.         //Loop through List of Enemy objects.
    158.         for (int i = 0; i < enemies.Count; i++)
    159.         {
    160.             //Call the MoveEnemy function of Enemy at index i in the enemies List.
    161.             enemies[i].MoveEnemy();
    162.  
    163.             //Wait for Enemy's moveTime before moving next Enemy,
    164.             yield return new WaitForSeconds(enemies[i].moveTime);
    165.         }
    166.         //Once Enemies are done moving, set playersTurn to true so player can move.
    167.         playersTurn = true;
    168.  
    169.         //Enemies are done moving, set enemiesMoving to false.
    170.         enemiesMoving = false;
    171.     }
    172. }
    Because off the changes in the SceneManager, they suggest we use OnLevelFinishedLoading for initialize the game, well that's a good sugesttion but we have to do more changes in the code. We must remove InitGame from the Awake because if we dont when we start the game we will have 2 boards loaded(1 from Awake and from OnLevelFinishedLoading). We only want InitGame on OnLevelFinishedLoading. We must also change the private int level to start in zero or better remove any initialization because int default value is zero.

    Other recommendations i can do (for user's and teachers), use string.Format to construct strings is better and easy, exemple :

    Code (CSharp):
    1. foodText.text = string.Format("Food: {0}", food);
    And when is collectibles please don't put the object "inactive", Destroy it!

    Code (CSharp):
    1. //Add pointsPerSoda to players food points total
    2.                 food += pointsPerSoda;
    3.                 foodText.text = string.Format("+{0} Food: {1}", pointsPerSoda, food);
    4.  
    5.                 //Call RandomizeSfx of SoundManager to play the drink sound, passing in two audio clips to choose from.
    6.                 SoundManager.instance.RandomizeSfx(drinkSound1, drinkSound1);
    7.  
    8.                 //Destroy the soda object the player collided with.
    9.                 Destroy(other.gameObject);
    The objective in this tutorials should be teaching good ways too, if we start from the beginning with bad roots the tree will fall.

    I hope that nobody gets angry with anything i said.

    Best regards
     
    Last edited: Feb 1, 2018
    oferzivony and Emilylyn1 like this.
  18. BashiDono

    BashiDono

    Joined:
    Oct 23, 2017
    Posts:
    3
    Hi! So I have a slight problem. I've just finished video 11 of 14 for the Rogue@D, but for some reason my player doesn't register the Inner Walls as blocking layers, he and the enemies both walk right over them like they are the floor. I can't notice anything wrong in the programming, and neither can my friend, but obviously something is wrong. Please help?


    Wall code:
    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. public class Wall : MonoBehaviour {
    5.  
    6.     public Sprite dmgSprite;
    7.     public int hp = 4;
    8.  
    9.     private SpriteRenderer spriteRenderer;
    10.  
    11.     // Use this for initialization
    12.     void Awake ()
    13.     {
    14.         spriteRenderer = GetComponent<SpriteRenderer>();
    15.     }
    16.    
    17.     public void DamageWall (int loss)
    18.     {
    19.         spriteRenderer.sprite = dmgSprite;
    20.         hp -= loss;
    21.         if (hp <= 0)
    22.             gameObject.SetActive(false);
    23.     }
    24. }
    25.  

    Player code:
    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.SceneManagement;
    4.  
    5. public class Player : MovingObject
    6. {
    7.     public int wallDamage = 1;
    8.     public int pointsPerFood = 10;
    9.     public int pointsPerSoda = 20;
    10.     public float restartLevelDelay = 1f;
    11.  
    12.     private Animator animator;
    13.     private int food;
    14.  
    15.     // Use this for initialization
    16.     protected override void Start()
    17.     {
    18.         animator = GetComponent<Animator>();
    19.  
    20.         food = GameManager.instance.playerFoodPoints;
    21.  
    22.         base.Start();
    23.     }
    24.  
    25.     private void OnDisable()
    26.     {
    27.         GameManager.instance.playerFoodPoints = food;
    28.     }
    29.  
    30.     // Update is called once per frame
    31.     private void Update()
    32.     {
    33.         if (!GameManager.instance.playersTurn) return;
    34.  
    35.         int horizontal = 0;
    36.         int vertical = 0;
    37.  
    38.         horizontal = (int)(Input.GetAxisRaw("Horizontal"));
    39.         vertical = (int)(Input.GetAxisRaw("Vertical"));
    40.  
    41.         if(horizontal != 0)
    42.         {
    43.             vertical = 0;
    44.         }
    45.  
    46.         if (horizontal != 0 || vertical != 0)
    47.             AttemptMove<Wall>(horizontal, vertical);
    48.     }
    49.  
    50.     protected override void AttemptMove <T> (int xDir, int yDir)
    51.     {
    52.         food--;
    53.  
    54.         base.AttemptMove<T>(xDir, yDir);
    55.  
    56.         RaycastHit2D hit;
    57.  
    58.         if (Move (xDir, yDir, out hit))
    59.         {
    60.  
    61.         }
    62.  
    63.         CheckIfGameOver();
    64.  
    65.         GameManager.instance.playersTurn = false;
    66.     }
    67.  
    68.    protected override void OnCantMove <T> (T component)
    69.     {
    70.         Wall hitwall = component as Wall;
    71.         hitwall.DamageWall(wallDamage);
    72.         animator.SetTrigger("playerChop");
    73.     }
    74.  
    75.     private void OnTriggerEnter2D(Collider2D other)
    76.     {
    77.         if (other.tag == "Exit")
    78.         {
    79.             Invoke("Restart", restartLevelDelay);
    80.             enabled = false;
    81.         }
    82.         else if (other.tag == "Food")
    83.         {
    84.             food += pointsPerFood;
    85.             other.gameObject.SetActive(false);
    86.         }
    87.         else if (other.tag == "Soda")
    88.         {
    89.             food += pointsPerSoda;
    90.             other.gameObject.SetActive(false);
    91.         }
    92.     }
    93.     private void Restart()
    94.     {
    95.         SceneManager.LoadScene(0);
    96.     }
    97.  
    98.     public void LoseFood (int loss)
    99.     {
    100.         animator.SetTrigger("playerHit");
    101.         food -= loss;
    102.         CheckIfGameOver();
    103.     }
    104.  
    105.     private void CheckIfGameOver()
    106.     {
    107.         if (food <= 0)
    108.         {
    109.             GameManager.instance.GameOver();
    110.         }
    111.     }
    112. }

    Enemy Code:
    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. public class Enemy : MovingObject
    5. {
    6.  
    7.     public int playerDamage;
    8.  
    9.     private Animator animator;
    10.     private Transform target;
    11.     private bool skipMove;
    12.  
    13.     protected override void Start ()
    14.     {
    15.         GameManager.instance.AddEnemyToList(this);
    16.         animator = GetComponent<Animator>();
    17.         target = GameObject.FindGameObjectWithTag("Player").transform;
    18.         base.Start();
    19.     }
    20.  
    21.     protected override void AttemptMove<T>(int xDir, int yDir)
    22.     {
    23.         if (skipMove)
    24.         {
    25.             skipMove = false;
    26.             return;
    27.         }
    28.  
    29.         base.AttemptMove<T>(xDir, yDir);
    30.  
    31.         skipMove = true;
    32.     }
    33.  
    34.     public void MoveEnemy()
    35.     {
    36.         int xDir = 0;
    37.         int yDir = 0;
    38.  
    39.         if (Mathf.Abs(target.position.x - transform.position.x) < float.Epsilon)
    40.             yDir = target.position.y > transform.position.y ? 1 : -1;
    41.         else
    42.             xDir = target.position.x > transform.position.x ? 1 : -1;
    43.  
    44.         AttemptMove<Player>(xDir, yDir);
    45.     }
    46.  
    47.     protected override void OnCantMove<T>(T component)
    48.     {
    49.         Player hitPlayer = component as Player;
    50.  
    51.         animator.SetTrigger("enemyAttack");
    52.  
    53.         hitPlayer.LoseFood(playerDamage);
    54.     }
    55. }
     
  19. archteck

    archteck

    Joined:
    Jan 29, 2018
    Posts:
    2

    Hi there, my guess off a plausible cause for this is :
    • Check if your Wall prefab's are untagged and the Layer selected is the same as the Player and the Enemy's, BlockingLayer.
    You may found more problems later, so i recommend you to read my post above(https://forum.unity.com/threads/2d-roguelike-q-a.297180/page-22#post-3375746), because you will have probably 2 boards at the same time.

    P.S. Please use Destroy(gameObject) instead off turning the gameObject.SetActive(false), because that Wall will never be used again, it will be instantiated a new one.

    Best regards
     
  20. BashiDono

    BashiDono

    Joined:
    Oct 23, 2017
    Posts:
    3
    Thank you for the script help, but now there seems to be a problem. The play screen is all black except for the player, you can see them, but they aren't dancing, and I checked my walls, all are Untagged BlockingLayers, and it loads the error:
    NullReferenceException: Object reference not set to an instance of an object
    GameManager.InitGame () (at Assets/Mine/Scripts/GameManager.cs:56)
    GameManager.OnLevelFinishedLoading (Scene scene, LoadSceneMode mode) (at Assets/Mine/Scripts/GameManager.cs:39)
    UnityEngine.SceneManagement.SceneManager.Internal_SceneLoaded (Scene scene, LoadSceneMode mode) (at C:/buildslave/unity/build/artifacts/generated/common/runtime/SceneManagerBindings.gen.cs:245)
     
  21. hailtonothing

    hailtonothing

    Joined:
    Sep 17, 2014
    Posts:
    2
    Hi all,

    I'm on step 5. Copied out the code exactly and it refuses to recognise boardmanager, and consequently does not recognise setupscene "(boardmanager does not contain a definition for setupscene") in the init function. I can't work out why and I'm tearing my hair out.

    The GameManager gameobject is created, both scripts are added to it. I've followed the video step by step as far as I can tell.

    Maybe worth noting that In the script inspector, neither of the scripts have visible variables - i.e. there's no way for me to drag prefabs onto the arrays etc. I assume these issues are related but...
    Also the gamemanager script icon always changes to a gear instead of the script icon. No idea why. I've deleted and recreated it 10 times and can't get it to not do this. it doesn't show this way in the completed game script.

    Some screens below... appreciate any help!

    Edit: Unity version is 2017.3

    upload_2018-2-5_22-14-4.png

    upload_2018-2-5_22-15-2.png

    upload_2018-2-5_22-16-7.png
     

    Attached Files:

  22. hailtonothing

    hailtonothing

    Joined:
    Sep 17, 2014
    Posts:
    2
    Never mind, I am a buffoon, and accidentally had all of BoardManager functions and variables INDSIDE the Count class. Sigh.

    On the plus side, I have saved money on haircuts.
     
  23. Varishaa

    Varishaa

    Joined:
    Feb 19, 2018
    Posts:
    16
    Hi,
    i got all things working but have a question just for my understanding.
    I wonder how it is done that the floor tiles are not overlapping. They are 32x32 in size and are aligned like:
    (0,0,0) first tile, (1,0,0) second tile, (2,0,0) 3rd tile, etc.

    Why is this sufficient, why is it not necessary to put the second tile at (32,0,0)?

    Regards Marcus
     
  24. Billedo

    Billedo

    Joined:
    Nov 24, 2016
    Posts:
    1
    If you click on the "Scavengers_SpriteSheet" in the "Sprites" folder, you open the "Import Settings" window (see attached image), and there is specified "32 pixels per unit".

    This may explain why it is sufficient to put the second tile at (2, 0, 0).
     

    Attached Files:

    pittmakesgames likes this.
  25. Beta4

    Beta4

    Joined:
    Nov 6, 2014
    Posts:
    34
    So is there a solution to this tutorial on making a restart function work properly by using a keyboard press like an R for example when your character loses or is still still up in the air. Im currently using Unity 2017.3 0f3 Personal Edition. Any tips to getting it work properly and not restarting at level 2 and then losing at level 4 when you take your first step would be greatly appreciated.
     
  26. Beta4

    Beta4

    Joined:
    Nov 6, 2014
    Posts:
    34
    bump
     
  27. guilhermecorintho

    guilhermecorintho

    Joined:
    Sep 24, 2017
    Posts:
    11
    Hey, about 2d Dungeon Generation

    What if I dont want to use 32x32 tiles? I've spent hours trying to find a solution. For example: When I try with 16x6 tiles, the board creator generates empty spaces between every tile. I can't find any reference to change it to be able to do it correctly with tiles that are not 32x32. Thank you

     
  28. Aminpk

    Aminpk

    Joined:
    Feb 24, 2018
    Posts:
    4
    it is a very detailed tutorial in an easy way, but the script creation is a little complicated.
    can i scale up the sprite sheet, for example it is 256x224 . i want to scale it 1000x500
    if i scale where can i change coding to make it fit.
     
  29. calebjackson

    calebjackson

    Joined:
    Mar 1, 2018
    Posts:
    1
    //This line:

    protected override void AttemptMove<T>(int xDir, int yDir)

    //Turns up this error:

    `Player.AttemptMove<T>(int, int)' cannot override inherited member 'MovingObject.AttemptMove<T>(int,int)' because it is not marked virtual, abstract, or override

    IT IS MARKED OVERRIDE! ...Isn't it? I replicated the error by copying the code straight from Unity's website. :/
     
  30. Aminpk

    Aminpk

    Joined:
    Feb 24, 2018
    Posts:
    4
    I changed the following part from 8 to 25, while the output in the game is just 10 cells.

    public int columns = 25; //Number of columns in our game board.
    public int rows = 25; //Number of rows in our game board.

    plz help anybody

    in video no. 4 I learnt the following

    " These will delineate the dimensions of our game board

    · 02:38 - 02:40

    and will allow us to make our game board

    · 02:40 - 02:42

    larger or smaller by changing them

    · 02:42 - 02:43

    if we want to.

    · 02:43 - 02:46

    In this case we're going to initialise them each to 8

    · 02:46 - 02:49

    meaning we're going to have an 8 by 8 game board.

    · 02:50 - 02:53 "



    why i am not getting a 25 by 25 gameboard ?
     
    Last edited: Mar 7, 2018
  31. Aminpk

    Aminpk

    Joined:
    Feb 24, 2018
    Posts:
    4




    ..........................................................




    Thanks everybody.
    I got it myself from GameManager's inspector window as below
     

    Attached Files:

  32. omalleym1115

    omalleym1115

    Joined:
    Aug 7, 2012
    Posts:
    2
    Hello all,

    I just finished the tutorial, but I am having some problems. Followed all of the steps in the thread and in the PDF, but my scenes won't transition. I am using the onEnable and it hits it, but now the OnLevelFinishedLoading and I don't know why. Can anyone see what I am doing wrong?


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using UnityEngine.SceneManagement;
    6.  
    7. public class GameManager : MonoBehaviour {
    8.  
    9.     public float levelStartDelay = 2f;                      //Time to wait before starting level, in seconds.
    10.     public float turnDelay = 0.1f;                          //Delay between each Player turn.
    11.     public int playerFoodPoints = 100;                      //Starting value for Player food points.
    12.     public static GameManager instance = null;              //Static instance of GameManager which allows it to be accessed by any other script.
    13.     [HideInInspector] public bool playersTurn = true;       //Boolean to check if it's players turn, hidden in inspector but public.
    14.  
    15.  
    16.     private Text levelText;                                 //Text to display current level number.
    17.     private GameObject levelImage;                          //Image to block out level as levels are being set up, background for levelText.
    18.     private BoardManager boardScript;                       //Store a reference to our BoardManager which will set up the level.
    19.     private int level = 1;                                  //Current level number, expressed in game as "Day 1".
    20.     private List<Enemy> enemies;                            //List of all Enemy units, used to issue them move commands.
    21.     private bool enemiesMoving;                             //Boolean to check if enemies are moving.
    22.     private bool doingSetup = true;                         //Boolean to check if we're setting up board, prevent Player from moving during setup.
    23.  
    24.  
    25.  
    26.     void OnEnable()
    27.     {
    28.         //Tell our ‘OnLevelFinishedLoading’ function to start listening for a scene change event as soon as this script is enabled.
    29.         Debug.Log("Calling onEnable!");
    30.         SceneManager.sceneLoaded += OnLevelFinishedLoading;
    31.     }
    32.  
    33.     //This is called each time a scene is loaded.
    34.     void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode)
    35.     {
    36.         Debug.Log("OnLevelFinishedLoading: " + scene.name);
    37.         Debug.Log(mode);
    38.         Debug.Log("Calling OnLevelFinishedLoading!");
    39.         //Add one to our level number.
    40.         level++;
    41.         //Call InitGame to initialize our level.
    42.         Debug.Log("Calling init game!");
    43.         InitGame();
    44.     }
    45.     void OnDisable()
    46.     {
    47.         Debug.Log("Calling onDisable!");
    48.         //Tell our ‘OnLevelFinishedLoading’ function to stop listening for a scene change event as soon as this script is disabled.
    49.         //Remember to always have an unsubscription for every delegate you subscribe to!
    50.         SceneManager.sceneLoaded -= OnLevelFinishedLoading;
    51.     }
    52.     // Use this for initialization
    53.     //Awake is always called before any Start functions
    54.     void Awake()
    55.     {
    56.         //Check if instance already exists
    57.         if (instance == null)
    58.  
    59.             //if not, set instance to this
    60.             instance = this;
    61.  
    62.         //If instance already exists and it's not this:
    63.         else if (instance != this)
    64.  
    65.             //Then destroy this. This enforces our singleton pattern, meaning there can only ever be one instance of a GameManager.
    66.             Destroy(gameObject);
    67.  
    68.         //Sets this to not be destroyed when reloading scene
    69.         DontDestroyOnLoad(gameObject);
    70.  
    71.         //Assign enemies to a new List of Enemy objects.
    72.         enemies = new List<Enemy>();
    73.  
    74.         //Get a component reference to the attached BoardManager script
    75.         boardScript = GetComponent<BoardManager>();
    76.  
    77.         //Call the InitGame function to initialize the first level
    78.       //  InitGame();
    79.     }
    80.     void InitGame()
    81.     {
    82.         doingSetup = true;
    83.  
    84.         levelImage = GameObject.Find("LevelImage");
    85.         levelText = GameObject.Find("LevelText").GetComponent<Text>();
    86.         levelText.text = "Day " + level;
    87.         levelImage.SetActive(true);
    88.  
    89.         Debug.Log("starting invode to hide level image! ");
    90.         //Call the HideLevelImage function with a delay in seconds of levelStartDelay.
    91.         Invoke("HideLevelImage", levelStartDelay);
    92.        
    93.         enemies.Clear(); //clears enemies out from previous levels.
    94.  
    95.         boardScript.SetupScene(level);
    96.     }
    97.  
    98.     private void HideLevelImage()
    99.     {
    100.         levelImage.SetActive(false);
    101.         doingSetup = false;
    102.     }
    103.  
    104.     public void GameOver()
    105.     {
    106.         levelText.text = "After " + level + " days, you starved";
    107.         levelImage.SetActive(true);
    108.         enabled = false;
    109.     }
    110.  
    111.     // Update is called once per frame
    112.     void Update()
    113.     {
    114.         if (playersTurn || enemiesMoving || doingSetup)
    115.             return;
    116.  
    117.         StartCoroutine(MoveEnemies());
    118.     }
    119.  
    120.     public void AddEnemyToList(Enemy script)
    121.     {
    122.         enemies.Add(script);
    123.     }
    124.  
    125.     IEnumerator MoveEnemies()
    126.     {
    127.         enemiesMoving = true;
    128.         yield return new WaitForSeconds(turnDelay);
    129.         if (enemies.Count ==0)
    130.         {
    131.             yield return new WaitForSeconds(turnDelay);
    132.         }
    133.  
    134.         for (int i = 0; i < enemies.Count; i++)
    135.         {
    136.             enemies[i].MoveEnemy();
    137.             yield return new WaitForSeconds(enemies[i].moveTime);
    138.         }
    139.  
    140.         playersTurn = true;
    141.         enemiesMoving = false;
    142.     }
    143.  
    144.  
    145.  
    146. }
    147.    
    148.  
    149.  
     
  33. omalleym1115

    omalleym1115

    Joined:
    Aug 7, 2012
    Posts:
    2
    Meant to say it won't hit OnLevelFinishedLoading right after hitting onEnable. Won't let me hit edit to fix the text.
     
  34. guilhermecorintho

    guilhermecorintho

    Joined:
    Sep 24, 2017
    Posts:
    11
    What if I want to build larger corridors using the Basic 2D Dungeon Generation?
     
  35. Merlin143

    Merlin143

    Joined:
    Apr 19, 2018
    Posts:
    1
    where r the instructions???
    I click on page to get to them but they not there
    I require answer in less than hour... school project due tomorrow...
     
  36. gamemaster0007

    gamemaster0007

    Joined:
    Apr 30, 2018
    Posts:
    3
    Hey all, I finished the player.cs script, but when I was done there was the following error
    Assets/scripts/Player.cs(23,26): error CS0115: `Player.attemptMove<T>(int, int)' is marked as an override but no suitable method found to override
    and then the same thing but for Player.onCantMove<T>(int,int)
    I don't understand what the problem is. here is the code
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Completed;
    5. using UnityEngine.SceneManagement;
    6. public class Player : MovingObject
    7. {
    8.     public int WallDamage = 1;
    9.     public int pointsPerFood = 10;
    10.     public int pointsPerSoda = 20;
    11.     public float restartLevelDelay = 1f;
    12.     private Animator animator;
    13.     private int food = 100;
    14.     // Use this for initialization
    15.     protected override void Start () {
    16.         animator = GetComponent<Animator> ();
    17.         food = GameManager.instance.playerFoodPoints;
    18.         base.Start;
    19.     }
    20.     public void onDisable(){
    21.         GameManager.instance.playerFoodPoints = food;
    22.     }
    23.     protected override void attemptMove<T>(int xdir,int ydir){
    24.         food -= 1;
    25.         base.attemptMove<T> (xdir, ydir);
    26.         Raycast2D hit;
    27.         checkIfGameOver ();
    28.         GameManager.instance.playersTurn = false;
    29.     }
    30.     // Update is called once per frame
    31.     void Update () {
    32.         if (!GameManager.instance.payersTurn) {
    33.             return;
    34.         }
    35.             int horizantal = 0;
    36.             int vertical = 0;
    37.         horizantal = (int)Input.GetAxisRaw ("Horizantal");
    38.         vertical = (int)Input.GetAxisRaw ("Vertical");
    39.         if (horizantal != 0) {
    40.             vertical = 0;
    41.         }
    42.         if (horizantal != 0 || vertical != 0) {
    43.             attemptMove <WallDamage> (horizantal,vertical);
    44.         }
    45.     }
    46.     public override void onCantMove<T>(T component){
    47.         Wall hitWall = component as Wall;
    48.         hitWall.damageWall (WallDamage);
    49.         animator.SetTrigger ("playerChop");
    50.     }
    51.     private void onTriggerEnter2D (Collider2D other){
    52.         if (other.Tag == "Exit") {
    53.             Invoke ("restart", restartLevelDelay);
    54.             enabled = false;
    55.         } else if (other.tag == "Food") {
    56.             food += pointsPerFood;
    57.             other.gameObject.SetActive(false);
    58.         }else if (other.tag == "Soda") {
    59.             food += pointsPerSoda;
    60.             other.gameObject.SetActive(false);
    61.         }
    62.     }
    63.     private void restart(){
    64.         SceneManager.LoadScene (0);
    65.     }
    66.     public void loseFood(int loss){
    67.         animator.SetTrigger ("playerHit");
    68.         food -= loss;
    69.         checkIfGameOver ();
    70.     }
    71.     private void checkIfGameOver(){
    72.         if (food <= 0) {
    73.             GameManager.instance.GameOver ();
    74.         }
    75.     }
    76. }
    77.  
    and moving object
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using Completed;
    4. //The abstract keyword enables you to create classes and class members that are incomplete and must be implemented in a derived class.
    5. public abstract class MovingObject : MonoBehaviour
    6. {
    7.     public float moveTime = 0.1f;           //Time it will take object to move, in seconds.
    8.     public LayerMask blockingLayer;         //Layer on which collision will be checked.
    9.  
    10.  
    11.     private BoxCollider2D boxCollider;      //The BoxCollider2D component attached to this object.
    12.     private Rigidbody2D rb2D;               //The Rigidbody2D component attached to this object.
    13.     private float inverseMoveTime;          //Used to make movement more efficient.
    14.  
    15.  
    16.     //Protected, virtual functions can be overridden by inheriting classes.
    17.     protected virtual void Start ()
    18.     {
    19.         //Get a component reference to this object's BoxCollider2D
    20.         boxCollider = GetComponent <BoxCollider2D> ();
    21.  
    22.         //Get a component reference to this object's Rigidbody2D
    23.         rb2D = GetComponent <Rigidbody2D> ();
    24.  
    25.         //By storing the reciprocal of the move time we can use it by multiplying instead of dividing, this is more efficient.
    26.         inverseMoveTime = 1f / moveTime;
    27.     }
    28.  
    29.  
    30.     //Move returns true if it is able to move and false if not.
    31.     //Move takes parameters for x direction, y direction and a RaycastHit2D to check collision.
    32.     protected bool Move (int xDir, int yDir, out RaycastHit2D hit)
    33.     {
    34.         //Store start position to move from, based on objects current transform position.
    35.         Vector2 start = transform.position;
    36.  
    37.         // Calculate end position based on the direction parameters passed in when calling Move.
    38.         Vector2 end = start + new Vector2 (xDir, yDir);
    39.  
    40.         //Disable the boxCollider so that linecast doesn't hit this object's own collider.
    41.         boxCollider.enabled = false;
    42.  
    43.         //Cast a line from start point to end point checking collision on blockingLayer.
    44.         hit = Physics2D.Linecast (start, end, blockingLayer);
    45.  
    46.         //Re-enable boxCollider after linecast
    47.         boxCollider.enabled = true;
    48.  
    49.         //Check if anything was hit
    50.         if(hit.transform == null)
    51.         {
    52.             //If nothing was hit, start SmoothMovement co-routine passing in the Vector2 end as destination
    53.             StartCoroutine (SmoothMovement (end));
    54.  
    55.             //Return true to say that Move was successful
    56.             return true;
    57.         }
    58.  
    59.         //If something was hit, return false, Move was unsuccesful.
    60.         return false;
    61.     }
    62.  
    63.  
    64.     //Co-routine for moving units from one space to next, takes a parameter end to specify where to move to.
    65.     protected IEnumerator SmoothMovement (Vector3 end)
    66.     {
    67.         //Calculate the remaining distance to move based on the square magnitude of the difference between current position and end parameter.
    68.         //Square magnitude is used instead of magnitude because it's computationally cheaper.
    69.         float sqrRemainingDistance = (transform.position - end).sqrMagnitude;
    70.  
    71.         //While that distance is greater than a very small amount (Epsilon, almost zero):
    72.         while(sqrRemainingDistance > float.Epsilon)
    73.         {
    74.             //Find a new position proportionally closer to the end, based on the moveTime
    75.             Vector3 newPostion = Vector3.MoveTowards(rb2D.position, end, inverseMoveTime * Time.deltaTime);
    76.  
    77.             //Call MovePosition on attached Rigidbody2D and move it to the calculated position.
    78.             rb2D.MovePosition (newPostion);
    79.  
    80.             //Recalculate the remaining distance after moving.
    81.             sqrRemainingDistance = (transform.position - end).sqrMagnitude;
    82.  
    83.             //Return and loop until sqrRemainingDistance is close enough to zero to end the function
    84.             yield return null;
    85.         }
    86.     }
    87.  
    88.  
    89.     //The virtual keyword means AttemptMove can be overridden by inheriting classes using the override keyword.
    90.     //AttemptMove takes a generic parameter T to specify the type of component we expect our unit to interact with if blocked (Player for Enemies, Wall for Player).
    91.     protected virtual void AttemptMove <T> (int xDir, int yDir)
    92.         where T : Component
    93.     {
    94.         //Hit will store whatever our linecast hits when Move is called.
    95.         RaycastHit2D hit;
    96.  
    97.         //Set canMove to true if Move was successful, false if failed.
    98.         bool canMove = Move (xDir, yDir, out hit);
    99.  
    100.         //Check if nothing was hit by linecast
    101.         if(hit.transform == null)
    102.             //If nothing was hit, return and don't execute further code.
    103.             return;
    104.  
    105.         //Get a component reference to the component of type T attached to the object that was hit
    106.         T hitComponent = hit.transform.GetComponent <T> ();
    107.  
    108.         //If canMove is false and hitComponent is not equal to null, meaning MovingObject is blocked and has hit something it can interact with.
    109.         if(!canMove && hitComponent != null)
    110.  
    111.             //Call the OnCantMove function and pass it hitComponent as a parameter.
    112.             OnCantMove (hitComponent);
    113.     }
    114.  
    115.  
    116.     //The abstract modifier indicates that the thing being modified has a missing or incomplete implementation.
    117.     //OnCantMove will be overriden by functions in the inheriting classes.
    118.     protected abstract void OnCantMove <T> (T component)
    119.         where T : Component;
    120. }
    121.  
    122.  
     
  37. gwnguy

    gwnguy

    Joined:
    Apr 25, 2017
    Posts:
    144
    line 23 of 'public class Player : MovingObject' references class named "attemptMove" (lower case a in attempt)
    protected override void attemptMove<T>(int xdir,int ydir){

    line 91 of 'public abstract class MovingObject : MonoBehaviour' defines class named "AttemptMove" (upper case A in Attempt)
    protected virtual void AttemptMove <T> (int xDir, int yDir)
    where T : Component

    Try changing line 23 of 'public class Player : MovingObject' to
    protected override void AttemptMove<T>(int xdir,int ydir){

    and see if that helps


    Same thing with onCantMove, upper vs lower case
     
  38. Smokeythebud

    Smokeythebud

    Joined:
    Aug 9, 2017
    Posts:
    34
    Hello, I am on part 4 of the tutorial and just wondering about the for loop why
    Code (CSharp):
    1. For (int x = 1; x &lt; columns -1; x++;)
    Instead of
    Code (CSharp):
    1. For (int x = 1; x < columns -1; x++;)
    thanks in advance
     
  39. Epic-Jargon

    Epic-Jargon

    Joined:
    Mar 23, 2013
    Posts:
    1
    Code (CSharp):
    1. public class SoundManager : MonoBehaviour {
    2.  
    3.     public AudioSource efxSource;                   //Drag a reference to the audio source which will play the sound effects.
    4.     public AudioSource musicSource;                 //Drag a reference to the audio source which will play the music.
    5.     public static SoundManager instance = null;     //Allows other scripts to call functions from SoundManager.          
    6.    
    7.     public float lowPitchRange = .95f;              //The lowest a sound effect will be randomly pitched.
    8.     public float highPitchRange = 1.05f;            //The highest a sound effect will be randomly pitched.
    9.  
    10.  
    11.     void Awake()
    12.     {
    13.         //Check if there is already an instance of SoundManager
    14.         if (instance == null)
    15.             //if not, set it to this.
    16.             instance = this;
    17.         //If instance already exists:
    18.         else if (instance != this)
    19.             //Destroy this, this enforces our singleton pattern so there can only be one instance of SoundManager.
    20.             Destroy(gameObject);
    21.  
    22.         //Set SoundManager to DontDestroyOnLoad so that it won't be destroyed when reloading our scene.
    23.         DontDestroyOnLoad(gameObject);
    24.     }
    25.  
    26.  
    27.     //Used to play single sound clips.
    28.     public void PlaySingle(AudioClip clip)
    29.     {
    30.         //Set the clip of our efxSource audio source to the clip passed in as a parameter.
    31.         efxSource.clip = clip;
    32.  
    33.         //Play the clip.
    34.         efxSource.Play();
    35.     }
    36.  
    37.  
    38.     //RandomizeSfx chooses randomly between various audio clips and slightly changes their pitch.
    39.     public void RandomizeSfx(params AudioClip[] clips)
    40.     {
    41.         //Generate a random number between 0 and the length of our array of clips passed in.
    42.         int randomIndex = Random.Range(0, clips.Length);
    43.  
    44.         //Choose a random pitch to play back our clip at between our high and low pitch ranges.
    45.         float randomPitch = Random.Range(lowPitchRange, highPitchRange);
    46.  
    47.         //Set the pitch of the audio source to the randomly chosen pitch.
    48.         efxSource.pitch = randomPitch;
    49.  
    50.         //Set the clip to the clip at our randomly chosen index.
    51.         efxSource.clip = clips[randomIndex];
    52.  
    53.         //Play the clip.
    54.         efxSource.Play();
    55.     }
    im on part 13 : Audio and Sound Manager but the sound manager seems to break the game any time a sound would play ie code such as
    SoundManager.instance.RandomizeSfx(drinkSound1, drinkSound2);


    would run i get an error like:
    NullReferenceException: Object reference not set to an instance of an object
    Player.OnTriggerEnter2D (UnityEngine.Collider2D other) (at Assets/Scripts/Player.cs:214)


    im not sure whats happening as the sound manager is definatly instanciated, its in the hierachy and playing background music. after i got this error and couldnt figure it out i started just replacing my code with theres to make sure i hadnt copied it wrong but i still get the same errors

    edit: added sound manager script in, its there script but figured if i didnt someone would ask me to include it. figuring that id screwed up (if i have let me know :))
     
    Last edited: May 4, 2018
  40. Emilylyn1

    Emilylyn1

    Joined:
    May 5, 2018
    Posts:
    1
    Thanks for this. I was about to post here asking for help when I came across this post. It resolved the bugs I was seeing. :)
     
  41. D-E-L-B

    D-E-L-B

    Joined:
    Aug 27, 2013
    Posts:
    21
    Does anyone know why when the game first launches the character speed is faster than when you go to the next scene/next day?

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. namespace RogueKnight
    5. {
    6.     public abstract class MovingElement : MonoBehaviour
    7.     {
    8.         // BoxCollider2D, Rigidbody2D and float variable (which is used to make the movement more refined)
    9.         private BoxCollider2D boxCollider2D;
    10.         private float oppositeMoveTime;
    11.         private new Rigidbody2D rigidbody2D;
    12.  
    13.         // This is the time it will take for an element to move
    14.         public float movingElementTime;
    15.         // Layer for collision detection
    16.         public LayerMask blockingLayerMask;      
    17.  
    18.  
    19.         //Protected, virtual functions can be overridden by inheriting classes.
    20.         protected virtual void Start ()
    21.         {
    22.             // Reference to "THIS" element's "BoxCollider2D" component
    23.             boxCollider2D = GetComponent <BoxCollider2D> ();
    24.  
    25.             // Reference to "THIS" element's "Rigidbody2D" component
    26.             rigidbody2D = GetComponent <Rigidbody2D> ();
    27.  
    28.             // Stores the reciprocal of movingElementTime we can use it by doing multiplication
    29.             oppositeMoveTime = 1f / movingElementTime;
    30.         }
    31.        
    32.        
    33.         // This function returns a "true" if it is available to move, otherwise it's false
    34.         // Takes an x and y for direction and a RaycastHit2D to check for a collision
    35.         protected bool MoveElement(int x, int y, out RaycastHit2D raycastHit)
    36.         {
    37.             // Use this variable to assign a start position to move from
    38.             Vector2 startPos = transform.position;
    39.            
    40.             // This is used to calculate the end position based on direction params passed into this function
    41.             Vector2 endPos = startPos + new Vector2 (x, y);
    42.  
    43.             // This disables the boxCollider2D so that the linecast doesn't hit the element's collider
    44.             boxCollider2D.enabled = false;
    45.  
    46.             // Casts a line from a start point to an end point whilst checking collision on blockingLayerMask
    47.             raycastHit = Physics2D.Linecast (startPos, endPos, blockingLayerMask);
    48.            
    49.             // Enable the boxCollider2D again
    50.             boxCollider2D.enabled = true;
    51.            
    52.             // Check if something had been hit
    53.             if(raycastHit.transform == null)
    54.             {
    55.                 // If there was nothing to hit then start the "SmoothMovement" coroutine whilst passing the "Vector2" end as the destination
    56.                 StartCoroutine (SmoothElementMovement(endPos));
    57.                
    58.                 // If there was a "Move" then return true
    59.                 return true;
    60.             }
    61.            
    62.             // If there was a collision, the "Move" was not successful
    63.             return false;
    64.         }
    65.        
    66.        
    67.         // This is a coroutine for moving entities from one space to the next space
    68.         protected IEnumerator SmoothElementMovement(Vector3 end)
    69.         {
    70.             // This variable is used to calculate the leftover distance to move along by using the square magnitude of the difference between the current pos and end param
    71.             // Square magnitude is used instead of magnitude because it's computationally cheaper.
    72.             float sqredRemainingDistance = (transform.position - end).sqrMagnitude;
    73.            
    74.             // While sqredRemainingDistance is greater than a miniscule amount:
    75.             while(sqredRemainingDistance > float.Epsilon)
    76.             {
    77.                 // Find a new position that is closer to the end based on the oppositeMoveTime
    78.                 Vector3 newPos = Vector3.MoveTowards(rigidbody2D.position, end, oppositeMoveTime * Time.deltaTime);
    79.                
    80.                 // Call the MovePosition on the attached "Rigidbody2D" and move it to the calculated pos
    81.                 rigidbody2D.MovePosition (newPos);
    82.  
    83.                 // Calculate the leftover distance again after an element
    84.                 sqredRemainingDistance = (transform.position - end).sqrMagnitude;
    85.  
    86.                 // Return and keep repeating until sqredRemainingDistance is approximately zero to end this function
    87.                 yield return null;
    88.             }
    89.         }
    90.  
    91.  
    92.         // The virtual keyword makes sure that "TryMove" can be overridden by inheriting classes using "override"
    93.         // "TryMove" takes a generic parameter to specify the type of the component we expect our entity to interact with if the entity is blocked
    94.         protected virtual void TryMove <T> (int x, int y)
    95.             where T : Component
    96.         {
    97.             // Hit will hold what the linecast hits when "MoveElement" is invoked
    98.             RaycastHit2D hit;
    99.  
    100.             // canMove is set to true if "MoveElement" was successful
    101.             bool moveAllowed = MoveElement(x, y, out hit);
    102.  
    103.             // This checks to see if nothing was hit by the linecast
    104.             if (hit.transform == null)
    105.             {
    106.                 // If nothing was hit at all then get out of this function
    107.                 return;
    108.             }
    109.  
    110.             // Gets a "component" reference to the type T (a generic) that is attached to the element that was hit
    111.             T hitComponent = hit.transform.GetComponent<T>();
    112.  
    113.             // If canMove is false and also hitComponent is not equal to null
    114.             if (!moveAllowed && hitComponent != null)
    115.             {
    116.                 // Call the IfCantMove function and pass hitComponent as the param
    117.                 IfCantMove(hitComponent);
    118.             }
    119.         }
    120.  
    121.         // This function in an inherited class
    122.         protected abstract void IfCantMove <T> (T component)
    123.             where T : Component;          
    124.     }
    125. }
    126.  
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;    //Allows us to use UI.
    4. using UnityEngine.SceneManagement;
    5.  
    6. namespace RogueKnight
    7. {
    8.     // "Player" inherits from MovingElement
    9.     public class Knight : MovingElement
    10.     {
    11.         // Adds more energy when the player picks up a cake
    12.         public int pointsPerCake = 15;
    13.  
    14.         //Delay time to restart level
    15.         public float levelRestartDelay = 1f;      
    16.  
    17.         // The amount of damage a player does to a wall when stabbing it
    18.         public int damagedWall = 1;
    19.  
    20.         // Adds more energy when the player picks up wine
    21.         public int pointsPerWine = 25;              
    22.  
    23.         // This is used to store the player food points total during the level
    24.         private int energy;
    25.  
    26.         // Text to display how much energy you have
    27.         public Text energyText;                      
    28.  
    29.         // References to "AudioClips" to play sounds for a variety of different reasons
    30.         public AudioClip moveSound1;              
    31.         public AudioClip moveSound2;              
    32.         public AudioClip eatSound1;                  
    33.         public AudioClip eatSound2;                  
    34.         public AudioClip drinkSound1;              
    35.         public AudioClip drinkSound2;              
    36.         public AudioClip gameOverSound;              
    37.        
    38.         // Reference to access the player animations
    39.         private Animator animator;                    
    40.        
    41.        
    42.         // This will override the Start function in "MovingObject"
    43.         protected override void Start ()
    44.         {
    45.             // Gets a reference to the Player's "animator" component
    46.             animator = GetComponent<Animator>();
    47.            
    48.             // Gets the current energy point total stored in GameManager.instance and is shared between levels
    49.             energy = GameManager.instance.playerFoodPoints;
    50.  
    51.             // Sets the energyText to reflect the current energy total
    52.             energyText.text = "Energy: " + energy;
    53.            
    54.             // Calls the "Start" function of the "MovingObject" base class
    55.             base.Start ();
    56.         }
    57.        
    58.        
    59.         // This function is called when "THIS" game object the script is attached to is disabled
    60.         private void OnDisable ()
    61.         {
    62.             // When the "Player" object is disabled, it stores the current local energy total in the "GameManager" so it can be shared to the next level
    63.             GameManager.instance.playerFoodPoints = energy;
    64.         }
    65.        
    66.        
    67.         private void Update ()
    68.         {
    69.             // If it isn't the player's turn then don't run this function anymore
    70.             if (!GameManager.instance.knightsTurn)
    71.             {
    72.                 return;
    73.             }
    74.  
    75.             // These variables are used to store the horizontal and vertical direction
    76.             int vertical = 0;
    77.             int horizontal = 0;
    78.  
    79.             // Assigns "horizontal" and "vertical" to the axes in Unity
    80.             vertical = (int)(Input.GetAxisRaw("Vertical"));
    81.             horizontal = (int) (Input.GetAxisRaw ("Horizontal"));
    82.            
    83.             // If moving horizontally, you aren't moving vertically
    84.             if(horizontal != 0)
    85.             {
    86.                 vertical = 0;
    87.             }
    88.  
    89.             //Check if we have a non-zero value for horizontal or vertical
    90.             if(horizontal != 0 || vertical != 0)
    91.             {
    92.                 // Invoke "TryMove" whilst passing in the param "BreakableWall," since that is what the Player might encounter
    93.                 // Pass in the "horizontal" and "vertical" as params to tell the direction to move the Player in
    94.                 TryMove<BreakableWall> (horizontal, vertical);
    95.             }
    96.         }
    97.        
    98.         // Takes a generic "T" which will be of type "Wall," it also takes the integers for the x and y direction to move in
    99.         protected override void TryMove <T> (int x, int y)
    100.         {
    101.             // Each time the player moves, subtract the energy points
    102.             energy--;
    103.  
    104.             // Update the food text display to reflect the current amount of energy
    105.             energyText.text = "Energy: " + energy;
    106.            
    107.             // Call the "TryMove" function in the base class by passing in the generic "T" (the wall) and the x and y to move in
    108.             base.TryMove<T> (x, y);
    109.  
    110.             // RaycastHit2D allows a reference to the result of the Linecast done in "MoveObject"
    111.             RaycastHit2D raycastHit;
    112.  
    113.             // If "MoveObject" does return true then the player can move into an empty space
    114.             if (MoveElement(x, y, out raycastHit))
    115.             {
    116.                 // This will play a random sound, either moveSound1/2
    117.                 SoundManager.instance.RandomSoundEffect(moveSound1, moveSound2);
    118.             }
    119.            
    120.             // Check to see if the player has no cake points left
    121.             IsGameOver ();
    122.            
    123.             // The players turn is now over, so they cannot move when the enemies are moving
    124.             GameManager.instance.knightsTurn = false;
    125.         }
    126.  
    127.         // This function takes a generic "T" which in this scenario is the "Wall"
    128.         protected override void IfCantMove <T> (T component)
    129.         {
    130.             // Set hitWall to equal the component passed in as the param
    131.             BreakableWall wallHit = component as BreakableWall;
    132.  
    133.             // Call the HitWall function of the Wall we are now hitting
    134.             wallHit.HitWall (damagedWall);
    135.            
    136.             // Set it so the player is now stabbing
    137.             animator.SetTrigger ("playerStab");
    138.         }
    139.        
    140.         private void OnTriggerEnter2D (Collider2D other)
    141.         {
    142.             // Check if the player collided with a game object with the tag "NextDungeon"
    143.             if(other.tag == "NextDungeon")
    144.             {
    145.                 // Call the "Restart" function to start the next level with a delay of restartLevelDelay
    146.                 Invoke ("Restart", levelRestartDelay);
    147.                
    148.                 // Disable the player object since the level is now over
    149.                 enabled = false;
    150.             }
    151.            
    152.             // If the player collected some cake
    153.             else if(other.tag == "Cake")
    154.             {
    155.                 // Add some energy
    156.                 energy += pointsPerCake;
    157.  
    158.                 // Update the energyText to show the current amount of energy that the player possesses
    159.                 energyText.text = "+" + pointsPerCake + " Energy: " + energy;
    160.  
    161.                 // Invoke the RandomSoundEffect function pass in two eat sounds to choose from
    162.                 SoundManager.instance.RandomSoundEffect(eatSound1, eatSound2);
    163.                
    164.                 // Don't show the cake the player collided with
    165.                 other.gameObject.SetActive (false);
    166.             }
    167.            
    168.             // Same as above but for the wine
    169.             else if(other.tag == "Wine")
    170.             {
    171.                 energy += pointsPerWine;
    172.  
    173.                 energyText.text = "+" + pointsPerWine + " Energy: " + energy;
    174.                
    175.                 SoundManager.instance.RandomSoundEffect(drinkSound1, drinkSound2);
    176.                
    177.                 other.gameObject.SetActive (false);
    178.             }
    179.         }
    180.        
    181.        
    182.         // This reloads the scene
    183.         private void Restart ()
    184.         {
    185.             //Load the last scene loaded and load it in "Single" mode to replace the existing one
    186.             SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex, LoadSceneMode.Single);
    187.         }
    188.        
    189.        
    190.         // This is called when any enemy attacks the player
    191.         public void LoseEnergy (int energyLoss)
    192.         {
    193.             // Set it so the player has been hurt
    194.             animator.SetTrigger ("playerHurt");
    195.  
    196.             //Subtract energyLoss from the total amount of energy
    197.             energy -= energyLoss;
    198.  
    199.             // Update the food display with the most up-to-date energy total
    200.             energyText.text = "-" + energyLoss + " Energy: " + energy;
    201.            
    202.             // Check to see if game has been ended
    203.             IsGameOver ();
    204.         }
    205.        
    206.        
    207.         // If there is no more energy left then play a sound and end the game
    208.         private void IsGameOver()
    209.         {
    210.             if (energy <= 0)
    211.             {              
    212.                 SoundManager.instance.musicSource.Stop();
    213.                 GameManager.instance.GameOver ();
    214.             }
    215.         }
    216.     }
    217. }
    218.  
    I have tried to rebuild it myself so variables and comments are different.

    Thanks.
     
  42. Czar-Man

    Czar-Man

    Joined:
    May 10, 2013
    Posts:
    20
    When starting the completed project on my phone, it doesn't detect touch input on my phone outside of the menus.
     
  43. AlfredvanRaal

    AlfredvanRaal

    Joined:
    Feb 27, 2017
    Posts:
    5
    Thanks, this helped me to solve two of my bugs in gameplay:
    - The game started on Day 2 and then next level was Day 4.
    - On day four scene began with food points zero. After one move, sprite "starved".
    I already thought it had something to do with loading scripts double time instead of single, but couldn't find the solution.

    Still have some bugs left:
    - i can move through enemy.
    - And in player script: "The variable "hit" is declared but never used"
     
  44. AlfredvanRaal

    AlfredvanRaal

    Joined:
    Feb 27, 2017
    Posts:
    5
    ______________

    Thanks! I searched two hours myself for this and couldnt find it!
    This is exactly what i need to stop my sprite from moving through enemies!
     
  45. AlfredvanRaal

    AlfredvanRaal

    Joined:
    Feb 27, 2017
    Posts:
    5
    Thought i almost were there. But now i finished the Audio and Soundmanager and for some reason the game states at starting te Level after just 1 move "you starved".
    No idea why? What does Soundmanager and Audio have to do with that? Maybe some-one knows?
     
  46. Negtiv

    Negtiv

    Joined:
    Mar 27, 2018
    Posts:
    1
    i have a problem with the player. i can only move once after that it doesn't move anymore

    Player.cs script.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5.  
    6. public class Player : MovingObject
    7. {
    8.  
    9.     public int wallDamage = 1;
    10.     public int pointsPerFood = 10;
    11.     public int pointsPerSoda = 20;
    12.     public float restartLevelDelay = 1f;
    13.  
    14.     private Animator animator;
    15.     private int food;
    16.  
    17.  
    18.     protected override void Start()
    19.     {
    20.         animator = GetComponent<Animator>();
    21.  
    22.         food = GameManager.instance.playerFoodPoints;
    23.  
    24.         base.Start();
    25.     }
    26.  
    27.     private void OnDisable()
    28.     {
    29.         GameManager.instance.playerFoodPoints = food;
    30.     }
    31.  
    32.     void Update()
    33.     {
    34.         if (!GameManager.instance.playersTurn) return;
    35.  
    36.         int horizontal = 0;
    37.         int vertical = 0;
    38.  
    39.         horizontal = (int)Input.GetAxisRaw("Horizontal");
    40.         vertical = (int)Input.GetAxisRaw("Vertical");
    41.  
    42.         if (horizontal != 0)
    43.             vertical = 0;
    44.  
    45.         if (horizontal != 0 || vertical != 0)
    46.             AttemptMove<Wall>(horizontal, vertical);
    47.     }
    48.  
    49.     protected override void AttemptMove<T>(int xDir, int yDir)
    50.     {
    51.         food--;
    52.  
    53.         base.AttemptMove<T>(xDir, yDir);
    54.  
    55.         RaycastHit2D hit;
    56.  
    57.         CheckIfGameOver();
    58.  
    59.         GameManager.instance.playersTurn = false;
    60.     }
    61.  
    62.     private void OnTriggerEnter2D(Collider2D other)
    63.     {
    64.         if (other.tag == "Exit")
    65.         {
    66.             Invoke("Restart", restartLevelDelay);
    67.             enabled = false;
    68.         }
    69.         else if (other.tag == "Food")
    70.         {
    71.             food += pointsPerFood;
    72.             other.gameObject.SetActive(false);
    73.         }
    74.         else if (other.tag == "Soda")
    75.         {
    76.             food += pointsPerSoda;
    77.             other.gameObject.SetActive(false);
    78.         }
    79.  
    80.     }
    81.  
    82.     protected override void OnCantMove<T>(T component)
    83.     {
    84.         Wall hitWall = component as Wall;
    85.         hitWall.DamageWall(wallDamage);
    86.         animator.SetTrigger("playerChop");
    87.     }
    88.  
    89.     private void Restart()
    90.     {
    91.         SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    92.     }
    93.  
    94.     public void LoseFood(int loss)
    95.     {
    96.         animator.SetTrigger("playerHit");
    97.         food -= loss;
    98.         CheckIfGameOver();
    99.     }
    100.  
    101.     private void CheckIfGameOver()
    102.     {
    103.         if (food <= 0)
    104.             GameManager.instance.GameOver();
    105.     }
    106. }
    GameManager.cs

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class GameManager : MonoBehaviour
    6. {
    7.     public float turnDelay = .1f;
    8.     public static GameManager instance = null;
    9.     public BoardManager boardScript;
    10.     public int playerFoodPoints = 100;
    11.     [HideInInspector] public bool playersTurn = true;
    12.  
    13.     private int level = 3;
    14.     private List<Enemy> enemies;
    15.     private bool enemiesMoving;
    16.  
    17.  
    18.     void Awake()
    19.     {
    20.         if (instance == null)
    21.             instance = this;
    22.         else if (instance != this)
    23.             Destroy(gameObject);
    24.  
    25.         DontDestroyOnLoad(gameObject);
    26.         enemies = new List<Enemy>();
    27.         boardScript = GetComponent<BoardManager>();
    28.         InitGame();
    29.     }
    30.  
    31.     void InitGame()
    32.     {
    33.         enemies.Clear();
    34.         boardScript.SetupScene(level);
    35.     }
    36.  
    37.     public void GameOver()
    38.     {
    39.         enabled = false;
    40.     }
    41.  
    42.     void Update()
    43.     {
    44.         if (playersTurn || enemiesMoving)
    45.             return;
    46.  
    47.         StartCoroutine(MoveEnemies());
    48.     }
    49.  
    50.     public void AddEnemyToList(Enemy script)
    51.     {
    52.         enemies.Add(script);
    53.     }
    54.  
    55.     IEnumerator MoveEnemies()
    56.     {
    57.         enemiesMoving = true;
    58.         yield return new WaitForSeconds(turnDelay);
    59.         if (enemies.Count == 0)
    60.         {
    61.             yield return new WaitForSeconds(turnDelay);
    62.         }
    63.  
    64.         for (int i = 0; i < enemies.Count; i++)
    65.         {
    66.             enemies[i].MoveEnemy();
    67.             yield return new WaitForSeconds(enemies[i].moveTime);
    68.         }
    69.  
    70.         playersTurn = true;
    71.         enemiesMoving = false;
    72.     }
    73. }
     
    paulatkins88 likes this.
  47. Smokeythebud

    Smokeythebud

    Joined:
    Aug 9, 2017
    Posts:
    34
    hello, I worked my way through all of step 11, when I play tested everything works fine except the enemies will not attack, I compared the compete code to mine and cant see the difference. Although when I use the completed code it works fine so I must be missing something and here is the code

    mine not working:
    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class Enemy : MovingObject
    7. {
    8.     public int playerDamage;
    9.  
    10.     private Animator animator;
    11.     private Transform target;
    12.     private bool skipMove;
    13.  
    14.     protected override void Start()
    15.     {
    16.         GameManager.instance.AddEnemyToList(this);
    17.         animator = GetComponent<Animator>();
    18.         target = GameObject.FindGameObjectWithTag("Player").transform;
    19.         base.Start();
    20.     }
    21.  
    22.     protected override void AttemptMove<T>(int xDir, int yDir)
    23.     {
    24.         if (skipMove)
    25.         {
    26.             skipMove = false;
    27.             return;
    28.         }
    29.  
    30.         base.AttemptMove<T>(xDir, yDir);
    31.         skipMove = true;
    32.     }
    33.     public void MoveEnemy()
    34.     {
    35.         int xDir = 0;
    36.         int yDir = 0;
    37.         if (Mathf.Abs(target.position.x - transform.position.x) > float.Epsilon)
    38.             yDir = target.position.y > transform.position.y ? 1 : -1;
    39.         else
    40.             xDir = target.position.x > transform.position.x ? 1 : -1;
    41.  
    42.         AttemptMove<Player>(xDir, yDir);
    43.     }
    44.  
    45.     protected override void OnCantMove<T>(T component)
    46.     {
    47.         Player hitPlayer = component as Player;
    48.         hitPlayer.LoseFood(playerDamage);
    49.         animator.SetTrigger("enemyAttack");
    50.     }
    51. }
    52.  
    and the completed code from the kit:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Enemy : MovingObject
    6. {
    7.     public int playerDamage;
    8.  
    9.     private Animator animator;
    10.     private Transform target;
    11.     private bool skipMove;
    12.  
    13.     protected override void Start()
    14.     {
    15.         GameManager.instance.AddEnemyToList(this);
    16.         animator = GetComponent<Animator>();
    17.         target = GameObject.FindGameObjectWithTag("Player").transform;
    18.         base.Start();
    19.     }
    20.  
    21.     protected override void AttemptMove<T>(int xDir, int yDir)
    22.     {
    23.         if (skipMove)
    24.         {
    25.             skipMove = false;
    26.             return;
    27.         }
    28.  
    29.         base.AttemptMove<T>(xDir, yDir);
    30.         skipMove = true;
    31.     }
    32.     public void MoveEnemy()
    33.     {
    34.         int xDir = 0;
    35.         int yDir = 0;
    36.         if (Mathf.Abs(target.position.x - transform.position.x) < float.Epsilon)
    37.             yDir = target.position.y > transform.position.y ? 1 : -1;
    38.         else
    39.             xDir = target.position.x > transform.position.x ? 1 : -1;
    40.  
    41.         AttemptMove<Player>(xDir, yDir);
    42.     }
    43.  
    44.     protected override void OnCantMove<T>(T component)
    45.     {
    46.         Player hitPlayer = component as Player;
    47.         hitPlayer.LoseFood(playerDamage);
    48.         animator.SetTrigger("enemyAttack");
    49.     }
    50. }
    51.  
    52.  
    it has to be something in there, but I went though it 3 times and they look identical
     
  48. gamemaster0007

    gamemaster0007

    Joined:
    Apr 30, 2018
    Posts:
    3
    I have a problem where the first two levels are fine. however, then it skips to day four with 0 food and then it says I survived 5 days, why is that?
    the player script
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System.Collections;
    4. using UnityEngine.SceneManagement;      //Allows us to use SceneManager
    5. using Completed;
    6. //Player inherits from MovingObject, our base class for objects that can move, Enemy also inherits from this.
    7. public class Player : MovingObject
    8. {
    9.     public float restartLevelDelay = 1f;        //Delay time in seconds to restart level.
    10.     public int PointsPerGold = 10;
    11.     public int PointsPerJewel = 20;
    12.     public int pointsPerFood = 10;              //Number of points to add to player food points when picking up a food object.
    13.     public int pointsPerSoda = 20;              //Number of points to add to player food points when picking up a soda object.
    14.     public int wallDamage = 1;                  //How much damage a player does to a wall when chopping it.
    15.     public Text foodText;
    16.     public Text GoldText;
    17.     private Animator animator;                  //Used to store a reference to the Player's animator component.
    18.     private int food;                           //Used to store player food points total during level.
    19.     private int Cash;
    20.     public AudioClip MoveSound1;
    21.     public AudioClip MoveSound2;
    22.     public AudioClip EatSound1;
    23.     public AudioClip EatSound2;
    24.     public AudioClip DrinkSound1;
    25.     public AudioClip DrinkSound2;
    26.     public AudioClip GameOverSound;
    27.     //Start overrides the Start function of MovingObject
    28.     protected override void Start ()
    29.     {
    30.         //Get a component reference to the Player's animator component
    31.         animator = GetComponent<Animator>();
    32.  
    33.         //Get the current food point total stored in GameManager.instance between levels.
    34.         Cash = GameManager.instance.PlayerCashPoints;
    35.         food = GameManager.instance.playerFoodPoints;
    36.         foodText.text = "Food: " + food;
    37.         GoldText.text = "Cash: $" + Cash;
    38.         //Call the Start function of the MovingObject base class.
    39.         base.Start ();
    40.     }
    41.  
    42.  
    43.     //This function is called when the behaviour becomes disabled or inactive.
    44.     private void OnDisable ()
    45.     {
    46.         //When Player object is disabled, store the current local food total in the GameManager so it can be re-loaded in next level.
    47.         GameManager.instance.playerFoodPoints = food;
    48.         GameManager.instance.PlayerCashPoints = Cash;
    49.     }
    50.  
    51.  
    52.     private void Update ()
    53.     {
    54.         //If it's not the player's turn, exit the function.
    55.         if(!GameManager.instance.playersTurn) return;
    56.  
    57.         int horizontal = 0;     //Used to store the horizontal move direction.
    58.         int vertical = 0;       //Used to store the vertical move direction.
    59.  
    60.  
    61.         //Get input from the input manager, round it to an integer and store in horizontal to set x axis move direction
    62.         horizontal = (int) (Input.GetAxis ("Horizontal"));
    63.  
    64.         //Get input from the input manager, round it to an integer and store in vertical to set y axis move direction
    65.         vertical = (int) (Input.GetAxis ("Vertical"));
    66.  
    67.         //Check if moving horizontally, if so set vertical to zero.
    68.         if(horizontal != 0)
    69.         {
    70.             vertical = 0;
    71.         }
    72.  
    73.         //Check if we have a non-zero value for horizontal or vertical
    74.         if(horizontal != 0 || vertical != 0)
    75.         {
    76.             //Call AttemptMove passing in the generic parameter Wall, since that is what Player may interact with if they encounter one (by attacking it)
    77.             //Pass in horizontal and vertical as parameters to specify the direction to move Player in.
    78.             AttemptMove<Wall> (horizontal, vertical);
    79.         }
    80.     }
    81.  
    82.     //AttemptMove overrides the AttemptMove function in the base class MovingObject
    83.     //AttemptMove takes a generic parameter T which for Player will be of the type Wall, it also takes integers for x and y direction to move in.
    84.     protected override void AttemptMove<T>  (int xDir, int yDir)
    85.     {
    86.         //Every time player moves, subtract from food points total.
    87.         food--;
    88.         foodText.text = "Food: " + food;
    89.         GoldText.text = "Cash: $" + Cash;
    90.         //Call the AttemptMove method of the base class, passing in the component T (in this case Wall) and x and y direction to move.
    91.         base.AttemptMove<Wall>  (xDir, yDir);
    92.  
    93.         //Hit allows us to reference the result of the Linecast done in Move.
    94.         RaycastHit2D hit;
    95.  
    96.         //If Move returns true, meaning Player was able to move into an empty space.
    97.         if (Move (xDir, yDir, out hit))
    98.         {
    99.             SoundManager.instance.RandomizeSfx (MoveSound1, MoveSound2);
    100.         }
    101.  
    102.         //Since the player has moved and lost food points, check if the game has ended.
    103.         CheckIfGameOver ();
    104.  
    105.         //Set the playersTurn boolean of GameManager to false now that players turn is over.
    106.         GameManager.instance.playersTurn = false;
    107.     }
    108.  
    109.  
    110.     //OnCantMove overrides the abstract function OnCantMove in MovingObject.
    111.     //It takes a generic parameter T which in the case of Player is a Wall which the player can attack and destroy.
    112.     protected override void OnCantMove<T>  (T component)
    113.     {
    114.         //Set hitWall to equal the component passed in as a parameter.
    115.         Wall hitWall = component as Wall;
    116.  
    117.         //Call the DamageWall function of the Wall we are hitting.
    118.         hitWall.DamageWall (wallDamage);
    119.  
    120.         //Set the attack trigger of the player's animation controller in order to play the player's attack animation.
    121.         animator.SetTrigger ("playerChop");
    122.     }
    123.  
    124.  
    125.     //OnTriggerEnter2D is sent when another object enters a trigger collider attached to this object (2D physics only).
    126.     private void OnTriggerEnter2D (Collider2D other)
    127.     {
    128.         //Check if the tag of the trigger collided with is Exit.
    129.         if (other.tag == "Exit") {
    130.             //Invoke the Restart function to start the next level with a delay of restartLevelDelay (default 1 second).
    131.             Invoke ("Restart", restartLevelDelay);
    132.  
    133.             //Disable the player object since level is over.
    134.             enabled = false;
    135.         }
    136.  
    137.         //Check if the tag of the trigger collided with is Food.
    138.         else if (other.tag == "Food") {
    139.             //Add pointsPerFood to the players current food total.
    140.             food += pointsPerFood;
    141.             foodText.text = "+ " + pointsPerFood + " Food: " + food;
    142.             SoundManager.instance.RandomizeSfx (EatSound1, EatSound2);
    143.             //Disable the food object the player collided with.
    144.             other.gameObject.SetActive (false);
    145.         }
    146.  
    147.         //Check if the tag of the trigger collided with is Soda.
    148.         else if (other.tag == "Soda") {
    149.             //Add pointsPerSoda to players food points total
    150.             food += pointsPerSoda;
    151.             foodText.text = "+ " + pointsPerSoda + " Food: " + food;
    152.             SoundManager.instance.RandomizeSfx (DrinkSound1, DrinkSound2);
    153.             //Disable the soda object the player collided with.
    154.             other.gameObject.SetActive (false);
    155.         } else if (other.tag == "gold") {
    156.             Cash += PointsPerGold;
    157.             GoldText.text = "+" + PointsPerGold + "Cash: $" + Cash;
    158.             other.gameObject.SetActive (false);
    159.         } else if (other.tag == "Jewel") {
    160.             Cash += PointsPerJewel;
    161.             GoldText.text = "+" + PointsPerJewel + "Cash: $" + Cash;
    162.             other.gameObject.SetActive (false);
    163.         }
    164.     }
    165.  
    166.  
    167.     //Restart reloads the scene when called.
    168.     private void Restart ()
    169.     {
    170.         //Load the last scene loaded, in this case Main, the only scene in the game.
    171.         SceneManager.LoadScene (0);
    172.     }
    173.  
    174.  
    175.     //LoseFood is called when an enemy attacks the player.
    176.     //It takes a parameter loss which specifies how many points to lose.
    177.     public void LoseFood (int loss)
    178.     {
    179.         //Set the trigger for the player animator to transition to the playerHit animation.
    180.         animator.SetTrigger ("playerHit");
    181.  
    182.         //Subtract lost food points from the players total.
    183.         food -= loss;
    184.         foodText.text = "- " + loss + " Food: " + food;
    185.         //Check to see if game has ended.
    186.         CheckIfGameOver ();
    187.     }
    188.  
    189.  
    190.     //CheckIfGameOver checks if the player is out of food points and if so, ends the game.
    191.     private void CheckIfGameOver ()
    192.     {
    193.         //Check if food point total is less than or equal to zero.
    194.         if (food <= 0)
    195.         {
    196.             SoundManager.instance.RandomizeSfx (GameOverSound);
    197.             SoundManager.instance.musicSource.Stop ();
    198.             //Call the GameOver function of GameManager.
    199.  
    200.             GameManager.instance.GameOver ();
    201.         }
    202.     }
    203. }
    204.  
    the game manager
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using Completed;
    4. using UnityEngine.UI;
    5. using System.Collections.Generic;       //Allows us to use Lists.
    6. using UnityEngine.SceneManagement;
    7. public class GameManager : MonoBehaviour
    8. {
    9.     public float levelStartDelay = 2f;                      //Time to wait before starting level, in seconds.
    10.     public float turnDelay = 0.1f;                          //Delay between each Player turn.
    11.     public int playerFoodPoints = 100;                      //Starting value for Player food points.
    12.     public int PlayerCashPoints = 0;
    13.     public static GameManager instance = null;              //Static instance of GameManager which allows it to be accessed by any other script.
    14.     [HideInInspector] public bool playersTurn = true;       //Boolean to check if it's players turn, hidden in inspector but public.
    15.  
    16.     private Text LevelText;
    17.     private GameObject LevelImage;
    18.     private BoardManager boardScript;                       //Store a reference to our BoardManager which will set up the level.
    19.     private int level = 1;                                  //Current level number, expressed in game as "Day 1".
    20.     private List<Enemy> enemies;                           //List of all Enemy units, used to issue them move commands.
    21.     private bool enemiesMoving;                             //Boolean to check if enemies are moving.
    22.     private bool DoingSetup;
    23.  
    24.  
    25.     //Awake is always called before any Start functions
    26.     void Awake()
    27.     {
    28.         //Check if instance already exists
    29.         if (instance == null)
    30.  
    31.             //if not, set instance to this
    32.             instance = this;
    33.  
    34.         //If instance already exists and it's not this:
    35.         else if (instance != this)
    36.  
    37.             //Then destroy this. This enforces our singleton pattern, meaning there can only ever be one instance of a GameManager.
    38.             Destroy(gameObject);  
    39.  
    40.         //Sets this to not be destroyed when reloading scene
    41.         DontDestroyOnLoad(gameObject);
    42.  
    43.         //Assign enemies to a new List of Enemy objects.
    44.         enemies = new List<Enemy>();
    45.  
    46.         //Get a component reference to the attached BoardManager script
    47.         boardScript = GetComponent<BoardManager>();
    48.  
    49.         //Call the InitGame function to initialize the first level
    50.         InitGame();
    51.     }
    52.  
    53.     void OnLevelWasLoaded(int index)
    54.     {
    55.         //Add one to our level number.
    56.         level++;
    57.         //Call InitGame to initialize our level.
    58.         InitGame();
    59.     }
    60.     //Initializes the game for each level.
    61.     void InitGame()
    62.     {
    63.         DoingSetup = true;
    64.         LevelImage = GameObject.Find ("LevelImage");
    65.         LevelText = GameObject.Find ("LevelText").GetComponent<Text>();
    66.         LevelText.text = "Day " + level;
    67.         LevelImage.SetActive (true);
    68.         Invoke ("HideLevelImage",levelStartDelay);
    69.         //Clear any Enemy objects in our List to prepare for next level.
    70.         enemies.Clear();
    71.  
    72.         //Call the SetupScene function of the BoardManager script, pass it current level number.
    73.         boardScript.SetupScene(level);
    74.  
    75.     }
    76.  
    77.     private void HideLevelImage(){
    78.         LevelImage.SetActive (false);
    79.         DoingSetup = false;
    80.     }
    81.     //Update is called every frame.
    82.     void Update()
    83.     {
    84.         //Check that playersTurn or enemiesMoving or doingSetup are not currently true.
    85.         if(playersTurn || enemiesMoving || DoingSetup)
    86.  
    87.             //If any of these are true, return and do not start MoveEnemies.
    88.             return;
    89.  
    90.         //Start moving enemies.
    91.         StartCoroutine (MoveEnemies ());
    92.     }
    93.  
    94.     //Call this to add the passed in Enemy to the List of Enemy objects.
    95.     public void AddEnemyToList(Enemy script)
    96.     {
    97.         //Add Enemy to List enemies.
    98.         enemies.Add(script);
    99.     }
    100.  
    101.  
    102.     //GameOver is called when the player reaches 0 food points
    103.     public void GameOver()
    104.     {
    105.         //Set levelText to display number of levels passed and game over message
    106.         LevelText.text = "After " + level + " days, you starved.";
    107.         LevelImage.SetActive(true);
    108.  
    109.         //Disable this GameManager.
    110.         enabled = false;
    111.     }
    112.  
    113.  
    114.     //Coroutine to move enemies in sequence.
    115.     IEnumerator MoveEnemies()
    116.     {
    117.         //While enemiesMoving is true player is unable to move.
    118.         enemiesMoving = true;
    119.  
    120.         //Wait for turnDelay seconds, defaults to .1 (100 ms).
    121.         yield return new WaitForSeconds(turnDelay);
    122.  
    123.         //If there are no enemies spawned (IE in first level):
    124.         if (enemies.Count == 0)
    125.         {
    126.             //Wait for turnDelay seconds between moves, replaces delay caused by enemies moving when there are none.
    127.             yield return new WaitForSeconds(turnDelay);
    128.         }
    129.  
    130.         //Loop through List of Enemy objects.
    131.         for (int i = 0; i < enemies.Count; i++)
    132.         {
    133.             //Call the MoveEnemy function of Enemy at index i in the enemies List.
    134.             enemies[i].MoveEnemy ();
    135.  
    136.             //Wait for Enemy's moveTime before moving next Enemy,
    137.             yield return new WaitForSeconds(enemies[i].moveTime);
    138.         }
    139.         //Once Enemies are done moving, set playersTurn to true so player can move.
    140.         playersTurn = true;
    141.  
    142.         //Enemies are done moving, set enemiesMoving to false.
    143.         enemiesMoving = false;
    144.     }
    145. }
     
    unity_gNf04-k13wyxCA likes this.
  49. chipuchipu

    chipuchipu

    Joined:
    Jun 20, 2017
    Posts:
    1
    Hey! Great tutorials! I learned a lot!

    I managed to merge both the 2D-Roguelike tutorial with the Basic 2D Dungeon Generation but I have a question regarding the Objective Tile.

    Currently, the first level works flawlessly. However, once the player enters level 2, the hierarchy seems to spawn two boardHolders and the map becomes impossible to navigate as the player spawns in walls.

    For testing purposes, I manually deleted one of the boardHolders and got my player moving again. Interestingly, if the player enters level 3, the player game object is destroyed somehow and exceptions are thrown about the enemies unable to locate the player.

    I was just wondering if anyone could help me with this weird issue.
     
  50. AlfredvanRaal

    AlfredvanRaal

    Joined:
    Feb 27, 2017
    Posts:
    5
     
Thread Status:
Not open for further replies.