Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Combine an int value with a float rate?

Discussion in 'Scripting' started by Thirdea, Sep 2, 2023.

  1. Thirdea

    Thirdea

    Joined:
    Nov 14, 2022
    Posts:
    2
    Hi everybody,

    i am sure the solution is easy but i am facing some issues with the following scenario:

    In my game the player collects coins which are ints. I am working on a function where the collected coins can be deposited whenever the player holds down a certain button. Which looks like this and works fine:

    public void DepositMoney()
    {
    if (Input.GetButtonDown("Melee"))
    {
    scoreValue--; // store the collected coins somewhere else

    }
    }

    Since i am calling this in the Update method the coins get deposited nearly instantly, but i want a float rate
    to handle the speed of the function. (So the player will be satisfied with a loooong lasting deposit of all the valuable coins.)

    The simple solution would be:

    public void DepositMoney()
    {
    if (Input.GetButtonDown("Melee"))
    {
    scoreValue -= transferRate * Time.deltaTime; // add a transfer rate to control the duration
    }
    }

    With all variables as floats, this works fine. But since my scoreValue is an int, its not working. I tried certain methods of rounding and converting but to my own surprise i struggle really hard with this issue which i thought chatGPT could solve within a second (it didnt.)

    There must be a pretty simple solution, right?

    Thanks in advance!
     
  2. ijmmai

    ijmmai

    Joined:
    Jun 9, 2023
    Posts:
    188
    chatGPT gives three different ways to do it. The first and simple one being this


    Code (CSharp):
    1. float floatValue = 42.75f;
    2. int intValue = (int)floatValue;
    3.  
     
  3. POOKSHANK

    POOKSHANK

    Joined:
    Feb 8, 2022
    Posts:
    73
    create a float called timer and each frame add to it with deltatime* said speed multiplier, and only allow it to deposit at
    <= 1 or something, and then reset the timer once it reaches your maximum. or you could just use a coroutine.
     
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    4,028
    Separate data from presentation!

    Data assignment is instant. This triggers an animation though which makes numbers run through from current value down to zero.

    This also prevents bugs where something would stop or break the depositing process and the player losing or gaining extra points. The animation can be safely aborted, the actual value has already been updated.
     
    CodeRonnie, Bunny83, Sluggy and 4 others like this.
  5. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    @CodeSmile has the appropriate solution here, unless the player is supposed to be able to stop half-way through depositing the coins. But as this is about a score conversion, i dont think you need to handle such a case.

    So when the player deposits his coins, directly set his actual coins to zero, and set some floating point value to the amount of coins he had, which you then display as decreasing until it reaches 0 (over how long or short a period you desire). This decreasing can happen on the float value itself, but for the representation you likely want to cast it as an integer, since it's still supposed to represent coins :)
     
    Bunny83 likes this.
  6. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Quite obviously this can't work, as you're losing information every time you tamper with the intermediate result.
    You need to do this
    Code (csharp):
    1. scoreValue -= transferRate * Time.deltaTime; // this is what you compute
    2. scoreValueInt = (int)Mathf.Floor(scoreValue); // this is what you display
     
    Bunny83 and Chubzdoomer like this.
  7. Thirdea

    Thirdea

    Joined:
    Nov 14, 2022
    Posts:
    2
    Thanks for your replies! That was pretty helpful. In my specific case, since i wanted the player to be able to interrupt the deposit when releasing the button, i now implemented a workaround: I instantiate the coin prefab f.e. 5 per second, allowing only as much prefabs as the score itself. The prefabs then get sucked into the deposit zone via physics where they get added to the final score. Maybe a little "fancy" but it works fine and gives the result i wanted without breaking anything else.

    Again, thank you very much!
     
    ijmmai likes this.