Search Unity

  1. Are you interested in providing feedback directly to Unity teams? Sign up to become a member of Unity Pulse, our new product feedback and research community.
    Dismiss Notice

Help Wanted Why the scaling never ending at 0.001f ?

Discussion in 'Scripting' started by shamenraze1988, Jul 5, 2021.

  1. shamenraze1988

    shamenraze1988

    Joined:
    Nov 24, 2020
    Posts:
    208
    The goal is to move the transform to destinationTransform and then make transform child of destinationTransform and this part is working fine. I want to add a scaling so while the transform is at state TransitionState.MovingTowards and then at state TransitionState.Transferring that the transform will scale down all the way while the transform is moving until the transform is a child. When the transform is a child the transform scaling size should be 0.001f on X Y Z.

    now what it does is scaling down but in the end, I see that transform scaling on X Y Z value is -0.0001960797 and not 0.001f

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class NaviManager : MonoBehaviour
    7. {
    8.     public enum TransitionState
    9.     {
    10.         None,
    11.         MovingTowards,
    12.         Transferring
    13.     }
    14.  
    15.     public Transform player;
    16.     public Transform carte;
    17.     public Animation anim;
    18.     public Transform destinationTransform;
    19.     public float speed;
    20.     public float distanceToStop;
    21.     public float lerpTime;
    22.     public UnlockCrate unlockCarte;
    23.  
    24.     private GameObject rig_f_middle;
    25.     private Transform originTransform;
    26.     private float timer;
    27.     private bool openonce = false;
    28.     private TransitionState state = TransitionState.MovingTowards;
    29.     private Vector3 temp;
    30.  
    31.     void Start()
    32.     {
    33.         rig_f_middle = GameObject.Find("rig_f_middle.02.R");
    34.     }
    35.  
    36.     void Update()
    37.     {
    38.         var dist = Vector3.Distance(carte.position, player.position);
    39.  
    40.         if (dist < 1.5f)
    41.         {
    42.             if (openonce == false)
    43.             {
    44.                 anim.Play("Crate_Open");
    45.                 openonce = true;
    46.             }
    47.  
    48.             if (transform.localScale.x >= 0.001f)
    49.             {
    50.                 temp = transform.localScale;
    51.                 temp.x -= Time.deltaTime * speed;
    52.                 temp.y -= Time.deltaTime * speed;
    53.                 temp.z -= Time.deltaTime * speed;
    54.  
    55.                 transform.localScale = temp;
    56.             }
    57.  
    58.             switch (state)
    59.             {
    60.                 case TransitionState.MovingTowards:
    61.                     var v = rig_f_middle.transform.position - transform.position;
    62.                     if (v.magnitude < 0.001f)
    63.                     {
    64.                         state = TransitionState.Transferring;
    65.                         originTransform = rig_f_middle.transform;
    66.                         timer = 0;
    67.                         return;
    68.                     }
    69.                     Vector3 moveDir = v.normalized;
    70.                     transform.position += moveDir * speed * Time.deltaTime;
    71.                     break;
    72.  
    73.                 case TransitionState.Transferring:
    74.                     timer += Time.deltaTime;
    75.                     this.transform.position = Vector3.Lerp(originTransform.position, destinationTransform.position, timer);
    76.                     if (timer >= 1.0f)
    77.                     {
    78.                         this.transform.parent = destinationTransform;
    79.                         state = TransitionState.None;
    80.                         this.enabled = false;
    81.                         return;
    82.                     }
    83.                     break;
    84.  
    85.                 default:
    86.                     this.enabled = false;
    87.                     return;
    88.             }
    89.         }
    90.     }
    91. }
    92.  
     
  2. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Well, you can't expect this to be accurate ever. You will overshoot the value. Use Lerp instead, this is its job.
     
    shamenraze1988 likes this.
  3. shamenraze1988

    shamenraze1988

    Joined:
    Nov 24, 2020
    Posts:
    208
    How do I use the Lerp ? It does nothing it's not scaling it down at all.

    I added to the top of script :

    Code (csharp):
    1.  
    2. int counter = 0;
    3. int time = 1;
    4. Vector3 initS;
    5.  
    In Start()

    Code (csharp):
    1.  
    2. initS = transform.localScale;
    3.  
    In Update()

    Code (csharp):
    1.  
    2. float inter = (float)counter / time;
    3.             transform.localScale = Vector3.Lerp(initS,
    4.                 new Vector3(0.001f, 0.001f, 0.001f), inter);
    5.  
     
  4. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    It's always helpful to read the docs when not knowing what a specific function does.
    The last component needs to be "animated", Basically it needs to go from 0 to 1,so just start summing up deltaTime into a variable and use that
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    18,331
    Bust out your Debug.Log() and you'll immediately notice bad numbers.

    Here's one example: assuming
    speed == 1.0f
    and
    Time.deltaTime
    is about
    1.0f / 60.0f
    (which is 0.01667f), as you enter this code with a theoretical scale of 0.002f, you will end up at:

    0.002f - 0.01667f  --> -0.01467


    Nothing is going to stop it from going negative... right below zero.

    Instead of constantly molesting the transformScale property (which has who knows what bizarre side effects in the Transform), as @gorbit99 above suggests, use Lerp() controlled externally.

    In other words, decide "I want this to go from scale 1 to scale 0.001 in DesiredInterval seconds" and make it happen.

    EDIT: hacked my original answer up based on @gorbit99's sharp eyes. Thanks Gorb!

    Coroutine solution:

    Code (csharp):
    1. float fraction = 0;
    2. for (float time = 0; fraction < 1; time += Time.deltaTime)
    3. {
    4.   fraction = time / DesiredInterval;
    5.   float newScale = Mathf.Lerp( 1.0f, 0.001f, fraction);
    6.   transform.localScale = Vector3.one * newScale;
    7.   yield return null;
    8. }
    OR if you are not doing coroutines:

    When you start:

    Code (csharp):
    1. float fraction = 0;
    2. float time = 0;
    Every frame:

    Code (csharp):
    1. if (fraction < 1)
    2. {
    3.   time += Time.deltaTime;
    4.   fraction = time / DesiredInterval;
    5.   float newScale = Mathf.Lerp( 1.0f, 0.001f, fraction);
    6.   transform.localScale = Vector3.one * newScale;
    7. }
    8. else
    9. {
    10.   Debug.Log( "Finished, we have reached 0.001f");
    11. }
    12.  
     
    Last edited: Jul 5, 2021
  6. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Keep in mind, that while he's using a for loop here, that will run in one frame, you want to do the inner logic one frame at a time in update
     
    Kurt-Dekker likes this.
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    18,331
    You're totally correct. My bad. I half-assedly created a coroutine. I am going to go edit the code above. Thanks!
     
unityunity