- Home /
Create facing camera quad at runtime given start and end points
Hello, I want to create a quad at runtime given 2 points (the middle center edges) trying to face the camera at all time.
What I'm trying to achieve is a the flashlight effect, I want to throw a raycast from the flashlight (point A) to whatever object it touches (point B) and then create quad "trying to face" the camera.
Here's the quad I want to achieve.
A is the starting point of the quad and the middle point of vertices X and Y, and B is the ending point and middle point of vertices Z and V. I say trying because obviously the quad won't be able to face the camera like a billboard 100% because of the fixed points A and B, I don't know what calculations I have to do to get points X, Y, Z and V.
You are asking specifically for the coordinates of X,Y,Z,V. Is this really what you need, or are you just trying to put a quad in the position you specify in your question?
I need coordinates X,Y,Z and V given A and B which are the middle points of XY and ZB respectively. Put it this way, given 2 points A and B I need a plane which is oriented to the camera but the orientation can only be in the AB axis.
I understand what you are asking for. What I mean is that it would be easier to start with an already existing Quad either from the Game Object menu if you have a recent version or using the CreatePlane editor script, and then position and scale the quad to match the parameters rather than to calculate these specific points. Anyway I don't have time at the moment to write you an answer, but I'll answer this evening (morning now).
Is it possible to scale the quad to match the distance of AB segment?
Answer by robertbu · Sep 04, 2013 at 04:37 PM
I'm going to give you what I think you want rather than what you specificallly asked for. If it is not right, let me know, and I can revise. Normally with a rotation problem I've not solved before, I test it in Unity, but I'm traveling and don't have access to a computer with Unity at the moment. So to make this work you need to start with a vertical plane one unit on a side with the normals facing backwards. The latest versions of Unity have a Quad on the Game Object menu that will work, or you can use a plane created using the Unity Wiki CreatePlane script with a 'vertical' specification. 'v3A', and 'v3B' are two Vector3s containing your positions A and B from your diagram above:
var direction = v3B - v3A;
var midPoint = v3A + direction * 0.5;
var fromCamera = transform.position - Camera.main.transform.position;
transform.position = midPoint;
transform.localScale = Vector3(direction.magnitude, height, 1);
transform.forward = fromCamera;
transform.rotation = Quaternion.FromToRotation(transform.right, direction) * transform.rotation;
Note you did not specify the height of your Quad, so I just used 'height'. The code places a Quad at the midpoint between A and B, then it scale it so that it will span from A to B along the local 'x' axis, and finally it first rotates it so that it is billboarded to the camera and then does an additional rotation to align the local X (left and right of the plane) with the A to B direction.
Hmm, but this is rotating the object, what i meant was calculating the world coordinates of the vertices.
First, if you apply the above code to an empty game object, you can use the corners to calculate the four world coordinates. That is you can use Transform.TransformPoint() to the local coordinates of: (-0.5, 0.5, 0), (0.5, 0.5, 0), (0.5, -0.5, 0), and (-0.5, -0.5, 0). But you can also calculate them more directly:
var v3Right = (v3B - v3A).normalized;
var fromCamera = transform.position - Camera.main.transform.position;
var halfWidth fromCamera.magnitude / 2.0; var v3Up = Vector3.cross(v3Right,fromCamera).normalized.
var upperLeftCorner = -v3Right * halfWidth + v3Up * halfHeight;
var upperRightCorner = v3Right * halfWidth + v3Up * halfHeight;
var lowerLeftCorner = -v3Right * halfWidth - v3Up * halfHeight;
var lowerRightCorner = v3Right * halfWidth - v3Up * halfHeight;
I don't have access to Unity at the moment, so this is untested. You may have to fiddle a bit. In particular, I may have the parameters to the Vector3.Cross() backwards.
I've tried this but the quad starts way back point A but it finishes correct at B.
What do you mean by 'this'? Please post your code so I can take a look.
Your last code, but yeah now I'm getting the idea of the mathematics involved here.