[HELP][SCALE] localScale doesn't follow the object's pivot
Hi all, I wish to make a scrollbar that can scale the object I chose in respect to the handle's position. The job is done, but I have one problem: no matter if I have the object in mention's pivot in the center, it gets scales from the corner. (it's a game object containing multiple game objects but that shouldn't be a problem). I'm using transform.localScale by the way. All the help appreciated. The editor's scale tool does the job right, however I don't know how to access that from script to change its value.
Answer by TBruce · Aug 05, 2016 at 06:59 PM
@agiro You did not give any code or much to go on (Is this 2D/3D, are you scaling an UI.Image, SpriteRenderer or other type of object - e.g. 3D Cube).
But the following script will handle it all (note it uses a UI slider object in place of the scroll bar)
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class ScaleObject : MonoBehaviour
{
public Slider slider;
public GameObject objectToScale;
public float maxScale = 5; // max scalue value of objectToScale
public float defaultScale = 1; // scale value for objectToScale to start at
void Start()
{
if (objectToScale == null)
{
Debug.LogError("objectToScale has not been set in the inspector. Please set the objectToScale and try again.");
}
else
{
if (slider == null)
{
Debug.LogError("Slider has not been set in the inspector. Please set the Slider and try again.");
}
else
{
slider.onValueChanged.AddListener(ScaleImageListener);
slider.value = defaultScale / maxScale; // set the scale of objectToScale to its default scale
}
}
}
void ScaleImageListener(float value)
{
float scaleValue = maxScale * value;
objectToScale.transform.localScale = new Vector3(scaleValue, scaleValue, 1);
}
}
Thanks for the reply @$$anonymous$$avina. If I get it right, you use the localScale field, right? I could get the scrollbar working, it does scale the object. The issue is only that it uses a child of it as pivot.
public void OnScrollerValueChanged()
{
//now we have to either scale up or down the cards
//in respect to the scroller position.
GameLogic.cardCollection.transform.localScale = new Vector3(cardCollectionInitialSize.x + cardsSizeScroller.value / 4.0f,
cardCollectionInitialSize.y + cardsSizeScroller.value / 4.0f,
cardCollectionInitialSize.z);
}
The game objects is just an object, but has some cards under it, those cards have 3d box colliders and sprites. By the way when I scale using the editor it does it fine - as I said - but it also changes the transform values of my object. When using the scrollbar to scale, the transform stays the same, thus the shift.
Another thing @$$anonymous$$avina I noticed that the reason why the editor's scale works fine and the local via script isn't is that using the editor the attack point is set to center. however, the gameobject's pivot is at the pivot of its first child and that is what localScale uses to scale the object. Is there a way to change that to center in the script? Parenting it under another gameobject didn't work, by the way as I said this containter gameobject I have been talking about is the child of the world.
@agiro It is difficult to answer your question properly without knowing what type of objects you want scaled (e.g. Normal GameObjects - 2D/3D or UI objects - UI Image/UI Panel).
Having said that and without knowing anything else the following code will work for UI objects by setting the width and height ins$$anonymous$$d of scaling the object, this scales the object only and not the children (This could also be done for a SpriteRenderer or even a $$anonymous$$esh - e.g. Quad but this will require more work).
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class ScaleObject : $$anonymous$$onoBehaviour
{
public Slider slider;
public GameObject objectToScale;
public float maxScale = 5; // max scalue value of objectToScale
public float defaultScale = 1; // scale value for objectToScale to start at
public Canvas canvas;
private RectTransform rectTransform = null;
private float rectTransformX;
private float rectTransformY;
void Start()
{
if (objectToScale == null)
{
Debug.LogError("objectToScale has not been set in the inspector. Please set the objectToScale and try again.");
}
else
{
if (slider == null)
{
Debug.LogError("Slider has not been set in the inspector. Please set the Slider and try again.");
}
else if (canvas == null)
{
Debug.LogError("canvas has not been set in the inspector. Please set the canvas and try again.");
}
else
{
rectTransform = objectToScale.GetComponent<RectTransform>();
if (rectTransform != null)
{
rectTransformX = rectTransform.sizeDelta.x;
rectTransformY = rectTransform.sizeDelta.y;
slider.onValueChanged.AddListener(ScaleImageListener);
slider.value = defaultScale / maxScale;
}
}
}
}
void ScaleImageListener(float value)
{
float xScaleValue = rectTransformX * maxScale * value;
float yScaleValue = rectTransformY * maxScale * value;
rectTransform.sizeDelta = new Vector2(xScaleValue, yScaleValue);
}
}
Edit: When setting up you UI object (e.g. Image), leave the RectTransform scale at 1,1,1.
@agiro Did this answer help you? If so, would you be so kind as to click the "Accept" button above to accept the answer. Thank you!
In my case it did not, but generally speaking it is true so others will find it helpful for sure. As for me, when someone parents objects under another via script it should be noted that the first child object's pivot will be the parent's pivot. This can be corrected by getting all the children's pivot, making an average out of them and move the parent by the difference between its current and desired location, the move the children backwards the same amount, thus maintaining the same locations yet giving the parent a centered pivot. Unity should add something like this into the package (already posted an idea for that). All in all, thanks for the answer.
Your answer
Follow this Question
Related Questions
My GameObject disappears when running this script. 0 Answers
hey im trying to make a pause menu, it keeps poping up at the start and i have no idea how to fix. 1 Answer
How do I change the shape scale in the Particle System via script? 1 Answer
c# How to scale a game object using another (non-parent) object as pivot 1 Answer
why did the script change 0 Answers