Pawn Mouse Movement (similar to Freelancer)

(holding down left click will rotate the ship to face the mouse cursor)

I’ve been trying for a lot of hours over the past couple of days to recreate movement like you see here in the video, but I’ve came across quite a few issues.

The first time I implemented it, it worked okay. I could hold down the left mouse button and my ship would rotate to look at the mouse. It did this instantly, so I added some interpolation in there and then it did it a bit smoothly. However there were a few issues.

[Issue 1]
When I tried to do a 360 (I’m not sure what the name of the axis is, but it involves the pitch), it stops when I’m looking directly up or directly down. I can’t do a full 360 and go upside-down. I read somewhere that this issue is called gimbal lock (so I believe) and can be solved by using quaternions. From what I remember I could make the ship rotate a full 360 degrees using this method, but the moment I changed it so that it was rotating to face my mouse cursor (the rotation for the mouse cursor is retrieved by getting the world vector for the cursor and then getting the rotator from that vector).

[Issue 2]
Upon moving the camera using my first method (I mean on the component), if I want to reposition the camera which is attached to a spring arm, it will mess up the movement.

[Issue 3]
In the game you can see how the ship will move to the left, right, top or bottom of the screen depending on how far away your mouse cursor is while your moving (so the larger the angle), the camera kind of lags behind the ship a little. I do not know how to achieve such an effect and I have no idea what you would call this effect.

[Issue 4]
With that set up the actual ship itself will rotate on all axes to face the mouse cursor and it will do it smoothly as well. Again, I have no idea how to achieve this effect. My pawn also stops rotating instantly as soon as you release the left mouse button which can look very unnatural and it doesn’t feel very nice to use.

I know I have covered a lot of issues here, but I really just need some guidance on the basic logic on how to do these things. I’m sure I could eventually tackle Issues 3 and 4, but the first two Issues I have no idea how to resolve and they’re the two main ones. Issue 1 is my priority though and I’ve been ripping my hair out trying to fix it.

If you have anything that you think can help me, please post.

Thank you,

  • Alex.

I’m having a hard time understanding exactly what your problem is on issue 1. Are you saying you are getting a crash or a that you are getting unreliable behavior? I believe you are right about gimbal lock. You are also right about using quaternions to fix it, but it’s hard to see what’s going wrong with your description.

Issue 2: The hiearchy should prevent moving the behavior you are describing. Moving the spring arm should not move what the camera is attached to. I THINK. I’m not an expert on this. But you should be able to move the camera by adjusting the spring arm values: TargetArmLength, RelativeRotation, etc.

Issue 3: You could try and use this value on your spring arm: SpringArmComponent->CameraLagSpeed = 3.0f;

Issue 4: If I remember correctly freelancer’s ship just always tried to steer towards the direction of the mouse. Maybe you could try to work in screen space. Get the screen position of the ship, get the screen position of the mouse, and then apply impulses or whatever, or order to steer the ship in the direction of the mouse. If you look at the video, the ship always stays in the middle of the screen and it maintains a constant turn rate depending on the distance of the mouse from the screen (The further the mouse from center, the faster the turn).

Hope that helps.

Your post was very helpful thank you. :slight_smile: The only real issue I have is that I need the ship to rotate to face the mouse cursor. If I use quaternions it’s fine unless I’m using it combined with the mouse position.

This is my current code:



	ASpaceGamePlayerController* PlayerController = (ASpaceGamePlayerController*) GetWorld()->GetFirstPlayerController();
	FTransform Transform;
	FRotator Rotation;
	FVector MouseLocation;
	FVector MouseDirection;

	PlayerController->DeprojectMousePositionToWorld(MouseLocation, MouseDirection);
	Rotation = MouseDirection.Rotation();

	Transform = this->GetTransform();
	Transform.SetRotation(Rotation.Quaternion());
	Transform.NormalizeRotation();

	this->SetActorTransform(Transform);


(I was messing around with stuff so that’s kind of rough. Before I had interpolation.)
To be honest if I could find a method that can apply some sort of force to rotate the object that would be even better. I could just make it apply that force until the ship aligns with the cursor.