- Home /
GameObject not following its Transform's Vector
Hi,
I know that my question is very weird, but that's mainly because I do not really know what is going wrong. The point of my script is to do a crudely simple drag & drop system:
When you click a selectable GameObject, well... it is selected. These GameObjects will be referenced as datasets, for my comfort ;
When the Fire1 button is lifted, the position of the dataset is checked:
If it is on near a "slot", a dropable position, the dataset moves to the center of the Slot's GameObject. If not, the dataset's position simply becomes Vector3.zero.
This works by having a dataset class which takes in its associated GameObject and its position. That's redundant, but just for safety. Also have a slot class, with a position and and boolean that is true if the slot is occupied, false if its free. Roughly, its just a classic constructor:
public class Slot
{
public Vector3 position ;
public bool isOccupied ;
public Slot(Vector3 _position, bool _isOccupied)
{
position = _position ;
isOccupied = _isOccupied ;
}
}
And same for the datasets.
Then the Drag & Drop scripts starts by creating a list of datasets, and of slots which are taken from the scene. And then interesting part (sorry its a wee long...):
//A very rough drag and drop system:
if (Input.GetButtonDown("Fire1"))
{
//When the fire1 button is pressed, we loop through our list of datasets to assess which one has been selected.
for (int i = 0 ; i < nb_datasets ; ++i)
{
//isClicked is just the function I use to check if the object is clicked. Didn't use unity's raycast for performance reasons. Or just for fun.
if (isClicked(datasetList[i].pos,cam))
{
//The selection boolean keeps track of whether a dataset is currently being selected.
selection = true ;
//selectedDS allows to keep track of which dataSet has been selected.
selectedDS = datasetList[i] ;
dropPosition = Vector3.zero ;
}
}
}
if (Input.GetButtonUp("Fire1") && selection)
{
selection = false ;
//Get the screen position at which the object is dropped, to compare it with the slot's screen position.
dropPosition.x = Input.mousePosition.x/Screen.width ;
dropPosition.y = Input.mousePosition.y/Screen.height ;
for (int i = 0 ; i < nb_datasets ; ++i)
{
//Compute the distance between the drop point and a slot:
setSlotDist = distance(worldToCamPos(slotList[i].position,cam),dropPosition) ;
//If the dataset is dropped sufficiently close to the slot's transform, and that the slot is not occupied, then the dataset is placed in the slot.
if (setSlotDist < slctArea && !slotList[i].isOccupied)
{
datasetList[selectedDS.index].pos = slotList[i].position ;
datasetList[selectedDS.index].dataset.transform.position = datasetList[selectedDS.index].pos ;
slotList[i].isOccupied = true ;
}
else
{
datasetList[selectedDS.index].pos = Vector3.zero ;
datasetList[selectedDS.index].dataset.transform.position = datasetList[selectedDS.index].pos ;
slotList[i].isOccupied = false ;
}
}
}
Similarly to the above, if the selection button is lifted, then the code checks if it's sufficiently close to any of the slots for it to placed in a slot. If not, the dataset goes to (0,0,0) world coordinates.
And here comes my problem!! For some reason, the code works with only one of the slots. When I try to drop the datasets in the other slots, they are sent to (0,0,0). Now here is the magic: After some quick debugging, I found out that the code still "thinks" the game object to be into the slot of interest. The position that is registered by the dataset class is indeed that of the slot, the class's game object position too, and the slot is set to occupied state. But... the dataset goes to (0,0,0)... Except for only one of the slots.
Well that is it for me! Thank you very much for your attention, and hope to hear from you!
Thanks!
Only had a quick look but the final loop seems strange to me. You will indeed always set datasetList[selectedDS.index].pos = Vector3.zero ;
in every case apart from when the "found slot" is the last one you look at in that loop.
You have a comment that says "//If the dataset is dropped sufficiently close to the slot's transform, and that the slot is not occupied, then the dataset is placed in the slot." but what you actually do is place the dataset in the slot and then continue looking at and acting on all the remaining slots.
Could this explain why it only works for one of them? You could try breaking out of that loop as soon as you've found a slot to use. Or, perhaps more normal for this kind of thing, use the loop to determine a slot to use, and then do whatever you need to with that slot after the loop has finished.
Answer by rh_galaxy · Mar 24 at 12:28 PM
Without checking exactly everything, my suggestion is to just save the index like this
selectedDS = i; //selectedDS should be an *int*
Keeping the index in two places like that seems dangerous and unnecessary. Try to eliminate DataSet.index so
datasetList[selectedDS.index] => datasetList[selectedDS]
That's my guess, but you are not showing the code for where you create the DataSet array. Also it seems odd that you loop i=0..nb_datasets but use datasetList[selectedDS.index] and slotList[i]. Is dataset list and slot list mapped 1 to 1? If the problem persist you should show the code where you create the two lists.
Hi,
Very sorry for the delay, and thank you very much for providing some ideas. To try out my indexing, I "debugged.log" it at each step of the process, and it seamed to work just fine. On my behalf, I still don't have a clue of what is wrong.
When dropping the dataset in slot n°2: The index of the slot as well as of the game object is right. The game object does move to the intended position and everything works just fine. Now, the really weird part is that it works only with this slot. With other slots here is what happens:
When dropping the dataset in any of the other slots: The position vector of the "dataset object" is indeed and correctly updated, that of the intermediary dataset, the so called "selectedDS" too, and the indexes of the slot as well as that of dataset are just fine (observed when printing their values at each step of the process). However, the dataset is moved to the default Vector.zero position.
And here's the bit of code that initializes the list of slots and datasets:
Here the constructor of the dataset class. Both constructors (that of datasets and slots) use only UnityEngine.
using UnityEngine;
public class Dataset
{
public Vector3 pos ;
public GameObject dataset ;
public int index ;
public Dataset(Vector3 _pos, GameObject _dataset, int _index)
{
pos = _pos ;
dataset = _dataset ;
index = _index ;
}
}
The code of the slot class:
using UnityEngine;
public class Slot
{
public Vector3 position ;
public bool isOccupied ;
public Slot(Vector3 _position, bool _isOccupied)
{
position = _position ;
isOccupied = _isOccupied ;
}
}
And eventually, lists of both are initialized through a respective method which is call on start:
void InitializeDatasets ()
{
datasetList = new Dataset[nb_datasets] ;
for (int i = 0 ; i<nb_datasets ; ++i)
{
GameObject datasetObj = GameObject.Find("Dataset_"+i) ;
Vector3 datasetPos = datasetObj.transform.position ;
datasetList[i] = new Dataset(datasetPos, datasetObj, i) ;
}
}
void InitializeSlots()
{
slotList = new Slot[nb_datasets] ;
for (int i = 0 ; i<(nb_datasets) ; ++i)
{
Vector3 slotPos = GameObject.Find("Slot_"+i).transform.position ;
slotList[i] = new Slot(slotPos, false) ;
}
}
Again, thank you very much for your help, it is very much appreciated.
Feel free to ask for any further information.
Your answer
Follow this Question
Related Questions
Why can't I assign transform.position to a Vector3 object? 3 Answers
How to find a transform with name in prefab 2 Answers
Getting Transform position using mouse position 3 Answers
How to correctly store tile and terrain type data? 2 Answers
How can i fix a position of a gameobject after it meets its condition 1 Answer