Unity: transform child's position and leave parent where it is - unity3d

I want to move the itemChild away from the parent, but the parent always move to the new position with the child. Why the parent follow the child's position? How can I move the child and leave the parent where it is.
My code:
GameObject go = new GameObject("go");
go.transform.parent = GameObject.FindGameObjectWithTag("Canvas").transform;
itemChild.transform.SetParent(go.transform);
itemChild.transform.localPosition = new Vector2(itemChild.transform.position.x, itemChild.transform.position.y + 250);

Parent should stand still. Are you sure parent is moving with the child ? I mean you are just creating an empty GameObject, can share with us the x,y,z of parent and child ? I tried your code with a bit of change and it is working for me. Here is my code : https://imgur.com/khXrZ07 If you just create an empty game object and click on it in the canvas, since your parent("go" in your case) is empty it will just focus on your child object and it might confuse you.

Related

Unity - How to react to scene picking? How to force select a parent by picking its child in the sceneview

I have the following situation I need an answer to:
I have a parent object with children. These children all have unique meshes. Whenever these children are selected in the SceneView, the parent needs to be selected in stead. The children should never have their inspectors exposed (not even a fraction of a second).
How do I do this?
There are two possible solutions that I have come up with which are not the solution I wish to go for.
First being using [SelectionBase] attribute on the parent object. This work perfectly, but only once. The first time the child is selected, the parent gets selected. However, when I click the child again, it still gets selected.
Second solution was to react on Selecten.onSelectionChanged. This however is too slow. I can set the selection to the parent if a child gets selected, but the child gets exposed for a few frames still.
Is there an instant solution to this which can guarantee me the functionality of SelectionBase, but then every time in stead of only the first time I click it?
Thanks in advance! :)
I have found a way to do exactly what i want. I combine the [SelectionBase] attribute with a piece of code in the editor OnSceneGui.
First add the [SelectionBase] attribute to your class
Second add this code to its editor class
private void OnSceneGUI()
{
HandleUtility.AddDefaultControl(0);
//Get the transform of the component with the selection base attribute
Transform selectionBaseTransform = component.transform;
//Detect mouse events
if (Event.current.type == EventType.MouseDown)
{
//get picked object at mouse position
GameObject pickedObject = HandleUtility.PickGameObject(Event.current.mousePosition, true);
//If selected null or a non child of the component gameobject
if (pickedObject == null || !pickedObject.transform.IsChildOf(selectionBaseTransform))
{
//Set selection to the picked object
Selection.activeObject = pickedObject;
}
}
}
This allows the first pick to select the component. From then on, only when you select non-child objects in the scene, selection will actually change.

How to get exact touch location of object to add new child object at the same place

I have a base plane and when I click on the plane I need to add some other object at the exact location the user is touched. the newly added object is not a child of base plane it will be a child of another object which will present the same base plane
I tried using raycast position but it didn't work well.
Vector3 objLocation = new Vector3(raycastHit.transform.position.x, 180.0f, raycastHit.transform.position.z);
GameObject newObj = Instantiate(singleDustBin, objLocation, Quaternion.identity); newObj.transform.SetParent(dustBinPrefab.transform);
Instead of raycastHit.transform.position use raycastHit.point - that should do the trick

Unity Update Text on Gameobject initiated from script from other Gameobject

I am developing for the HoloLens and I Made an object that follows me around. This Gameobject is actually an UI Canvas with text in it which I set like this because i want to keep the original object as well. (Just like in the MS example):
/// <summary>
/// The object to tag along set in the unity editor
/// </summary>
public GameObject ObjectToTagAlong;
/// <summary>
/// The instantiated object to tag along that follows you around.
/// </summary>
private GameObject instantiatedObjectToTagAlong;
this.instantiatedObjectToTagAlong = GameObject.Instantiate(this.ObjectToTagAlong);
this instantiatedObject tags along just fine but now I want to update the Text on instantiatedObjectToTagAlong but have no idea how to do this. (I can very easily update the text on the 1st object but i want to do it this way)
Does anyone know how to update the text on a gameobject that is initiated from another GameObject?
To build on what Serlite commented with, you need to use GetComponent in combination with another script.
public class MyTextUpdater: MonoBehavior
{
public Text SuperText2;
}
Apply MyTextUpdater to your ObjectToTagAlong prefab (or GameObject if not a prefab) and, in the editor, set the value of SuperText2 to the Text object you want to update (typically this is a child of the ObjectToTagAlong GameObject).
Now anytime you want to update that Text object on your instance, instantiatedObjectToTagAlong, you can do this:
MyTextUpdater text = instantiatedObjectToTagAlong.GetComponent<MyTextUpdate>();
if (text!=NULL && text.SuperText2!=NULL) { /*do whatever you need to do on the text.SuperText2 object*/ }
EDIT:
When Unity instantiates a copy of a GameObject, it makes a "deep" copy of sorts, meaning that the copy will have the exact same structure of child GameObjects.
Original Copy
- Child A - Child A (copy)
- Child B Instanitate => - Child B (copy)
- - Grandchild A - - Grandchild A (copy)
Each child is instantiated with it's own new copy. On top of that, if Original has a MonoBehavior script that points to one of it's children (or grandchildren etc), Copy will have a script that points to the appropriately copied child.
MyTextUpdater [Original] MyTextUpdater [Copy]
- SuperText2 = Child B => - SuperText2 = Child B (copy)
Regarding the question of why have the extra script (the MyTextUpdater script):
Original is just a GameObject. In the editor you can see it has children, but that does not represent a class. You can not do something like this in a script:
Original.ChildB.Text = "Hello World!";
in the same way, you can't do this:
Copy.ChildB.Text = "Hello Copy World!";
You could create code to iterate through all the children of the GameObject looking for a child with the correct name ("ChildB"), but that is inefficient and probably bad programming.
The better way is to create a script class that actually does give you access to the child as a field in that class. And that is where the MyTextUpdater script comes in.
This would be invalid:
GameObject Copy = Instantiate(Original);
Copy.SuperText2.Text = "Some text here";
Copy does not have a field or method called SuperText2, or ChildB, or whatever you would call it. But you could do this:
GameObject Copy = Instantiate(Original);
MyTextUpdater mtu = Copy.GetComponent<MyTextUpdater>();
mtu.SuperText2.Text = "Some text here";
Assuming of course that you applied the MyTextUpdater script to Original and made the right connections to the child text component.

Node added to stage/scene graph event?

I am trying to add a StackPane to another StackPane at runtime and setting the width of the child StackPane to 800, but when I try to get the width of the child StackPane, it is showing as 0.
Which is the event that gets fired from Javafx using which I can recognize that child node is added to scene graph with the desired properties.
Node has scene and parent properties. You can register a change listener on the scene property. When the value of the scene property changes to non-null, it means the node became part of a scene graph.
Note, however, that node's width and height will not return correct values until the next layout pass.

GWT Drag and Drop within tree and between tree grids

We're using GWT and We're required to create two drag and drop tree grids. Each tree contains parents and children (max two level for now).
Here's what we need to be able to do:
Use cases
Drag a parent from one tree grid to the other.
Drag a parent 1 to parent 2 (1 will become child of 2, and all 1's children will become children of 2) -> please don't ask :D
Drag a child from one parent to another (within the same tree grid)
Drag a child to top level within the same tree grid (child will become a parent)
Drag a child to the other tree grid with two options
1 - Top level - child from tree 1 will become a parent on tree 2.
2 - Parent - Child from tree 1 will become child of a parent on the tree grid 2.
If this doesn't make much sense, we don't have the full context yet, so that's all we know.
Problem
We can drag on the same tree grid. If the row we want to drag the cell to is hidden, we set the scroll to true, so that the grid scrolls when the user is dragging inside it. Something like so:
private void setDraggableOptions(DragAndDropColumn<?, ?> column) {
// retrieve draggableOptions on the column
DraggableOptions draggableOptions = column.getDraggableOptions();
draggableOptions.setScroll(true);
// use template to construct the helper. The content of the div will be set
// after
draggableOptions.setHelper(HelperType.CLONE);
// opacity of the helper
draggableOptions.setOpacity((float) 0.8);
// cursor to use during the drag operation
draggableOptions.setCursor(Cursor.MOVE);
// set the revert option
draggableOptions.setRevert(RevertOption.ON_INVALID_DROP);
// prevents dragging when user click on the category drop-down list
draggableOptions.setCancel("select");
column.setDraggableOptions(draggableOptions);
}
Now the problem is, setting the tree grid to scroll, the user will never be able to drag the object to the second tree as the scroll will try to keep the object always inside the grid.
We're using the gwtquery-plugins
Is there any idea to work around this? Thank you very much in advance.
See my response to your question here