Hard Light Productions Forums

Off-Topic Discussion => Programming => Topic started by: Alienguard on December 31, 2012, 01:04:43 pm

Title: Need Help With Enemy Rotation
Post by: Alienguard on December 31, 2012, 01:04:43 pm
I am working in a 3D spaceship game and I am in the enemy class. For now I am working on XNA and if I manage to do a cool project then I will port it to unity. OK. The thing is that I am stuck with the following.
I want to create an enemy that will turn towards the player position at any of the X, Y and Z axis. I already have somewhat working code, but for some reason it only works in one axis only.

This is what I have so far.

Code: [Select]
private float TurntoFace(Vector3 position, Vector3 faceThis, float currentAngle, float turnSpeed)
        {
            float x = faceThis.X - position.X;
            float z = faceThis.Z - position.Z;
            float retval;

            float desiredAngle = (float)Math.Atan2(-z, x);
           

            float difference = desiredAngle - currentAngle;//WrapAngle(desiredAngle - currentAngle);
           

            if (difference > TURN_RATE)
            {
                look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(up_, TURN_RATE));
                retval = currentAngle + TURN_RATE;
            }
            else if (difference < -TURN_RATE)
            {
                look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(up_, -TURN_RATE));
                retval = currentAngle - TURN_RATE;
            }
            else
            {
                look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(up_, difference));
                retval = currentAngle + difference;
            }

           
            right_ = Vector3.Cross(look_, up_);
           
           
            return retval;
        }

As I said, this code makes the enemy turns towards the player on one axis only. But it won't make it roll or pitch towards it. I tried many other ways to achieve my desired results, but nothing seems to work. I modified the code in the follosing way.

Code: [Select]
private float TurntoFace(Vector3 position, Vector3 faceThis, float currentAngle, float turnSpeed)
        {
            float x = faceThis.X - position.X;
            float z = faceThis.Z - position.Z;
            float y = faceThis.Y - position.Y;
            float retval;

            float desiredAngle = (float)Math.Atan2(-z, x);
            float otherAngle = (float)Math.Atan2(-z, y);

            float difference = desiredAngle - currentAngle;//WrapAngle(desiredAngle - currentAngle);
            float otherDifference = otherAngle - currentAngle;

            if (difference > TURN_RATE)
            {
                look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(up_, TURN_RATE));
                retval = currentAngle + TURN_RATE;
            }
            else if (difference < -TURN_RATE)
            {
                look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(up_, -TURN_RATE));
                retval = currentAngle - TURN_RATE;
            }
            else
            {
                look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(up_, difference));
                retval = currentAngle + difference;
            }

            if (otherDifference > TURN_RATE)
            {
                look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(right_, TURN_RATE));
                retval = currentAngle + TURN_RATE;
            }
            else if (otherDifference < -TURN_RATE)
            {
                look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(right_, -TURN_RATE));
                retval = currentAngle - TURN_RATE;
            }
            else
            {
                look_ = Vector3.Transform(look_, Matrix.CreateFromAxisAngle(right_, otherDifference));
                retval = currentAngle + otherDifference;
            }
            right_ = Vector3.Cross(look_, up_);
           
            return retval;
        }

This stops the enemy from rotating towards the player and instead makes it rotate constantly, but still it won't pitch or roll. Any help will be appreciated.

Thanks
Title: Re: Need Help With Enemy Rotation
Post by: Aardwolf on January 01, 2013, 09:08:12 pm
You can use the dot product to find the angle between the look_ vector and the desired forward vector, and the cross product to find an axis perpendicular to both of them. Then you can use Matrix.CreateFromAxisAngle to come up with a rotation, and rotate look_, up, and right by it.

Not sure what the point of currentAngle or retval is :blah: Also I notice you've got a param turnSpeed but inside the function you're using TURN_RATE instead. Also, unless you make the enemy turn faster on pitch than on yaw (or vice versa), there's no reason it should have to roll to turn from one heading to another.