My Tutorial Project Woes!! RPG Tutorial Issues

Hello fellow developers (or enthusiasts if you do this for the fun)

I decided to try and break into this crazy world of making video games!

My Goals where to learn things that i would actually use or could actually improve on once my knowledge and understanding of things got better!! While i have a begginer understanding of TorqueScript from messing around with Torque2D the change to C+ is proving to have its difficult moments!

So i created some of the Tutorial Projects (The Nightmare Survival Shooter and The Survival Rogue-like) and while i really liked the tutorials i got to the point of copying all the scripts in, Going “Yeah they work” and moving on. Then I Found a tower defense tutorial on “noobtuts” and i completed it.

So i moved on, Created a little defense game of a 3D Castle that has 2D guards defending and 2D Slimes, The original guards (Basically the ones that are around on Map Start) Just run to the final Defensive positions while the Slimes endlessly spawn, every 10 seconds i would spawn another wave of guards who would rush out of the castle to try and stem the wave!! I loved the creation of this, it was great fun but as my knowledge was still in the learning stages and i didn’t understand how to implement in the things i wanted to add i decided to move past this little endless defensive battle onto another project!

(alas the reason for this blog post
Side Note: Everything up to this point i have done offline, I am Close to moving house so we disconnected the internet. All Tutorials i saved the Transcripts offline or for the webpages i had saved to offline viewing. Sure it made things harder but if you want to learn you will not let tiny things such as “internet” stop you!!)

RPG Tutorial: How To Create A Unity RPG - Comprehensive Guide - GameDev Academy

This tutorial is awesome (excuse the language), I followed it as precise as i could! I created the Title scene with no worries, moved onto the town scene (World Map or whatever else you would personally call it) and had no problems there (Besides making the judgement call to not create all the Animations for the Animation Controller, i know how to do that and i didnt have an issue with my Sprite being a Static Object on the town Scene

Then i moved onto the Battle Scene, WOW this was where the major headaches begin!!

First Issue is with my HUDCanvas, i know i have followed the setup correctly as it all looks fine with the object layout and i have the child objects when compared to the source file!
and the scripts i was told to implement i have copied straight from the webpage and i didnt get any compiler errors and yet the script for AddButtonCallback is clearly not working for the buttons i have implemented it on (the HUDCanvas (PhysicalAttack, MagicalAttack)) as whenever i click on a button nothing happens!!

I continued with the tutorial as i decided that even if i manage to do everything the tutorial asks i could fix the issues and bugs at the end.

So i followed the tutorial on without further issues until i reached the creating of the TurnSystem, Same as before i have copied the scripting over from the Source and i have made sure that everything else that should be effecting the code is the same as the source (For instance the only differences between my Battle Scene and the Source are little things like the Background Canvas or the fact that the scene is called “Battle Scene” and not “Battle” like in the source

So here are the error logs in the console
error 1:
NullReferenceException: Object reference not set to an instance of an object
PlayerUnitAction.updateHUD () (at Assets/Scripts/PlayerUnitAction.cs:22)
SelectUnit.selectCurrentUnit (UnityEngine.GameObject unit) (at Assets/Scripts/SelectUnit.cs:31)
TurnSystem.nextTurn () (at Assets/Scripts/TurnSystem.cs:62)
KillDamageText.OnDestroy () (at Assets/Scripts/KillDamageText.cs:16)

And thats pretty much my post!! I understand that my issue could possibly be stemming out of a few different script files such as “PlayerUnitAction” or any of the other scripts that are involved with the turn system and they can all be seen from the tutorial link i posted above.

Maybe this is abit of an Advanced Tutorial for a beginner like me? Maybe the Unity Engine has been changed and therefore some of the scripting commands have changed? Either way i will keep at it but i am really hoping that some of the wonderful forum users could help??

Thanks for reading my first Blogpost/WordDump and thank you for reading this far!
As i continue to work and reach this last error i must admit that i have no idea as to whats going wrong as i can simply go “//playerUnitFace.GetComponent().sprite = this.faceSprite;” and when i reach the battle scene my debug logs: Enemy Unit Acting, calculateNextTurn(x5), Player Unit Acting and then finishes. the game runs but buttons dont work :confused:

Edits: Changing Errorlogs as i continue to “work/experiment” Moved Scripts

Here is the Script for Turn System

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TurnSystem : MonoBehaviour {

    private List<UnitStats> unitsStats;

    private GameObject playerParty;

    public GameObject enemyEncounter;

    [SerializeField]
    private GameObject actionsMenu, enemyUnitsMenu;

    void Start()
    {
        this.playerParty = GameObject.Find("PlayerParty");

        unitsStats = new List<UnitStats>();
        GameObject[] playerUnits = GameObject.FindGameObjectsWithTag("PlayerUnit");
        foreach (GameObject playerUnit in playerUnits)
        {
            UnitStats currentUnitStats = playerUnit.GetComponent<UnitStats>();
            //NullReferenceException:Object reference not Set to an instance of an Object
            // TurnSystemStart() (Was Line 25) (Now Line 27 Due to Comments)
            currentUnitStats.calculateNextActTurn(0);

            unitsStats.Add(currentUnitStats);
        }
        GameObject[] enemyUnits = GameObject.FindGameObjectsWithTag("EnemyUnit");
        foreach (GameObject enemyUnit in enemyUnits)
        {
            UnitStats currentUnitStats = enemyUnit.GetComponent<UnitStats>();
            currentUnitStats.calculateNextActTurn(0);
            unitsStats.Add(currentUnitStats);
        }
        unitsStats.Sort();

        this.actionsMenu.SetActive(false);
        this.enemyUnitsMenu.SetActive(false);

        this.nextTurn();
    }

    public void nextTurn()
    {
        UnitStats currentUnitStats = unitsStats[0];
        unitsStats.Remove(currentUnitStats);

        if (!currentUnitStats.isDead())
        {
            GameObject currentUnit = currentUnitStats.gameObject;

            currentUnitStats.calculateNextActTurn(currentUnitStats.nextActTurn);
            unitsStats.Add(currentUnitStats);
            unitsStats.Sort();

            if (currentUnit.tag == "PlayerUnit")
            {
                Debug.Log("Player unit acting");
                this.playerParty.GetComponent<SelectUnit>().selectCurrentUnit(currentUnit.gameObject);
            }
            else
            {
                currentUnit.GetComponent<EnemyUnitAction>().act();
            }
        }
        else
        {
            this.nextTurn();
        }
    }
}

and the script for the CreateEnemyMenuItem

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

public class CreateEnemyMenuItem : MonoBehaviour {

    [SerializeField]
    private GameObject targetEnemyUnitPrefab;

    [SerializeField]
    private Sprite menuItemSprite;

    [SerializeField]
    private Vector2 initialPosition, itemDimensions;

    [SerializeField]
    private KillEnemy killEnemyScript;

    // Use this for initialization
    void Awake()
    {
        GameObject enemyUnitsMenu = GameObject.Find("EnemyUnitsMenu");

        GameObject[] existingItems = GameObject.FindGameObjectsWithTag("EnemyUnit");
       Vector2 nextPosition = new Vector2(this.initialPosition.x + (existingItems.Length * this.itemDimensions.x), this.initialPosition.y);

        GameObject targetEnemyUnit = Instantiate(this.targetEnemyUnitPrefab, enemyUnitsMenu.transform) as GameObject;
        targetEnemyUnit.name = "Target" + this.gameObject.name;
        targetEnemyUnit.transform.localPosition = nextPosition;
        targetEnemyUnit.transform.localScale = new Vector2(0.7f, 0.7f);
        targetEnemyUnit.GetComponent<Button>().onClick.AddListener(() =>
          selectEnemyTarget());
        targetEnemyUnit.GetComponent<Image>().sprite = this.menuItemSprite;

        killEnemyScript.menuItem = targetEnemyUnit;
    }

    public void selectEnemyTarget()
    {
        GameObject partyData = GameObject.Find("PlayerParty");
        partyData.GetComponent<SelectUnit>().attackEnemyTarget(this.gameObject);
    }

}

Unit Stats

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

public class UnitStats : MonoBehaviour, System.IComparable
{

    [SerializeField]
    private Animator animator;

    [SerializeField]
    private GameObject damageTextPrefab;
    [SerializeField]
    private Vector2 damageTextPosition;

    public float health;
    public float mana;
    public float attack;
    public float magic;
    public float defense;
    public float speed;



    public int nextActTurn;

    private bool dead = false;

    private float currentExperience;

    void Start()
    {

    }

    public void receiveDamage(float damage)
    {
        this.health -= damage;
        animator.Play("Hit");

        GameObject HUDCanvas = GameObject.Find("HUDCanvas");
        GameObject damageText = Instantiate(this.damageTextPrefab, HUDCanvas.transform) as GameObject;
        damageText.GetComponent<Text>().text = "" + damage;
        damageText.transform.localPosition = this.damageTextPosition;
        damageText.transform.localScale = new Vector2(1.0f, 1.0f);

        if (this.health <= 0)
        {
            this.dead = true;
            this.gameObject.tag = "DeadUnit";
            Destroy(this.gameObject);
        }
    }

    public void calculateNextActTurn(int currentTurn)
    {
        this.nextActTurn = currentTurn + (int)System.Math.Ceiling(100.0f / this.speed);
        Debug.Log("calculateNextActTurn");
    }

    public int CompareTo(object otherStats)
    {
        return nextActTurn.CompareTo(((UnitStats)otherStats).nextActTurn);
    }

    public bool isDead()
    {
        return this.dead;
    }

    public void receiveExperience(float experience)
    {
        this.currentExperience += experience;
        Debug.Log("experience!!");
    }
A
}

AddButtonCallBack Code

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

public class AddButtonCallback : MonoBehaviour {

    [SerializeField]
    private bool physical;

    // Use this for initialization
    void Start()
    {
        this.gameObject.GetComponent<Button>().onClick.AddListener(() => addCallback());
    }

    private void addCallback()
    {
        GameObject playerParty = GameObject.Find("PlayerParty");
        playerParty.GetComponent<SelectUnit>().selectAttack(this.physical);
    }

}

Have you solved the problem? I use the same tutorial. I have a similar error.

  • UnitStats currentUnitStats = playerUnit.GetComponent();
  • //NullReferenceException:Object reference not Set to an instance of an Object
  • // TurnSystemStart() (Was Line 25) (Now Line 27 Due to Comments)
  • currentUnitStats.calculateNextActTurn(0);

The null reference exception happens because GetComponent can return null if your playerUnit does not have a component of the type you are asking for. In this case UnitStats. Without having your project to look at I can only guess but the first thing I would check is to make sure all of your playerUnits have indeed a UnitStats component.