Position Child Object to center of Parent Object [SOLVED]
What I'm trying to achieve is snapping a child object to the center of its parent object after dragging and dropping it. The moving object successfully follows the mouse, and drops. It also successfully selects a dynamic parent when it moves over a new node.
Here is all of my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Object_Moveable : MonoBehaviour {
private Vector2 mousePos;
public float moveSpeed;
public float offset = 0f;
private bool following;
private GameObject SelectedNode;
// Use this for initialization
void Start () {
following = false;
offset += 10;
}
void Update(){
if (Input.GetMouseButtonDown(0) && ((Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position).magnitude <= offset)) {
following = true;
}
if (following) {
transform.position = Vector2.Lerp(transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition), moveSpeed);
}
if (Input.GetMouseButtonUp (0)) {
following = false;
//Attach (Node, 0, 0);
transform.localPosition = SelectedNode.transform.position;
}
}
void OnTriggerEnter2D (Collider2D trigger) {
if (trigger.tag == "pipenode") {
transform.SetParent (trigger.transform);
SelectedNode = trigger.gameObject;
}
}
}
EDIT: I finally found the solution to this problem through trial and error. Here is the code that ended up working:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Object_Moveable : MonoBehaviour {
Vector3 mousePos;
Vector2 mousePos2D;
private GameObject SelectedNode;
private bool IsActiveSelection;
private float moveSpeed = 1f;
private bool following;
// Use this for initialization
void Start () {
following = true;
IsActiveSelection = true;
}
void Update(){
if (Input.GetMouseButtonDown(0)) {
mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mousePos2D = new Vector2(mousePos.x, mousePos.y);
RaycastHit2D hit = Physics2D.Raycast(mousePos2D, Vector2.zero);
if (hit.collider != null) {
if (hit.collider.tag == "selectable") {
hit.collider.gameObject.GetComponent<Object_Moveable>().SetThisObject();
} else {
Debug.Log ("Nothing was hit");
}
}
}
if (Input.GetMouseButtonUp (0)) {
following = false;
SnapObject ();
//transform.localPosition = SelectedNode.transform.position;
}
if (following) {
this.transform.position = Vector2.Lerp(transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition), moveSpeed);
}
Debug.Log (SelectedNode);
}
void SetThisObject () {
IsActiveSelection = true;
following = true;
}
void SnapObject () {
if (IsActiveSelection) {
IsActiveSelection = false;
if (!following) {
transform.position = new Vector3 (SelectedNode.transform.position.x, SelectedNode.transform.position.y, 0);
}
}
}
void OnTriggerEnter2D (Collider2D trigger) {
if (trigger.tag == "node") {
SelectedNode = trigger.gameObject;
}
}
}
An explanation of what is happening in the above code:
The "Object_Moveable" is attached to an object the instantiates under the mouse when a UI button is clicked, and follows the mouse until it is released. While moving, it is hitting 2D collider triggers attached to parent objects on a node grid. When it contacts a node, it sets that node as the parent. When the mouse is released the object then snaps to the most recent parent's position.
The Raycast2D is to make sure the "SetThisObject()" method only selects the object that the mouse is over to allow it to move around again once clicked. Without this, "SetThisObject()" will select and move every single object that has "Object_Moveable" attached to it.
Worth Noting: Part of the reason, I discovered, that the snap positioning was not working is because neither the object nor the node had a Rigidbody attached, and had no transform to move around or move to. Adding the Rigidbody allowed them to begin moving, but not correctly until the code was fixed.
Answer by Cuttlas-U · Mar 05, 2018 at 08:03 PM
hey; first of all your code will be runing multiple times in this part ;
if (following) {
transform.position = Vector2.Lerp(transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition), moveSpeed);
}
cause while u dont put your mouse up the following is true and this will repeate ;
so better idea is to do this when u put the mouse donw like here :
if (Input.GetMouseButtonDown(0) && ((Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position).magnitude <= offset)) {
transform.position = Vector2.Lerp(transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition), moveSpeed);
}
so this will fix the multiple attempt problem and will do only once;
but for your snapp problem i need more detailes;
better way is to create an empty object in the parent and try to set the object position related to it ;
Well that doesn't do quite what I need it to. There are going to be several objects that have this script attached to them (up to 128 in a scene) and so I have several checks that set the "following" bool more specifically. That's why I have it set that way.
As far as the snap setting I am talking about. I actually do have it set the way you suggested. There are empty parent game objects, and a child object is being dragged around the screen with the mouse (this is ultimately going to be for mobile, so the player's finger will stay down while dragging). Both the parent and child objects have 2D trigger colliders, and as the cild object contacts the empty parents objects, it sets the most recent contact as the current parent. When the player lets go of the object, I want it to snap to the center of the selected parent, and it previously would not snap to anything at all.
I have added this snippet of code to the object, but it now snaps to the center of the screen, and not the center of the parent object.
void Update () {
if (Input.Get$$anonymous$$ouseButtonUp (0)) {
following = false;
SnapChild ();
}
}
void SnapChild () {
if (this.IsActiveSelection) {
this.IsActiveSelection = false;
if (!following) {
this.transform.localPosition = SelectedNode;
}
}
}
Your answer
Follow this Question
Related Questions
Cant get setParent to actually set the parent for child. 0 Answers
snap object to gridwise 0 Answers
Calculate a point in space based on a triangle 0 Answers
How do I draw a local space line render between parent and child objects ? 1 Answer
Need help getting randomly moving particles to head to the nearest of 4 coordinates. 1 Answer