Character Generator

Ok, post the code up again, with the code formatting this time :wink:

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

public class RollStats : MonoBehaviour {

    public void DiceRoller()
    {
        int[] results = Dice.Roll(Dice.DieType.D6, 4, Dice.SortOrder.Descending);
        


        for (int i = 0; i < results.Length; i++)

        {

            Debug.Log(results[i].ToString());

            
        }
        int sumOfDiceRolls = 0;

        for (int i = 0; i < 3; i++)
        {
            sumOfDiceRolls += results[i];
        }

        Debug.Log("Total was : " + sumOfDiceRolls);

    }
    public void RollStrength()
    {
        // intentionally left empty
    }
    public void RollDexterity()
    {
        // intentionally left empty
    }
    public void RollConsititution()
    {
        // intentionally left empty
    }
    public void RollIntelligence()
    {
        // intentionally left empty
    }
    public void RollWisdom()
    {
        // intentionally left empty
    }
    public void RollCharisma()
    {
        // intentionally left empty
    }
}

Please do use the code formatting, I am currently replying via my mobile whilst trying to resolve some laptop issues, so having the code more readable is really useful. See the link above.

So, the class is starting to come along nicely. Let me know when the other changes are all done.

I’m sorry for that i did not see the post with code formatting. i have cleaned up the Hierarchy by naming the GameObjects

That’s ok… I seem to be having a drive problem so having to respond via the mobile, it’s a bit of a pain, but the code formatting should be used whenever you copy/paste code up to the forum, it allows people to read it more easily and they can then just copy/paste parts of it back to you where they offer help etc… much easier than screenshots… they are great however for the Unity editor or errors.

Ok… so, GameObjects all renamed to appropriate things, including the buttons and the new text boxes which we will be using for outputting out dice rolls in. Script renamed and we have a method stub for each of our methods.

Are the buttons all wired up to their respective methods too?

they are but they are not displaying any rolls yet

That’s ok… we have them wired to those empty stub methods, which don’t actually do anything yet.

Right, lets make some more code changes to support what we want to do.

The DiceRoller method does pretty much what we want for the creation of these characteristics, but we could tidy it up a little bit.

As only this class is going to be using it at the moment, it can now have an access modifier of private, instead of public. We will call this method from our stub methods in due course.

Also, we don’t really need the Debug.Log statements which are in there either now, we have seen that it is working. I still don’t like the hard coded 4 or the hard coded 3, but, we know that those numbers are appropriate for creating all of these stats, so, for now, lets leave them in but perhaps add a comment to remind us to improve this later…

private void DiceRoller()
{
	// TODO: remove the hard-coded "4"
	int[] results = Dice.Roll(Dice.DieType.D6, 4, Dice.SortOrder.Descending);

	int sumOfDiceRolls = 0;

	// TODO: remove the hard-coded "3"
	for (int i = 0; i < 3; i++)
	{
		sumOfDiceRolls += results[i];
	}
}

That’s a bit better, easier to read. If we are going to call this method from our characteristic specific methods, this one is going to need to actually return a value back to them, at the moment it is set to void, which means we will get nothing back.

As we are expecting a sum of our ints back, lets set this method to return the data type of int and also return our sum;

private int DiceRoller()
{
	// TODO: remove the hard-coded "4"
	int[] results = Dice.Roll(Dice.DieType.D6, 4, Dice.SortOrder.Descending);

	int sumOfDiceRolls = 0;

	// TODO: remove the hard-coded "3"
	for (int i = 0; i < 3; i++)
	{
		sumOfDiceRolls += results[i];
	}

	return sumOfDiceRolls;
}	

Let me know when you’ve got the above in place, also, let me know if there’s anything going on here you aren’t sure about, access modifiers or the difference between methods that return/don’t return values/objects etc.

what is hard coded?

Sorry, I should have explained…

Ok, in this code example;

int[] results = Dice.Roll(Dice.DieType.D6, 4, Dice.SortOrder.Descending);

We have specifically stated we are going to roll “4” dice. That means that our DiceRoller method currently will always roll 4 dice. They will always be D6s and the sort order will always be descending.

Instead of having those values set within the method, we could expose some parameters on the DiceRoller method for them instead, and then use those instead of the values we have specified. That way, should we ever want to change our game rules in the future, we could just pass in a value of say “3” instead of “4” and our method would still run happily. Example;

private void DiceRoller(int diceToRoll)
{
int[] results = Dice.Roll(Dice.DieType.D6, diceToRoll, Dice.SortOrder.Descending);

In the above snippet, we now have a parameter which allows us to pass in an int value when we call the DiceRoller method, we then use the parameter in the Dice.Roll method call, thus the hard-coded “4” is now gone.

I wouldn’t worry about changing the code to support this just yet, but its something to be aware of, as we don’t want to start copying methods over and over again just to use different values, if the methods all do the same thing, we need to make them a little more dynamic.

Make sense?

/slaps own wrist for using jargon!

Ok so if we wanted to use the same script for damage for weapons then we could set it up just have the weapons scripts change the dice according right?

Potentially yes.

So, if weapon damage perhaps only required 2 dice to be rolled, the we could pass in a “2” via the parameter and use that in our subsequent method call.

This is a simplified analogy because in the big BIG picture, you would presumably have all sorts of modifiers and things like that in play also. But for now, lets keep it simple :slight_smile:

Another way of thinking about the hard coded values. If you think about a Pac-Man arcade machine, you put your money in, you get three lives. The value of “3” has been hard coded into the game. It doesn’t matter what you do, whether you throw more money at it, you still only get “3”. To change that value it would take the developer of the software to come along and make a change. But, if we changed it a little bit, we could use the same “SetLives” method, but perhaps pass in the day of the week, maybe on a Friday you get “5” lives for example. We didn’t need to write a separate method for Fridays, we just used the same code but extended it a little.

You can worry about these things too much in the early stages, and then you end up creating a beast of a solution for scenarios that may never occur (hence only 3 lives in Pac-Man!), but, if we are aware of it, and pop a comment in, we can find it later on and make an informed decision about it then. :slight_smile:

ok that makes scenes. i have made the changes to the script but when i had it as a private void DiceRoller the return had a red underline so i changed it to int and it went away is that right?

public class RollStats : MonoBehaviour {

    private int DiceRoller()
    {
        // TODO: remove the hard-coded "4"
        int[] results = Dice.Roll(Dice.DieType.D6, 4, Dice.SortOrder.Descending);

        int sumOfDiceRolls = 0;

        // TODO: remove the hard-coded "3"
        for (int i = 0; i < 3; i++)
        {
            sumOfDiceRolls += results[i];
        }

        return sumOfDiceRolls;
1 Like

Excellent - you spotted my, erm, deliberate mistake :wink: I was copying/pasting things into a text editor to solve the tab/spacing issues and forgot to change that before posting it here, sorry for any confusion - but well done for working that out and resolving it.

We need to give a little bit of thought to our next step. We have buttons wired up to our methods, but there isn’t really anything linking back to those text boxes we are going to use to display our results in. There are a few ways we could do this, for now I am going to propose that we create a set of public variables, one for each Text UI GameObject that represents the characteristic.

Inside our class, and above the DiceRoller method definition, lets add those variables. We will be referencing Text types from the scene, so;

public class RollStats : MonoBehaviour {

    public Text strength;
    public Text dexterity;

    // add the rest

These are known as member variables, they belong to our class (members). Add one for each of the characteristics. When you save the script, in the Inspector you will see 6 new fields appear. From the Hierarchy, drag the corresponding GameObject to the field, e.g. the UI-Text GameObject which will hold our value.

Let me know when you’re done :slight_smile:

lol I thought it was a test :laughing:

1 Like

:smiley:

erm… yeah… it was… honest! :smiley:

i have a red underline for Text

This is because the UI Text class is in a different namespace, and in order to use them within our class we need to set an additional using directive at the top of our script, by doing so we get access to the classes that are within that namespace.

Add the following;

using UnityEngine.UI;

i was trying to remember how that was tryped

ok they are loaded

The Unity documentation is really very good, so if you come up against things like this I whole-heartedly recommend doing some simple searches in Google, “unity Text UI”, you’ll find that their documentation links come up very high in the results. But what is really useful is that in their documentation it mentions the namespace that their class(es) are in.

I probably visit their site at least once every day, if not more, definitely a habit which can help :slight_smile:

Privacy & Terms