Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm working on a project where you can draw lines between points. You select one point and drag the mouse onto another point and a line is drawn between them.

The line itself is a 3d object which is scaled to match the length between points. Currently you can draw lines that are horizontal or vertical. But drawing a line that starts and ends on a different level fail.

Horizontal and vertical work well. Horizontal and verticals work fine

Here the lines should go like indicated by the grey lines. But it adds the Z-rotation(Up/down) to the Y-rotation(direction) - (Setting the Y-rotation by hand to match the horizontal line results the line being drawn correctly).

When the height level changes, the lines go wrong.

            Vector3 dir = junctionFinderHit.transform.position - startPos;  /// Direction vector
            float angleY = Vector3.Angle(dir, new Vector3(1, 0, 0));
            float angleZ = Vector3.Angle(dir, new Vector3(0, 1, 0));

            //Debug.Log(angleY + " - " + AngleDir(new Vector3(0, 1, 0), dir, Vector3.up));

            Vector3 rotationVector = new Vector3(0,0,0);

            if (AngleDir(new Vector3(1, 0, 0), dir, Vector3.up) < 0)    /// 360 movement instead of 180
                rotationVector.y = 360-angleY;
            else
                rotationVector.y = angleY;

            /// -90 degrees to make it horizontal by default, negative to make it point to the right direction
            rotationVector.z = (angleZ-90f)*-1; 

            activeStick.transform.eulerAngles = rotationVector;

What do I need to do to get the rotations correct?

share|improve this question
1  
Consider using Transform.LookAt. –  chaosTechnician Mar 19 '13 at 8:05
    
@chaosTechnician Problem with the transform.LookAt is that it uses the forward vector(Z). A line's length is along the X-axis(ends up broadsiding), so this does not provide a solution. answers.unity3d.com/questions/22003/… –  Esa Mar 19 '13 at 8:41
1  
It does if you follow the Unity standard and make your lines go along the Z axis instead of X. If you're not going to orient it that way, can you explain how you're doing it to help ensure the math is done on the correct axes? (i.e., is +Y up and +Z right?) –  chaosTechnician Mar 19 '13 at 9:34
    
@chaosTechnician I changed to the Unity standard and brief tests show that it now works with LookAt. Thank you! But I'm still very interested in how you'd do it with math. The axes are: Y=Left/Right and Z=Up/Down. –  Esa Mar 19 '13 at 10:25
add comment

3 Answers

up vote 1 down vote accepted

Using the LookAt function is probably a better practical solution.

The reason that your code doesn't work is that your angleY calculation does not just get the angle in the horizontal plane, witch is what you need, but rather get the full angle including any vertical component. Projecting the direction on the horizontal plane before the calculation should solve the problem. I'm not able to test it, but I think this will give you the desired behaviour:

float angleY = Vector3.Angle(dir-Vector3.Project(dir,new Vector3(0, 1, 0)), new Vector3(1, 0, 0));
share|improve this answer
    
Using the projection made the angles just as I had planned them. –  Esa Mar 20 '13 at 5:33
add comment

There's a simple solution. Don't use angles. Just draw the vertices for the objects starting at the start point and finishing at the end point.

share|improve this answer
add comment

I just implemented in C a way to calculate the angle between two vectors A,B, given an origin C. Look at this Wikipedia article to understand where I am coming from. Here's the pseudo-code:

/*
    A dot B = |A| * |B| * cos(theta)
    Therefor theta = acos (A dot B / |A||B|)
*/
double Vector3AngleBetweenTwoPoints(Vector3 p1, Vector3 p2)
{
    return acos(Vector3DotProduct(p1, p2) / (Vector3Magnitude(p1) * Vector3Magnitude(p2)));
}

double Vector3AngleBetweenABWithCOrigin(Vector3 A, Vector3 B, Vector3 C)
{
    return Vector3AngleBetweenTwoPoints(Vector3Subtract(A, C), Vector3Subtract(B, C));
}

It's probably not the "proper" Unity way to do it, but it should help you understand how to calculate the angle between two vectors (if that's really the question you want answered :P).

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.