简体   繁体   中英

Unity Mathf.Lerp only executes ones

void Fire(float firingRate)
{
    TimePerFrame += Time.deltaTime;
    if(TimePerFrame >= firingRate)
    {
        Vector3 ProjectileDistance = new Vector3(0, 30, 0); //distance between center of the campion and it's head
        GameObject beam = Instantiate(projectile, transform.position + ProjectileDistance, Quaternion.identity) as GameObject;
        beam.GetComponent<Rigidbody2D>().velocity = new Vector3(0, projectileSpeed, 0);
        //  AudioSource.PlayClipAtPoint(fireSound, transform.position);
        TimePerFrame = 0;
    }
}

void Update ()
{
    if (freezePosition == false)
    {
        Fire(firingRate);
        PositionChaning();
        firingRate = Mathf.Lerp(minFiringRate, maxFiringRate, 0.1f);
        Debug.Log(firingRate);
    }
}

I want my firerate to be flexible, i want it to start by shooting fast and let it automatically lower it's fire rate. (the bigger the firingRate float is the slower the speed is)

The problem is that firingRate = Mathf.Lerp(minFiringRate, maxFiringRate, 0.1f); triggers once and only once. It doesn't seem to change it's value every frame.

Debug.Log(firingRate); tells the value every frame but it seems to remain a constant.

Why does this happen?

The update triggers every Frame, and so does your Mathf.Lerp However you are not changing the interpolation, which in your case is defined as 0.1f .

By changing this interpolation, you will be able to achieve the 'shifting' of fire rate.

In your case you could define a variable t outside the scope of your update, and update it inside the Update() through t += 0.5f * Time.deltaTime;

The Mathf.Lerp documentation has a pretty good sample of how todo so as well

void Update()
{
    // animate the position of the game object...
    transform.position = new Vector3(Mathf.Lerp(minimum, maximum, t), 0, 0);

    // .. and increate the t interpolater
    t += 0.5f * Time.deltaTime;

    // now check if the interpolator has reached 1.0
    // and swap maximum and minimum so game object moves
    // in the opposite direction.
    if (t > 1.0f)
    {
        float temp = maximum;
        maximum = minimum;
        minimum = temp;
        t = 0.0f;
    }
}

Your problem is here:

firingRate = Mathf.Lerp(minFiringRate, maxFiringRate, 0.1f);

As you can see here your t has to be calculated every frame.

public static float Lerp(float a, float b, float t);

You can change it like this:

private float fireTimer = 1.0f;
public float fireLimiter = 0.05f;

void Fire(float firingRate)
{
    TimePerFrame += Time.deltaTime;
    if(TimePerFrame >= firingRate)
    {
        Vector3 ProjectileDistance = new Vector3(0, 30, 0); //distance between center of the campion and it's head
        GameObject beam = Instantiate(projectile, transform.position + ProjectileDistance, Quaternion.identity) as GameObject;
        beam.GetComponent<Rigidbody2D>().velocity = new Vector3(0, projectileSpeed, 0);
        //  AudioSource.PlayClipAtPoint(fireSound, transform.position);
        TimePerFrame = 0;
    }
}

void Update ()
{
    if (freezePosition == false)
    {
        if(fireTimer > 0.0f){
            fireTimer -= Time.deltaTime * fireLimiter;
        }
        Fire(firingRate);
        PositionChaning();
        firingRate = Mathf.Lerp(minFiringRate, maxFiringRate, fireTimer);
        Debug.Log(firingRate);
    }
}

Do not forget to reset fireTimer to 1.0f after shooting! The delay of the firerate can be controlled by fireLimiter

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM