- Home /
Change position relative to object
Hello, I want some gameobjects to be alligned relative to a "leader" gameobject, so they can make a square. I store them in a list and change their position with an offset according to their list position. The problem is that the objects get alligned in world positions, not including the "leader" gameobject's rotation. Any help?
Here's a drawing of what I mean:
This is my script:
//more stuff...
var posToGo : Vector3 = hit.point;
for (var l : int = 0; l < man.selectedUnits.Count; l++)
{
if(man.selectedUnits.IndexOf(gameObject) == 0)
{
offX = 0;
offZ = 0;
}
else if(man.selectedUnits.IndexOf(gameObject) == 1)
{
offX = 2;
offZ = 0;
}
if(man.selectedUnits.IndexOf(gameObject) == 2)
{
offX = -2;
offZ = 0;
}
else if(man.selectedUnits.IndexOf(gameObject) == 3)
{
offX = 0;
offZ = -2;
}
if(man.selectedUnits.IndexOf(gameObject) == 4)
{
offX = 2;
offZ = -2;
}
else if(man.selectedUnits.IndexOf(gameObject) == 5)
{
offX = -2;
offZ = -2;
}
if(man.selectedUnits.IndexOf(gameObject) == 6)
{
offX = 0;
offZ = -4;
}
else if(man.selectedUnits.IndexOf(gameObject) == 7)
{
offX = 2;
offZ = -4;
}
if(man.selectedUnits.IndexOf(gameObject) == 8)
{
offX = -2;
offZ = -4;
}
}
posToGo.x += offX;
posToGo.z += offZ;
StartCoroutine(Motion(posToGo));
//more stuff...
function Motion(pos : Vector3)
{
while(Vector3.Distance(transform.position, pos) > 0.1)
{
animation.CrossFade("run");
var targetRotation = Quaternion.LookRotation(pos - transform.position);
transform.rotation = Quaternion.Slerp (transform.rotation, targetRotation, Time.deltaTime * 10);
transform.position = Vector3.MoveTowards(transform.position, pos, Time.deltaTime * movementSpeed);
if(Vector3.Distance(transform.position, pos) <= 0.1)
{
animation.CrossFade("idle");
}
yield;
}
}
Answer by PrisVas · Feb 05, 2015 at 02:25 PM
By the image, I imagine that the leader is rotated. So you could rotate the leader to zero, then make the others as children of the leader, and then rotate back. So the cheildren will follow the parent(leader) rotation.
Yes, the leader gets rotated as he walks to the point I clicked. (It's an RTS game). If I make the other gameObjects/units children of the leader, they will have a strange motion path to walk. Is there any way so I can calculate the position of the leader offseted by X units relative to his rotation?
I thing it could work with transform.forward, transform.right or transform.up to get the side os the leader, and then send the unit there. something like posToGo = transform.right * distance
I did not try that, transform.right should get the side of the leader, even if rotated
Answer by daneislazy · Feb 05, 2015 at 05:55 PM
You can use transform.right to get a local relative right vector from the transform then add that to the transform position to get world co-ords. Since your picture shows z,x coordinates you might have to play around to figure out which ones you need, and probably set up some variables to store them in for easier coding. If your z,x axis is correct you would have to have the camera under the x/z plane looking up so I wonder if it's not quite accurate(probably just mixed up x & z that would make sense). But anyways you can get a relativeRight = leaderTransform.right;
and relativeDown = leaderTransform.back;
variable (or .forwards to keep using negative values) then use that to set positions like
posToGo = leaderTransform.position + (relativeRight * offX) + (relativeDown * offZ);
Hope that helps!
Hmm... The problem is that the leader is moving as well, so the other units will calculate their destination accordingly to the position of the leader before he gets to his destination
Ahh, yea that is a bit trickier. If the leader has the correct rotation/facing when the script is run just use the leader's target destination in place of leaderTransform.position. If not and the group is moving in a straight line you can get a forwards relative vector by taking the (leaderTargetPosition - leaderCurrent.Position).Normalized
then a relative right vector is just a transposition of the z & x values into a new Vector3(relFor.z, y, -relFor.x);
.(also works if you know what forward should be when they arrive)
But another solution is to make 8 empty child objects attached to the leader and in the right formation. Then just have the followers always follow their corresponding empty around.
Answer by Dawdlebird · Sep 22, 2017 at 08:22 AM
Old thread, but for those that stumble upon this and would like a quick way to have a position/direction relative to a transform; Unity has build-in functions called Transform.TransformPoint and Transform.TransformDirection. These will convert any vector3 position or direction to be relative to whatever transform you apply these to. In your case the TransformPoint will suffice.
Example vector3 posOffset = new Vector3(1.0f, 0f, -1.0f); // this is your fixed relative position to the leader
vector3 posGoTo = leaderTransform.TransformPoint (posOffset); // this one you keep updating as the leader moves
Your answer
Follow this Question
Related Questions
Local Lerp to origin 1 Answer
Rigidbody move relative position ? 2 Answers
Get child position in world space 4 Answers
Move object on local axis instead of world axis after rotation 0 Answers
Accessing local system ( File Browser ) 2 Answers