Only seeing 1 object out of an array of 3 in XNA - c#

Can anyone see where I am going wrong here.
I have a CameraObject class (its not a camera, simply the Model of a box to represent a "camera") that has a Model and a Position. It also has the usual LoadContent(), Draw() and Update() methods.
However, when I draw the array of Models, I only see 1 model on the screen (well, there might be 3 but they might all be in the same location)?
The Draw() method for the CameraModel class looks like this:
public void Draw(Matrix view, Matrix projection)
{
transforms = new Matrix[CameraModel.Bones.Count];
CameraModel.CopyAbsoluteBoneTransformsTo(transforms);
// Draw the model
foreach(ModelMesh myMesh in CameraModel.Meshes)
{
foreach (BasicEffect myEffect in myMesh.Effects)
{
myEffect.World = transforms[myMesh.ParentBone.Index];
myEffect.View = view;
myEffect.Projection = projection;
myEffect.EnableDefaultLighting();
myEffect.SpecularColor = new Vector3(0.25f);
myEffect.SpecularPower = 16;
}
myMesh.Draw();
}
}
Then in my Game1 class I create an array of CameraObject objects:
CameraObject[] cameraObject = new CameraObject[3];
Which I Initialize() - so each new object should be at +10 from the previous object
for (int i = 0; i < cameraObject.Length; i++)
{
cameraObject[i] = new CameraObject();
cameraObject[i].Position = new Vector3(i * 10, i * 10, i * 10);
}
And finally Draw()
Matrix view = camera.viewMatrix;
Matrix projection = camera.projectionMatrix;
for (int i = 0; i < cameraObject.Length; i++)
{
cameraObject[i].Draw(view, projection);
}
Where view and projection are from my Camera() class which looks like so:
viewMatrix = Matrix.Identity;
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), 16 / 9, .5f, 500f);
But I only see 1 object drawn to the screen? I have stepped through the code and all seems well but I cant figure out why I cant see 3 objects?
Can anyone spot where I am going wrong?
This is the code in my Camera() class to UpdateViewMatrix:
private void UpdateViewMatrix(Matrix chasedObjectsWorld)
{
switch (currentCameraMode)
{
case CameraMode.free:
// To be able to rotate the camera and and not always have it looking at the same point
// Normalize the cameraRotation’s vectors, as those are the vectors that the camera will rotate around
cameraRotation.Forward.Normalize();
cameraRotation.Up.Normalize();
cameraRotation.Right.Normalize();
// Multiply the cameraRotation by the Matrix.CreateFromAxisAngle() function,
// which rotates the matrix around any vector by a certain angle
// Rotate the matrix around its own vectors so that it works properly no matter how it’s rotated already
cameraRotation *= Matrix.CreateFromAxisAngle(cameraRotation.Right, pitch);
cameraRotation *= Matrix.CreateFromAxisAngle(cameraRotation.Up, yaw);
cameraRotation *= Matrix.CreateFromAxisAngle(cameraRotation.Forward, roll);
// After the matrix is rotated, the yaw, pitch, and roll values are set back to zero
yaw = 0.0f;
pitch = 0.0f;
roll = 0.0f;
// The target is changed to accommodate the rotation matrix
// It is set at the camera’s position, and then cameraRotation’s forward vector is added to it
// This ensures that the camera is always looking in the direction of the forward vector, no matter how it’s rotated
target = Position + cameraRotation.Forward;
break;
case CameraMode.chase:
// Normalize the rotation matrix’s forward vector because we’ll be using that vector to roll around
cameraRotation.Forward.Normalize();
chasedObjectsWorld.Right.Normalize();
chasedObjectsWorld.Up.Normalize();
cameraRotation = Matrix.CreateFromAxisAngle(cameraRotation.Forward, roll);
// Each frame, desiredTarget will be set to the position of whatever object we’re chasing
// Then set the actual target equal to the desiredTarget, can then change the target’s X and Y coordinates at will
desiredTarget = chasedObjectsWorld.Translation;
target = desiredTarget;
target += chasedObjectsWorld.Right * yaw;
target += chasedObjectsWorld.Up * pitch;
// Always want the camera positioned behind the object,
// desiredPosition needs to be transformed by the chased object’s world matrix
desiredPosition = Vector3.Transform(offsetDistance, chasedObjectsWorld);
// Smooth the camera’s movement and transition the target vector back to the desired target
Position = Vector3.SmoothStep(Position, desiredPosition, .15f);
yaw = MathHelper.SmoothStep(yaw, 0f, .1f);
pitch = MathHelper.SmoothStep(pitch, 0f, .1f);
roll = MathHelper.SmoothStep(roll, 0f, .1f);
break;
case CameraMode.orbit:
// Normalizing the rotation matrix’s forward vector, and then cameraRotation is calculated
cameraRotation.Forward.Normalize();
// Instead of yawing and pitching over cameraRotation’s vectors, we yaw and pitch over the world axes
// By rotating over world axes instead of local axes, the orbiting effect is achieved
cameraRotation = Matrix.CreateRotationX(pitch) * Matrix.CreateRotationY(yaw) * Matrix.CreateFromAxisAngle(cameraRotation.Forward, roll);
desiredPosition = Vector3.Transform(offsetDistance, cameraRotation);
desiredPosition += chasedObjectsWorld.Translation;
Position = desiredPosition;
target = chasedObjectsWorld.Translation;
roll = MathHelper.SmoothStep(roll, 0f, .2f);
break;
}
// Use this line of code to set up the View Matrix
// Calculate the view matrix
// The up vector is based on how the camera is rotated and not off the standard Vector3.Up
// The view matrix needs an up vector to fully orient itself in 3D space, otherwise,
// the camera would have no way of knowing whether or not it’s upside-down
viewMatrix = Matrix.CreateLookAt(Position, target, cameraRotation.Up);
}

I'm not seeing in your code where your cameraObject[n].Position (which is probably the only thing that uniquely differentiates the position between the three models) is affecting the effect.World property.
effect.World = transforms[myMesh.ParentBone.Index];
does not typically take individual model position into account.
Try something like this:
for (int i = 0; i < cameraObject.Length; i++)
{
cameraObject[i].Draw(view, projection, cameraObject[i].Position);
}
//later in the draw method
public void Draw(Matrix view, Matrix projection, Vector3 pos)
{
// ...
myEffect.World = transforms[myMesh.ParentBone.Index] * Matrix.CreateTranslation(pos);
// ...
}

CameraObject[1] & [2] are located at a greater positive Z value than camera[0] and the view matrix is located at the origin & looking in a negative Z direction (remember, the view matrix is the inverted equivalent of a world matrix).
Instead of setting your viewMatrix to Matrix.Identity, set it to this and you might see all three:
viewMatrix = Matrix.CreateLookAt(new Vector3(0,0,75), Vector3.Zero, Vector3.Up);

Related

Drawing collider boundaries (Unity)

everyone!
I ran into the problem. I need to draw a radius of enemy attack. The radius needs to be equal radius of SphereCollider that is hanging on it. I've tried to do it with the help of LineRenderer which draws circle. Yeah, actually it draws circle correctly, but the radius of my circle is less than radius of collider on it, despite the fact that I've given the value of a variable from the GetComponent().
Does anyone know what the problem is?
Part of my code:
float x;
float z;
float change = 2 * (float)Math.PI / segments;
float angle = change;
x = Mathf.Sin(angle) * radius;
_line.SetPosition(0, new Vector3(x, 0, Mathf.Cos(angle) * radius));
for (int i = 1; i < (segments + + 2); i++)
{
x = Mathf.Sin(angle) * radius;
z = Mathf.Cos(angle) * radius;
yield return new WaitForSeconds(drawSpeed);
_line.SetPosition((int)i, new Vector3(x, 0, z));
angle += change;
}
In the comments you mentioned that you get your radius from
float radius = _collider.radius;
where _collider is your SphereCollider.
So note that the SphereCollider.radius
The radius of the sphere measured in the object's local space.
The sphere radius will be scaled by the transform's scale.
It appears to me that either your object or one of its parent is somehow scaled differently than 1,1,1 in which case the actual final radius will be influenced by that scale.
You would need to scale the radius accordingly by the transform.lossyScale like e.g.
// Get the lossyScale
// this is the localScale of all parent objects and this localScale combined
var lossyScale = _collider.transform.lossyScale;
// find the biggest extends of the lossyScale
// if you already know they are always equal anyway simply use e.g. lossyScale.x instead
float maxScale = 0;
for(var i = 0; i < 3; i++)
{
maxScale = Mathf.Max(maxScale, Mathf.Abs(lossyScale[i]);
}
float radius = _collider.radius * maxScale;
It's a little hacky, but I've used a sphere outline sprite for just this sort of thing. Just put it on the game object and make sure it is scaled same as your collider. No need for fancy line drawing.
Don't use collider component for the enemy attack range!
Instead of adding a circle collider component you should a collider via code & physics.
What should you do?
This is an example of using a collider via code & physics:
float theCircleRadios = /* You radios */;
Collider2D[] detectedEnemiesColliders = Physics2D.OverlapCircleAll(theCirclePosition, theCircleRadios, DetectedLayers);
Then make your line lineRenderer radios == theCircleRadios.

In Unity Calculate Points a Given Distance Perpendicular to a Line at Angles on a Circle

I crafted a model to illustrate what I am trying to calculate. Given a line (vector) between two anchor points, I want to place one or more game objects a certain distance tangential to the midpoint of that vector and at designated angles (radians?) along a circle that is perpendicular to the vector.
In this illustration, an imaginary circle is placed at midpoint and perpendicular to the line between Anchor 1 and Anchor 2. I want to calculate the Vector3 positions of three points (P1, P2, and P3). The intent is to place objects at each of those points. The entire assembly will a gameobject that can rotate in space. (There will be a single game object with each object a child.)
I have scoured StackOverflow and the Unity communities and cannot find examples that help me make those three placements.
Any ideas?
Instead of trig, consider vector math and quaternions. Use cross products to find the 0 angle offset and quaternions to rotate it according to the angle. See comments for explanation.
public void PlaceObjects(Transform anchor1, Transform anchor2, float r,
List<Transform> objs, List<float> angles)
{
// lists must be non-null and same size
Debug.Assert(objs != null);
Debug.Assert(angles != null);
Debug.Assert(objs.Count == angles.Count);
// Find midpoint and axis of rotation
Vector3 midpoint = 0.5f * (anchor1.position + anchor2.position);
Vector3 axis = (anchor2.position - anchor1.position).normalized;
// What direction should the the "zero" offset be based on?
// Base it on the local up of the "assembly parent" this script is attached to?
// or Vector3.up if "0 angle" should approximate world up?
Vector3 upDirection = transform.up;
// Of directions perpendicular to the axis find the closest to upDirection
// See https://stackoverflow.com/a/57698547/1092820 for more information
Vector3 axisRight = Vector3.Cross(upDirection, axis);
if (axisRight == Vector3.zero)
{
// upDirection & axis are colinear, no unique "up-ish" exists.
// Just give up and don't move anything.
return;
}
Vector3 zeroOffsetDir = Vector3.Cross(axis, axisRight);
for (int i = 0 ; i < objs.Count ; i++)
{
Transform obj = objs[i];
float angle = angles[i];
// Find a rotation that describes how to rotate a "0 angle" offset into the one
// the current object needs
Quaternion rot = Quaternion.AngleAxis(angle, axis);
// Find the offset by rotating the "zero" offset, then extending it by the radius
Vector3 offset = r * (rot * zeroOffsetDir);
// Set the object's position based on its offset and the location of the midpoint
obj.position = midpoint + offset;
// Optionally, set the object's rotation based on its current forward and the new up:
// obj.rotation = Quaternion.LookRotation(obj.forward, offset);
}
}
For those interested, here's my Component adaptation of #Ruzihm's solution. The PlaceObjectsOnCirclePerpendicularToVectorLine component is placed on an empty game object.
using System.Collections.Generic;
using UnityEngine;
public class PlaceObjectsOnCirclePerpendicularToVectorLine : MonoBehaviour
{
// Adapted from https://stackoverflow.com/a/63308834/13052746, by Ruzihm.
public Transform anchor1;
public Transform anchor2;
public float radius;
public List<Transform> objs;
public List<float> angles;
private Vector3 anchor1PriorPosition;
private Vector3 anchor2PriorPosition;
// Start is called before the first frame update
void Start()
{
PlaceObjects(
anchor1,
anchor2,
radius,
objs,
angles);
}
// Update is called once per frame
void Update()
{
PlaceObjects(
anchor1,
anchor2,
radius,
objs,
angles);
}
public void PlaceObjects(
Transform anchor1,
Transform anchor2,
float radius,
List<Transform> objs,
List<float> angles)
{
if (anchor1PriorPosition == anchor1.position &&
anchor2PriorPosition == anchor2.position)
{
// The anchors haven't moved.
return;
} else
{
anchor1PriorPosition = anchor1.position;
anchor2PriorPosition = anchor2.position;
}
// lists must be non-null and same size
Debug.Assert(objs != null);
Debug.Assert(angles != null);
Debug.Assert(objs.Count == angles.Count);
// Find midpoint and axis of rotation
Vector3 midpoint = 0.5f * (anchor1.position + anchor2.position);
Vector3 axis = (anchor2.position - anchor1.position).normalized;
// What direction should the the "zero" offset be based on?
// Base it on the local up of the "assembly parent" this script is attached to?
// or Vector3.up if "0 angle" should approximate world up?
Vector3 upDirection = transform.up;
// Of directions perpendicular to the axis find the closest to upDirection
// See https://stackoverflow.com/a/57698547/1092820 for more information
Vector3 axisRight = Vector3.Cross(upDirection, axis);
//if (axisRight == Vector3.zero)
//{
// // upDirection & axis are colinear, no unique "up-ish" exists.
// // Just give up and don't move anything.
// return;
//}
Vector3 zeroOffsetDir = Vector3.Cross(axis, axisRight);
for (int i = 0; i < objs.Count; i++)
{
Transform obj = objs[i];
float angle = angles[i];
// Find a rotation that describes how to rotate a "0 angle" offset into the one
// the current object needs
Quaternion rot = Quaternion.AngleAxis(angle, axis);
// Find the offset by rotating the "zero" offset, then extending it by the radius
Vector3 offset = radius * (rot * zeroOffsetDir);
// Set the object's position based on its offset and the location of the midpoint
obj.position = midpoint + offset;
}
}
}
Here's what it looks like in the Scene view:
And here's what the component looks like in the inspector:
Again, brilliant, #Ruzihm! Exactly what I wanted!

How would you lerp the positions of two matrices?

In my code, I create 2 matrices that store information about two different meshes, using the following code:
Mesh mesh;
MeshFilter filter;
public SphereMesh SphereMesh;
public CubeMesh CubeMesh;
public Material pointMaterial;
public Mesh pointMesh;
public List<Matrix4x4> matrices1 = new List<Matrix4x4>();
public List<Matrix4x4> matrices2 = new List<Matrix4x4>();
[Space]
public float normalOffset = 0f;
public float globalScale = 0.1f;
public Vector3 scale = Vector3.one;
public int matricesNumber = 1; //determines which matrices to store info in
public void StorePoints()
{
Vector3[] vertices = mesh.vertices;
Vector3[] normals = mesh.normals;
Vector3 scaleVector = scale * globalScale;
// Initialize chunk indexes.
int startIndex = 0;
int endIndex = Mathf.Min(1023, mesh.vertexCount);
int pointCount = 0;
while (pointCount < mesh.vertexCount)
{
// Create points for the current chunk.
for (int i = startIndex; i < endIndex; i++)
{
var position = transform.position + transform.rotation * vertices[i] + transform.rotation * (normals[i].normalized * normalOffset);
var rotation = Quaternion.identity;
pointCount++;
if (matricesNumber == 1)
{
matrices1.Add(Matrix4x4.TRS(position, rotation, scaleVector));
}
if (matricesNumber == 2)
{
matrices2.Add(Matrix4x4.TRS(position, rotation, scaleVector));
}
rotation = transform.rotation * Quaternion.LookRotation(normals[i]);
}
// Modify start and end index to the range of the next chunk.
startIndex = endIndex;
endIndex = Mathf.Min(startIndex + 1023, mesh.vertexCount);
}
}
The GameObject starts as a Cube mesh, and this code stores the info about the mesh in matrices1. Elsewhere in code not shown, I have it so that the Mesh changes to a Sphere and then changes matricesnumber to 2, then triggers the code above to store the info of the new Sphere mesh in matrices2.
This seems to be working, as I'm able to use code like Graphics.DrawMesh(pointMesh, matrices1[i], pointMaterial, 0);
to draw 1 mesh per vertex of the Cube mesh. And I can use that same line (but with matrices2[i]) to draw 1 mesh per vertex of the Sphere mesh.
The Question: How would I draw a mesh for each vertex of the Cube mesh (info stored in matrices1) on the screen and then make those vertex meshes Lerp into the positions of the Sphere mesh's (info stored in matrices2) vertices?
I'm trying to hack at it with things like
float t = Mathf.Clamp((Time.time % 2f) / 2f, 0f, 1f);
matrices1.position.Lerp(matrices1.position, matrices2.position, t);
but obviously this is invalid code. What might be the solution? Thanks.
Matrix4x4 is usually only used in special cases for directly calculating transformation matrices.
You rarely use matrices in scripts; most often using Vector3s, Quaternions and functionality of Transform class is more straightforward. Plain matrices are used in special cases like setting up nonstandard camera projection.
In your case it seems to me you actually only need to somehow store and access position, rotation and scale.
I would suggest to not use Matrix4x4 at all but rather something simple like e.g.
// The Serializable makes them actually appear in the Inspector
// which might be very helpful in you case
[Serializable]
public class TransformData
{
public Vector3 position;
public Quaternion rotation;
public Vector3 scale;
}
Then with
public List<TransformData> matrices1 = new List<TransformData>();
public List<TransformData> matrices2 = new List<TransformData>();
you could simply lerp over
var lerpedPosition = Vector3.Lerp(matrices1[index].position, matrices2[index].position, lerpFactor);
And if you then need it as a Matrix4x4 you can still create it ad-hoc like e.g.
var lerpedMatrix = Matrix4x4.Translation(lerpedPosition);
or however you want to use the values.

How do you increase the translation speed after zooming in?

I have a control that zooms in and out, and pans. By clicking a choice of two buttons, the user may zoom in or out respectively. My issue is with the translations after zooming in or out: If I zoom out to about .2F, I have to click-pan multiple times to move the same distance I could have at base 0. I seemed to solved this by dividing the zoom by its self squared: z/(z*z) but that seems to transform the entire matrix - and I'm NOT translating the matrix with this on any line!
Here is my code:
Matrix mtrx = new Matrix();
mtrx.Translate(pan.X, pan.Y);
mtrx.Scale(zoom, zoom);
e.Graphics.Transform = mtrx;
// To-Do drawing code here
Basic notes:
Zoom increases and decreases by .12F on button click event
The control being painted on is an inherited UserControl class
The developing environment is C# 2010
The drawing code deals with two rectangles who's location is {0, 0}
I just want to be able to pan at the same speed as I can at base 0 (not zoomed in or out) when I am zoomed in or out a ways. ~ no motion-lag feelings
EDIT: I've updated the code above to an improved version of what I was dealing with before. This handles the panning speed for after zooming, but the new issue is with where the zoom is taking place: it's as if the point of zoom is being translated as well...
Edit: How I would do this in 3D (XNA):
public class Camera
{
private float timeLapse = 0.0f;
private Vector3 position, view, up;
public Camera(Vector2 windowSize)
{
viewMatrix = Matrix.CreateLookAt(this.position, this.view, this.up);
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.Pi / 4.0f,
(float)windowSize.X / (float)windowSize.Y, 0.005f, 1000.0f);
}
//Sets time lapse between frames
public void SetFrameInterval(GameTime gameTime)
{
timeLapse = (float)gameTime.ElapsedGameTime.Milliseconds;
}
//Move camera and view position according to gamer's move and strafe events.
private void zoomHelper(Vector3 direction, float speed)
{
speed *= (float)timeLapse; // scale rate of change
direction *= speed;
position.Y += direction.Y;
position.X += direction.X; // adjust position
position.Z += direction.Z;
view.Y += direction.Y;
view.X += direction.X; // adjust view change
view.Z += direction.Z;
}
//Allows the camera to move forward or backward in the direction it is looking.
public void Zoom(float amount)
{
Vector3 look = new Vector3(0.0f, 0.0f, 0.0f);
Vector3 unitLook;
// scale rate of change in movement
const float SCALE = 0.005f;
amount *= SCALE;
// update forward direction
look = view - position;
// get new camera direction vector
unitLook = Vector3.Normalize(look);
// update camera position and view position
zoomHelper(unitLook, amount);
viewMatrix = Matrix.CreateLookAt(position, view, up);
}
//Allows the camera to pan on a 2D plane in 3D space.
public void Pan(Vector2 mouseCoords)
{
// The 2D pan translation vector in screen space
Vector2 scaledMouse = (mouseCoords * 0.005f) * (float)timeLapse;
// The camera's look vector
Vector3 look = view - position;
// The pan coordinate system basis vectors
Vector3 Right = Vector3.Normalize(Vector3.Cross(look, up));
Vector3 Up = Vector3.Normalize(Vector3.Cross(Right, look));
// The 3D pan translation vector in world space
Vector3 Pan = scaledMouse.X * Right + -scaledMouse.Y * Up;
// Translate the camera and the target by the pan vector
position += Pan;
view += Pan;
viewMatrix = Matrix.CreateLookAt(position, view, up);
}
}
Used like this:
Camera cam; // object
effect.Transform = cam.viewMatrix * cam.projectionMatrix;
// ToDo: Drawing Code Here
try this:
Matrix mtrx = new Matrix();
mtrx.Scale(zoom, zoom);
mtrx.Translate(pan.X/zoom, pan.Y/zoom, MatrixOrder.Append);
e.Graphics.Transform = mtrx;
// To-Do drawing code here

control a spaceship in 3 axes in XNA

when i control the spaceship in 1 axis all is fine, that is, the depth(z) and the rotation on the z plane 360 degrees, so thats 2 axis. I also have a camera right behind it which i have to maintain its position. When the 3rd comes in place all go bad. let me show you some code:
Here is the part that fails:
draw method of spaceship :
public void Draw(Matrix view, Matrix projection)
{
public float ForwardDirection { get; set; }
public float VerticalDirection { get; set; }
Matrix[] transforms = new Matrix[Model.Bones.Count];
Model.CopyAbsoluteBoneTransformsTo(transforms);
Matrix worldMatrix = Matrix.Identity;
Matrix worldMatrix2 = Matrix.Identity;
Matrix rotationYMatrix = Matrix.CreateRotationY(ForwardDirection);
Matrix rotationXMatrix = Matrix.CreateRotationX(VerticalDirection); // me
Matrix translateMatrix = Matrix.CreateTranslation(Position);
worldMatrix = rotationYMatrix * translateMatrix;
worldMatrix2 = rotationXMatrix * translateMatrix;
//worldMatrix*= rotationXMatrix;
foreach (ModelMesh mesh in Model.Meshes) //NEED TO FIX THIS
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.World =
worldMatrix * transforms[mesh.ParentBone.Index]; ; //position
//effect.World =
//worldMatrix2 * transforms[mesh.ParentBone.Index]; ; //position
effect.View = view; //camera
effect.Projection = projection; //2d to 3d
effect.EnableDefaultLighting();
effect.PreferPerPixelLighting = true;
}
mesh.Draw();
}
}
For the extra axis the worldMatrix2 is implemented which i DONT know how to combine with the other axis. Do i multiply it? Also:
The camera update method has a similar problem:
public void Update(float avatarYaw,float avatarXaw, Vector3 position, float aspectRatio)
{
//Matrix rotationMatrix = Matrix.CreateRotationY(avatarYaw);
Matrix rotationMatrix2 = Matrix.CreateRotationX(avatarXaw);
//Vector3 transformedheadOffset =
//Vector3.Transform(AvatarHeadOffset, rotationMatrix);
Vector3 transformedheadOffset2 = Vector3.Transform(AvatarHeadOffset, rotationMatrix2);
//Vector3 transformedheadOffset2 = Vector3.Transform(transformedheadOffset, rotationMatrix2);
//Vector3 transformedReference =
//Vector3.Transform(TargetOffset, rotationMatrix);
Vector3 transformedReference2 = Vector3.Transform(TargetOffset, rotationMatrix2);
//Vector3 transformedReference2 = Vector3.Transform(transformedReference, rotationMatrix2);
Vector3 cameraPosition = position + transformedheadOffset2; /** + transformedheadOffset; */
Vector3 cameraTarget = position + transformedReference2; /** + transformedReference; */
//Calculate the camera's view and projection
//matrices based on current values.
ViewMatrix =
Matrix.CreateLookAt(cameraPosition, cameraTarget, Vector3.Up);
ProjectionMatrix =
Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(GameConstants.ViewAngle), aspectRatio,
GameConstants.NearClip, GameConstants.FarClip);
}
}
Lastly here is the method of the Game class Update:
spaceship.Update(currentGamePadState,
currentKeyboardState); // this will be cahnged when asteroids are placed in the game, by adding a new parameter with asteroids.
float aspectRatio = graphics.GraphicsDevice.Viewport.AspectRatio;
gameCamera.Update(spaceship.ForwardDirection,spaceship.VerticalDirection,
spaceship.Position, aspectRatio);
Somewhere in your code, you probably have methodology that manipulates and sets the variables 'ForwardDirection' & 'VerticalDirection' which seem to represent angular values around the Y & X axis respectively. Presumably you may intend to have a variable that represents an angular value around the Z axis as well. I'm also assuming (and your code implies) that these variables are ultimately how you store your spaceship's orientation from frame to frame.
As long as you continue to try to represent an orientation using these angles, you will find it difficult to achieve the control of your spaceship.
There are several types of orientation representations available. The 3 angles approach has inherent weaknesses when it comes to combining rotations in 3 dimensions.
My recommendation is that you shift paradigms and consider storing and manipulating your orientations in a Matrix or a Quaternion form. Once you learn to manipulate a matrix or quaternion, what you are trying to do becomes almost unbelievably easy.

Categories

Resources