Search Unity

transform.position = Vector3.Lerp NOT working properly

Discussion in 'Scripting' started by radim1, Aug 4, 2015.

  1. radim1

    radim1

    Joined:
    Mar 3, 2015
    Posts:
    7
    I have a floating island made of 3D cubes (Minecraft style) and at the start of the level I let all cubes "fly" into their position to assemble into the floating island. The island is prefab which consists of many of those cubes and each cube has attached a simple script. All works fine for cubes but does not work for the trees and other objects which are made of many Poly surfaces. In fact if I have only one object made of poly surfaces the script works. As soon as I add the second object the script stops working. No error is shown. Simply nothing happens. How do I Lerp GameObject properly?

    Code (CSharp):
    1. private Transform objectTransform;
    2. private float moveDistance = 10f;
    3. private Vector3 startPos;
    4. private Vector3 endPos;
    5.  
    6. void Awake ()
    7.     {
    8.         objectTransform = gameObject.transform as Transform;
    9.         endPos = objectTransform.position;
    10.         startPos = endPos - Vector3.down * moveDistance * endPos.y;
    11.     }
    12.  
    13. void Update ()
    14.     {
    15.         //increment timer once per frame
    16.         currentLerpTime += Time.deltaTime;
    17.         if (currentLerpTime > lerpTime) {
    18.             currentLerpTime = lerpTime;
    19.         }
    20.          
    21.         //lerp!
    22.         float perc = currentLerpTime / lerpTime;
    23.         objectTransform.position = Vector3.Lerp (startPos, endPos, perc);
    24.  
    25.     }
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    I'm going to point out that Vector3.Lerp does EXACTLY what it's supposed to.

    If Vector3.Lerp didn't do exactly what it's supposed to, nearly ever unity developer in the world would be speaking up about it. The algorithm behind Vector3.Lerp is a very simple and classic formula:

    result = (end - start) * t + start

    it works in any dimension


    What you mean to say is that you have code that uses Vector3.Lerp, and the results you are getting aren't what you expect.

    Now... what's going on? Well, I'd start by saying your code is very... messy. For example, this script is going to be constantly moving your things towards their positions forever. Just once they reach there they'll be updating their position as HERE every frame. Why not stop updating once the target is reached? You can do this with a coroutine:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class MoverScript : MonoBehaviour
    6. {
    7.  
    8.     public float moveDistance = 10f;
    9.     public float lerpTime = 1f;
    10.  
    11.     private void Start()
    12.     {
    13.         this.StartCoroutine(this.UpdateRoutine());
    14.     }
    15.      
    16.     private IEnumerator UpdateRoutine()
    17.     {
    18.         var trans = this.transform;
    19.         var endPos = trans.position;
    20.         var startPos = endPos - Vector3.down * moveDistance * endPos.y;
    21.      
    22.         float t = 0f;
    23.         while(t < lerpTime)
    24.         {
    25.             t += Time.deltaTime;
    26.             trans.position = Vector3.Lerp(startPos, endPos, t / lerpTime);
    27.             yield return null;
    28.         }
    29.         trans.position = endPos;
    30.     }
    31.  
    32. }
    33.  
    Now there is a weird part I see in this code:

    endPos - Vector3.down * moveDistance * endPos.y;

    moveDistance in this is 10f, but you're multiplying that by endPos.y. endPos.y is the current height of the object. So you want to move it a distance that is 10 times its height? Weird standard of movement, but ok, if that's the effect you want, that's the effect you want.

    Other than that, this should do exactly what you describe.

    If it's not, you may not be setting it up correctly, maybe attaching it to the wrong gameobjects? I don't know how you have your 'multi Poly' objects set up, so I couldn't tell... but this code has nothing to do with it.
     
    Last edited: Aug 4, 2015
  3. radim1

    radim1

    Joined:
    Mar 3, 2015
    Posts:
    7
    Thank you for taking the time and looking at the script. However your script has exactly same problem as my script. It works only for one object made of poly meshes. As soon as there is a second object it does not work anymore.

    But I noticed that values are changing in the Editor but mesh is not moving. This is the case for both scripts. It must really be the way poly mesh objects are set up.

    I purchased the objects on Unity Asset store so I can't really say why only these objects don't work. I'll try to contact the seller.
     
  4. radim1

    radim1

    Joined:
    Mar 3, 2015
    Posts:
    7
    Ok, I figured it out. The problem is that objects are "Static". I purchased them on the asset store and didn't notice that seller made them static. I unchecked static and now everything is lerping properly.
     
    cantstopthechase likes this.
  5. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    I was just about to come and say that it's probably a static mesh.

    When you said that the 'mesh' is not moving, but the values are changing.

    By doing that, unity can more efficiently render meshes that are static, it just precalculates all the information and only updates it if something on the rendering side changes. Ignoring motion of the GameObject itself (which is not predictable from the renderer).



    Note, my version of the script is still a better choice, as it avoids calling update the lifetime of the gameobject. And instead only updates for the duration of the animation.