Home > OS >  How can I detect the amount a value has changed?
How can I detect the amount a value has changed?

Time:09-24

I am making a 2D game in unity using C#, I want the "time" to increase based on the amount of change occurring in the x and y values of the gameobject, for example if the gameobject starts at 1 position y and falls until 0.2 position y the score would add 0.8, except I want it to be an integer so something more like 10.

I tried to do some code but it doesn't really work as it just adds the position of x and y until unity crashes, can someone please help me with this? Thanks!

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

public class ScoreEasy : MonoBehaviour
{
    public float time = 1;
    public float posX;
    public float posY;
    public Text score;
    public Rigidbody2D rb;

    public void Start()
    {

    }
    public void Update()
    {
        posX = gameObject.transform.position.x;
        posY = gameObject.transform.position.y;

        time = posX   posY;

        score.text = time.ToString("0");
    }
}

CodePudding user response:

You are going to want to cache the position of the object from the last frame to determine the change of position. As well, it seems you want the overall displacement from the last frame, not the distance as distance is both a direction and scalar. Meaning it can be negative, which would decrease your score.

The reason Unity crashes with your program is most likely an overflow. You are continually adding the position of your object together and adding that to a variable every frame.

You can do something like:

public class ScoreEasy : MonoBehaviour
{
    public float time = 1;
    public Text score;
    public Rigidbody2D rb;

    private float lastXPos;
    private float lastYPos;
    
    private void Start()
    {
        lastXPos = transform.position.x;
        lastYPos = transform.position.y;
    }

    public void Update()
    {
        // increase our time by a factor of the movement we had since last frame
        time  = 10f * (Mathf.Abs(lastXPos - transform.position.x)   Mathf.Abs(lastYPos - transform.position.y));
        
        // store our current frame as our last for the next frame
        lastXPos = transform.position.x;
        lastYPos = transform.position.y;
        
        // visually update the value
        score.text = time.ToString("0");
    }
}

Instead of adding the positions together, I am adding the absolute difference of the position from the last frame. As you also mentioned wanting the score to be larger, you can just multiply the value by 10 or some other scalar.

Edit: Here is a gif of the above example. The score can get rather high, so you can reduce the scalar of 10 to any factor you desire.

Example

Edit 2: To have the speed of the object factor into the score added, you can simply have the distance moved be scaled by the magnitude of the velocity of the object. If this value appears to be too great, you can divide the magnitude or clamp it so it is not so severe.

time  = rb.velocity.magnitude * (Mathf.Abs(lastXPos - transform.position.x)   Mathf.Abs(lastYPos - transform.position.y));

Edit 3: Here is the updated code working:

Updated code

  • Related