Data Reference not showing correctly

Hi,

Currently I am trying to make a fight arena for a RPG game I am making.
My problem here is, that I use in my eyes a quite simple code I have used before but this time it isn’t working.

(in data script) MonsterHealth = 56182
(in data script) BrokenBarrelHealth = 12412
data.MonsterHealth = data.BrokenBarrelHealth;

Debug.log(MonsterHealth);
Result = 12412

But when I use, MonsterHealth.text = data.MonsterHealth.tostring();
it will show the integer 10;

When I mirror the line data.MonsterHealth = data.BrokenBarrelHealth;
the integer will show 0.

When I attack the monster, the code now removes 5 health after the timer is done.
value 10 will go to 5, but the debug.log stays the same.

I can’t find the issue here, help is really appreciated!

Edit; nowhere in my script I use the value 10

Your given code examples are highly confusing to me. At first you indicate your integer variables are spelled in UpperCamelCase, ie MonsterHealth. You also access them the same way when writing data.MonsterHealth. Later however you write data.monsterhealth, in all lower case, and use the UpperCamelCase one like a UI element by accessing its .text - so which is it? What is what? Or do you have data.MonsterHealth aswell as data.monsterhealth, and your UI elements are actually called the same… :face_with_spiral_eyes:

Maybe post the actual code. As is, i cant grasp what is going on, let alone help with this.
Maybe your problem is the same.

3 Likes

oh my bad!

It’s all MonsterHealth and BrokenBarrelHealth.
Only two integers are being used here.

Changing the MonsterValues.

 public void MonsterMechanism()
    {
        if (AttackMonster == 1)
        {
            PlayerStats();

            data.MonsterCombatLevel = data.BrokenBarrelCombatLevel;
            data.MonsterHealth = data.BrokenBarrelHealth;
            data.MonsterMaxHealth = 100;
            data.MonsterAttack = data.BrokenBarrelAttack;
            data.MonsterDefence = data.BrokenBarrelDefence;
            data.MonsterStrength = data.BrokenBarrelStrength;
            data.MonsterMage = data.BrokenBarrelMage;
            data.MonsterMageDef = data.BrokenBarrelMageDefence;

            MonsterName.text = "Broken Barrel";
            MonsterAtt.text = "Attack: " + data.MonsterAttack;
            MonsterStr.text = "Strength: " + data.MonsterStrength;
            MonsterDef.text = "Defence: " + data.MonsterDefence;
            MonsterMage.text = "Mage: " + data.MonsterMage;
            MonsterMageDef.text = "Mage Defence: " + data.MonsterMageDef;
            MonsterMaxHit.text = "Max Hit: " + (data.MonsterStrength * data.MonsterCombatLevel * 1.2 * 10).ToString();
            MonsterAttDef.text = "Attack Defence: " + (data.MonsterCombatLevel * data.MonsterDefence * 10).ToString();
            MonsterRngDef.text = "Range Defence: " + (data.MonsterCombatLevel * data.MonsterDefence * 1.20 * 10).ToString();
            MonsterMageDef.text = "Mage Defence: " + (data.MonsterCombatLevel * data.MonsterDefence * 1.40 * 10).ToString();
        }
    }

Showing the health (in the future also other values)

public void sliders()
    {
        MonsterHealthArea.text = "Health: " + data.MonsterHealth + " / " + data.MonsterMaxHealth;
    }

Attacking Script

public void playerAttackInterval()
    {
        if (PlayerAttackInterval == true && AttackMonster == 1)
        {
            PlayerAttackIntervalTimer += Time.deltaTime * (1 / Time.timeScale);
            {
                if (PlayerAttackIntervalTimer >= 5)
                {
                    data.BrokenBarrelHealth -= 5;
                    PlayerAttackInterval = false;
                    PlayerAttackIntervalTimer = 0;
                  
                }
            }
        }
}

Data Script Values

   //Monster Data
    // -----------------
    public int MonsterCombatLevel = 0;
    public int MonsterHealth = 56182;
    public int MonsterMaxHealth = 0;
    public int MonsterAttack = 0;
    public int MonsterStrength = 0;
    public int MonsterDefence = 0;
    public int MonsterMage = 0;

//BrokenBarrelValues
    public int BrokenBarrelCombatLevel = 18;
    public int BrokenBarrelHealth = 12412;
    public int BrokenBarrelAttack = 17;
    public int BrokenBarrelStrength = 16;
    public int BrokenBarrelDefence = 2;
    public int BrokenBarrelMage = 15;
    public int BrokenBarrelMageDefence = 2;
    public double BrokenBarrelAttackInterval = 2.6;

using these “weird” values was to search for the problem myself, but can’t seem to find it.

Data comes from many places. Your script is just ONE potential place.

Serialized properties in Unity are initialized as a cascade of possible values, each subsequent value (if present) overwriting the previous value:

  • what the class constructor makes (either default(T) or else field initializers)

  • what is saved with the prefab

  • what is saved with the prefab override(s)/variant(s)

  • what is saved in the scene and not applied to the prefab

  • what is changed in Awake(), Start(), or even later etc.

Make sure you only initialize things at ONE of the above levels, or if necessary, at levels that you specifically understand in your use case. Otherwise errors will seem very mysterious.

Here’s the official discussion: https://blog.unity.com/technology/serialization-in-unity

Field initializers versus using Reset() function and Unity serialization:

https://discussions.unity.com/t/829681/2

https://discussions.unity.com/t/846251/8

In general, it sounds like it is time for you to start debugging!

Here is how you can begin your exciting new debugging adventures:

You must find a way to get the information you need in order to reason about what the problem is.

Once you understand what the problem is, you may begin to reason about a solution to the problem.

What is often happening in these cases is one of the following:

  • the code you think is executing is not actually executing at all
  • the code is executing far EARLIER or LATER than you think
  • the code is executing far LESS OFTEN than you think
  • the code is executing far MORE OFTEN than you think
  • the code is executing on another GameObject than you think it is
  • you’re getting an error or warning and you haven’t noticed it in the console window

To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run? what order does it run in?
  • what are the names of the GameObjects or Components involved?
  • what are the values of the variables involved? Are they initialized? Are the values reasonable?
  • are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

Knowing this information will help you reason about the behavior you are seeing.

You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as Debug.Log("Problem!",this);

If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

You could also just display various important quantities in UI Text elements to watch them change as you play the game.

Visit Google for how to see console output from builds. If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer or iOS: https://discussions.unity.com/t/700551 or this answer for Android: https://discussions.unity.com/t/699654

If you are working in VR, it might be useful to make your on onscreen log output, or integrate one from the asset store, so you can see what is happening as you operate your software.

Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

https://discussions.unity.com/t/839300/3

“When in doubt, print it out!™” - Kurt Dekker (and many others)

Note: the print() function is an alias for Debug.Log() provided by the MonoBehaviour class.

1 Like

So… i dont know where your bug is at a glance. As Kurt said, just print values. Inputs, Outputs, calculation results… find where your actual values differ from your expectations and then figure out why that is and where the wrong values come from.

However, and maybe more importantly, you should really look into making your code more modular and object oriented. You still didnt post your full scripts, but by how you handle things, im guessing your “data” script contains the data for tons of different monsters, which you then assign to the, what seems like, “current monster” variables in that MonsterMechanism() method.

Usually we want things to be as modular as possible, which is where object oriented programming helps you greatly. You could just make a script and call it Monster. Put all common shared variables in there, like CombatLevel and Health. If there is some things not all monsters share, make a subclass. For example RangedMonster, which inherits from Monster and adds a Range attribute.

Now you can simply make prefabs of objects where you attach this script to. Wanna create a Barrel enemy? Take a Barrel model, slap the Monster script on the same gameobject, set the values to what Barrel enemies should have, turn it into a prefab… and whenever you need to spawn a barrel enemy, simply instantiate that prefab.

This obviously depends a bit on the type of game you are making, but unless im mistaken on how you currently handle things, i cant really come up with a usecase where this would be an elegant solution.

Also, a bit off-topic, but you dont have to compare booleans to true or false. The statement (someBool == true) is identical to just (someBool) and (someBool == false) is identical to (!someBool).

1 Like

Hi Kut,

I’ve been looking through the scripts a while now.
These are so far, the only two scripts available in the current project, besides that in both script I don’t have a value that’s 10, there’s also not a calculation that will make it 10, also there’s no gameobject in my game that will make it 10. the number 10 is currently non existent in the game. So as you see I am lost, what’s new.

I also used the print command you adviced me to use, weirdly that gives me an outpot of 10, while debug.log gives me an output of said MonsterHealth.


Thanks for your answer Yoreki!

You are correct, posting the whole script, will take ages to scroll, with the ctrl + f command, I tried looking for the value 10, also used debug.log and print command on several cases. interestingly is that with the MonsterHealth value, the output value with debug is the “correct” value while with MonoBehaviour the value is 10 as seen in the game.

Also good advice on using a seperate script for creating base monster values, my game I am trying to create is a text based-ish game just like Melvor Idle and other text games. There’s no “world” in my game only a menu :).

So as mentioned above, the print command gives the value 10, while debug.log gives the right value. That’s the only thing I can find right now and yes these are the only 2 scripts.

Thank you for explaining the part about booleans, appreciate it :slight_smile:


Edit; Kurt*