I'm trying to test some code to create Vector2 from its angle and its distance from the player position. I've looked up online how to do this and found the Vector2.Angle function to get the angle between two vectors, and the Vector2.Distance function to find the distance between two vectors, and I thought that I would be able to recreate the original (check_points[i]) Vector using these values, but when I run this code this is what I get (the white lines are from position to check_points[i], and the red lines are from position to other, which is the vector I'm trying to create from the values):
I would have expected the red and white lines to be the same, how can I make them this way?
float angle = Vector2.Angle(position, check_points[i]) * Mathf.Deg2Rad;
float dist = Vector2.Distance(position, check_points[i]);
Vector2 other = new Vector2(Mathf.Cos(angle) * dist, Mathf.Sin(angle) * dist);
Debug.DrawLine(position, check_points[i], Color.white);
Debug.DrawLine(position, other, Color.red);
The point of this is to track the corners of obstacles so I can generate a mesh from the triangles made between the corners and the player, to do line of sight checking. I've previously gotten it to work just casting a ray out for every degree of rotation (0-360), but I've read this tutorial and am trying to implement corner tracking to get it to look smoother: https://ncase.me/sight-and-light/
So the issue is that your position and check_point[i] are both positions .. you are not really taking directions here.
As noted in the comments e.g. a position of 0,0,0 wouldn't work at all since this vector has no direction so any angle between this and another position should be undefined.
What you want to do is take directions like Vector2.right and check_points[i] - position.
The next issue was that Vector2.Angle is always positive so you want to rather use SignedAngle here!
float angle = Vector2.SignedAngle(Vector2.right, check_points[i] - position) * Mathf.Deg2Rad;
float dist = Vector2.Distance(position, check_points[i]);
Then later note that a position vector has one more component than only an Angle and a Distance (which alone is only a direction): A StartPoint. You want to use this vector and start at your position (which now also can be 0,0,0) like
Vector2 other = position + new Vector2(Mathf.Cos(angle) * dist, Mathf.Sin(angle) * dist);
Debug.DrawLine(position, check_points[i], Color.white);
Debug.DrawLine(position, other, Color.red);
As you can see the white lines are exatly covered by the red ones so you only see the red lines recalculated from the angle and distance
Related
I have a camera, it is attached to the capsule, and rotates independently of it.
But I need the capsule to rotate along the Y axis following the camera. How to get the Y-axis rotation values of the camera? Tried through transform.rotation.y. But it gives an error.
Transform.rotation returns a Quaternion (see also Wikipedia - Quaternion) - it has not 3 but 4 components x, y, z and w!
=> Unless you know exactly what you are doing - which is almost never the case ^^ - you do never want to touch any of its components directly.
Unfortunately also the Transform.eulerAngles are not really reliable for your use case.
So what I would do is rely on Vector3 instead.
// take camera's forward vector
private forward = yourCamera.transform.forward;
// erase the Y axis => vector is now only on the XZ plane rotating around Y
forward.y = 0;
// rotate the capsule so its forward vector aligns with "forward"
yourCapsule.transform.rotation = Quaternion.LookRotation(forward);
// could also do
//yourCapsule.transform.forward = forward;
see also Quaternion.LookRotation
I have a player which is rotating around one point and I need to make an enemy aim in front of the player to actually shoot and hit the player.
In the figure below, the red point is my object that is moving around yellow point (enemy), and im trying to find out how I can make the enemy shoot ahead to actually hit the red. If I shoot at the last known location, the bullet passes behind red. I want to calculate a position in front of red to aim at so that I can actually hit red.
Thanks
The easiest way would be to calculate how much angle does the red object sweep per second. float A = 2 * Mathf.pi * Mathf.Rad2Deg * radius / red_linear_speed
Multiply that with how long it takes for yellow's bullet to reach the circle. That's the amount of angle that you have to aim ahead of red. FrontA = A * radius / bullet_speed
Rotate the vector from yellow to red by that angle and shoot. (assuming y is up) Vector3 shootDirection = Quaternion.AngleAxis(FrontA, Vector3.up) * (red.transform.position - yellow.transform.position).normalized
You may have to try -FrontA or Vector3.down at this last step to ensure you get the direction right.
You'll hit red, guaranteed!
Actually, i'm programming a little spaceshooter game (2.5D, Topdown View). The player can move along the XZ Axies and rotate the spaceship via right ministick (gamepad) or look to the cursor position (keyboard + mouse).
So, the movement and rotation (Y-Axies, Yaw) are seperated.
The whole thing works fine and looks good - but now i want to do the following:
If the spaceship moves sideways, it should rotate around the X / Pitch axies / lean left and right a bit, dependent on the sideways speed.
So, i have to compute the sideways speed from the following, given input:
Velocity Vector (Movement on X and Z Axies, Y is always '0')
Direction Vector (Rotation on Y Axies, X and Z are always '0')
And with the amount of sideways speed, i could rotate my spaceship around the X axies and multiply the resulting quaternion by the rotation around the y axies.
Anyone who has a solution for this?
Solution: Just "rotate" the velocity vector by the heading of the spaceship and use the "roll/z" axis as the sideways rotation about the X axis (the axis, where your ships nose points towards):
Quaternion Rotation = Quaternion.Euler(0, mHeading.y, 0);
Vector3 RealVeloctiy = Quaternion.Euler(0, -mHeading.y, 0) * Velocity;
float Angle = RealVeloctiy.z * 2.5f;
Rotation = Rotation * Quaternion.Euler(Angle, 0, 0);
A couple of possibilities:
Compare the velocity vector with local left direction of the spaceship (make sure they're in the same coordinate space first). You could use the Vector3.Angle function, or a dot product to do the comparison. Scale the result appropriately, and apply a local rotation around the forward axis.
Take user input directly. If the user is strafing in a direction, apply a roll value. You could use a float between -1 and +1, along with a rate of change. If they're strafing left, move the value towards -1 at that rate, or if they're strafing left, to +1. If neither key is being pressed, move the value back towards 0. (You might like to play around with the Lerp, SmoothStep and SmoothDamp functions too). Scale the value to apply an appropriate rotation about the relevant axis.
I'm trying to create an isometric (35 degrees) view by using a camera.
I'm drawing a triangle which rotates around Z axis.
For some reason the triangle is being cut at a certain point of the rotation
giving this result
I calculate the camera position by angle and z distance
using this site: http://www.easycalculation.com/trigonometry/triangle-angles.php
This is how I define the camera:
// isometric angle is 35.2º => for -14.1759f Y = 10 Z
Vector3 camPos = new Vector3(0, -14.1759f, 10f);
Vector3 lookAt = new Vector3(0, 0, 0);
viewMat = Matrix.CreateLookAt(camPos, lookAt, Vector3.Up);
//projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Game.GraphicsDevice.Viewport.AspectRatio, 1, 100);
float width = GameInterface.vpMissionWindow.Width;
float height = GameInterface.vpMissionWindow.Height;
projMat = Matrix.CreateOrthographic(width, height, 1, 1000);
worldMat = Matrix.Identity;
This is how I recalculate the world matrix rotation:
worldMat = Matrix.CreateRotationZ(3* visionAngle);
// keep triangle arround this Center point
worldMat *= Matrix.CreateTranslation(center);
effect.Parameters["xWorld"].SetValue(worldMat);
// updating rotation angle
visionAngle += 0.005f;
Any idea what I might be doing wrong? This is my first time working on a 3D project.
Your triangle is being clipped by the far-plane.
When your GPU renders stuff, it only renders pixels that fall within the range (-1, -1, 0) to (1, 1, 1). That is: between the bottom left of the viewport and the top right. But also between some "near" plane and some "far" plane on the Z axis. (As well as doing clipping, this also determines the range of values covered by the depth buffer.)
Your projection matrix takes vertices that are in world or view space, and transforms them so that they fit inside that raster space. You may have seen the standard image of a view frustum for a perspective projection matrix, that shows how the edges of that raster region appear when transformed back into world space. The same thing exists for orthographic projections, but the edges of the view region are parallel.
The simple answer is to increase the distance to your far plane so that all your geometry falls within the raster region. It is the fourth parameter to Matrix.CreateOrthographic.
Increasing the distance between your near and far plane will reduce the precision of your depth buffer - so avoid making it any bigger than you need it to be.
I think your far plane is cropping it, so you should make bigger the projection matrix far plane argument...
projMat = Matrix.CreateOrthographic(width, height, 1, 10000);
I'm writing a little test project. I have an object (with a position and bounding box) at an origin, and when something happens (say a mouse click/touch on phone), I want a line to be drawn from the origin object to the point.
Using a texture, I realise I'm going to have to use the rotation here, but have no idea how to work out how much to rotate the texture by. Any help would be appreciated.
So far, I have:
Vector2 Origin
Vector2 TouchPoint
and that's about it.
Thanks all!
Theres a simple formula for calculating an angle based on the X and Y coordinates:
float angle = Math.Atan2(TouchPoint.Y - Origin.Y, TouchPoint.X - Origin.X);
You can use this angle in an overload of the SpriteBatch.Draw() that accept an angle for the rotation.
See this for reference:
http://msdn.microsoft.com/en-us/library/ff433992.aspx
You may want to convert between degrees and radians:
float rad = deg * Math.PI/180;
float deg = rad * 180/Math.PI;