I want to be able to drag all of my game objects tagged “Selected” around the scene. I am able to do so with my current script, but it lumps all of the objects together at the mouse position. My current script is
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MouseManager : MonoBehaviour
{
private Vector3 offset;
private GameObject[] selection;
void OnMouseDown()
{
offset = gameObject.transform.position -
Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10.0f));
}
void OnMouseDrag()
{
selection = GameObject.FindGameObjectsWithTag("Selected");
if (gameObject.tag == "Selected")
{
foreach (GameObject s in selection)
{
Vector3 newPosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10.0f);
s.transform.position = Camera.main.ScreenToWorldPoint(newPosition) + offset;
}
}
}
}
If I remove the s at the beginning of the last line
transform.position = Camera.main.ScreenToWorldPoint(newPosition) + offset;
I can move only one “selected” object at a time, but it at least doesn’t jump to the mouse position. All I’m trying to do is avoid my “selected” items from lumping together, and still be able to move them all at once, but relative to their current position.
Okay. So based on what i understood, you have many gameObjects, some of them are tagged with “Selected” and some of them aren’t tagged. What you want to do is move the gameObjects that are tagged only. A good way to achieve this is to child the gameObjects that are tagged to a parent gameObject. And then, proceed with moving only one gameObject (The Parent). This is a much better way that calculating distances of all gameObjects from the position of the mouse (While keeping the same distances). This is how you can do it:
- Make an empty gameObject from the inspector and make sure that its positioned 0 on all axis. Then, assign that gameObject from the inspector.
- Make a public gameObject list and add all gameObject to the list from the inspector.
- Use a for loop to check all the gameObjects for the tag “Selected” and then, child each gameObject with the “Selected” tag to the empty gameObject that you assigned earlier.
- The last step is to continue with your code and make the drag function on the parent gameObject
This is how to start the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveSelectedObjects : MonoBehaviour {
public GameObject[] allObjects;
public GameObject parentObject;
// Update is called once per frame
void Update()
{
for (int i = 0; i < allObjects.Length; i++)
{
if (allObjects*.gameObject.tag == "Selected")*
{
allObjects*.transform.parent = movingObjects.transform;*
}
}
* }*
// onMouseDrag function to move the parentObject
}
Of course there are many other ways to do this. But this is what i would use. All the best
The reason its not working is because each item that you are dragging is going to need its own offset based on where you initially clicked. But as of right now all you have is one offset setting the position of all of them to the same position. This is how i would set it up…
MouseManager.cs
private GameObject[] _selection;
// Parallel list of offsets
private List<Vector3> _offsets;
public void OnMouseDown() {
_selection = GameObject.FindGameObjectsWithTag("Selected");
Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
_offsets.Clear();
// Set initial offset for each item
for (int i = 0; i < _selection.Length; i++) {
Vector3 offset = _selection*.transform.position - mouseWorldPos;*
offset.z = 10f;
_offsets.add(offset);
}
}
void OnMouseDrag() {
Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
if (gameObject.tag == “Selected”) {
// Drag each item
for (int i = 0; i < _selection.Length; i++) {
Vector3 newPos = mouseWorldPos + _offsets*;*
newPos.z = 10f;
selection*.transform.position = newPos;*
}
}
}_