How to preserve size of children when changing scale of parent

Hi all

Got a bit of a conundrum. I have some scaled objects which I would like to be able to shrink, revealing within them other objects.
Consider it a rock with gems inside I want to shrink the rock to show the gems.

After having a bit of a read through these pages it seemed the simplest thing to do in order to preserve the scale of the gems would be to un-parent the gems, change the scale of the rock, then re-parent the gems.
Something like this.

void NewRockSize(float Size)
{
    gem.transform.parent=null;

    rock.transform.localscale=new Vector3(Size,Size,Size);

    gem.transform.parent=rock.transform;    
}

In direct contradiction to the doc page Here the scale of the gem is not recalculated and, as it inherits the scale of its parent rock it appears the wrong size.

Answer me these questions three…
Am I doing something wrong ?
Are the Docs wrong ?
Is there a known way to do this right ?

Hi there! I figure out this solution :smiley:

Just set this script to your child :wink: It also works in Edit Mode so that you can set up the scale you need.

At the FixeScale set up the size of your child you need and at the parent set your parent model.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteInEditMode]
public class FixedScale : MonoBehaviour {

 public float FixeScale =1 ;
	public GameObject parent;
	
	// Update is called once per frame
	void Update () {
		transform.localScale = new Vector3 (FixeScale/parent.transform.localScale.x,FixeScale/parent.transform.localScale.y,FixeScale/parent.transform.localScale.z);

			}
		}

Have you solved this problem yet?
If not, try this.

float rockOriginalScale = rock.transform.localScale.x ; 

void Resize(float size)   
{ 
     float scale = rock.transform.localScale.x / size ; 
     float gemOrg = gem.transform.localScale.x ; 
     rock.transform.localScale = new Vector3(size, size, size) ; 
     gem.transform.localScale = new Vector3(gemOrg*scale, gemOrg*scale, gemOrg*scale) ;
}

This should work!

removing and re-adding children seems to work fine for me:

private void ChangeParentScale(Transform parent,Vector3 scale)
{
	List<Transform> children= new List<Transform>();
	foreach(Transform child in parent) {
	    child.parent = null;
	    children.Add(child);
	}
	parent.localScale = scale;
	foreach(Transform child in children) child.parent = parent;	
}

here’s my solution :stuck_out_tongue:

Create an object/variable of the scale you want… do not parent it… its a template… then during scaling operations check to see if your child object has exceeded one of the template’s vector3 lengths… if so… scale the child object back to template size ^^

  var child: GameObject;     //child of some other object in another script perhaps. 
    var atemplate :GameObject;
               
         Update(){  
    if(Child.lossyScale.x!=atemplate.lossyScale.x)
    child.transform.localScale=atemplate.transform.localScale;
   }

You could make an empty parent object, and then make your two object siblings instead of parent/child. In other words, you have a parent with two children, one that you want to scale, and one that you don’t. Now you can scale the one without affecting the other.

You can put your script on the parent, and the mesh, or whatever it is you’re scaling, on the child.