Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Bug GameObject moves when scaling from script.

Discussion in 'Scripting' started by winterdark92, Sep 2, 2023.

  1. winterdark92

    winterdark92

    Joined:
    Aug 30, 2022
    Posts:
    4
    I'm using the following code to scale a GameObject in the x-direction over a certain period of time. When I press the key to scale down (to half its current scale) it works as expected, but when I scale the object up (from its current scale) the object also moves a certain distance to the right. The object has a Rigidbody2D, a Sprite Renderer, and a BoxCollider2D. There's something I'm missing and can't seem to find it.

    Note that this is not the full code but the portion of it that I'm using to scale (that' s why there is no use of
    m_rb
    ).

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. public class Player : MonoBehaviour {
    5.  
    6.     Rigidbody2D m_rb;
    7.     float m_shrinkScale = 0.5f;
    8.     float m_shrinkSeconds = 1.0f;
    9.  
    10.     void Start()
    11.     {
    12.         m_rb = gameObject.GetComponent<Rigidbody2D>();
    13.     }
    14.  
    15.     void Update()
    16.     {
    17.         if (Input.GetKeyDown(KeyCode.U))
    18.         {
    19.             StartCoroutine(ScaleAnimation(m_shrinkSeconds, m_shrinkScale));
    20.         }
    21.  
    22.         if (Input.GetKeyDown(KeyCode.D))
    23.         {
    24.             StartCoroutine(ScaleAnimation(m_shrinkSeconds, 1f / m_shrinkScale));
    25.         }
    26.     }
    27.  
    28.     IEnumerator ScaleAnimation(float time, float toScaleFactor)
    29.     {
    30.         float i = 0;
    31.         float rate = 1 / time;
    32.  
    33.         Vector3 fromScale = transform.localScale;
    34.         Vector3 toScale = new Vector3(transform.localScale.x * toScaleFactor, transform.localScale.y, transform.localScale.z);
    35.  
    36.         while (i < 1)
    37.         {
    38.             i += Time.deltaTime * rate;
    39.             transform.localScale = Vector3.Lerp(fromScale, toScale, i);
    40.             yield return 0;
    41.         }
    42.     }
    43. }
     
    Last edited: Sep 3, 2023
  2. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    I don't see any use for this, does this get called separately somewhere else?

    But if you scale along the x-axis both left and right sides should push out, so not sure if you're trying to contain it so it only pushes out on one side?
     
  3. winterdark92

    winterdark92

    Joined:
    Aug 30, 2022
    Posts:
    4
    As it stands, it doesn't have any use. It's just part of something I'm trying to implement.

    Also, the GameObject has no parent and is not contained on either side.
     
  4. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    Then nothing should be moving it's transform, as the root position will never move with scaling, unless coded to do otherwise.
     
  5. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    It shouldnt move when you scale it, unless its visual center is not at the center of the object.

    Is there an actual difference in its position, or does it move visually only?

    Also, likely unrelated to your current issue, but keep in mind that coroutines usually cause more issues than they solve. For example, you could press U or D several times while one of the coroutines still runs. This will cause multiple coroutines to run at the same time, since you dont save and stop previously started ones. Since you base your scaling on the current scale aswell, you will run into unintended results when you start a new coroutine midway through a running one, as the scale is neither min nor max at that point.

    What's your actual context / usecase here? I would probably suggest saving the min and max scale as a constant / variable, and handling the scaling through a statemachine of some sort.
     
  6. winterdark92

    winterdark92

    Joined:
    Aug 30, 2022
    Posts:
    4
    Yes, there is an actual difference in the position of the object, it is not only a visual issue.

    Thanks for your comment on the use of coroutines. I removed lines in the code I posted to give just a MWE and declutter it to show the problematic part only. In my project, the coroutines will not be called on button presses but as a response to a collision event.

    The context is as follows. I have a platform that can be moved by the player only in the x-direction (I'm working on 2D). Now, if the platform collides with a given object, then it shrinks to half its size (that's where the scaling enters the picture), and after some time, it goes back to the original size (not implemented yet). To avoid coroutines launching simultaneously, I'm planning on adding a variable that indicates if the object has already reached its target and prevent any other coroutine from launching if it has not.
     
  7. winterdark92

    winterdark92

    Joined:
    Aug 30, 2022
    Posts:
    4
    What puzzles me is that the object only moves to the right when scaling up and not down. It works perfectly when it shrinks, but the method is the same for both cases...