Mathf.SmoothDamp not changing speed (reference variable not changing)

Hi,

I want my moveForwards speed to change from 0f to -2f over 3 seconds if one condition is true, and from 0f to -2f if another condition is true.

So instead of the commented out lines where the speed is set instantly: I would like them to be gradually set to this final speed over 3 seconds.

But I can’t get this to work correctly: the speed is just set once to -0.2f (and the reference variable to -27) and doesn’t increase. Does anyone know what I’ve done wrong?

        public float moveForwards = 0f;
    	public float speed2 = 0f;
    	public float speed1 = 0f;
    	
    	void Update () {
    	
    		
    		if (lastspeed < 40f && speedGPS.speedInKmPerHour >= 40f)
    		{

    			moveForwards = Mathf.SmoothDamp (moveForwards, -2f, ref speed2, 3f * Time.deltaTime);
            //moveForwards = -2f;

    		}
    		
    		if (lastspeed >= 40f && speedGPS.speedInKmPerHour < 40f)
    		{

    			moveForwards = Mathf.SmoothDamp (moveForwards, 0f, ref speed1, 3f * Time.deltaTime);
               //moveForwards = 0f;
    
    		}

All the best,
Laurien

Edit: This is the working script.

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

public class TerrainMover : MonoBehaviour {
	
	public float moveForwards = 0f;
	public GameObject terrain1;
	public Vector3 targetPos = new Vector3 (0,0 -384);
	public GameObject terrain2;
	public Speedometer speedGPS;
	public PerspectiveSwitcher persp;
	public TouchDetect touch;

	public GameObject [] terrainMultiples;
	private List<GameObject> terrainDeck;
	
	
	public Vector3 startPos = new Vector3 (0,0,0);
	public Vector3 endPos;
	
	static public float speed = 15f;
	
	float lastspeed = 0f;
	
	public float speed2 = 0f;
	public float targetSpeed = 0.0f;

	void Start()
	{

		terrainDeck = new List<GameObject>(terrainMultiples);
		foreach (var t in terrainMultiples)
		{
			t.SetActive (false);
		}

		terrain1 = ChooseTerrain();
		terrain1.transform.position = new Vector3 (-4.5f, -16f, 267.5f);
		terrainDeck.Remove(terrain1);

		terrain2 = ChooseTerrain();
		terrain2.transform.position = new Vector3(-4.5f, -16f, 817.5f);
		terrainDeck.Remove(terrain2);

		terrain1.SetActive(true);
		terrain2.SetActive(true);
	}
	
	void Update () {
		
		
		if (lastspeed < 40f && speedGPS.speedInKmPerHour >= 40f)
		{
			persp.orthoToggle(false);
			
			targetSpeed = -3.5f;
			speed2=0;
		}
		
		if (lastspeed >= 40f && speedGPS.speedInKmPerHour < 40f)
		{
			persp.orthoToggle(true);
		
			targetSpeed = 0;
			speed2=0;	
		}
		
		if (Mathf.Abs(moveForwards - targetSpeed) > 0.01f )	
			moveForwards = Mathf.SmoothDamp (moveForwards, targetSpeed, ref speed2, 3f);
		else
			moveForwards = targetSpeed;
		
		terrain1.transform.Translate(Vector3.forward * Time.deltaTime * moveForwards * speed);
		terrain2.transform.Translate(Vector3.forward * Time.deltaTime * moveForwards * speed);
		
		lastspeed = speedGPS.speedInKmPerHour;
		
		if (Input.GetKeyDown("w"))
			speedGPS.speedInKmPerHour = 60f;
		
		if (Input.GetKeyUp("e"))
			speedGPS.speedInKmPerHour = 0f;
		
		
		
		if (touch.moveToCentre == true)
		{
			terrain1.transform.Translate(Vector3.forward * Time.deltaTime *  - touch.bagCurrentPosFloat * 0.4f);
			terrain2.transform.Translate(Vector3.forward * Time.deltaTime * - touch.bagCurrentPosFloat * 0.4f);
		}
		
	}
	
	void LateUpdate()
	{
		if (targetPos.z - terrain1.transform.position.z > - 10f)
		{
			terrain1.SetActive(false);
			terrainDeck.Add(terrain1);
			terrain1 = ChooseTerrain();
			terrainDeck.Remove(terrain1);
			terrain1.transform.position = terrain2.transform.position + new Vector3(0.0f, 0.0f, +550); 
			terrain1.SetActive(true);

		}
		
		else if (targetPos.z - terrain2.transform.position.z > - 10f)
		{
			terrain2.SetActive(false);
			terrainDeck.Add(terrain2);
			terrain2 = ChooseTerrain();
			terrainDeck.Remove(terrain2);
			terrain2.transform.position = terrain1.transform.position + new Vector3(0.0f, 0.0f, +550);
			terrain2.SetActive(true);
		}
	}


	GameObject ChooseTerrain()
	{
		int index = Random.Range (0, terrainDeck.Count -1);
		return terrainDeck [index];
	}
	
}

I haven’t read through all your code and haven’t even tried to understand what it’s supposed to do. However those two lines are causing problems:

if (lastspeed < 40f && speedGPS.speedInKmPerHour >= 40f)

and

lastspeed = speedGPS.speedInKmPerHour;

This will make your if statement only true for one frame whenever your speed crosses the 40f mark. SmoothDamp has to be called every frame in order work properly. That method does not “start” some magic code that runs in the background. It just calculates a new value each time you call the method. The “ref” speed variable is used to track the current state of the damping.

Using SmoothDamp

Looking at the pertinent aspects of the SmoothDamp signature:

SmoothDamp(float current, float target, ref float currentVelocity, float smoothTime);

You are multiplying your desired smooth time (i.e. 3f) by Time.deltaTime—meaning your smooth time is actually a fraction of your desired smooth time.

If you were to remove your reference to Time.deltaTime in the 4th parameter, e.g:
moveForwards = Mathf.SmoothDamp (moveForwards, -2f, ref speed2, 3f);

I believe you’ll be much closer to the effect you’re after.