So, I’m trying to position an object’s clone relative to a plane according to the original’s position to another plane. However, I want the position and rotation of the cloned object to be behind the second plane:
Where A is the original and B is the clone. The arrows represent the objects’ transform.forward directions.
I’ve been looking into unity’s Matrix4x4 methods, and so far I’ve come up with:
var m = plane2.transform.localToWorldMatrix * plane1.transform.worldToLocalMatrix * objectA.transform.localToWorldMatrix;
Vector3 newPos = m.getColumn(3);
Quaternion newRot = m.rotation;
This places objectB exactly at objectA’s location (in front and facing the second plane). However, I’m not sure how to get from here to what I want.
Thanks for any help!
It’s late here so sorry if I misunderstood but I think you are trying to set object b to a position where it would be if plane 1 was a mirror so it is like a reflected position and rotation, is that correct? If so, Vector3 has a reflect method that will do the work for you.
//Get relative position for Obj1 to Plane1
var offset = plane1.transform.position - objA.transform.position;
//Relect Position
var newPos = plane1.transform.InverseTransformPoint(Vector3.Reflect(offset, plane1.transform.forward));
//Calc rotation difference
var rotation = objA.transform.rotation * Quaternion.Inverse(plane1.transform.rotation);
//Move object 2 to relative relfeclted position
objB.transform.position = plane2.transform.TransformPoint(newPos);
//Add the rotation difference
objB.transform.rotation = plane2.transform.rotation * rotation;
This is untested but I think it will do what you want, maybe?
3 Likes
I was having trouble getting the position right with the reflect method, however I looked up the TransformPoint and InverseTransformPoint functions you used and got a solution!
//First, get objectA's position relative to plane1 and find the same location and rotation relative to plane2
var m = plane2.transform.localToWorldMatrix * plane1.transform.worldToLocalMatrix * objectA.transform.localToWorldMatrix;
//If you want to keep the objects on the same side of their respective planes, you can just set objectB's position and rotation to m.getColumn(3) and m.rotation
//To take the new position, I took first found the relative position in plane2's local space
Vector3 localPos = plane2.transform.InverseTransformPoint(m.getColumn(3));
//Flipped it across the center of the plane
localPos = Vector3.Scale(localPos, new Vector3(-1f, -1f, -1f));
//And brought it back into world space
Vector3 newPos = linkedPortal.transform.TransformPoint(localPos);
//Then I had to adjust the y position because the two planes may not be at the same y position
float yoffset = plane1.transform.position.y - objectA.transform.position.y;
newPos.y = plane2.transform.position.y - yoffset;
//Finally, objectB is still facing the same direction as objectA, so rotation by 180 around the y axis
Quaternion newRot = Quaternion.Euler(m.rotation.eulerAngles.x, m.rotation.eylerAngles.y + 180f, m.rotation.eulerAngles.z);
objectB.transform.SetPositionAndRotation(newPos, newRot);
Works great now, so thanks for the help!