XNA Creators Club Online
Page 1 of 1 (5 items)
Sort Posts: Previous Next

Correcting Bullet Spawning Offset(AKA, Matrix Problems)

Last post 5/25/2009 2:31 PM by Steve Hazen. 4 replies.
  • 5/24/2009 4:16 AM

    Correcting Bullet Spawning Offset(AKA, Matrix Problems)

    Hey all,

    I'm running into a problem, that I'm pretty sure is caused by what I'm doing with my matrices and how. I know that matrix math isn't communicative(I think thats the correct phrase, correct me if I'm wrong), in that A * B != B * A. I figured out that this line: 

    effect.World = mgBullet.mgBulletWorld *

    Matrix.CreateTranslation(mgBullet.mgBulletPosition);

    has something to do with my problem. I have an AI ship that is supposed to always face the player, move towards it, while firing a bullet. When it is a set distance from the player it is supposed to stop moving and just face the player and fire. It can only fire when the distance between it and the player is less than or equal to a distance I've set. The problem I've got is that when I fly around my ship, the place the bullets spawn is no longer from the ship, and aren't being fire even remotely close to the player. If I remove Matrix.CreateTranslation(mgBullet.mgBulletPosition), then everything works perfectly except for that my bullets don't actually move. I have tried switching the order of the multiplication, etc, but that just breaks it even worse.

     

            //This code is what determines the rotation of the AI ship, which is        
            //what we set the world matrix of the bullet to when we create it.  
            public void FollowTarget(Vector3 targetPos)  
            {  
                shipWorld = Matrix.Identity;  
                shipWorld.Forward = Vector3.Normalize(targetPos - myShipPos);  
                shipWorld.Right = Vector3.Normalize(Vector3.Cross(shipWorld.Forward, Vector3.Up));  
                shipWorld.Up = Vector3.Cross(shipWorld.Right, shipWorld.Forward);  
                shipWorld.Translation = myShipPos;  
            }                  
     
                    //This is the code that creates the bullet being fired, it is                
                    //located in the main game update function  
                    if (enemyClip >= 0 && !enemyMGBClip[enemyClip].isAlive) //&& (enemyFireDelay >= .1f))  
                    {  
                        soundBank.PlayCue("Machine_Gun3");  
                        enemyMGBClip[enemyClip].isAlive = true;  
                        enemyMGBClip[enemyClip].vel += 10;  
                        enemyMGBClip[enemyClip].mgBulletPosition = enemy.myShipPos;  
                        enemyMGBClip[enemyClip].mgBulletWorld = enemy.shipWorld;  
                        enemyClip -= 1;  
                        enemy.isFiring = false;  
                        enemyFireDelay = 0;  
                        if (enemyClip <= 0)  
                            enemyClip = 49;  
                    }  
            void DrawMGBullet(MGBullet mgBullet)  
            {  
                foreach (ModelMesh mesh in mgBullet.mgBullet.Meshes)  
                {  
                    foreach (BasicEffect effect in mesh.Effects)  
                    {  
                        effect.EnableDefaultLighting();  
                        effect.PreferPerPixelLighting = true;  
                        effect.World = mgBullet.mgBulletWorld * Matrix.CreateTranslation(mgBullet.mgBulletPosition);  
                        effect.Projection = cameraProjectionMatrix;  
                        effect.View = cameraViewMatrix;  
                    }  
                    mesh.Draw();  
                }  
            }  

    Here is most of the relevant code. I've check and recheck and re-rechecked everything and I cant for the life of me figure out why its doing what its doing. Please let me know if you need more of the code!

    Thanks in Advance!
    -Merc

     

  • 5/24/2009 2:00 PM In reply to

    Re: Correcting Bullet Spawning Offset(AKA, Matrix Problems)

    I don't see where you are updating the bullet's position.
    Each frame mgBulletPosition must be updated based on its own Matrix's forward vector and speed. Generally something like this:

    // in the bullet's update method
    float elapsed = gameTime.ElapsedGameTime.TotalSeconds;
    mgBulletPosition += mgBulletWorld.Forward * bulletVelocity * elapsed;//bulletVelocity being a float that represents the speed of the bullet in units per second
    mgBullet.mgBulletWorld.Translation = mgBulletPosition;

    // later, in the draw()
    effect.World = mgBullet.mgBulletWorld;
    Unlock The *I don't use 3 angles in a Vector3 for rotations anymore* Achievement Here
  • 5/24/2009 5:36 PM In reply to

    Re: Correcting Bullet Spawning Offset(AKA, Matrix Problems)

    to be a little more clear, you were right to remove the translation from the effect.World line but then it wasn't moving because the bullet's position wasn't being updated each frame which my first post addresses. the bullet's matrix.translation vector must be set each frame by the bullet position vector which is updated each frame.
    Unlock The *I don't use 3 angles in a Vector3 for rotations anymore* Achievement Here
  • 5/24/2009 11:33 PM In reply to

    Re: Correcting Bullet Spawning Offset(AKA, Matrix Problems)

    Ah, that fixed it. You were right, my bullet position update function was  incorrect, I wasnt multiplying by the timeElapsed. Now lets say that I want the bullet to shoot from a specific point on the model. Would I go in to a modeling program, add a bone there, and just reference that bone something like, mGBulletModel.Bones... where would I go from here? Can I just do Bones.myBoneName? And im assuming it has some sort of .Position property, so I would then add the bones position to the models, to get my location from which to spawn bullets?

    Thanks Steve!
    -Merc
  • 5/25/2009 2:31 PM In reply to

    Re: Correcting Bullet Spawning Offset(AKA, Matrix Problems)

    creating a bone for that is one way but also might be overkill. But it's not really the 'bone' you need but a Bone.Transform (the bone's matrix). Currently, when you set the bullet's initial position, you set it to the ship's position. If you are wanting to place the gun, say. on the right wing of your ship and you know how many units to the ship's right that is, and how many up or down it is, you can just set the initial position accordingly.

    //set up these offsets instead of creating a bone. values are arbitrary, adjust for your needs.
    float rightGunLateralOffset = 25f;//units that gun is from center of craft
    float rightGunVerticalOffset = 5f;
    float rightGunLongitudinalOffset = 2f;
    //create the 3 floats for a left wing gun or just make them negative values when used later


    //in your create bullet code block
    vector3 GunOffset = (enemy.shipWorld.Forward * rightGunLongitudinalOffset) +
                                (enemy.shipWorld.Up * rightGunVerticalOffset) +
                                (enemy.shipWorld.right * rightGunLateralOffset);
    enemyMGBClip[enemyClip].mgBulletPosition = enemy.myShipPos + gunOffset;
    enemyMGBClip[enemyClip].mgBulletWorld = enemy.shipWorld;
    enemyMGBClip[enemyClip].mgBulletWorld.Translation += gunOffset;//now both the position & world matrix have been adjusted for the offset

    So this is the quick & easy way but if your ship goes through arbitrary scaling transforms and you really don't know what the offset should be set to, then you might want to go back to your modeling app & create a 'gun' modelMesh  so it will indeed have its own bone transform and that transform is what you set mgBulletWorld to. If that's the direction you want to go, let us know & we'll help with the implementation there.




    Unlock The *I don't use 3 angles in a Vector3 for rotations anymore* Achievement Here
Page 1 of 1 (5 items) Previous Next