I have a simple parent object {Buttons Holder} that has a Horizontal Layout Group component attached to it, so when the game starts I instantiate multiple buttons in the Buttons Holder so that they line up perfectly.
And just for example lets say that I have 2 buttons instantiated and I want at some point these 2 buttons to switch positions so that the first button goes to the second button's position and the second button's switches to the first button's position.
And heres what i'm trying to do:
Vector3 pos1 = buttonPrefabs[0].transform.position;
Vector3 pos2 = buttonPrefabs[1].transform.position;
buttonPrefabs[0].transform.position = Vector3.Lerp(pos1, pos2, Time.deltaTime * 2);
I mean I don't want to snap them to their new positions I just want them to smoothly travel to their new positions using Vector2.lerp or something.
Since the parent object has a Horizontal Layout Group attached to it i'm not able to do that.
Help please.
You can not lerp them to their new position while the position is controlled by the Layout Group. Only thing I can think of is
temporarily disable the Layout Group
then move the child objects smoothly via e.g. MoveTowards
update their child index values to reflect their new order accordingly
enable the layout group again
A more sophisticated approach would require you writing your own Layout Group that offers functionality to let child objects switch positions. That way your own Layout Group could still keep all other children properly positioned, even while two children switch positions.
Related
I am working on learning how to use Unity and have been unable to solve this problem of mine. I am currently working on a prototype of a game and need to change the RectTransform Pos X to a value that I want.
However, so far I was unable to do it. I tried Vector2 and Vector3 converations but I can't seem to get it right.
Here is what I have atm (I know the new RectTransform is doing nothing, bu I am simply out of ideas.):
void Start()
{
changeTransform = GameObject.FindGameObjectWithTag("NextButton").GetComponent<RectTransform>();
changeTransform = new RectTransform();
}
And all I want is to set the Pos X of the rect transform to be 25.
Anything helps. Thanks a lot.
EDIT:
When I change the value of the Pos X in the inspector it gets overwritten back to the value seen in the picture.
EDIT2:
Below is how my buttons look right now. I just want the Next-Button to be aligned with the other buttons on the left side without it chaning its size.
For what you want to achieve
I just want the Next-Button to be aligned with the other buttons on the left side without it chaning its size.
simply wrap your NextButton under another object
- NextButtonContainer
|-- NextButton
=> make NextButton be left aligned within the NextButtonContainer
Now the NextButtonContainer can simply grow like the other buttons, have no visual components at all and allow the next button to be left aligned within it and have a fixed size
I can see that some properties of the Rect Transform component are being overridden by the Content Size Fitter component.
You should remove the Content Size Fitter component from the GameObject or set the horizontal and vertical fit in this component to unconstrained. If this doesn't work, please let me know of what other components are attached to this GameObject.
I have an object in my scene's sky and want to prevent it from getting cut out of the view, no matter the screen ratio. So I set up a canvas and a PlaceHolder RectTransform on it, that - as being UI element - gets scaled and repositioned in respect to the screen aspect ratio. My goal is to use this position to determine where to put my scene object by using the following script:
Camera mainCam;
RectTransform placeHolder;
private void Start()
{
mainCam = GameObject.FindGameObjectWithTag("MainCamera")
.GetComponent<Camera>();
placeHolder = GameObject.FindGameObjectWithTag("SkyObjectPlaceholder")
.GetComponent<RectTransform>();
var screenPos = mainCam.ScreenToWorldPoint(
new Vector3(placeHolder.rect.x, placeHolder.rect.y, 0));
transform.position = new Vector3(screenPos.x, screenPos.y,
transform.position.z);
}
The issue is that my sky object is always placed in the center of the screen. It is not a child of anything on the scene, I just put it there. The placeholder is to the upper right in the canvas. Note that I tried playing with anchors for the UI element, set it to be left bottom, right top, no change, the scene object is always in the center of the screen.
What am I doing wrong? How to make a Scene element match up the position of a Canvas element, so it gets right behind it?
Note: I'm using a perspective camera. I don't know if it matters, but I thought I mention it, just in case.
Yet another edit: after messing around with the issue a bit, I found that the problem is possibly linked to the Z input I give the ScreenToWorldPoint, in my case it's 0. I couldn't get a viable Z to input though.
Hmmm... i think you should change the sorting layer of that object
I got problem when set position of child to as it parent position.
Below the screenshot :
My script :
RightNext.transform.GetChild (0).gameObject.transform.SetParent (TemporaryPage.transform,false); // TemporaryPage = Cherry Cake
RightNext.transform.GetChild (0).GetComponent<RectTransform> ().localScale = new Vector3 (1, 1, 1);
RightNext.transform.GetChild (0).gameObject.transform.parent = RightNext.transform;
RightNext.transform.GetChild (0).transform.position = RightNext.transform.position;
And i put it in update to make sure the position is not changing.
Why my child position is not inside and same position with parent even i have set it to the same position with parent ?
Thanks
Dennis
You need to change this line:
RightNext.transform.GetChild (0).transform.position = RightNext.transform.position;
to this:
RightNext.transform.GetChild(0).GetComponent<RectTransform>().localPosition = Vector2.zero;
OR this:
RightNext.transform.GetChild(0).GetComponent<RectTransform>().position = RightNext.transform.GetComponent<RectTransform>().position;
Edit after your comment: the two lines I suggested are used to make the child pivot point coincide with the parent pivot point, I thought you wanted that and not to always place the child object pivot at the center of the parent object regardless of its pivot.
With the line you suggested (you can use the 2D version since we're dealing with UI):
RightNext.transform.GetChild(0).GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
you put the child pivot at the center of the parent object, so you need to set the child pivot at (0.5,0.5).
However, I strongly suggest to get references to the RectTransform of both parent and child in the Start method (or after instantiating a new child), to avoid the constant use of the GetComponent method inside Update, since it's a slow method.
I am creating a 3D game which is going to be a strategy game. I want to create a panel (UI group of a bunch of texts and buttons) by code (C#) and then move them so they are on top of a GameObject in the Canvas layout. So I am doing this:
if (ThisBuilding == null)
ThisBuilding = this.gameObject;
Panel = Canvas.Instantiate(Panel);
Panel.transform.SetParent(canvas.transform, false); //false to prevent stupid scaling issues created by the parent change
Vector3 centerPosition = ThisBuilding.GetComponentInChildren<MeshRenderer>().bounds.center; //the building GameObject contains a MeshRenderer component in its only children.
panelRect.anchoredPosition = Vector3.Lerp(panelRect.anchoredPosition, centerPosition, 1.0f);
The thing is that this script is run (on Start()) once per building, hoping that the panel would get instantiated 3 times and each panel corresponds to a building, but for some strange reason this does not work.
EXPECTED RESULT: each time the panel gets instantiated, the position is the same as of the building that instantiated it (the building GameObject holds the script and activates / deactivates the panel)
ACTUAL RESULT: even though the panel does get instantiated 3 times as it should, they are all in the same position and do not change even when my Update() function changes its position. What am I doing wrong?
Giving the world position of the buildings results in the panels being positioned basically in the same location on screen. What is needed is to calculate the world position to the screen position and use the calculated screen position to place the panels.
Try something like this:
panel.transform.position = Camera.main.WorldToScreenPoint(this.gameObject.transform.position);
I am instantiating an object with following code
public Object ball;
Instantiate(ball, hit.point , Quaternion.identity) ;
Where hit.point is a position and ball is a prefab I created, but unfortunately this prefab has a Position animation - jumping ball - and because of that as it animates it stays in animation's position. I can't even Translate it.
How can I move it or change animation somehow ?
There is more than one way to solve this problem, depending on your other goals/constraints if any.
One simple approach is to separate this problem into two spaces, via the introduction of an empty parent node.
If you construct..
[Empty Parent Node] (created dynamically)
|- [Ball] (created from your prefab)
..then you can still apply the animation to [Ball], now within a "local space" defined by [Empty Parent Node]. Further, you can now specify an arbitrary position for the parent node, which acts to place the ball overall.
Another possible solution is to change your animation from a position animation to a localPosition animation. Then, you'll be able to change its Transform.position attribute with scripts.