Help with some extra results coming from somewhere.....

So, I’m getting an extra ‘0’ debug value somehow. It seems to be something to do with the ‘CalculatePercentageDeductions’ function. If I bypass it, I seem to get a single log, but after multiplying it in the function, I get the extra result. Also, I’ve done a Cntr + f to look for any active log statements that I might have missed, but I’m not seeing anything.

Sorry for the convoluted code. I’m newer to this, so I know that I have extraneous stuff going on. But the short version is that the script at the bottom “Revenue Sources” takes an input from a field, converts it to a percentage, and assigns it to the variable ‘percentage’ (ln 24.) The upper script, “GameObjectInsta” has the function ‘CalculatePercentageDeductions’ (ln 149), which on mouse up (ln 71) takes that variable, ‘percentage’, and then multiplies it by the function, ‘AddTotalGrossPay’.

If, for example, I put a 5 into the percent field, and 100 under the gross pay, I correctly get a 5 (.05 * 100), but I also get an additional 0. If I then add something to the deductions (to still make the gross equal 100), I get 5, 0, 0.

So, I’m guessing that there is an issue going on that I’m not aware of going on with the foreach commands in the different functions. Another set of eyes would be very appreciated, thank you!

public class GameObjectInsta : MonoBehaviour
{
    public List<Employees> fields;
    public GameObject parentOfField;
    public Employees fieldToCreate;
    public bool buttonWasPressed = false;

    public float totalHours;
    public TMP_Text outputHoursField;//bottom right, gives total
    string totalHoursString;

    int numbEmps;
    public float hourlyRate;
    public TMP_Text outputHourlyRateField;
    public float totalGrossPay;
    public float payEach;
    float iPayEach;
    // public TMP_InputField finalHoursField;

    // Gross Pay Variables
    public List<RevenueSources> revenueSourcesList;
    public GameObject parentOfRevenuePayField;
    public RevenueSources RevenuePrefabToCreate;
    public TMP_Text outputTotalRevenueField;
    public float totalRevenue;

    //Flat Deduction Variables
    public GameObject parentOfFlatDeductionsField;
    public RevenueSources flatDeductionsToCreate;
    public TMP_Text outputTotalFlatDeductionsField;
    public float totalFlatDeductions;

    //Percentage Deduction Variables
    public GameObject parentOfPercentDeductionsField;
    public RevenueSources percentDeductionsToCreate;
    // public TMP_Text outputTotalPercentDeductionsField;
    public float totalPercentDeductions;
    public float iPercentPayEach;

    public void Start()
    {
    }
    public void MakeField()
    {
        Employees fieldClone = Instantiate(fieldToCreate);
        fieldClone.transform.SetParent(parentOfField.transform, false);
        fields.Add(fieldClone);
        //finalHoursField = fieldClone.VisiblePayField;
    }
    public void MakeRevenuePayField()
    {
        RevenueSources fieldCloneRevSrcs = Instantiate(RevenuePrefabToCreate);
        fieldCloneRevSrcs.transform.SetParent(parentOfRevenuePayField.transform, false);
        revenueSourcesList.Add(fieldCloneRevSrcs);
    }

    public void MakeFlatDeductionsField()
    {
        RevenueSources fieldCloneFltDed = Instantiate(flatDeductionsToCreate);
        fieldCloneFltDed.transform.SetParent(parentOfFlatDeductionsField.transform, false);
        revenueSourcesList.Add(fieldCloneFltDed);
    }

    public void MakePercentageDeductionsField()
    {
        RevenueSources fieldClonePrctDed = Instantiate(percentDeductionsToCreate);
        fieldClonePrctDed.transform.SetParent(parentOfPercentDeductionsField.transform, false);
        revenueSourcesList.Add(fieldClonePrctDed);
    }

    public void OnMouseUp()
    {
        buttonWasPressed = true;
        AddTotalHours();
        CalculatePayEach();
        GetHourlyRate();
        CalculatePercentageDeductions();
    }
    float AddTotalHours()
    {
        totalHours = 0;
        if (buttonWasPressed == true)
        {
            foreach (Employees e in fields)

                totalHours += e.hours;
            outputHoursField.text = totalHours.ToString();
        }
        // buttonWasPressed = false;
        return totalHours;
    }
    public float GetHourlyRate()
    {
        hourlyRate = totalGrossPay / totalHours;
               outputHourlyRateField.text = hourlyRate.ToString("f2") + " p/h";
        return hourlyRate;
    }
    public void CalculatePayEach()
    {// doesn't look like a need for a button press indicator
     // do i need to go ahead and assign it to the list within the loop?

        foreach (Employees e in fields)
        {
            iPayEach = GetHourlyRate() * e.hours;
            e.pay = iPayEach.ToString("f2");
            // e.pay = iPayEach; put pay back to float to work
            // finalHoursField.text = e.pay.ToString();
        }
        /*foreach (Employees employees in fields)
        {
            Debug.Log(employees.name);
            Debug.Log(employees.hours);
            Debug.Log(employees.pay);
        }*/
    }
    public float AddTotalRevenue()
    {
        totalRevenue = 0;
        {
            foreach (RevenueSources r in revenueSourcesList)

            totalRevenue += r.revenueAmount;
            outputTotalRevenueField.text = totalRevenue.ToString();
            //Debug.Log(totalRevenue);
        }
        // buttonWasPressed = false;
        return totalRevenue;
    }
    public float AddTotalGrossPay()
    {
        totalGrossPay = (totalRevenue - totalFlatDeductions);
            return totalGrossPay;
    }

    public float AddTotalFlatDeductions()
    {
        totalFlatDeductions = 0;
        {
            foreach (RevenueSources r in revenueSourcesList)

                totalFlatDeductions += r.flatDeductionsAmount;
            outputTotalFlatDeductionsField.text = totalFlatDeductions.ToString();
           // Debug.Log(totalFlatDeductions);
        }
        // buttonWasPressed = false;
        return totalFlatDeductions;
    }

    public void CalculatePercentageDeductions()
    {
            foreach (RevenueSources p in revenueSourcesList)
            {
            iPercentPayEach = p.percent * AddTotalGrossPay();//currently, post flat deductions

            // finalHoursField.text = e.pay.ToString();
          Debug.Log(iPercentPayEach);
            }
    }
    private void Update()
    {
        AddTotalRevenue();
        AddTotalFlatDeductions();
        AddTotalGrossPay();
 
        numbEmps = fields.Count;
    }
}
public class RevenueSources : MonoBehaviour
//This is the class, pulling in the 'percentage' variable
{
    public string revenueName;
    public float revenueAmount;
    public float flatDeductionsAmount;

    public float percent;// actual percentage inputed
    public string percentDeductionsAmount;//after calculation amount (to be displayed)
    public TMP_InputField visiblePercentageDeductionsField;//
 
    public void RevenueAmountAssigner(string revenueField)
    {
        float x = float.Parse(revenueField);
        this.revenueAmount = x;
   
    }
    public void FlatDeductionsAmountAssigner(string flatDeductionsField)
    {
        float x = float.Parse(flatDeductionsField);
        this.flatDeductionsAmount = x;
    }

    public void PercentAssigner(string percentage)
    {
        float x = float.Parse(percentage) * .01f;
        { this.percent = x; }
    }
 
        public void prnt()
    {
      //  Debug.Log(revenueAmount);
    }
    void Update() {
      //  Debug.Log(percent);
    }
}

Don’t stop adding Debug.Logs()… simplify your input data to the minimum dataset that shows the issue, then just start instrumenting your code, even if it takes a Debug per line to figure out. Otherwise, attach the debugger and step through.

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

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

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.

If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.

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:

@Acoustic125 Where are you seeing this value? Please show the Debug.Log output for this value, as Kurt mentioned. You mentioned “I get 5, 0, 0.”, where exactly are you seeing this? In a text field perhaps? Please share a screenshot if so.

Here’s a screenshot just to give you an idea. Clicking on every warning points it back to this same line. But, I’m pretty sure that section isn’t the issue now…

I think I just got it isolated down to almost having to be an assignment issue, the first script up top. I can get it to reproduce by only having a debug statement in the that script. I did check into that already, and it all seemed ok. It seemed to behave correctly up until this point, giving me correct totals in the functions. But it was all addition or subtraction, so I might not have noticed any extra data.

There are three sets of prefabs all very similar, just 2 or 3 input fileds, and I am assigning the values through that first script up there by calling it with the ‘on value changed’ event(?) in the inspector, corresponding with the proper field in the prefab . If I put a Debug.Log for any of the three variables/fields, I get the proper log, but also get a zero for any additional field that is created within that class from either of the other two prefabs (like in the screenshot.)

I’m reading up more on the assignment aspect, I thought I at least understood it well enough to be functional. I have an entire other section in the project that uses a similar technique and I don’t have the same issue, but I’m obviously missing something here.

Any insight would be great, but I’ll keep investigating and see if I can find out what I’m missing,

You are inside a foreach loop and is why you are seeing 3 outputs each time. On the last two, either p.percent or AddTotalGrossPay() is zero. Or both. Debug.Log each of those to find out which one, like

Debug.Log("Percent = " + p.percent.ToString());
Debug.Log("GrossPay = + AddTotalGrossPay.ToString());

I’m not sure why you would call AddTotalGrossPay() in a loop like that since you don’t seem to be passing any parameters. Wouldn’t you want to call it before the foreach in that case?

No one may even see this part, but just to follow up… It looks like it was an effect of how I had the class and lists set up. I was creating new, unintended, list items with the instantiation of the other fields. I was treating the list as if it was integrating the data.

Jeff, as far as calling that method, you’re right. I can and should call it once, and I’ll eventually fix that. Like I said, I’m still newer, so doing inside was just the simplest brute force way in the moment to just get it done.