- Home /
Replicating Unity's Rect Tranform tool at runtime.
I've been beating my head against the wall for a week now off and on trying to figure this out. I want the same functionality you get with the tool in Unity, but at runtime for a level editor I'm working on.
private void OnMouseDown() {
pointerStart = Camera.main.ScreenToWorldPoint(Input.mousePosition);
sizeStart = myTool.myEditingObject.GetComponent<SpriteRenderer>().bounds.size;
scaleStart = myTool.myEditingObject.transform.localScale;
positionStart = myTool.myEditingObject.transform.localPosition;
}
private void OnMouseDrag() {
if (scaleSide == ScaleSide.RIGHT) {
pointerTravel = (Vector2)Camera.main.ScreenToWorldPoint(Input.mousePosition) - pointerStart;
scaleX = ((sizeStart.x + pointerTravel.x) / sizeStart.x) * scaleStart.x;
positionX = positionStart.x + (pointerTravel.x / 2);
var scale = new Vector2(scaleX, myTool.myEditingObject.localScale.y);
var pos = new Vector2(positionX, myTool.myEditingObject.localPosition.y);
myTool.Scale(scale, pos); //Just applies the above math to the object the math is meant for.
}
This code works perfectly... that is, until you rotate the object. Then it falls apart. http://i.imgur.com/CSiGarG.gifv There is a gif of the problem.
Basically, I need to figure out the math to move against the mouse on the Y axis like I do for X to compensate for the new downward motion when the object is rotated. Unfortunately, myself and everyone I've talked to in a few gamedev Discord's can't seem to get it to work just right.
Any help appreciated, thanks! :)
Answer by Bunny83 · Jul 25, 2017 at 12:09 AM
Your pointerTravel vector is a worldspace vector. You should transform that vector into the local space of your object. Though you have to use InverseTransformDirection as that will only apply the inverse rotation without scale or translation.
Just do this:
pointerTravel = (Vector2)Camera.main.ScreenToWorldPoint(Input.mousePosition) - pointerStart;
pointerTravel = myTool.myEditingObject.transform.InverseTransformDirection(pointerTravel);
Now "pointerTravel" is in local space of your object. So even if the object is rotated so it's x axis points downwards, a movement downwards will still result in a positive "x" value in local space.
edit
ps: Keep in mind that your translation assumes that the pivot is in the center of the object. If you moved the pivot this line would be wrong:
positionX = positionStart.x + (pointerTravel.x / 2);
You should do this instead:
positionX = positionStart.x + (pointerTravel.x * yourRectTransform.pivot.x);
This of course assumes that you actually try to operate on an UI object that has a RectTransform.
Note that this only applies to the "right" side. For the left side you would need to use
positionX = positionStart.x + (pointerTravel.x * (1f - yourRectTransform.pivot.x));
The pivot is defined as a normalized position within your rect. So pivot.x is 0 when the pivot is at the left side. The scale always scale around the pivot. So when dragging the left side we need to apply 100% of the translation. When dragging the right side with the pivot left the translation will be 0%.
The value for pointerTravel remains the same before and after the InverseTransformDirection is applied and thus, nothing about the behavior changed.
Answer by umbreon89 · Aug 28, 2018 at 10:01 PM
Hi! Did you manage to fix this in the end? If so, how? Thanks!
Your answer
![](https://koobas.hobune.stream/wayback/20220612131041im_/https://answers.unity.com/themes/thub/images/avi.jpg)