0
\$\begingroup\$

I am building a space game that I would like to be controlled in third person.

Basically I would like the camera and the ship to remain tied together and remain the same distance from each other but for the camera to remain in the same position relative to the ship from the world perspective. This position of the camera relative to the ship can only be altered by mouse movement and not by ship movements.

Example of the functionality required would be:

  • User can rotate the the ship on the x, y, z axis and the camera can observe these rotations
  • User can position the camera on the right side of the ship using mouse movements and activate thrusters to observe the ship in the center of the screen and the background objects passing
  • User can fly ship into an asteroid and observe rigidbody collider cause the ship to bounce back and start to rotate violently in a direction but the camera will remain stable and at a constant distance to the ship

Explanation from technical sense:

  • The camera must remain at (0,0,-100) from the ship in world coordinates and this position only changed using mouse movement using local position
  • Putting camera and ship in the same player object allows to control local coordinate to (0,0,-100) but from world perspective the positing of the camera to ship actually changes

Currently the main problem is that I can only either have the camera stuck in a constant position relative to the ship (cannot change perspective with mouse) OR I can change perspective with mouse but the rigitbody physics get applied to camera (if I hit an asteroid the camera rotates with the ship)

I also tried to use a dummy camera to track mouse movements and to just add it to the constant camera but when the ship rotated very quickly it wasn't very accurate.

Any suggestions for what I could use in order to get accurate response?

\$\endgroup\$
  • 1
    \$\begingroup\$ This question appears to be off-topic because it is about debugging your code for you. Could you describe more what you're trying to do and less how you're trying to do it? \$\endgroup\$ – Anko Feb 12 '14 at 13:40
  • \$\begingroup\$ Thanks, I updated the post. Let me know if you have any suggestions. \$\endgroup\$ – Roman Khrystynych Feb 12 '14 at 20:52
  • \$\begingroup\$ I see a contradiction: It seems you'd like to have a camera that the player can freely rotate around a spaceship, like in this picture, but at the same time, you'd like the camera to rotate along with the ship. You can't have both, though you could could give each influence a different weight and calculate their influence based on those. Is that what you mean? \$\endgroup\$ – Anko Feb 12 '14 at 21:21
  • \$\begingroup\$ No, the camera should not rotate along with the ship, only around it while keeping consistent distance. \$\endgroup\$ – Roman Khrystynych Feb 13 '14 at 1:26
1
\$\begingroup\$

I think that you need is this:

//Calculate the vector between the camera and the ship
Vector3 direction = shipRef.position - transform.position;
//Assigns the vector to the camera
transform.forward = direction;
//Calculate the projection vector
Vector3 vpp = shipRef.position - shipRef.forward * CameraDistanceFromShip;
//calculate the new direction of the camera
Vector3 direction2 = vpp - transform.position;
//Apply the movement
transform.position += direction2 * CameraVelocity * Time.deltaTime;

This script is attached to the camera. You don't need to make the camera child of the ship

///* EDITED *///

So, I found This Orbit Camera.

I converted to c#, I think it is what you want.

public Transform target;
public float distance = 10.0f;

public float xSpeed = 250.0f;
public float ySpeed = 120.0f;

public float yMinLimit = -20;
public float yMaxLimit = 80;

private float x = 0.0f;
private float y = 0.0f;


public float smoothTime = 0.3f;

private float xSmooth = 0.0f;
private float ySmooth = 0.0f; 
private float xVelocity = 0.0f;
private float yVelocity = 0.0f;

private Vector3 posSmooth = Vector3.zero;
private Vector3 posVelocity = Vector3.zero;

void Start ()
{
    Vector3 angles = transform.eulerAngles;
    x = angles.y;
    y = angles.x;

    // Make the rigid body not change rotation
    if (rigidbody)
        rigidbody.freezeRotation = true;
}

void Update()
{
    //Calculate the vector between the camera and the ship
    Vector3 direction = target.position - transform.position;
    //Assigns the vector to the camera
    transform.forward = direction;
    //Calculate the projection vector
    Vector3 vpp = target.position - target.forward;
    //calculate the new direction of the camera
    Vector3 direction2 = vpp - transform.position;
    //Apply the movement
    transform.position += direction2 * 5 * Time.deltaTime;
}

void LateUpdate ()
{
    if (target)
    {
        x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
        y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;

        xSmooth = Mathf.SmoothDamp(xSmooth, (float) x, ref xVelocity, smoothTime);
        ySmooth = Mathf.SmoothDamp(ySmooth, (float) y, ref yVelocity, smoothTime);

        ySmooth = ClampAngle(ySmooth, yMinLimit, yMaxLimit);

        var rotation = Quaternion.Euler(ySmooth, xSmooth, 0);

        // posSmooth = Vector3.SmoothDamp(posSmooth,target.position,posVelocity,smoothTime);

        posSmooth = target.position; // no follow smoothing

        transform.rotation = rotation;
        transform.position = rotation * new Vector3(0.0f, 0.0f, -distance) + posSmooth;
    }
}

static float ClampAngle (float angle, float min, float max)
{
    if (angle < -360)
        angle += 360;
    if (angle > 360)
        angle -= 360;

    return Mathf.Clamp (angle, min, max);
}
\$\endgroup\$
  • \$\begingroup\$ How would you add mouse movement to the equation in order to allow it to rotate around the ship? i.imgur.com/kgWn0zs.png \$\endgroup\$ – Roman Khrystynych Feb 14 '14 at 16:56
  • \$\begingroup\$ I edited my answer @RomanKhrystynych. See if it is what you want. \$\endgroup\$ – Dyego Feb 15 '14 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.