+1 vote

Hello, I've been struggling with this for a long time and I hope someone can help.

I'm working on a 3D top down space shooter and would like to have the ship always pointing towards the mouse cursor location while using wasd for forward, backward and strafe side to side. I would like to do this with a rigid-body but can not for the life of me figure out how to properly. I know how to rotate towards the mouse not using rigid bodies but since this is a space shooter I would like to use the physic engine.

I am ray casting down to a terrain layer to find the mouse location then calculating the angle between the ship and mouse location. So my question is how do I properly rotate the ship to face towards the mouse cursor while having it play nice in the physics system?

This is what I currently have for my code (does not work as intended):

public override void _Input(InputEvent @event)
{
    if (@event is InputEventMouseMotion eventMouseMotion)
    {
        from = camera.ProjectRayOrigin(GetViewport().GetMousePosition());
        to = camera.ProjectRayNormal(GetViewport().GetMousePosition()) * rayLength;
    }
}

public override void _IntegrateForces(PhysicsDirectBodyState state)
{
    //Rotate to mouse
    if (from != Vector3.Zero && to != Vector3.Zero)
    {
        Godot.Collections.Dictionary ray;
        ray = state.GetSpaceState().IntersectRay(from, to);

        if (ray["collider"] is CSGMesh)
        {
            Vector3 resultVector = (Vector3)ray["position"];

            Vector3 objectPosition = Translation;
            resultVector = objectPosition - resultVector;

            float angle = new Vector2(resultVector.x, resultVector.z).AngleTo(new Vector2(objectPosition.x, objectPosition.z));

            Transform xform = state.Transform.Rotated(Vector3.Up, angle);
            state.Transform = xform;
        }
    }

    //Movement
    if (Input.IsActionPressed("player_move_forward"))
    {
        AddCentralForce(GlobalTransform.basis.z * speed);
    }
    else if (Input.IsActionPressed("player_move_backward"))
    {
        AddCentralForce(-GlobalTransform.basis.z * speed);
    }

    if (Input.IsActionPressed("player_move_left"))
    {
        AddCentralForce(GlobalTransform.basis.x * speed); 
    }
    else if (Input.IsActionPressed("player_move_right"))
    {
        AddCentralForce(-GlobalTransform.basis.x * speed);
    }
}
in Engine by (19 points)

1 Answer

0 votes
by (19 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.