Search Unity

Resolved Override Input Field Calculation

Discussion in 'Scripting' started by LazPhoto, Mar 2, 2021.

  1. LazPhoto

    LazPhoto

    Joined:
    Sep 11, 2019
    Posts:
    11
    What I want: In a cost calculator project, I need to have a field with a calculated result that is able to be overridden and recalculated by user input, i.e., the calculation is a suggested number of units to purchase based on the calculation, however, the user should be able to override that with their own number and be reflected in the calculation of TotalRacks().

    What I've tried: My current approach has been to use an Input Field and have the placeholder text be the result of the calculation. This works fine on its own (the calculation shows up correctly). The problem is when I manually input a number in that field and attempt to recalculate (I have a "Calculate" button in the UI), the result doesn't change.

    I don't if my approach is on track but I'm missing something or if I'm completely off base with my line of thought. Any help/suggestions/solutions please? I've included my code (sorry if it's messy or no optimal, I'm relatively new to programming) and a screenshot of the project, but please let me know if more information is needed.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System;
    4.  
    5. public class InputSFCalc : MonoBehaviour
    6. {
    7.  
    8.     public InputField Field1;
    9.     public InputField Field2;
    10.     public InputField Field3;
    11.     public InputField CostPerRack;
    12.     public InputField RacksSuggested;
    13.    
    14.     public Text sfResult;
    15.     public Text rollsCost;
    16.     public Text rollsNeeded;
    17.     public Text velcroLength;
    18.     public Text velcroFree;
    19.     public Text racksTotal;
    20.    
    21.  
    22.     int rollWidth = 6;
    23.     int rollDivider = 75;
    24.     int rackRollDivider = 7000;
    25.  
    26.     bool rack;
    27.  
    28.     public void Start()
    29.     {
    30.  
    31.         RacksSuggested.onValueChanged.AddListener(delegate { RackValueChange(); });
    32.  
    33.     }
    34.  
    35.     public void Update()
    36.     {
    37.        
    38.     }
    39.  
    40.     public void Sum()
    41.     {
    42.         int a = Convert.ToInt32(Field1.text);
    43.         int b = Convert.ToInt32(Field2.text);
    44.         int c = a + b;
    45.         sfResult.text = c.ToString();
    46.     }
    47.  
    48.  
    49.     public void Product()
    50.     {
    51.         int a = Convert.ToInt32(Field1.text);
    52.         int b = Convert.ToInt32(Field2.text);
    53.         int c = a * b;
    54.         sfResult.text = c.ToString("n0");
    55.     }
    56.  
    57.     public void RollsCost()
    58.     {
    59.        
    60.         decimal a = Convert.ToDecimal(Field3.text);
    61.         decimal b = Convert.ToDecimal(sfResult.text);
    62.         decimal c = a * b;
    63.         rollsCost.text = c.ToString("C");
    64.     }
    65.  
    66.     public void RollsNeeded()
    67.     {
    68.         int a = Convert.ToInt32(Field2.text);
    69.         int c = a / rollWidth;
    70.         rollsNeeded.text = c.ToString();
    71.        
    72.     }
    73.  
    74.     public void VelcroLength()
    75.     {
    76.         int a = Convert.ToInt32(rollsNeeded.text);
    77.         int b = Convert.ToInt32(Field1.text);
    78.         int c = (a * b) - b;
    79.         velcroLength.text = c.ToString("n0") + " ft";
    80.     }
    81.  
    82.  
    83.     public void VelcroFree()
    84.     {
    85.         double a = Convert.ToInt64(rollsNeeded.text);
    86.         double b = Convert.ToInt64(Field1.text);
    87.         double c = (a * b) - b;
    88.         double d = c / rollDivider;        
    89.         double e = Math.Ceiling(d);
    90.         velcroFree.text = e.ToString();
    91.              
    92.     }
    93.  
    94.     public void RackValueChange()
    95.     {
    96.         rack = RacksSuggested.GetComponent<InputField>().placeholder.GetComponent<Text>().text == null;
    97.        
    98.         Debug.Log("Rack Value is Null");
    99.  
    100.     }
    101.  
    102.  
    103.  
    104.     public void RacksNeeded() //default value is 1
    105.     {
    106.         if (RacksSuggested.GetComponent<InputField>().placeholder.GetComponent<Text>().text == null)
    107.         {
    108.             RacksSuggested.text.ToString();
    109.         }
    110.         else
    111.         {
    112.             double a = Convert.ToInt32(Field1.text);
    113.             double b = Convert.ToInt32(Field2.text);
    114.             double c = a * b;
    115.             double d = c / rackRollDivider;
    116.             double e = Math.Ceiling(d);            
    117.             RacksSuggested.GetComponent<InputField>().placeholder.GetComponent<Text>().text =      e.ToString();
    118.            
    119.         }
    120.            
    121.     }
    122.  
    123.     public void RacksTotal()
    124.     {
    125.         if(RacksSuggested.GetComponent<InputField>().placeholder.GetComponent<Text>().text != null)
    126.         {
    127.             decimal w = Convert.ToInt32(Field1.text);
    128.             decimal x = Convert.ToInt32(Field2.text);
    129.             decimal y = w * x;
    130.             decimal z = y / rackRollDivider;
    131.             decimal v = Math.Ceiling(z);
    132.  
    133.             decimal b = v;
    134.             decimal a = Convert.ToDecimal(CostPerRack.text);
    135.             //decimal b = Convert.ToDecimal(RacksSuggested.text);
    136.             decimal c = a * b;
    137.             racksTotal.text = c.ToString("C");
    138.         }
    139.         else
    140.         {
    141.             decimal a = Convert.ToDecimal(CostPerRack.text);
    142.             decimal b = Convert.ToDecimal(RacksSuggested.text);
    143.             decimal c = a * b;
    144.             racksTotal.text = c.ToString("C");
    145.         }
    146.            
    147.  
    148.     }
    149.  
    150.    
    151.  
    152.  
    153.  
    154. }
    Screenshot 2021-03-02 at 14.00.15.png
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    Check how an InputField works... it can be a little tricky because it has two separate notions of the "text" it contains:

    InputField.text
    -> the actual internal payload of the UI.InputField, the quantity being edited

    Text.text
    -> the related UI.Text object used to display the above payload (which might not even be the entire string amount, if it is scrolled left /right)

    I see a lot of your code above setting UI.Text strings. If those belong to the Text field under control of an InputField, this isn't generally useful, as InputField uses it purely for output, based on what is inside the UI.InputField.text field.

    Line 125 also checks for null... does the placeholder field gets set null or only set to empty string? I would check for both with
    string.IsNullOrEmpty()
     
    LazPhoto likes this.
  3. LazPhoto

    LazPhoto

    Joined:
    Sep 11, 2019
    Posts:
    11
    Thanks @Kurt-Dekker for your response. I've read up on InputFields more in Unity docs, but still am a bit confused, I guess. Maybe I can rephrase what I'm trying to do below.

    So my idea is that the placeholder value of the InputField, in this case RacksNeeded(), is calculated if there is no user input. This works correctly (see images below). The idea of making the placeholder value "null" (yes, trying to set it as null) is so that if there is user input into the field, the user input is calculated instead of the placeholder value. What's happening is that it is always calculating the placeholder value and ignoring (or not recognising, whatever) the user input. So I'm trying to make the placeholder "null" (or at least make it so it is not included in the calculation) and the user input (what's entered manually in the text field) be used in the calculation. Perhaps trying to make the placeholder value "null" is not the right idea, but I can't seem to find any other way to do what I'm trying to do.

    I have used other values entered into the InputFields (Length (Field1), Width(Field2), Cost(Field3)))) in the calculations, so they seem to work and override the placeholder text.

    I'm not glued to this approach, it's just what I was able to come up with, in case you have a better suggestion of how to do this.


    Edit 1 - Screenshot 2021-03-02 at 15.21.19.png


    Edit 2 - Screenshot 2021-03-02 at 15.21.57.png
     
  4. LazPhoto

    LazPhoto

    Joined:
    Sep 11, 2019
    Posts:
    11
    @Kurt-Dekker I think I've solved my issue. Your reply got me digging more into strings and null values and led me to the right documentation. In short, "null" was the wrong idea. Instead, I used:

    inputField.GetComponent<InputField>().placeholder.GetComponent<Text>().text == "";

    ...and that seems to have done the trick.

    The OnValueChange stuff turned out unnecessary, so I removed it. Below is the part of the code that I changed for it to work:

    Code (CSharp):
    1. public void RacksNeeded()
    2.     {
    3.         if (RacksSuggested.GetComponent<InputField>().placeholder.GetComponent<Text>().text == "")
    4.         {
    5.             int x = Convert.ToInt32(RacksSuggested.text);
    6.             RacksSuggested.text = x.ToString();
    7.         }
    8.         else
    9.         {
    10.             double a = Convert.ToInt32(Field1.text);
    11.             double b = Convert.ToInt32(Field2.text);
    12.             double c = a * b;
    13.             double d = c / rackRollDivider;
    14.             double e = Math.Ceiling(d);          
    15.             RacksSuggested.GetComponent<InputField>().placeholder.GetComponent<Text>().text = e.ToString();
    16.            
    17.         }
    18.            
    19.     }
    20.  
    21.     public void RacksTotal()
    22.     {
    23.         if(RacksSuggested.GetComponent<InputField>().placeholder.GetComponent<Text>().text == "")
    24.         {
    25.             decimal w = Convert.ToInt32(Field1.text);
    26.             decimal x = Convert.ToInt32(Field2.text);
    27.             decimal y = w * x;
    28.             decimal z = y / rackRollDivider;
    29.             decimal v = Math.Ceiling(z);
    30.  
    31.             decimal b = v;
    32.             decimal a = Convert.ToDecimal(CostPerRack.text);
    33.             Convert.ToDecimal(RacksSuggested.text);
    34.             decimal c = a * b;
    35.             racksTotal.text = c.ToString("C");
    36.         }
    37.         else
    38.         {
    39.             decimal a = Convert.ToDecimal(CostPerRack.text);
    40.             decimal b = Convert.ToDecimal(RacksSuggested.text);
    41.             decimal c = a * b;
    42.             racksTotal.text = c.ToString("C");
    43.         }
    44.            
    45.  
    46.     }
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    It's possible that property cannot be set to null. You can see if this is the case by looking up the property in the UI source code, which nowadays is just another package manager, and can also be seen on github.