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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

How to scale child object independent of parent?

Discussion in 'Scripting' started by Velo222, Mar 16, 2013.

  1. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    Hello,

    I am having a hard time getting the child of an instantiated object to scale differently than its parent (i'm working on healthbars). I want my child object to stay at the same scale/length at all times, while the parent object is able to change length.

    I've tried attaching scripts to my parent object, and trying to manually change the localScale.x of the child object every update. That doesn't seem to work. I've also tried attaching a script onto the child object itself, and setting its localScale.x every update, but that didn't work either.

    It seems no matter what I do, the scale of the child always reflects the scale of the parent (even though if I look at the "x" scale of the child object, it always stays the same)......but that's what parenting is supposed to do I guess.

    So here are some of the variations of scripting I've tried. I've tried attaching this script to the parent object:

    Code (csharp):
    1. #pragma strict
    2.  
    3. private var thisTransform : Transform;
    4. private var healthBarChild : Transform;
    5. private var healthpercent : float;
    6.  
    7. function Awake () {
    8.  
    9. thisTransform = transform;
    10.  
    11. healthBarChild = thisTransform.Find("Healthbar4");
    12.  
    13. //healthBarChild.transform.lossyScale.x = 0.1987;
    14.  
    15. }
    16.  
    17. function Start () {
    18.  
    19. //thisTransform = transform;
    20.  
    21. //healthBarChild = thisTransform.Find("Healthbar4");
    22.  
    23.  
    24. }
    25.  
    26. function Update () {
    27.  
    28.  
    29. healthBarChild.transform.localScale.x = 0.1987;
    30.  
    31. }

    And I've tried a variation of this script that doesn't need to grab the child and just changes the child's transform directly.

    I should also mention, what I"m doing is on "Start", I instantiate a health bar prefab above several hundred unit's heads. So I'm working with quite a few game objects. And then via another script, I'm changing the parent healthbar's length relative to it's health percentage.


    All in all, I've tried quite a few methods to break the parent-child scale relationship, and it never seems to break it.
     
  2. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    if you scale a parent, it will scale the child, theres no avoiding that
    if possible, instead of having one a child of the other, have both as children of a third, never-scaled object.
    If the parent-child relationship is required, an alternative is scaling the child by (1/parentScale) (so if parent scale is 2, child scale is 0.5)
     
    angrypenguin and BeyondMASC like this.
  3. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    Hmm that's a good idea to have two childs on a never-scaled parent. I think I might try that.

    Thanks for the ideas hpjohn. I still really wish I could just break the parent-child relationship on at least one or two things, like scale or rotation. I've actually already gotten the effect I"m going for, but it requires maintaining the position of about 150 extra gameobjects every update.

    So I'm trying to optimize it. It's not really game-breaking, but it adds a lot of extra cpu load, causing my fps to drop down below the threshold I want it to be at. Making both gameobjects the child of a parent (non-scaled) object might work, so I'm gonna try that :)
     
  4. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    926
    another more simple way would be unparenting, scaling, reparenting.
     
  5. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    Perhaps. How would you un-parent via script though ValooFX?
     
  6. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    926
    Transform oldParent = transform.parent;
    transform.parent = null;
    transform.localScale = XXX;
    transform.parent = oldParent;
     
  7. KingOfColly

    KingOfColly

    Joined:
    May 25, 2013
    Posts:
    15
    This can be done with InverseTransformPoint. For example to 'world scale' a child gameobject 1x1x1: -

    transform.localScale = transform.parent.InverseTransformPoint(Vector3.one);
     
    Satyros likes this.
  8. tasd94

    tasd94

    Joined:
    Dec 31, 2013
    Posts:
    1
    :(
     
  9. CodeAssembler

    CodeAssembler

    Joined:
    Oct 15, 2011
    Posts:
    33
    Just to confirm to me this is the best solution. Like avoiding it if possible as suggested. Also remember that sometimes you might inadvertently attempt to resize the parent object so that its collider might fit a particular size / orientation forgetting that the collider is something you could just resize separately from the actual parent object if not a mesh collider :)
     
  10. shinoybabu

    shinoybabu

    Joined:
    Oct 27, 2016
    Posts:
    1
    Best way is multiply the current localScale with a value.
    Eg. If you want to double the size of the current size
    transform.localScale = new Vector3(transform.localScale.x / 2f, transform.localScale.y / 2f, transform.localScale.z / 2f);

    This will give a consistent look.
     
  11. edwin_s

    edwin_s

    Joined:
    Mar 10, 2015
    Posts:
    19
    Mildly off-topic, but you can scale Vectors with a scalar. What you wrote can be simplified to:

    Code (csharp):
    1. transform.localScale = transform.localscale / 2f;
    which is the same as:

    Code (csharp):
    1. transform.localScale /= 2f;
     
    Carterryan1990 likes this.
  12. walkeraki

    walkeraki

    Joined:
    Jan 31, 2014
    Posts:
    35
    this works :)
     
  13. joaot10112

    joaot10112

    Joined:
    Feb 18, 2020
    Posts:
    1
    Hey! I actually managed to avoid this just by dividing the parent scale by the child scale!

    Code (CSharp):
    1. transform.localScale.x = transform.parent.transform.localScale.x / [YOUR_DESIRED_SCALE];
    This will transform your desired scale into the equivalent based on the parent's scale!
     
    Siliko likes this.
  14. Siliko

    Siliko

    Joined:
    Sep 7, 2020
    Posts:
    8
    Hey, thanks for the idea but i think it's desired scale/ tranform parent
     
    avacio likes this.