Skip to main content
Touching up correction formula
Source Link
DMGregory
  • 140.8k
  • 23
  • 257
  • 401

This can be done with a very small modification to the script in the question Philipp linked:

public class BlendFollower : MonoBehaviour 
{    
    public Transform leader;
    public float followSharpness = 0.1f;

    Vector3 _followOffset;

    void Start()
    {
        // Cache the initial offset at time of load/spawn:
        _followOffset = transform.position - leader.position;
    }
        
    void LateUpdate () 
    {
        // Apply that offset to get a target position.
        Vector3 targetPosition = leader.position + _followOffset;

        // Keep our y position unchanged.
        targetPosition.y = transform.position.y;

        // Smooth follow.    
        transform.position += (targetPosition - transform.position) * followSharpness;
    }
}

Note that the rate of follow here is framerate-dependent, and using Time.deltaTime the way you have in your question won't correct for that (that particular use pattern only works for linear rates of motion, which is not what we have here)

If you have a very uneven framerate and want to improve consistency, the most robust solution is to move this to FixedUpdate and interpolate, but for purely visual effects this correction formula will suffice:

const float REFERENCE_TIMESTEPREFERENCE_FRAMERATE = 1f/30f;

// Then, in LateUpdate()...
float timeRatio = Time.deltaTime /* REFERENCE_TIMESTEP;REFERENCE_FRAMERATE;
float adjustedSharpness = 1f - Mathf.Pow(1f - followSharpness, timeRatio);

transform.position += (targetPosition - transform.position) * adjustedSharpness;

This can be done with a very small modification to the script in the question Philipp linked:

public class BlendFollower : MonoBehaviour 
{    
    public Transform leader;
    public float followSharpness = 0.1f;

    Vector3 _followOffset;

    void Start()
    {
        // Cache the initial offset at time of load/spawn:
        _followOffset = transform.position - leader.position;
    }
        
    void LateUpdate () 
    {
        // Apply that offset to get a target position.
        Vector3 targetPosition = leader.position + _followOffset;

        // Keep our y position unchanged.
        targetPosition.y = transform.position.y;

        // Smooth follow.    
        transform.position += (targetPosition - transform.position) * followSharpness;
    }
}

Note that the rate of follow here is framerate-dependent, and using Time.deltaTime the way you have in your question won't correct for that (that particular use pattern only works for linear rates of motion, which is not what we have here)

If you have a very uneven framerate and want to improve consistency, the most robust solution is to move this to FixedUpdate and interpolate, but for purely visual effects this correction formula will suffice:

const float REFERENCE_TIMESTEP = 1f/30f;

// Then, in LateUpdate()...
float timeRatio = Time.deltaTime / REFERENCE_TIMESTEP;
float adjustedSharpness = Mathf.Pow(followSharpness, timeRatio);

transform.position += (targetPosition - transform.position) * adjustedSharpness;

This can be done with a very small modification to the script in the question Philipp linked:

public class BlendFollower : MonoBehaviour 
{    
    public Transform leader;
    public float followSharpness = 0.1f;

    Vector3 _followOffset;

    void Start()
    {
        // Cache the initial offset at time of load/spawn:
        _followOffset = transform.position - leader.position;
    }
        
    void LateUpdate () 
    {
        // Apply that offset to get a target position.
        Vector3 targetPosition = leader.position + _followOffset;

        // Keep our y position unchanged.
        targetPosition.y = transform.position.y;

        // Smooth follow.    
        transform.position += (targetPosition - transform.position) * followSharpness;
    }
}

Note that the rate of follow here is framerate-dependent, and using Time.deltaTime the way you have in your question won't correct for that (that particular use pattern only works for linear rates of motion, which is not what we have here)

If you have a very uneven framerate and want to improve consistency, the most robust solution is to move this to FixedUpdate and interpolate, but for purely visual effects this correction formula will suffice:

const float REFERENCE_FRAMERATE = 30f;

// Then, in LateUpdate()...
float timeRatio = Time.deltaTime * REFERENCE_FRAMERATE;
float adjustedSharpness = 1f - Mathf.Pow(1f - followSharpness, timeRatio);

transform.position += (targetPosition - transform.position) * adjustedSharpness;
Updating to use LateUpdate, since we want to reflect the most recent position of the leader, which might have changed during Update()
Source Link
DMGregory
  • 140.8k
  • 23
  • 257
  • 401

This can be done with a very small modification to the script in the question Philipp linked:

public class BlendFollower : MonoBehaviour 
{    
    public Transform leader;
    public float followSharpness = 0.1f;

    Vector3 _followOffset;

    void Start()
    {
        // Cache the initial offset at time of load/spawn:
        _followOffset = transform.position - leader.position;
    }
        
    void UpdateLateUpdate () 
    {
        // Apply that offset to get a target position.
        Vector3 targetPosition = leader.position + _followOffset;

        // Keep our y position unchanged.
        targetPosition.y = transform.position.y;

        // Smooth follow.    
        transform.position += (targetPosition - transform.position) * followSharpness;
    }
}

Note that the rate of follow here is framerate-dependent, and using Time.deltaTime the way you have in your question won't correct for that (that particular use pattern only works for linear rates of motion, which is not what we have here)

If you have a very uneven framerate and want to improve consistency, the most robust solution is to move this to FixedUpdate and interpolate, but for purely visual effects this correction formula will suffice:

const float REFERENCE_TIMESTEP = 1f/30f;

// Then, in UpdateLateUpdate()...
float timeRatio = Time.deltaTime / REFERENCE_TIMESTEP;
float adjustedSharpness = Mathf.Pow(followSharpness, timeRatio);

transform.position += (targetPosition - transform.position) * adjustedSharpness;

This can be done with a very small modification to the script in the question Philipp linked:

public class BlendFollower : MonoBehaviour 
{    
    public Transform leader;
    public float followSharpness = 0.1f;

    Vector3 _followOffset;

    void Start()
    {
        // Cache the initial offset at time of load/spawn:
        _followOffset = transform.position - leader.position;
    }
        
    void Update () 
    {
        // Apply that offset to get a target position.
        Vector3 targetPosition = leader.position + _followOffset;

        // Keep our y position unchanged.
        targetPosition.y = transform.position.y;

        // Smooth follow.    
        transform.position += (targetPosition - transform.position) * followSharpness;
    }
}

Note that the rate of follow here is framerate-dependent, and using Time.deltaTime the way you have in your question won't correct for that (that particular use pattern only works for linear rates of motion, which is not what we have here)

If you have a very uneven framerate and want to improve consistency, the most robust solution is to move this to FixedUpdate and interpolate, but for purely visual effects this correction formula will suffice:

const float REFERENCE_TIMESTEP = 1f/30f;

// Then, in Update()...
float timeRatio = Time.deltaTime / REFERENCE_TIMESTEP;
float adjustedSharpness = Mathf.Pow(followSharpness, timeRatio);

transform.position += (targetPosition - transform.position) * adjustedSharpness;

This can be done with a very small modification to the script in the question Philipp linked:

public class BlendFollower : MonoBehaviour 
{    
    public Transform leader;
    public float followSharpness = 0.1f;

    Vector3 _followOffset;

    void Start()
    {
        // Cache the initial offset at time of load/spawn:
        _followOffset = transform.position - leader.position;
    }
        
    void LateUpdate () 
    {
        // Apply that offset to get a target position.
        Vector3 targetPosition = leader.position + _followOffset;

        // Keep our y position unchanged.
        targetPosition.y = transform.position.y;

        // Smooth follow.    
        transform.position += (targetPosition - transform.position) * followSharpness;
    }
}

Note that the rate of follow here is framerate-dependent, and using Time.deltaTime the way you have in your question won't correct for that (that particular use pattern only works for linear rates of motion, which is not what we have here)

If you have a very uneven framerate and want to improve consistency, the most robust solution is to move this to FixedUpdate and interpolate, but for purely visual effects this correction formula will suffice:

const float REFERENCE_TIMESTEP = 1f/30f;

// Then, in LateUpdate()...
float timeRatio = Time.deltaTime / REFERENCE_TIMESTEP;
float adjustedSharpness = Mathf.Pow(followSharpness, timeRatio);

transform.position += (targetPosition - transform.position) * adjustedSharpness;
Source Link
DMGregory
  • 140.8k
  • 23
  • 257
  • 401

This can be done with a very small modification to the script in the question Philipp linked:

public class BlendFollower : MonoBehaviour 
{    
    public Transform leader;
    public float followSharpness = 0.1f;

    Vector3 _followOffset;

    void Start()
    {
        // Cache the initial offset at time of load/spawn:
        _followOffset = transform.position - leader.position;
    }
        
    void Update () 
    {
        // Apply that offset to get a target position.
        Vector3 targetPosition = leader.position + _followOffset;

        // Keep our y position unchanged.
        targetPosition.y = transform.position.y;

        // Smooth follow.    
        transform.position += (targetPosition - transform.position) * followSharpness;
    }
}

Note that the rate of follow here is framerate-dependent, and using Time.deltaTime the way you have in your question won't correct for that (that particular use pattern only works for linear rates of motion, which is not what we have here)

If you have a very uneven framerate and want to improve consistency, the most robust solution is to move this to FixedUpdate and interpolate, but for purely visual effects this correction formula will suffice:

const float REFERENCE_TIMESTEP = 1f/30f;

// Then, in Update()...
float timeRatio = Time.deltaTime / REFERENCE_TIMESTEP;
float adjustedSharpness = Mathf.Pow(followSharpness, timeRatio);

transform.position += (targetPosition - transform.position) * adjustedSharpness;