- Home /
How to store the last 20 transform.position(vector3s) of an moving object in runtime and make a direction vector out of it?
Hey there!
An gameobject driven by a motion controller (PSmove/Move.Me) is doing some movements... I need the current direction of this gameobject. Not the direction of where it is facing, but the direction it is moving in space.
My attempt was to save the first and the next position of it. Something like this:
Quaternion movingDirection ;
GameObject myController;
Vector3 pos1;
Vector3 pos2;
pos1 = myController.transform.position;
movingDirection = Quaternion.LookRotation (pos2 - pos1);
pos2 = myController.transform.position;
But this isn't working well because the space (0 frame) between them is to small to calculate a steady direction.
So I think it could be much more steady if I could store the last maybe 20 positions of the gameobject to calculate the direction out of it.
My problem is I don't know how to store the last 20 transform.positions of a moving gameobject and a also don't know how the calculate a direction(Quaternion) out of it.
Do someone has a solution?
Answer by Habitablaba · Oct 02, 2014 at 05:27 PM
For storing the last 20 transforms, check out the queue data structure, if you're not familiar with it already.
Then, check out this pseudo code:
Queue<Transform> transformQueue = new Queue<Transform>();
int maxQueueSize = 20;
// elsewhere...
if(transformQueue.Count() >= maxQueueSize )
{
transformQueue.Dequeue();
}
transformQueue.Enqueue(this.transform);
For determining the direction, would an average be what you're looking for? Try:
var average = Quaternion.Identity;
foreach(var xform in transformQueue)
{
average += xform.rotation;
}
average /= transformQueue.Count();
Edit: After looking at your problem a bit more, I think we're trying to solve the wrong thing. The issue is that there isn't enough time passing between when you get pos1 and pos2 -- as you say, it's 0 frames. I may be misreading what you've done here, but try the following:
Quaternion movingDirection;
GameObject myController;
Vector3 currentPos;
Vector3 previousPos;
currentPos = myController.transform.position;
movingDirection = Quaternion.LookRotation (currentPos - previousPos);
previousPos = currentPos;
This will:
grab the most recent position and store it in pos1
calculate the look rotation for the vector from the last position (pos2) to the new position (pos1)
Store the most recent position in pos2 for use as the 'last position' next frame.
I changed your subtraction around, since you want the new vector computation to be in the form of (to - from), instead of (from - to). I changed the names of your variables because I kept getting confused. I remain unconvinced that we are trying to solve the right thing.
I couldn't test it right now, but I think calulating the average of every rotation value gives not what I need. The rotations are irrelevant because they could be every thing. $$anonymous$$ore interesting is the position. I need something like this:
movingDirection = Quaternion.LookRotation (pos2 - pos1);
But for the 20 positions. $$anonymous$$aybe taking the last and the first position of the Queue thing could be a solution. But sadly I 'm not sure how to extract them. Do you have an idea? Sorry I'm very new with coding.
I updated my answer for you. I'm not sure we're doing the right thing here, but I think we'll get it figured out if we keep working on it!
Hey Habitablaba, you're right my code was wrong (it was right out from my $$anonymous$$d..). But changing it to TO - FRO$$anonymous$$ doesn't help because the time in between is still zero. And this is why the direction is very uns$$anonymous$$dy. (Is a motion controller, drive by a human hand.)
So I need something like: pos1 $$anonymous$$INUS (wait 20 frames) pos2. So I think the queue thing could be a solution if I could somehow extract the 20 frames old position. But in first 20 frames I need the 1 - 19 old frames old position to avoid a gap. Do you understand want I mean?
Edit: Seams like queue.Peek() is what I'm looking for... let me check if I'm right.
Peek will give you the item at the front of the queue without removing it from the queue, which in your case would be the oldest position data. You should be able to check that against the current one, which should be 20 or so frames of data later.