Search Unity

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. Matthew-Schell

    Matthew-Schell

    Joined:
    Oct 1, 2014
    Posts:
    238
    No it's actually a bug with the tutorial, just use one of them twice.
     
  2. Elethana

    Elethana

    Joined:
    Feb 28, 2016
    Posts:
    3
    Are the any guidelines for capitalization? I'm working through the tutorial and appreciate the more advance concepts being demonstrated, but the capitalization of variables seem a little random. "gridPositions" and "gameObject" or is it "GameObject"?
    Is there a style guide or do people use their own naming conventions?

    Edited: Sorry, this post came off much more obnoxious than I intended. I'm just curious about your rationale for naming and capitalizing variables.
     
  3. Matthew-Schell

    Matthew-Schell

    Joined:
    Oct 1, 2014
    Posts:
    238
    No worries, not obnoxious at all:

    If you see GameObject capitalized we are declaring the type whereas if you see gameObject we are referring to a field or property.

    So we might write:
    Code (CSharp):
    1. void OnCollisionEnter(Collision coll)
    2. {
    3.      GameObject collidedGameObject = coll.gameObject;
    4. }
    In this case we're declaring a variable of the type GameObject called collidedObject and setting it to equal the gameObject variable stored in the collision coll.

    Basically class names and function names should always be capitalized and variable names should always be camelCase (first letter lower case, subsequent new words in the name upper case for readability).
     
    Elethana likes this.
  4. Redden44

    Redden44

    Joined:
    Nov 15, 2014
    Posts:
    159
    Hi, in a new project I created a c# script named GameManager and attached to a game object, then I noticed that the icon of the field is different from the usual one, it's not a white page with c# in blue, but it's a gray cog wheel.

    I did a research and discovered that the cog icon is used for scriptable objects or something like that and a link brought me to the code of this tutorial ("Writing the Game Manager") where a namespace called "completed" is used to encapsulate the GameManager script.

    Is there a problem in naming the script "GameManager"? Do I need to encapsulate the script like in the tutorial if I want to name the script "GameManager"? Thanks

    Links:
    http://answers.unity3d.com/questions/678637/cogwheel-icon-in-inspector.html
    http://unity3d.com/learn/tutorials/projects/2d-roguelike-tutorial/writing-game-manager
     
  5. ShokeR0

    ShokeR0

    Joined:
    Feb 24, 2016
    Posts:
    112
    I've completed the tutorial, the games runs perfectly fine in the editor but when I build and run the game the following bugs occur:
    I start the game at day 2
    the game advance two levels ahead instead of one
    after completing the first level i start the second with 0 food and die.
    Enemies spawn inside walls.

    Again those problems do not occur inside the editor, and I am almost 100% sure I followed the entire guide correctly.
    I am also using SceneManager to load the scene maybe this is the reason?
     
  6. robert4452

    robert4452

    Joined:
    Jan 25, 2016
    Posts:
    3
    So far, everything in the project works fine, but the enemies don't spawn. I'm assuming it is because the game keeps on reloading the first level over and over again, but i'm not totally sure. If there is anyone who can help me with this that would be fantastic. I can paste my code if need be.
     
  7. varun3

    varun3

    Joined:
    Dec 19, 2014
    Posts:
    19
    I just finished the Board manager part. I tried to make the board bigger by changing the values of rows and columns but it doesn't seem to work. Any help?
     
  8. littership

    littership

    Joined:
    Mar 13, 2016
    Posts:
    1
    oh my god I run into the exact same problem and was just trying to look for an answer here,can someone solve this?
     
  9. OboShape

    OboShape

    Joined:
    Feb 17, 2014
    Posts:
    836
    If this is the same thing that was happening in previous posts, with the OnLevelWasLoaded.
    Matt has advised that this is a bug and is should be adressed in the 5.4 release, see this post see if it helps you out in the meantime.
    http://forum.unity3d.com/threads/2d-roguelike-q-a.297180/page-12#post-2449003
     
    Matthew-Schell likes this.
  10. UnrealHowl

    UnrealHowl

    Joined:
    Oct 9, 2015
    Posts:
    2
    Hey Matt,
    I have just finished the Enemy Animator controller video (part 11) and have encountered a problem.
    when either the Player or the enemy collides with the outer wall or inner wall i get the error
    "NullReferenceException: Object reference not set to an instance of an object
    Player.OnCantMove[Wall] (.Wall component) (at Assets/Scripts/Player.cs:88)
    MovingObject.AttemptMove[Wall] (Int32 xDir, Int32 yDir) (at Assets/Scripts/MovingObject.cs:69)
    Player.AttemptMove[Wall] (Int32 xDir, Int32 yDir) (at Assets/Scripts/Player.cs:52)
    Player.Update () (at Assets/Scripts/Player.cs:44)".
    I have double and triple checked my code as well as making sure all the objects are referenced correctly but still unable to find a solution.

    Great Tutorial though I've learnt so much already.
     
  11. Matthew-Schell

    Matthew-Schell

    Joined:
    Oct 1, 2014
    Posts:
    238
    Did you confirm that the prefab for the object in question actually has a Wall script attached?
     
  12. Matthew-Schell

    Matthew-Schell

    Joined:
    Oct 1, 2014
    Posts:
    238
    Make sure you are changing the public inspector values in the editor, not the initialization values in the script.
     
  13. ronyp

    ronyp

    Joined:
    Mar 24, 2016
    Posts:
    1
    Hi, i just finished part 11 if this tutorial, and i have learned a lot for a beginner. The game run as expected until when facing 3 enemies, sometime i found out that the enemy spawned on top of the wall. I tried to compare my BoardManager class with the completed one, but didn't find any differences. Is it possible the RandomPosition() generate same position twice or is there something wrong with my code?
     
  14. Sannin

    Sannin

    Joined:
    Mar 12, 2016
    Posts:
    1
    Hello :) First of all, thank you very much for your lesson. I'm beginner to Unity (i worked with some other lessons), so excuse if my qusetions was asked earlier and sorry for my english.

    I have two questions.

    First: why the game is fine when i play it to Unity, and it's not correct when i play it from .exe file after build on PC?
    Concretely, trouble is that the first level equals 2 with start at once, not 1 how in Unity (food equals 100 in both cases). And the next level equals 4 and food equals 0. Maybe the project settings are bugging, it is magic for me.

    Second: is it normall that the game works slower when enemies are spawned more and more?

    Thank you for attention:)
     
  15. greatness

    greatness

    Joined:
    Feb 20, 2016
    Posts:
    199
    I'm on the Writing the Player Script part. I was writing this code:

    Code (csharp):
    1.  
    2. Application.LoadLevel (Application.loadedLevel);
    And I got these compile warnings:

    'Application.loaded' level is obsolete. 'Use SceneManager to determine what scenes have been loaded.'

    'Application.LoadLevel(int) is obsolete.'Use SceneManager.LoadScene'.

    What does this mean?

    Does the tutorial have a glitch or is it just me?






    Edit: The correct script for Unity 5.3 users and above is:
    Code (csharp):
    1.  
    2. SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
     
    Last edited: Mar 26, 2016
  16. greatness

    greatness

    Joined:
    Feb 20, 2016
    Posts:
    199
    I recently finished part 9 of the tutorial. I tested the game and found out that the character can only move once? What is happening?

    Edit: The player is supposed to move only once in part 9 of the tutorial. The game is turn-based, so the enemy has to move after the player did. Since the enemy script is not written yet, the player can only move once.
     
    Last edited: Mar 26, 2016
  17. greatness

    greatness

    Joined:
    Feb 20, 2016
    Posts:
    199
    I finished the scripting on part 10 of the tutorial. However, when I tested the game in the game view, nobody moves, including the player. I was able to make the player move in part 9. However, I can't make the player move right now.

    Edit: Attach a 2D Rigidbody component to the Player. Player had a 2D Box Collider but not a 2D Rigidbody.

    Code (csharp):
    1.  
    2.  
    3. using UnityEngine;
    4. using System.Collections;
    5. using System;
    6.  
    7. public class Enemy : MovingObject {
    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.         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.    
    24.         if (skipMove)
    25.         {
    26.             skipMove = false;
    27.             return;
    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.  
    37.         if (Mathf.Abs(target.position.x - transform.position.x) < float.Epsilon)
    38.           yDir = target.position.y > transform.position.y ? 1 : -1;
    39.    
    40.         else
    41.             xDir = target.position.x > transform.position.x ? 1 : -1;
    42.  
    43.         AttemptMove<Player>(xDir, yDir);
    44.  
    45.     }
    46.  
    47.     protected override void OnCantMove<T>(T component)
    48.     {
    49.         Player hitPlayer = component as Player;
    50.         hitPlayer.LoseFood(playerDamage);
    51.  
    52.     }
    53.  
    54.  
    55. }
     
    Last edited: Mar 27, 2016
  18. greatness

    greatness

    Joined:
    Feb 20, 2016
    Posts:
    199
    I'm on part 11 of the tutorial. For some reason, the player only moves once. The enemies move, but the player moves only once. The console is saying "NullReferenceException: Object reference not set to an instance of an object Player.Update () (at Assets/My Scripts/Player.cs:24)" and "NullReferenceException: Object reference not set to an instance of an object Player.OnDisable () (at Assets/My Scripts/Player.cs:37)"



    Game Manager:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class A_Game_Manager : MonoBehaviour
    6. {
    7.     public static A_Game_Manager instance = null;
    8.     public float turnDelay = 0.1f;
    9.     private BoardManager boardScript;
    10.     private int level = 3;
    11.     public int playerFoodPoints = 100;
    12.     [HideInInspector] public bool playerTurns = true;
    13.  
    14.     private List<Enemy> enemies;
    15.     private bool enemiesMoving;
    16.  
    17.     void Awake()
    18.     {
    19.         if (instance == null)
    20.             instance = this;
    21.         else if (instance != this)
    22.             DestroyObject(gameObject);
    23.  
    24.         enemies = new List<Enemy>();
    25.  
    26.         DontDestroyOnLoad(gameObject);
    27.         boardScript = GetComponent<BoardManager>();
    28.         InitGame();
    29.     }
    30.     void InitGame()
    31.     {
    32.         enemies.Clear();
    33.         boardScript.SetUp(level);
    34.     }
    35.     public void GameOver()
    36.     {
    37.         enabled = false;
    38.     }
    39.  
    40.     IEnumerator MoveEnemies()
    41.     {
    42.         enemiesMoving = true;
    43.         yield return new WaitForSeconds(turnDelay);
    44.         if (enemies.Count <= 0)
    45.             yield return new WaitForSeconds(turnDelay);
    46.  
    47.         for (int i = 0; i < enemies.Count; i++)
    48.         {
    49.             enemies[i].MoveEnemy();
    50.             yield return new WaitForSeconds(enemies[i].moveTime);
    51.         }
    52.         playerTurns = true;
    53.         enemiesMoving = false;
    54.     }
    55.  
    56.     void Update()
    57.     {
    58.         if (playerTurns || enemiesMoving)
    59.             return;
    60.         StartCoroutine(MoveEnemies());
    61.     }
    62.  
    63.     public void AddEnemy(Enemy script)
    64.     {
    65.         enemies.Add(script);
    66.     }
    67. }
    Player
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System;
    4. using UnityEngine.SceneManagement;
    5.  
    6.  
    7. public class Player : MovingObject {
    8.     public int wallDamage = 1;
    9.     public int pointsPerFood = 20;
    10.     public int pointsPerSoda = 10;
    11.     public float LevelDelay = 1f;
    12.  
    13.     private Animator animator;
    14.     private int food;
    15.  
    16.     // Use this for initialization
    17.     protected override void Start () {
    18.         animator = GetComponent<Animator>();
    19.         food = A_Game_Manager.instance.playerFoodPoints;
    20.         base.Start();
    21.     }
    22.     void Update()
    23.     {
    24.         if (!A_Game_Manager.instance.playerTurns) return;
    25.         int horizontal = 0;
    26.         int vertical = 0;
    27.         horizontal = (int)(Input.GetAxisRaw("Horizontal"));
    28.         vertical = (int) (Input.GetAxisRaw("Vertical"));
    29.         if (horizontal != 0)
    30.             vertical = 0;
    31.         if (horizontal != 0 || vertical != 0)
    32.             AttemptMove<Wall>(horizontal, vertical);
    33.     }
    34.  
    35.     private void OnDisable()
    36.     {
    37.         A_Game_Manager.instance.playerFoodPoints = food;
    38.     }
    39.  
    40.     protected override void AttemptMove<T>(int xDir, int yDir)
    41.     {
    42.         food -= 10;
    43.         base.AttemptMove<T>(xDir, yDir);
    44.         CheckIfGameOver();
    45.         A_Game_Manager.instance.playerTurns = false;
    46.     }
    47.     private void CheckIfGameOver()
    48.     {
    49.         if (food <= 0)
    50.             A_Game_Manager.instance.GameOver();
    51.     }
    52.  
    53.     private void OnTriggerEnter2D(Collider2D other)
    54.     {
    55.         if (other.CompareTag("Exit"))
    56.         {
    57.             Invoke("Restart", LevelDelay);
    58.             enabled = false;
    59.         }
    60.         if (other.CompareTag("Food"))
    61.         {
    62.             food += pointsPerFood;
    63.            Destroy(other.gameObject);
    64.         }
    65.         else if (other.CompareTag("Soda"))
    66.         {
    67.             food += pointsPerSoda;
    68.             Destroy(other.gameObject);
    69.         }
    70.     }
    71.  
    72.     // Update is called once per frame
    73.  
    74.     protected override void OnCantMove<T>(T component)
    75.     {
    76.         Wall hitWall = component as Wall;
    77.         hitWall.DamageWall(wallDamage);
    78.         animator.SetTrigger("PlayerChop");
    79.     }
    80.     private void Restart()
    81.     {
    82.  
    83.         SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    84.  
    85.     }
    86.     public void LoseFood(int loss)
    87.     {
    88.         animator.SetTrigger("PlayerHit");
    89.         food -= loss;
    90.         CheckIfGameOver();
    91.     }
    92.  
    93.  
    94. }
    Enemy
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System;
    5.  
    6. public class Enemy : MovingObject
    7. {
    8.  
    9.     public int playerDamage;
    10.  
    11.     private Animator animator;
    12.     private Transform target;
    13.     private bool skipMove;
    14.  
    15.     protected override void Start()
    16.     {
    17.         A_Game_Manager.instance.AddEnemy(this);
    18.         animator = GetComponent<Animator>();
    19.         target = GameObject.FindGameObjectWithTag("Player").transform;
    20.         base.Start();
    21.     }
    22.  
    23.     protected override void AttemptMove<T>(int xDir, int yDir)
    24.     {
    25.  
    26.         if (skipMove)
    27.         {
    28.             skipMove = false;
    29.             return;
    30.         }
    31.         base.AttemptMove<T>(xDir, yDir);
    32.         skipMove = true;
    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.  
    42.         else
    43.             xDir = target.position.x > transform.position.x ? 1 : -1;
    44.  
    45.         AttemptMove<Player>(xDir, yDir);
    46.  
    47.     }
    48.  
    49.     protected override void OnCantMove<T>(T component)
    50.     {
    51.         Player hitPlayer = component as Player;
    52.         animator.SetTrigger("enemyAttack");
    53.         hitPlayer.LoseFood(playerDamage);
    54.  
    55.     }
    56. }
     
    Last edited: Mar 28, 2016
  19. greatness

    greatness

    Joined:
    Feb 20, 2016
    Posts:
    199
    I still didn't manage to complete part 11 of the tutorial but I skipped to part 12. I finished part 12 but I still have so many errors. For some reason, I don't think that the game mangager is being created. I did the loader script which initizalizes the game manager prefab and the prefab has the game manager script. I recently just removed the loader script and instead added the game mangaer script to the main camera. However, when i test the game, i see that the game manager script keeps being disabled. i dont know why this keeps on happening. plz help me.

    Player:


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System;
    4. using UnityEngine.SceneManagement;
    5. using UnityEngine.UI;
    6.  
    7.  
    8.  
    9. public class Player : MovingObject {
    10.     public int wallDamage = 1;
    11.     public int pointsPerFood = 20;
    12.     public int pointsPerSoda = 10;
    13.     public float LevelDelay = 1f;
    14.     public int lossage = 5;
    15.     public Text foodText;
    16.     private Animator animator;
    17.     private int food;
    18.  
    19.     // Use this for initialization
    20.     protected override void Start () {
    21.         animator = GetComponent<Animator>();
    22.         food = A_Game_Manager.instance.playerFoodPoints;
    23.         foodForThought();
    24.         base.Start();
    25.     }
    26.     private void foodForThought()
    27.     {
    28.      
    29.         foodText.text = "Hunger Bar:" + food + "!";
    30.      
    31.      
    32.     }
    33.    private void Update()
    34.     {
    35.         if (!A_Game_Manager.instance.playerTurns) return;
    36.         int horizontal = 0;
    37.         int vertical = 0;
    38.         horizontal = (int)(Input.GetAxisRaw("Horizontal"));
    39.         vertical = (int) (Input.GetAxisRaw("Vertical"));
    40.         if (horizontal != 0)
    41.             vertical = 0;
    42.         if (horizontal != 0 || vertical != 0)
    43.             AttemptMove<Wall>(horizontal, vertical);
    44.     }
    45.  
    46.     private void OnDisable()
    47.     {
    48.         A_Game_Manager.instance.playerFoodPoints = food;
    49.     }
    50.  
    51.     protected override void AttemptMove<T>(int xDir, int yDir)
    52.     {
    53.         food -= lossage;
    54.         foodForThought();
    55.         base.AttemptMove<T>(xDir, yDir);
    56.      
    57.         CheckIfGameOver();
    58.         A_Game_Manager.instance.playerTurns = false;
    59.     }
    60.     private void CheckIfGameOver()
    61.     {
    62.         if (food <= 0)
    63.             A_Game_Manager.instance.GameOver();
    64.     }
    65.  
    66.     private void OnTriggerEnter2D(Collider2D other)
    67.     {
    68.         if (other.CompareTag("Exit"))
    69.         {
    70.             Invoke("Restart", LevelDelay);
    71.             enabled = false;
    72.         }
    73.         if (other.CompareTag("Food"))
    74.         {
    75.             food += pointsPerFood;
    76.             foodText.text = "+" + pointsPerFood + " Hunger Bar:" + food + "!";
    77.            Destroy(other.gameObject);
    78.         }
    79.         else if (other.CompareTag("Soda"))
    80.         {
    81.             food += pointsPerSoda;
    82.             foodText.text = "+" + pointsPerSoda + " Hunger Bar:" + food + "!";
    83.             Destroy(other.gameObject);
    84.         }
    85.     }
    86.  
    87. A_Game_Manager
    88.  
    89.     // Update is called once per frame
    90. [code=CSharp]using UnityEngine;
    91. using System.Collections;
    92. using System.Collections.Generic;
    93. using UnityEngine.UI;              
    94.  
    95. public class A_Game_Manager : MonoBehaviour
    96. {
    97.     public float levelStartDelay = 2f;
    98.     public static A_Game_Manager instance = null;
    99.     public float turnDelay = 0.1f;
    100.     private BoardManager boardScript;
    101.     private int level = 1;
    102.     public int playerFoodPoints = 100;
    103.     [HideInInspector] public bool playerTurns = true;
    104.  
    105.     private List<Enemy> enemies;
    106.     private bool enemiesMoving = false;
    107.     private Text textLevel;
    108.     private GameObject levelImage;
    109.     private bool boardSetUp = true;
    110.  
    111.     private void OnLevelWasLoaded()
    112.     {
    113.         level++;
    114.         InitGame();
    115.     }
    116.  
    117.     private void Awake()
    118.     {
    119.         enabled = true;
    120.         if (instance == null)
    121.             instance = this;
    122.         else if (instance != this)
    123.             DestroyObject(gameObject);
    124.  
    125.         enemies = new List<Enemy>();
    126.  
    127.         DontDestroyOnLoad(gameObject);
    128.         boardScript = GetComponent<BoardManager>();
    129.         InitGame();
    130.     }
    131.  
    132.     void InitGame()
    133.     {
    134.         boardSetUp = false;
    135.         levelImage = GameObject.Find("Image");
    136.         textLevel = GameObject.Find("Level Text").GetComponent<Text>();
    137.         textLevel.text = "Level " + level;
    138.         levelImage.SetActive(true);
    139.         enemies.Clear();
    140.         boardScript.SetUp(level);
    141.         Invoke("HideLevel", levelStartDelay);
    142.     }
    143.     private void HideLevel()
    144.     {
    145.         levelImage.SetActive(false);
    146.         boardSetUp = false;
    147.     }
    148.     public void GameOver()
    149.     {
    150.         levelImage.SetActive(true);
    151.         textLevel.text = " After only " + level + " levels, you DIED!";
    152.         enabled = false;
    153.     }
    154.  
    155.     IEnumerator MoveEnemies()
    156.     {
    157.         enemiesMoving = true;
    158.         yield return new WaitForSeconds(turnDelay);
    159.         if (enemies.Count <= 0)
    160.             yield return new WaitForSeconds(turnDelay);
    161.  
    162.         for (int i = 0; i < enemies.Count; i++)
    163.         {
    164.             enemies[i].MoveEnemy();
    165.             yield return new WaitForSeconds(enemies[i].moveTime);
    166.         }
    167.         playerTurns = true;
    168.         enemiesMoving = false;
    169.     }
    170.  
    171.     void Update()
    172.     {
    173.         if (playerTurns || enemiesMoving||boardSetUp)
    174.             return;
    175.         StartCoroutine(MoveEnemies());
    176.     }
    177.  
    178.     public void AddEnemy(Enemy script)
    179.     {
    180.         enemies.Add(script);
    181.     }
    182. }
    183.  
    protected override void OnCantMove<T>(T component)
    {
    Wall hitWall = component as Wall;
    hitWall.DamageWall(wallDamage);
    animator.SetTrigger("PlayerChop");
    }
    private void Restart()
    {

    SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);

    }
    public void LoseFood(int loss)
    {
    animator.SetTrigger("PlayerHit");
    food -= loss;
    foodText.text = "-" + loss + " Hunger Bar:" + food + "!";
    CheckIfGameOver();
    }


    }
    [/code]

    Enemy

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System;
    4.  
    5. public class Enemy : MovingObject
    6. {
    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.         A_Game_Manager.instance.AddEnemy(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.  
    25.         if (skipMove)
    26.         {
    27.             skipMove = false;
    28.             return;
    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.  
    38.         if (Mathf.Abs(target.position.x - transform.position.x) < float.Epsilon)
    39.             yDir = target.position.y > transform.position.y ? 1 : -1;
    40.  
    41.         else
    42.             xDir = target.position.x > transform.position.x ? 1 : -1;
    43.  
    44.         AttemptMove<Player>(xDir, yDir);
    45.  
    46.     }
    47.  
    48.     protected override void OnCantMove<T>(T component)
    49.     {
    50.         Player hitPlayer = component as Player;
    51.         animator.SetTrigger("enemyAttack");
    52.         hitPlayer.LoseFood(playerDamage);
    53.  
    54.     }
    55. }
    56.  

    Moving Object

    using UnityEngine;
    using System.Collections;

    public abstract class MovingObject : MonoBehaviour {
    public float moveTime = 0.1f;
    public LayerMask blockingLayer;
    private BoxCollider2D boxCollider;
    private Rigidbody2D rb2D;
    private float inverseMoveTime;

    protected virtual void Start() {
    boxCollider = GetComponent<BoxCollider2D>();
    rb2D = GetComponent<Rigidbody2D>();
    inverseMoveTime = 1f / moveTime;

    }
    protected bool Move(int xDir, int yDir, out RaycastHit2D hit)
    {
    Vector2 start = transform.position;
    Vector2 end = start + new Vector2(xDir, yDir);
    boxCollider.enabled = false;
    hit = Physics2D.Linecast(start, end, blockingLayer);
    boxCollider.enabled = true;
    if (hit.transform == null)
    {
    StartCoroutine(SmoothMovement(end));
    return true;

    }
    return false;
    }
    protected IEnumerator SmoothMovement(Vector3 end)
    {
    float sqrRemaingDistance = (transform.position - end).sqrMagnitude;
    while (sqrRemaingDistance > float.Epsilon)
    {
    Vector3 moveTowards = Vector3.MoveTowards(rb2D.position, end, inverseMoveTime * Time.deltaTime);
    rb2D.MovePosition(moveTowards);
    yield return null;

    }
    }

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

    where T : Component {
    RaycastHit2D hit;
    bool canMove = Move(xDir, yDir, out hit);
    if (hit.transform == null)
    return;

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

    if(!canMove&&hitComponent!=null)
    OnCantMove(hitComponent);
    }

    protected abstract void OnCantMove<T>(T component)

    where T : Component;


    }


    Loader

    using UnityEngine;
    using System.Collections;

    public class Loader : MonoBehaviour {
    public GameObject gameManager;
    void Awake() {
    if (A_Game_Manager.instance== null)
    {
    Instantiate(gameManager);
    }

    }
    }



    Wall

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

    BoardManager

    using UnityEngine;
    using System.Collections.Generic;
    using System;
    using Random = UnityEngine.Random;




    public class BoardManager : MonoBehaviour
    {

    [Serializable]
    public class Count
    {
    public int maximum;
    public int mininum;
    public Count(int min, int max)
    {
    max = maximum;
    min = mininum;
    }
    }

    public int columns = 8;
    public int rows = 8;
    public Count wallCount = new Count(4, 8);
    public Count foodCount = new Count(2, 6);

    public GameObject exit;
    public GameObject[] floorTiles;
    public GameObject[] wallTiles;
    public GameObject[] foodTiles;
    public GameObject[] enemyTiles;
    public GameObject[] outerWallTiles;
    private Transform boardHolder;
    private List<Vector3> gridPositions = new List<Vector3>();

    void InstianlizeList()
    {
    gridPositions.Clear();
    for (int x = 1; x < columns-1; x++)
    {
    for (int y = 1; y < rows-1; y++)
    {
    gridPositions.Add(new Vector3(x, y, 0f));

    }
    }

    }

    void BoardSetUp()
    {
    boardHolder = new GameObject("Board").transform;
    for (int x = -1; x < columns+1; x++)
    {
    for (int y = -1; y < rows+1; y++)
    {
    GameObject toInstantiate = floorTiles[Random.Range(0, floorTiles.Length)];
    if (x == -1 || x == columns || y == -1 || y == rows)
    {
    toInstantiate = outerWallTiles[Random.Range(0, outerWallTiles.Length)];
    }

    GameObject instance;

    instance = Instantiate(toInstantiate, new Vector3(x, y, 0f), Quaternion.identity) as GameObject;
    instance.transform.SetParent(boardHolder);


    }
    }
    }

    Vector3 RandomPosition()
    {
    int randomIndex = Random.Range(0, gridPositions.Count);
    Vector3 randomPosition = gridPositions[randomIndex];
    gridPositions.RemoveAt(randomIndex);
    return randomPosition;
    }

    void LayoutObjectAtRandom(GameObject[] tileArray, int min, int max)
    {
    int objectCount = Random.Range(min, max + 1);
    for (int i = 0; i < objectCount; i++)
    {
    Vector3 randomPosition = RandomPosition();
    GameObject tileChoice = tileArray[Random.Range(0, tileArray.Length)];
    Instantiate(tileChoice, randomPosition, Quaternion.identity);

    }
    }

    public void SetUp(int level)
    {
    BoardSetUp();
    InstianlizeList();
    LayoutObjectAtRandom(wallTiles, wallCount.mininum, wallCount.maximum);
    LayoutObjectAtRandom(foodTiles, foodCount.mininum, foodCount.maximum);
    int enemyCount = (int)Mathf.Log(level, 2f);
    LayoutObjectAtRandom(enemyTiles, enemyCount, enemyCount);
    Vector3 coordinates = new Vector3(columns - 1, rows - 1, 0f);
    Instantiate(exit, coordinates, Quaternion.identity);

    }



    }
     
    Last edited: Mar 28, 2016
  20. chabode

    chabode

    Joined:
    Jul 12, 2015
    Posts:
    4
    im doing part 5 of 14
    when i tried to play it, outer walls has shown but the inner walls couldn't be shown

    where should i check to fixed this error?
     
  21. greatness

    greatness

    Joined:
    Feb 20, 2016
    Posts:
    199
    Have you tried fixing the camera? Maybe the camera position is not showing the outer walls. Otherwise, see if you initizalized the outer wall prefabs. That is all I can say.
     
  22. greatness

    greatness

    Joined:
    Feb 20, 2016
    Posts:
    199
    When I tested the game, I found out that when the player moved, the player always goes back to his original position. For example, if the player was at (0,0,0) and then I moved one space up, the player's coordinates will slowly increase in decimals and then go back to (0,0,0) once I let go of the arrow keys. Also,the player refuses to collect food and soda, destroy walls and fight enemies or even reload the scene when the player touches the exit.

    Game Manager:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine.UI;
    6.  
    7. public class A_Game_Manager : MonoBehaviour
    8. {
    9.     public float levelStartDelay = 2f;
    10.     public static A_Game_Manager instance = null;
    11.     public float turnDelay = 0.1f;
    12.     private BoardManager boardScript;
    13.     private int level = 1;
    14.     public int playerFoodPoints = 100;
    15.     [HideInInspector]
    16.     public bool playerTurns = true;
    17.  
    18.     private List<Enemy> enemies;
    19.     private bool enemiesMoving = false;
    20.     private Text textLevel;
    21.     private GameObject levelImage;
    22.     private bool boardSetUp = true;
    23.  
    24.     private void OnLevelWasLoaded()
    25.     {
    26.         level++;
    27.         InitGame();
    28.     }
    29.  
    30.     private void Awake()
    31.     {
    32.         enabled = true;
    33.         if (instance == null)
    34.             instance = this;
    35.         else if (instance != this)
    36.             DestroyObject(gameObject);
    37.  
    38.         enemies = new List<Enemy>();
    39.  
    40.         DontDestroyOnLoad(gameObject);
    41.         boardScript = GetComponent<BoardManager>();
    42.         InitGame();
    43.     }
    44.  
    45.     void InitGame()
    46.     {
    47.         boardSetUp = false;
    48.         levelImage = GameObject.Find("Image");
    49.         textLevel = GameObject.Find("Level Text").GetComponent<Text>();
    50.         textLevel.text = "             Level " + level;
    51.         levelImage.SetActive(true);
    52.         enemies.Clear();
    53.         boardScript.SetUp(level);
    54.         Invoke("HideLevel", levelStartDelay);
    55.     }
    56.     private void HideLevel()
    57.     {
    58.         levelImage.SetActive(false);
    59.         textLevel.text = "";
    60.         boardSetUp = false;
    61.     }
    62.     public void GameOver()
    63.     {
    64.         levelImage.SetActive(true);
    65.         textLevel.text = " After only " + level + " level(s), you DIED!";
    66.         enabled = false;
    67.     }
    68.  
    69.     IEnumerator MoveEnemies()
    70.     {
    71.         enemiesMoving = true;
    72.         yield return new WaitForSeconds(turnDelay);
    73.         if (enemies.Count <= 0)
    74.             yield return new WaitForSeconds(turnDelay);
    75.  
    76.         for (int i = 0; i < enemies.Count; i++)
    77.         {
    78.             enemies[i].MoveEnemy();
    79.             yield return new WaitForSeconds(enemies[i].moveTime);
    80.         }
    81.         playerTurns = true;
    82.         enemiesMoving = false;
    83.     }
    84.  
    85.     void Update()
    86.     {
    87.         if (playerTurns || enemiesMoving || boardSetUp)
    88.             return;
    89.         StartCoroutine(MoveEnemies());
    90.     }
    91.  
    92.     public void AddEnemy(Enemy script)
    93.     {
    94.         enemies.Add(script);
    95.     }
    96. }
    97. [code/]
    98.  
    99.  
    100. Player
    101. [code]
    102. using UnityEngine;
    103. using System.Collections;
    104. using UnityEngine.UI;
    105. using UnityEngine.SceneManagement;
    106.  
    107.  
    108.     public class Player : MovingObject
    109.     {
    110.         public float restartLevelDelay = 1f;
    111.         public int pointsPerFood = 20;              //Number of points to add to player food points when picking up a food object.
    112.         public int pointsPerSoda = 10;              //Number of points to add to player food points when picking up a soda object.
    113.         public int wallDamage = 1;                  //How much damage a player does to a wall when chopping it.
    114.         public Text foodText;                       //UI Text to display current player food total.
    115.     public AudioClip moveSound1, moveSound2, eatSound1, eatSound2, drinkSound1, drinkSound2, gameOverSound;     //Audio clips to play. Two of each type to not make sound effects sound repetitive.
    116.     private Rigidbody2D rigidBody2d;
    117.    
    118.         private Animator animator;                  //Used to store a reference to the Player's animator component.
    119.         public int food;                           //Used to store player food points total during level.
    120.        
    121.  
    122.  
    123.         //Start overrides the Start function of MovingObject
    124.         protected override void Start()
    125.         {
    126.  
    127.         rigidBody2d = GetComponent<Rigidbody2D>();
    128.             //Get a component reference to the Player's animator component
    129.             animator = GetComponent<Animator>();
    130.  
    131.             //Get the current food point total stored in GameManager.instance between levels.
    132.             food = A_Game_Manager.instance.playerFoodPoints;
    133.  
    134.             //Set the foodText to reflect the current player food total.
    135.             foodText.text = "Food: " + food;
    136.  
    137.             //Call the Start function of the MovingObject base class.
    138.             base.Start();
    139.         }
    140.  
    141.  
    142.         private void OnDisable()
    143.         {
    144.  
    145.             A_Game_Manager.instance.playerFoodPoints = food;
    146.         }
    147.  
    148.  
    149.     private void FixedUpdate()
    150.     {
    151.         //If it's not the player's turn, exit the function.
    152.         if (!A_Game_Manager.instance.playerTurns) return;
    153.  
    154.         int horizontal = 0, vertical = 0;     //Used to store the vertical move direction.
    155.  
    156.  
    157.         horizontal = (int)(Input.GetAxis("Horizontal"));
    158.  
    159.         //Get input from the input manager, round it to an integer and store in vertical to set y axis move direction
    160.         vertical = (int)(Input.GetAxis("Vertical"));
    161.  
    162.         //Check if moving horizontally, if so set vertical to zero.
    163.         if (horizontal != 0)
    164.         {
    165.             rigidBody2d.AddForce(new Vector2(1, 0 * Time.deltaTime));
    166.             vertical = 0;
    167.         }
    168.  
    169.         if (vertical != 0)
    170.         {
    171.             rigidBody2d.AddForce(new Vector2(1, 0 * Time.deltaTime));
    172.             horizontal = 0;
    173.         }
    174.  
    175.         //Call AttemptMove passing in the generic parameter Wall, since that is what Player may interact with if they encounter one (by attacking it)
    176.         //Pass in horizontal and vertical as parameters to specify the direction to move Player in.
    177.         if (horizontal != 0 || vertical != 0) AttemptMove<Wall>(horizontal, vertical);
    178.          
    179.     }
    180.          
    181.    
    182.  
    183.         //AttemptMove overrides the AttemptMove function in the base class MovingObject
    184.         //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.
    185.         protected override void AttemptMove<T>(int xDir, int yDir)
    186.         {
    187.             //Every time player moves, subtract from food points total.
    188.             food-=5;
    189.  
    190.             //Update food text display to reflect current score.
    191.             foodText.text = "Food: " + food;
    192.  
    193.             //Call the AttemptMove method of the base class, passing in the component T (in this case Wall) and x and y direction to move.
    194.             base.AttemptMove<T>(xDir, yDir);
    195.  
    196.         //Hit allows us to reference the result of the Linecast done in Move.
    197.         RaycastHit2D hit;
    198.    
    199.             //If Move returns true, meaning Player was able to move into an empty space.
    200.             if (Move(xDir, yDir, out hit))
    201.             {
    202.                 //Call RandomizeSfx of SoundManager to play the move sound, passing in two audio clips to choose from.
    203.                 SoundManager.instance.RandomizeMusic(moveSound1, moveSound2);
    204.             }
    205.  
    206.             //Since the player has moved and lost food points, check if the game has ended.
    207.             CheckIfGameOver();
    208.  
    209.             //Set the playersTurn boolean of GameManager to false now that players turn is over.
    210.             A_Game_Manager.instance.playerTurns = false;
    211.         }
    212.  
    213.  
    214.         //OnCantMove overrides the abstract function OnCantMove in MovingObject.
    215.         //It takes a generic parameter T which in the case of Player is a Wall which the player can attack and destroy.
    216.         protected override void OnCantMove<T>(T component)
    217.         {
    218.             //Set hitWall to equal the component passed in as a parameter.
    219.             Wall hitWall = component as Wall;
    220.  
    221.             //Call the DamageWall function of the Wall we are hitting.
    222.             hitWall.DamageWall(wallDamage);
    223.  
    224.             //Set the attack trigger of the player's animation controller in order to play the player's attack animation.
    225.             animator.SetTrigger("PlayerChop");
    226.         }
    227.    
    228.    
    229.  
    230.         //OnTriggerEnter2D is sent when another object enters a trigger collider attached to this object (2D physics only).
    231.         private void OnTriggerEnter2D(Collider2D other)
    232.         {
    233.             //Check if the tag of the trigger collided with is Exit.
    234.             if (other.CompareTag("Exit"))
    235.             {
    236.                 //Invoke the Restart function to start the next level with a delay of restartLevelDelay (default 1 second).
    237.                 Invoke("Restart", restartLevelDelay);
    238.  
    239.                 //Disable the player object since level is over.
    240.                 enabled = false;
    241.             }
    242.  
    243.            
    244.         }
    245.  
    246.  
    247.         //Restart reloads the scene when called.
    248.         private void Restart()
    249.         {
    250.         SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    251.         }
    252.  
    253.  
    254.         //LoseFood is called when an enemy attacks the player.
    255.         //It takes a parameter loss which specifies how many points to lose.
    256.         public void LoseFood(int loss)
    257.         {
    258.             //Set the trigger for the player animator to transition to the playerHit animation.
    259.             animator.SetTrigger("PlayerHit");
    260.  
    261.             //Subtract lost food points from the players total.
    262.             food -= loss;
    263.  
    264.             //Update the food display with the new total.
    265.             foodText.text = "-" + loss + " Food: " + food;
    266.  
    267.             //Check to see if game has ended.
    268.             CheckIfGameOver();
    269.         }
    270.  
    271.  
    272.         //CheckIfGameOver checks if the player is out of food points and if so, ends the game.
    273.         private void CheckIfGameOver()
    274.         {
    275.             //Check if food point total is less than or equal to zero.
    276.             if (food <= 0)
    277.             {
    278.                 //Call the PlaySingle function of SoundManager and pass it the gameOverSound as the audio clip to play.
    279.                 SoundManager.instance.PlaySingle(gameOverSound);
    280.  
    281.                 //Stop the background music.
    282.                 SoundManager.instance.backgroundMusic.Stop();
    283.  
    284.                 //Call the GameOver function of GameManager.
    285.                 A_Game_Manager.instance.GameOver();
    286.             }
    287.         }
    288.     }
    289.  
    290. [code/]
    291.  
    292. Food:
    293.  
    294. [code]
    295. using UnityEngine;
    296. using System.Collections;
    297. using UnityEngine.UI;
    298.  
    299. public class Food : MonoBehaviour {
    300.     //Instance of Player
    301.   private  Player player;
    302.     //Points per foodtype
    303.     public int foodpts = 10;
    304.     //foodtype=true means food. foodtype=false means soda.
    305.     public bool foodtype = true;
    306.     //instance of Sound Manager
    307.    private SoundManager soundManager;
    308.     //Food text
    309.    private Text foodText;
    310.  
    311.     // Check collision between food and player.
    312.     void OnTriggerEnter2D(Collider2D other)
    313.     {
    314.         //Add the food points
    315.         player.food += foodpts;
    316.         //Write the food text.
    317.        foodText.text= "+" + foodpts + " Food: " + player.food;
    318.         //If the food type is food, then one of two types of eatSounds will be played.
    319.         if (foodtype) soundManager.RandomizeMusic(player.eatSound1, player.eatSound2);
    320.         //If it is soda instead, one of two types of drinkSounds will be played.
    321.         else soundManager.RandomizeMusic(player.drinkSound1, player.drinkSound2);
    322.         //Destroy the game object because it is collected.
    323.         Destroy(gameObject);
    324.        
    325.  
    326.     }
    327. }
    328. [code/]
    329.  
    330. Wall
    331. [code]
    332. using UnityEngine;
    333. using System.Collections;
    334.  
    335. public class Wall : MonoBehaviour {
    336.     public Sprite dmgSprite;
    337.     public int hp = 4;
    338.     private SpriteRenderer spriteRenderer;
    339.     public AudioClip dmg1;
    340.     public AudioClip dmg2;
    341.  
    342.  
    343.     // Use this for initialization
    344.     void Awake () {
    345.         spriteRenderer = GetComponent<SpriteRenderer>();
    346.         spriteRenderer.sprite = dmgSprite;
    347.     }
    348.     public void DamageWall(int loss)
    349.     {
    350.         SoundManager.instance.RandomizeMusic(dmg1, dmg2);
    351.         hp -= loss;
    352.         if (hp <= 0)
    353.         {
    354.             gameObject.SetActive(false);
    355.         }
    356.     }
    357.    
    358. }
    359. [code/]
    360. Enemy
    361. [code]
    362. using UnityEngine;
    363. using System.Collections;
    364. using System;
    365.  
    366. public class Enemy : MovingObject
    367. {
    368.    
    369.     public int playerDamage;
    370.  
    371.     private Animator animator;
    372.     private Transform target;
    373.     private bool skipMove;
    374.  
    375.     public AudioClip enemy1;
    376.     public AudioClip enemy2;
    377.  
    378.     protected override void Start()
    379.     {
    380.         A_Game_Manager.instance.AddEnemy(this);
    381.         animator = GetComponent<Animator>();
    382.         target = GameObject.FindGameObjectWithTag("Player").transform;
    383.         base.Start();
    384.     }
    385.  
    386.     protected override void AttemptMove<T>(int xDir, int yDir)
    387.     {
    388.  
    389.         if (skipMove)
    390.         {
    391.             skipMove = false;
    392.             return;
    393.         }
    394.         base.AttemptMove<T>(xDir, yDir);
    395.         skipMove = true;
    396.     }
    397.     public void MoveEnemy()
    398.     {
    399.         int xDir = 0;
    400.         int yDir = 0;
    401.  
    402.         if (Mathf.Abs(target.position.x - transform.position.x) < float.Epsilon)
    403.             yDir = target.position.y > transform.position.y ? 1 : -1;
    404.  
    405.         else
    406.             xDir = target.position.x > transform.position.x ? 1 : -1;
    407.  
    408.         AttemptMove<Player>(xDir, yDir);
    409.  
    410.     }
    411.  
    412.     protected override void OnCantMove<T>(T component)
    413.     {
    414.         Player hitPlayer = component as Player;
    415.         animator.SetTrigger("enemyAttack");
    416.         SoundManager.instance.RandomizeMusic(enemy1, enemy2);
    417.         hitPlayer.LoseFood(playerDamage);
    418.  
    419.     }
    420. }
    421. [code/]
    422.  
    423. MovingObject
    424. [code]
    425. using UnityEngine;
    426. using System.Collections;
    427.  
    428. public abstract class MovingObject : MonoBehaviour
    429. {
    430.     public float moveTime = 0.1f;
    431.     public LayerMask blockingLayer;
    432.     private BoxCollider2D boxCollider;
    433.     private Rigidbody2D rb2D;
    434.     private float inverseMoveTime;
    435.  
    436.     protected virtual void Start()
    437.     {
    438.         boxCollider = GetComponent<BoxCollider2D>();
    439.         rb2D = GetComponent<Rigidbody2D>();
    440.         inverseMoveTime = 1f / moveTime;
    441.  
    442.     }
    443.     protected bool Move(int xDir, int yDir, out RaycastHit2D hit)
    444.     {
    445.         Vector2 start = transform.position;
    446.         Vector2 end = start + new Vector2(xDir, yDir);
    447.         boxCollider.enabled = false;
    448.         hit = Physics2D.Linecast(start, end, blockingLayer);
    449.         boxCollider.enabled = true;
    450.         if (hit.transform == null)
    451.         {
    452.             StartCoroutine(SmoothMovement(end));
    453.             return true;
    454.  
    455.         }
    456.         return false;
    457.     }
    458.     protected IEnumerator SmoothMovement(Vector3 end)
    459.     {
    460.         float sqrRemaingDistance = (transform.position - end).sqrMagnitude;
    461.         while (sqrRemaingDistance > float.Epsilon)
    462.         {
    463.             Vector3 moveTowards = Vector3.MoveTowards(rb2D.position, end, inverseMoveTime * Time.deltaTime);
    464.             rb2D.MovePosition(moveTowards);
    465.             yield return null;
    466.         }
    467.        
    468.     }
    469.  
    470.     protected virtual void AttemptMove<T>(int xDir, int yDir)
    471.  
    472.          where T : Component
    473.     {
    474.         RaycastHit2D hit;
    475.         bool canMove = Move(xDir, yDir, out hit);
    476.         if (hit.transform == null)
    477.             return;
    478.  
    479.         T hitComponent = hit.transform.GetComponent<T>();
    480.  
    481.         if (!canMove && hitComponent != null)
    482.             OnCantMove(hitComponent);
    483.     }
    484.  
    485.     protected abstract void OnCantMove <T>(T component)
    486.         where T : Component;
    487.  
    488.     }
    489. [code/]
    490.  
    491. Loader
    492. [code]
    493. using UnityEngine;
    494. using System.Collections;
    495.  
    496. public class Loader : MonoBehaviour {
    497.     public GameObject gameManager;
    498.     void Awake() {  
    499.       if (A_Game_Manager.instance== null)
    500.         {
    501.             Instantiate(gameManager);
    502.         }
    503.  
    504.     }
    505. }
    506. using UnityEngine;
    507. using System.Collections;
    508.  
    509. public class Loader : MonoBehaviour {
    510.     public GameObject gameManager;
    511.     void Awake() {  
    512.       if (A_Game_Manager.instance== null)
    513.         {
    514.             Instantiate(gameManager);
    515.         }
    516.  
    517.     }
    518. }
    519. [code/]
    520.  
    521.  
    522.  
    523. Board Manager
    524.  
    525. [code]
    526. using UnityEngine;
    527. using System.Collections.Generic;
    528. using System;
    529. using Random = UnityEngine.Random;
    530.  
    531.  
    532.  
    533.  
    534.     public class BoardManager : MonoBehaviour
    535.     {
    536.  
    537.         [Serializable]
    538.         public class Count
    539.         {
    540.             public int maximum;
    541.             public int mininum;
    542.             public Count(int min, int max)
    543.             {
    544.                 max = maximum;
    545.                 min = mininum;
    546.             }
    547.         }
    548.  
    549.         public int columns = 8;
    550.         public int rows = 8;
    551.         public Count wallCount = new Count(4, 8);
    552.         public Count foodCount = new Count(2, 6);
    553.  
    554.         public GameObject exit;
    555.         public GameObject[] floorTiles;
    556.         public GameObject[] wallTiles;
    557.         public GameObject[] foodTiles;
    558.         public GameObject[] enemyTiles;
    559.         public GameObject[] outerWallTiles;
    560.         private Transform boardHolder;
    561.         private List<Vector3> gridPositions = new List<Vector3>();
    562.  
    563.         void InstianlizeList()
    564.         {
    565.             gridPositions.Clear();
    566.             for (int x = 1; x < columns-1; x++)
    567.             {
    568.                 for (int y = 1; y < rows-1; y++)
    569.                 {
    570.                     gridPositions.Add(new Vector3(x, y, 0f));
    571.  
    572.                 }
    573.             }
    574.  
    575.         }
    576.  
    577.         void BoardSetUp()
    578.         {
    579.             boardHolder = new GameObject("Board").transform;
    580.             for (int x = -1; x < columns+1; x++)
    581.             {
    582.                 for (int y = -1; y < rows+1; y++)
    583.                 {
    584.                     GameObject toInstantiate = floorTiles[Random.Range(0, floorTiles.Length)];
    585.                     if (x == -1 || x == columns || y == -1 || y == rows)
    586.                     {
    587.                         toInstantiate = outerWallTiles[Random.Range(0, outerWallTiles.Length)];
    588.                     }
    589.  
    590.                     GameObject instance;
    591.                    
    592.                         instance = Instantiate(toInstantiate, new Vector3(x, y, 0f), Quaternion.identity) as GameObject;
    593.                         instance.transform.SetParent(boardHolder);
    594.                    
    595.                    
    596.                 }
    597.             }
    598.         }
    599.  
    600.         Vector3 RandomPosition()
    601.         {
    602.             int randomIndex = Random.Range(0, gridPositions.Count);
    603.             Vector3 randomPosition = gridPositions[randomIndex];
    604.             gridPositions.RemoveAt(randomIndex);
    605.             return randomPosition;
    606.         }
    607.  
    608.         void LayoutObjectAtRandom(GameObject[] tileArray, int min, int max)
    609.         {
    610.             int objectCount = Random.Range(min, max + 1);
    611.             for (int i = 0; i < objectCount; i++)
    612.             {
    613.                 Vector3 randomPosition = RandomPosition();
    614.                 GameObject tileChoice = tileArray[Random.Range(0, tileArray.Length)];
    615.                 Instantiate(tileChoice, randomPosition, Quaternion.identity);
    616.  
    617.             }
    618.         }
    619.  
    620.         public void SetUp(int level)
    621.         {
    622.             BoardSetUp();
    623.             InstianlizeList();
    624.             LayoutObjectAtRandom(wallTiles, wallCount.mininum, wallCount.maximum);
    625.             LayoutObjectAtRandom(foodTiles, foodCount.mininum, foodCount.maximum);
    626.             int enemyCount = (int)Mathf.Log(level, 2f);
    627.             LayoutObjectAtRandom(enemyTiles, enemyCount, enemyCount);
    628.             Vector3 coordinates = new Vector3(columns - 1, rows - 1, 0f);
    629.             Instantiate(exit, coordinates, Quaternion.identity);
    630.  
    631.         }
    632.  
    633.  
    634.  
    635.     }
    636. using UnityEngine;
    637. using System.Collections.Generic;
    638. using System;
    639. using Random = UnityEngine.Random;
    640.  
    641.  
    642.  
    643.  
    644.     public class BoardManager : MonoBehaviour
    645.     {
    646.  
    647.         [Serializable]
    648.         public class Count
    649.         {
    650.             public int maximum;
    651.             public int mininum;
    652.             public Count(int min, int max)
    653.             {
    654.                 max = maximum;
    655.                 min = mininum;
    656.             }
    657.         }
    658.  
    659.         public int columns = 8;
    660.         public int rows = 8;
    661.         public Count wallCount = new Count(4, 8);
    662.         public Count foodCount = new Count(2, 6);
    663.  
    664.         public GameObject exit;
    665.         public GameObject[] floorTiles;
    666.         public GameObject[] wallTiles;
    667.         public GameObject[] foodTiles;
    668.         public GameObject[] enemyTiles;
    669.         public GameObject[] outerWallTiles;
    670.         private Transform boardHolder;
    671.         private List<Vector3> gridPositions = new List<Vector3>();
    672.  
    673.         void InstianlizeList()
    674.         {
    675.             gridPositions.Clear();
    676.             for (int x = 1; x < columns-1; x++)
    677.             {
    678.                 for (int y = 1; y < rows-1; y++)
    679.                 {
    680.                     gridPositions.Add(new Vector3(x, y, 0f));
    681.  
    682.                 }
    683.             }
    684.  
    685.         }
    686.  
    687.         void BoardSetUp()
    688.         {
    689.             boardHolder = new GameObject("Board").transform;
    690.             for (int x = -1; x < columns+1; x++)
    691.             {
    692.                 for (int y = -1; y < rows+1; y++)
    693.                 {
    694.                     GameObject toInstantiate = floorTiles[Random.Range(0, floorTiles.Length)];
    695.                     if (x == -1 || x == columns || y == -1 || y == rows)
    696.                     {
    697.                         toInstantiate = outerWallTiles[Random.Range(0, outerWallTiles.Length)];
    698.                     }
    699.  
    700.                     GameObject instance;
    701.                    
    702.                         instance = Instantiate(toInstantiate, new Vector3(x, y, 0f), Quaternion.identity) as GameObject;
    703.                         instance.transform.SetParent(boardHolder);
    704.                    
    705.                    
    706.                 }
    707.             }
    708.         }
    709.  
    710.         Vector3 RandomPosition()
    711.         {
    712.             int randomIndex = Random.Range(0, gridPositions.Count);
    713.             Vector3 randomPosition = gridPositions[randomIndex];
    714.             gridPositions.RemoveAt(randomIndex);
    715.             return randomPosition;
    716.         }
    717.  
    718.         void LayoutObjectAtRandom(GameObject[] tileArray, int min, int max)
    719.         {
    720.             int objectCount = Random.Range(min, max + 1);
    721.             for (int i = 0; i < objectCount; i++)
    722.             {
    723.                 Vector3 randomPosition = RandomPosition();
    724.                 GameObject tileChoice = tileArray[Random.Range(0, tileArray.Length)];
    725.                 Instantiate(tileChoice, randomPosition, Quaternion.identity);
    726.  
    727.             }
    728.         }
    729.  
    730.         public void SetUp(int level)
    731.         {
    732.             BoardSetUp();
    733.             InstianlizeList();
    734.             LayoutObjectAtRandom(wallTiles, wallCount.mininum, wallCount.maximum);
    735.             LayoutObjectAtRandom(foodTiles, foodCount.mininum, foodCount.maximum);
    736.             int enemyCount = (int)Mathf.Log(level, 2f);
    737.             LayoutObjectAtRandom(enemyTiles, enemyCount, enemyCount);
    738.             Vector3 coordinates = new Vector3(columns - 1, rows - 1, 0f);
    739.             Instantiate(exit, coordinates, Quaternion.identity);
    740.  
    741.         }
    742.  
    743.  
    744.  
    745.     }
    746. [code/]
    747.  
    748.  
    749. Sound Manager
    750.  
    751. [code]
    752. using UnityEngine;
    753. using System.Collections;
    754.  
    755. public class SoundManager : MonoBehaviour {
    756.     public AudioSource soundEffects;
    757.     public AudioSource backgroundMusic;
    758.    
    759.  
    760.     public float lowPitch = .95f;
    761.     public float highPitch = 1.95f;
    762.     public static SoundManager instance = null;
    763.  
    764.     // Use this for initialization
    765.     void Awake () {
    766.         if (instance = null)
    767.             instance = this;
    768.  
    769.         else if (instance != this)
    770.             Destroy(gameObject);
    771.  
    772.  
    773.         DontDestroyOnLoad(gameObject);
    774.  
    775.  
    776.        
    777.     }
    778.  
    779.     public void PlaySingle(AudioClip clip)
    780.     {
    781.         soundEffects.clip = clip;
    782.         soundEffects.Play();
    783.     }
    784.  
    785.     public void RandomizeMusic(params AudioClip[] clips)
    786.     {
    787.         int randomIndex = Random.Range(0, clips.Length);
    788.         float randomPitch = Random.Range(lowPitch, highPitch);
    789.  
    790.         soundEffects.pitch = randomPitch;
    791.         soundEffects.clip = clips[randomIndex];
    792.         soundEffects.Play();
    793.  
    794.  
    795.     }
    796.    
    797.    
    798. }
    799. [code/]
     
  23. Dustin-Howard

    Dustin-Howard

    Joined:
    Mar 31, 2016
    Posts:
    12
    Hi.
    So I want to do this tutorial, for it is very informal to me and will also help me down the road.
    With that said, the assets package was outdated. It says it can't upgrade properly, but however, I don't want to downgrade my 5.3.3f1 version at all.
    Any help?
    Thanks
     
  24. chabode

    chabode

    Joined:
    Jul 12, 2015
    Posts:
    4
    in my case, they looked like this
    http://imgur.com/2N6CjmQ

    maybe i should check at inner walls / obstacle prefabs in complete folder and compare it to mine.
    i've checked my boardscript but there isn't any difference with tutorial

    #edited
    kek, i forgot to changed my innerwall prefab from floor to items. it does made a difference when game started. sorry guys
     
    Last edited: Mar 31, 2016
    Matthew-Schell likes this.
  25. Mryogi23

    Mryogi23

    Joined:
    Feb 2, 2016
    Posts:
    7
    For some reason, I managed to finish step 1 of Part 4, but the text is starting up a bit....funky. Instead of starting off with a black screen with day 1 and so on before getting rid of both except the food text, it immediately shows the level with no black screen before the leveltext disappears. I did everything else right, so what did I do wrong?
     
  26. chabode

    chabode

    Joined:
    Jul 12, 2015
    Posts:
    4
    i wondering if this happen to anyone but after i finished part 11, player only can move horizontal once and could destroy wall if the wall is in front of him after moved. and enemies tried moved to nearest position between our position in horizontal too. it seems either player or enemy vertical move is being "lost". is there any step i may be missed?
     
  27. UnrealHowl

    UnrealHowl

    Joined:
    Oct 9, 2015
    Posts:
    2
    Thanks for that, All the inner walls have the Wall script attached, Also seem to get the same issue if the enemy collides with the inner walls as well
     
  28. Krotux

    Krotux

    Joined:
    Apr 1, 2016
    Posts:
    4
    There is one issue I can't seem to get rid of, and that is that sometimes the zombies move on top of one another when moving almost at the same time.

    I did reduce the time between movement because the game was getting slow with more zombies. I divided the wait time between zombies by the number of zombies to get a more consistent turn timer. I also made zombies a bit smarter by allowing them to alternate between x and y(they get stuck way less). I don't know if that is the cause.

    I also wanted to implement a camera movement like super Mario, where it doesn't always snap to the player but instead waits for the player to move a certain distance away. However, I found that to be beyond my current understanding.

    Thank you for the tutorial. I'm completely new at both C# and Unity and I somehow managed to get it all working in 1 day. Your voice is clear and helped me understand everything easily.
     
  29. sanlys_

    sanlys_

    Joined:
    Apr 1, 2016
    Posts:
    15
    i am on part five and completed it. but if i try to test the game, i only see the floor tiles and the outer wall tiles.
    this is what it looks like
    Skjermbilde.PNG
     
  30. Matthew-Schell

    Matthew-Schell

    Joined:
    Oct 1, 2014
    Posts:
    238
    I would double check the sprite sorting layers to make sure that the player and item sprites are being rendered in the correct order.
     
  31. Matthew-Schell

    Matthew-Schell

    Joined:
    Oct 1, 2014
    Posts:
    238
    This is a known issue. The reason the enemies are delayed is to prevent them from getting on top of each other, so we can be sure the space is free before they move, that's why you have to wait longer as there are more enemies. Basically you need to limit their movement speed so all the moves can be resolved and avoid this happening. I actually wanted to find a better fix but had already spent many months getting the tutorial together so ended up going with this solution. If anyone in the community has a better idea I'd love to hear it!

    As far as the camera movement the easiest thing to do is just make the camera a child of the player. For the mario type movement you could try checking the distance between the camera and the player each turn to see if it gets above a certain number of units, then move, but as I've said previously, I'm here to help with the existing tutorial, extensions and modifications are beyond my ability to support.
     
  32. Matthew-Schell

    Matthew-Schell

    Joined:
    Oct 1, 2014
    Posts:
    238
    Can you post a screenshot of the hierarchy and the inspector for the LevelImage object? It sounds like for some reason the level image is not blocking out hte level when the game starts. Did you stretch it to fill the screen in it's rect transform when you created it?
     
  33. Matthew-Schell

    Matthew-Schell

    Joined:
    Oct 1, 2014
    Posts:
    238
    I tested the project in 5.3.4f1 and received no warnings or upgrade messages. Can you post more info about the error or warning you're encountering?
     
  34. Matthew-Schell

    Matthew-Schell

    Joined:
    Oct 1, 2014
    Posts:
    238
    I haven't seen this behavior before so I would double check your BoardManager against the BoardManager in the completed scripts folder.
     
  35. Matthew-Schell

    Matthew-Schell

    Joined:
    Oct 1, 2014
    Posts:
    238
    Thanks for pointing this out, I added an annotation to the video making this clear. The fact is that the old code will work, it just shows a warning, but it's good to make the updated code available. This was original written in 5.0 before the SceneManager API update in 5.3.
     
  36. andreobueno

    andreobueno

    Joined:
    Jan 27, 2014
    Posts:
    1
    Hello,

    I'm on part 2 (Level Generation) and, after creating the GameManager.cs and the BoardManager.cs and linking all the prefabs to it (on Inspector), I try to run it but I get these errors:

    IndexOutOfRangeException: Array index is out of range.
    BoardManager.BoardSetup () (at Assets/Scripts/BoardManager.cs:57)
    BoardManager.SetupScene (Int32 level) (at Assets/Scripts/BoardManager.cs:87)
    GameManager.InitGame () (at Assets/Scripts/GameManager.cs:30)
    GameManager.Awake () (at Assets/Scripts/GameManager.cs:24)
    Assets/Scripts/BoardManager.cs(10,22): error CS0101: The namespace `Completed' already contains a definition for `BoardManager'
    Assets/Scripts/GameManager.cs(8,22): error CS0101: The namespace `Completed' already contains a definition for `GameManager'
    Assets/Scripts/GameManager.cs(55,9): error CS8025: Parsing error
    All compiler errors have to be fixed before you can enter playmode!
    UnityEditor.SceneView:ShowCompileErrorNotification()

    I'm new to Unity and this is my first game development using it. Though, I'm a programmer.

    Thank you!
     
  37. Dustin-Howard

    Dustin-Howard

    Joined:
    Mar 31, 2016
    Posts:
    12
    When I try to download the project from the assest store, it says that it has 'trouble updating to Unity 5.'
    Thanks
     
  38. Mryogi23

    Mryogi23

    Joined:
    Feb 2, 2016
    Posts:
    7
    I actually have another problem, but i t's with the audio. The game music works fine, but when i move just once on the first level, the game just ends with the gamer over text and the music stops. Is there something wrong with the audio? I think it is, considering I didn't have this problem before I went into the audio part of the tutorial.
     
  39. Ambrus

    Ambrus

    Joined:
    Mar 30, 2016
    Posts:
    1
    I'm having trouble with floor tiles not spawning after creating the Board Manager and Game Manager scripts. I've checked my prefabs with the ones in the completed folder, I've check my code with the complete scripts and I can't find any errors. I also loaded the floor tiles array with the prefabs from the complete folder and they wont spawn either and there are no floor tiles in the hierarchy when the game is running. Everything else appears as it should. Here is the code for Board Setup function in the Board Manager script.

    Code (csharp):
    1.  voidBoardSetup()
    2. {
    3. boardHolder=newGameObject("Board").transform;
    4.  
    5. for(intx=-1;x<columns+1;x++)
    6. {
    7. for(inty=-1;y<rows+1;y++)
    8. {
    9. GameObjecttoInstantiate=floorTiles[Random.Range(0,floorTiles.Length)];
    10.  
    11. if(x==-1 || x==columns || y==-1 || y==rows)
    12. {
    13. toInstantiate=outerWallTiles[Random.Range(0,outerWallTiles.Length)];
    14.  
    15. GameObjectinstance=Instantiate(toInstantiate,newVector3(x,y,0f),Quaternion.identity)asGameObject;
    16.  
    17. instance.transform.SetParent(boardHolder);
    18. }
    19. }
    20. }
    21. }
    I haven't found any errors. Does anyone have any ideas where else I should look?
    Also, there are no errors or warnings in the console.
     
  40. vanni_001

    vanni_001

    Joined:
    Apr 8, 2016
    Posts:
    1
    Hi Matt,
    first of all, congratulations for the great work you are doing! We would like to use this for a presentation of an educational game, obviousely we will change some elements and the sprites. Do we need a your license to do this or is it enough a quote like this "By courtesy of Matthew Schell"?
    Thank you very much!
     
  41. awillshire

    awillshire

    Joined:
    Apr 29, 2014
    Posts:
    20
    Query Re best practice for persisting scenes in multi-level dungeon crawler

    Hi Matt,

    Thanks again by the way! Do you have any advice about the best way to persist the scenes in a multi-level crawler, particularly when the player has the option to backtrack and return to earlier scenes?

    I'm in the process of building on the Roguelike tutorial to create a complete game. I originally thought to call DontDestroyOnLoad for each level & it's components, but I am now thinking this might not be the right way to go. Especially when the player gets down to the lower levels, I thought it may add a lot of overhead and memory use that is unnecessary.

    Is it a better option to save out each scene as soon as the player leaves it, and keep only the current scene active? Then when the player returns to an earlier scene just reload everything the way it was earlier? If you know of any design patterns or templates that help with level management that would be awesome, as I've found very little in this space even after trawling through a heap of Unity books.

    Thanks again,
    Andrew.
     
  42. joshuaabidwell

    joshuaabidwell

    Joined:
    Apr 10, 2016
    Posts:
    3
    Hi Matt,
    I lost the ability to drag and drop asset files in the unity project window while working on this project. I dragged the idle sprites onto the player game object in the hierarchy and the editor automatically added an animator controller and new animation, but after that, I cannot reproduce the same effect or even move assets around in the project window. I now have to do everything asset-related in windows. I tried reloading the explorer process as admin, restarting computer, making a new, blank project, but nothing has worked.
    Thanks

    NEVERMIND, it seemed to be a layout issue. I changed layout to 2by3 and drag and drop works fine
     
    Last edited: Apr 10, 2016
    Matthew-Schell likes this.
  43. Dustin-Howard

    Dustin-Howard

    Joined:
    Mar 31, 2016
    Posts:
    12
    When I try to go to unity and download the prefabs and whatnot from the assets store,
    It says the following:
    "This package was published using Unity 4 and contains asset types which may not upgrade cleanly to Unity 5:

    Scripts

    Manager assets

    While Unity will generally attempt to upgrade assets to work, problems may still occur. For more information about upgrading projects to Unity 5, please refer to the Unity 5.0 Upgrade Guide."

    I copied and pasted the message when I try to download it from the assets store.
    Thanks.
     
  44. awillshire

    awillshire

    Joined:
    Apr 29, 2014
    Posts:
    20
    Hi Dustin,
    The project should load and execute cleanly in Unity 5 - I just re-loaded it last week and it's running fine. You may get the odd warning in the compiler window but nothing fatal.
    Cheers,
    Andrew.
     
    Matthew-Schell likes this.
  45. Dustin-Howard

    Dustin-Howard

    Joined:
    Mar 31, 2016
    Posts:
    12
    nnnnnooooppe
    still says the same message when I try to download it.
     
  46. awillshire

    awillshire

    Joined:
    Apr 29, 2014
    Posts:
    20
    You will get the message, but it should still run fine. Have you gone to the Completed folder, loaded up the Main scene and tried to play it?
     
    Matthew-Schell likes this.
  47. Dustin-Howard

    Dustin-Howard

    Joined:
    Mar 31, 2016
    Posts:
    12
    Where's that?
    There's no download link that I see.
    Plus, I can't really seem to download the assets.. obviously..
     
  48. Matthew-Schell

    Matthew-Schell

    Joined:
    Oct 1, 2014
    Posts:
    238
    For the 'Possible incompatibility' message please just hit 'Accept'. Then hit 'Import' for the complete project message that follows. I just tested again and it definitely works. This was uploaded last year with 4.6 so people on that version could still use it. It is definitely compatible with Unity 5.
     
  49. Matthew-Schell

    Matthew-Schell

    Joined:
    Oct 1, 2014
    Posts:
    238
    There are a few issues here. One is that you are copying and pasting scripts without removing them from the 'Completed' namespace. If you are going to copy and paste the scripts delete the line where it says: "namespace Completed" along with it's accompanying opening and closing brackets.

    If you see 'Array index is out of range' it probably means you haven't assigned the items to the array in the inspector. Generally speaking this tutorial is meant to be intermediate so you might be better off trying out some of the earlier tutorials first to learn how Unity works, even if you are a programmer already. This assumes you know Unity basics already.
     
  50. Matthew-Schell

    Matthew-Schell

    Joined:
    Oct 1, 2014
    Posts:
    238
    No, the audio would not cause this. Unless you have reached a point where the video tells you to play and test you may have stopped in an incomplete stage. It sounds to me like your player food points are being set to zero, which should cause the game to end and music to stop.
     
Thread Status:
Not open for further replies.