How to get a game object to lerp as a triggered effect?

Trying to make an object move using lerp for movement and a bool for detecting when the player is close enough to trigger the effect. Preferably would like it to stay at the position once within the detection range but, a reverse lerp variant would also be welcome once leaving detection range. The anchor tagged object is another gameobject on the same initial position as the object i want to move. I have tagged the player and anchor.

public float smooth;

public float detectionRange = 2;
private bool closeEnough;
public float raiseAmount = 1;


void Update () {
	
	Vector3 raise = new Vector3(0,raiseAmount,0);
	Vector3 player =  GameObject.FindGameObjectWithTag("Player").transform.position;
	Vector3 anchor = GameObject.FindGameObjectWithTag("Anchor").transform.position;
	
	closeEnough = false;
		if( Vector3.Distance( player, transform.position) <= detectionRange ){
		 closeEnough = true;
		}
		else if(closeEnough == true){
			transform.position = Vector3.Lerp(transform.position, raise, smooth * Time.deltaTime);
		}
		if( Vector3.Distance( anchor, transform.position) >= detectionRange ){
			closeEnough = false;
		}

	}
}

Your main problem is, that Vector3.Lerp is lerping between two world coordinates, but your variable “raise” is a relative vector. This means you are not “lerping upwards the Y-axis” as you probably want to, but lerping towards the world position “0,y,0”.

You can fix this, e.g. by using transform.position = transform.position + raise * smooth * Time.deltaTime instead of the lerp (which is basically a “lerp with relative vector”). Edit: It is not. See in comments. Use

raise = transform.position + new Vector3(...)

`
instead.

Some other problems with your code:

You are testing a 3D distance for the “detectionRange” from this object to the player. But then you move this object when the player is near. So unless you guarantee that the new position of this object is actually nearer to the player, it will be immediately moved out of detection range, jittering and stuttering every frame a bit. Easiest to fix this is to zero out the Y-axis before comparing the distance (to only calculate 2d distance). If you really need a full 3D distance, use some kind of “Schmidt-Trigger” which means you have a “detectionRange” when you enter the trigger and another “undetectionRange” slightly bigger that you test against for leaving the range.

Next, DO NOT USE ANY GameObject.Find* METHOD IN UPDATE() !!! It WILL kill your performance soon. Move them to Awake(). If you really need to find the player and anchor every frame (in case they might actually change a lot during the game - which I doubt. ;), then better have the player and anchor register/deregister themself in some of their scripts during their OnEnable/OnDisable.

regardless of all the other solutions that everybody pointed out, i think there is a small error in the if statements

if i’m not mistaken, by using the “else if” statement your basically canceling the entrance to that if statement.
meaning, if the distance is smaller than the detectionRange than you switch closeEnough to true,
but than as long as the distance will remain smaller than the detectionRange than the code inside the second if statement will not be performed.

try changing this:

         if( Vector3.Distance( p1, transform.position) <= detectionRange )
     {
          closeEnough = true;
     }
         else if(closeEnough == true)
     {
             transform.position = transform.position + raise * smooth * Time.deltaTime;
     }

to this:

      if( Vector3.Distance( p1, transform.position) <= detectionRange )
     {
          closeEnough = true;
     }
      if(closeEnough == true)
     {
             transform.position = transform.position + raise * smooth * Time.deltaTime;
     }

With everyone’s help it has accumulated to this. Anchor is now an individual GameObject so each object with this script can have their own anchor.

using UnityEngine;
using System.Collections;

public class Detection : MonoBehaviour {

public float smooth;
public float detectionRange = 2;
private bool closeEnough;
public float raiseAmount = 1;
private Transform player;
private Transform anchor;
public GameObject anchorOBJ;



void Awake ()
{
	player = GameObject.FindGameObjectWithTag("Player").transform;
	anchor = anchorOBJ.transform;
}

void Update () 
{
	Vector3 raise = anchor.position + new Vector3(0,raiseAmount,0);
	Vector3 p1 = player.position;
	Vector3 a1 = anchor.position;
	p1.y = 0;
	a1.y = 0;

			
	closeEnough = Vector3.Distance(p1, a1) <= detectionRange;
		if (closeEnough)
 			transform.position = Vector3.Lerp(transform.position, raise, smooth * Time.deltaTime);
		else
 			transform.position = Vector3.Lerp(transform.position, anchor.position, smooth * Time.deltaTime);

}

}