Unity 3D/C#: Rotate Camera around Object Given the Object's Height - c#

Given the following diagram, I am trying to accomplish the following. Does anyone know how to do this?
Notes:
The black line represents a sample trajectory of how the ball will (randomly) fly.
The camera should always remain the same distance away from the ball, indicated by the orange lines.
The Camera's height should be relative to the ball's height, but where the angle of the camera changes. (e.g. if the ball is high, the camera is above it, and if the ball is lower, the camera should have a lower angle.)
Extra Credit: Lowest possible angle should be 5 degrees, and highest possible angle should be 80 degrees.

Related

Make GameObject's Y Rotation be the same as the camera's

I have a Cinemachine Freelook camera and i want it similar to Skyrim, where the character's rotation follows where the camera is pointing, but only on the Y axis so that i can move my mouse and look at the character from up and down;
This video demonstrates how MrKrabs can move in 3 dimensions, but won't turn.
I already tried creating a blank object and putting it at the center of the character, then using transform.LookAt(Camera) to make it point to where the camera is, and finally getting the Y value of the object's rotation, inverting it with -transform.position.y and applying it to MrKrabs, but it didn't work: it was jittery and overall just a bad user experience, is there a way to turn the gameobject based on the camera's rotation? (having the camera always watching his back)
Something like this should do the trick.
transform.rotation = Quaternion.Euler(0, Camera.main.transform.eulerAngles.y, 0);
Beware that if your camera is a child of your object it will rotate with it.

Tracking Rotating Sprite

I am messing about in XNA and have run into a problem. I have a 48 * 48 sprite that I can keep track of its location in the game world by the top left corner of the sprite.
I want to be able to rotate the square and still keep track of the same point. For instance if I rotate 90degrees clockwise and the orginal X position was 200 the new X position should be 200 + 48(the size of the width of the image). Its fine for 90 degrees I am able to work that out in my head but each one in between is the problem!
I know there is probably some kind of formula to work this out.
Any help would be great! Oh the square is rotating on its center.
I'm just using spriteBatch.Draw()
spriteBatch.Draw( animations[currentAnimation].Texture,
Camera.WorldToScreen(WorldRectangle),
animations[currentAnimation].FrameRectangle,
color, rotationScale , new Vector2((float)frameHeight/2, (float)frameWidth/2), effect, TileMap.characterDepth);
If you have to keep track of a moving rotating sprite you can't use the top left corner, but its centroid. You already draw your sprite using the centroid to rotate it.
The problem is that the second parameter of your Draw call is a Rectangle, you sholud use a Vector2 position, instead.
You're building your application on top of a 3D graphics library. 3D graphics libraries are very good at solving this kind of problem! Break it down into smaller operations and let the library do the work for you.
First: it's easiest to think about these kinds of questions when you're working in model space rather than world space. In other words: you don't need to worry about where the rotating point is in absolute terms, you only need to worry about where it is relative to the untransformed model (in this case, your sprite without any rotation or translation).
So where is that? Simple:
var pt = new Vector3(-frameWidth / 2f, -frameHeight / 2f, 0f);
Your point of origin is the center of your sprite, so the center of your sprite in model space is (0, 0). This means that the top left corner of your sprite is half the width of the sprite in the negative x direction, and half the height of the sprite along the negative y direction.
Now create an object that represents the desired transformation. You can do this by creating a rotation matrix using XNA's built-in methods:
var transformation = Matrix.CreateRotationZ(MathHelper.ToRadians(90f));
Now apply the transformation to your original point:
var transformedPt = Vector3.Transform(pt, transformation);
This is still in model space, remember, so to get world coordinates you'll need to transform it into world space:
var transformedWorldX = transformedPt.X + spritePosition.X;
var transformedWorldY = transformedPt.Y + spritePosition.Y;
And there you go.

C# maths, collision detection, xna

Im doing collision detection in a game.
All the surfaces are orthagonal so I only need to determine which face of an obstacle my moving object has collided with.
I have the rectangle defining the intersection of the two objects and the vector representing the moving objects speed and direction of movement.
I reckon I need to translate the intersection rectangle along my moving objects vector until the intersection becomes a line, then I'll know which face was collided with 1st.
I have no idea how to do this mathematically of programatically however
Calculate the vector from (the corner of the obstacle internal to your object) to (the corner of your object internal to the obstacle). Whichever "side" of this vector your movement vector is on gives the "side" that touched first. If they have the same angle, the corner touched first.
E.g. here your movement vector is at about 260 degrees and then calculated vector is at about 240 degrees. Anticlockwise from calculated to movement is 20 degrees, clockwise is 340 degrees. Thus the anticlockwise side (bottom) collided first.
You need able to tell which two sides are in question, and which is "clockwise" and "anticlockwise" - I hope this is trivial.
You can compare the aspect ratio of the velocity vector to the aspect ratio of the intersection rectangle.
For this particular example, if the velocity vector is steeper than the intersection rectangle (i.e. defines a taller and skinnier rectangle), then the collision was on the bottom face.
If the velocity vector is shallower, then the collision was on the left face of the moving rectangle.
If the velocity vector is the same aspect ratio as the intersection rectangle (i.e. the velocity lays on the diagonal of the intersection rectangle), then they collided on the corners.
Actually I may have figured it out...
Find the point on the intersection rectangle that isnt on the objects
rectangle
draw a line from there in the vectors direction
whatever side it intersects with is the side that collided 1st

XNA Sprite Rotation Point

I'm busy with a little topdown shooter in XNA. Now I have a little Mathematical problem:
I have a sprite, a human that's holding a 9mm. Now the sprite looks at the mouse cursor.
When I shoot, I want to show a little muzzle flash # the end of the gun barrel. However, the coordinates of the end of the barrel will change when you rotate the character.
How can I get the correct coordinates in a sprite that is the end of the barrel when for example the end of the barrel is 14px above a players head?(topdown)
So basicly I need to know how to get coordinates of a certain point in a circle that has an certain angle with the orgin.
Thanks!
x=orig.x+cos(alpha)*r;
y=orig.y+sin(alpha)*r;
Where alpha is the angle between the x axis and the line extending the barrel; r is the radius of the circle (the lenght of the barrel).
One or both of the +s might have to be replaced with '-', depending on the orientation of the coordinate system (or play around with adding multiples of 90 degrees (up to 270) to alpha until you get it right).

moving on terrain - preventing move to high places xna

I have a fps camera and a model of a gun that follows her, and I have a terrain, the camera is moving on the terrain just fine, but I have a problem, I want to stop the movement if the camera is moving to high place (if it tries to move to a cliff or another high place I want to stop this option of moving to very high places) I dont mean preventing to move on high places I mean only when there is very high slope, hope you will understand and will be able to help!
If you are able to get information from the terrain where you are walking on, it is also possible to get information on the angle of the terrain.
The terrain exists out of different triangles, since it is a mesh. Every triangle has 3 vertices, but also has a so called: normal.
The normal of the face, is the direction that is pointing upwards. With simple angle calculations, you can check if the angle is too steep or not.
// in pseudo code:
public bool TooSteep(Vector3 position, float maxAngle)
{
// get your information from the terrain
// there is probably some function, or you have to write it,
// that returns the normal from the terrain
Vector3 normal = myTerrain.GetNormal(position);
// then we calculate the angle between the 'up'-vector and our normal vector
if (Vector3.Angle(normal, Vector3.up) > maxAngle)
return true;
else return false;
}
So suppose that our max angle is 45 degrees and we have a very steep normal. The angle between the up-vector and the normal will be large. Larger than our maxAngle and will therefore return: yes, it's too steep.

Categories