Moving and rotating camera around the ball

Hello everyone,
This is my first question here and I hope I’m doing it right. So, what I want is to have camera behind player. Player is sphere. I have set offset and camera is on set distance behind the player. Than I want to move player ahead when I press up arrow (this I can do on straight line). Problems start when I want to rotate. SO when I press left/right arrow keys, I would like that player turns and that camera rotates behind him. So when I press up arrow palyer will go forward again, and not on same axis as before turn.

I have found answers on here about this, but not one was combination of forward+rotation movement. So for now I have ballController from roll-a-ball tut:

public class BallControl : MonoBehaviour {

    public float speed;
    public float turnSpeed;

    private Rigidbody rb;

    // Use this for initialization
    void Start () {
        rb = GetComponent<Rigidbody>();
    }
   
    // Update is called once per frame
    void FixedUpdate () {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");
        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
        rb.AddForce(movement*speed);
    }
}

and camera offset and some try of rotation

public class CameraController : MonoBehaviour {

    public GameObject player;
    private Vector3 offset;

    // Use this for initialization
    void Start () {
        offset = transform.position - player.transform.position;
    }

    void LateUpdate() {
        transform.position = player.transform.position + offset;

        transform.RotateAround(transform.parent.position, new Vector3(0,1,0),10*Time.deltaTime);
    }

}

Could someone point me where I am wrong. Since at the moment my camera rotates on Z and Y axis?

Thank you,
Sasa

Not saying there is anything wrong with your approach, but have you considered attaching the camera to an empty object, and offsetting the camera. Then you can just rotate the object? In this video, I added a cube to simulate the “empty object”, the camera is a child of the cube, and all I do is rotate the cube.

Thanks Eternal, but yes, I have this setup at the moment. Sphere->ChildEmptyObj->ChildCamera. But as soon as I click play, my camera starts to rotate even without any keypress.
I’m lost, tried bunch already. I’ll give it some rest and then try again later.

Do you want the Camera to always be behind the Sphere(Player) in the same spot and just rotate with it? If so, don’t put any scripts on the Camera. Just make it a Child (of the Sphere/Player), and offset it like 0, 1.5, - 3 with a 20 degree X rotation.

The add a script like this to the Sphere(Player).

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Forum_Player : MonoBehaviour {

    public float moveSpeed = 5.0f;
    public float turnSpeed = 50.0f;

    void Update () {

        float w_Input = Input.GetAxis ("Vertical") * moveSpeed; //WS or UP/Down
        w_Input *= Time.deltaTime;
        float rotation = Input.GetAxis ("Horizontal") * turnSpeed;// AD or L/Right
        rotation *= Time.deltaTime;

        transform.Translate (0, 0, w_Input);
        transform.Rotate (0, rotation, 0);

    }
}

Example Video

Yes, that was the problem. I didn’t need to do anything on Camera except making it a child. Thank you.

Just to go further into the issue. When I tested it, as soon as I hit the wall or anything my ball starts rotating on all axises and that makes camera go al around again. Shouldn’t line 18 from your script prevent this?

I have tried to prevent it by adding this after line 18

playerX = transform.eulerAngles.x;
        playerY = transform.eulerAngles.y;
        playerZ = transform.eulerAngles.z;

        transform.eulerAngles = new Vector3 (playerX - playerX, playerY, playerZ - playerZ);

This works, but after contact, even if I let go all controls, ball continues to move very slowly. Is there some variable that I can look into to check what causes this?

With a Sphere Collider, what you’re running into now is simple physics. On your Sphere Rigidbody (If you don’t have one, Add Component > Rigidbody or top menu Component>Physics>Rigidbody to your Sphere (Player). Once done you can Freeze Rotation (checkboxes in rigidbody x,y,z) as if to avoid rotating from Physics interactions.

Having a RigidBody allows Physics to work as well, so with one you will be able to use things like velocity.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Forum_Player : MonoBehaviour
{

    public float moveSpeed = 5.0f;
    public float turnSpeed = 50.0f;

    Rigidbody rb;
    public float jumpStrength = 3.0f;

    void Start ()
    {
        rb = GetComponent<Rigidbody> (); // get the RIGIDBODY
    }

    void Update ()
    {

        float w_Input = Input.GetAxis ("Vertical") * moveSpeed; //WS or UP/Down
        w_Input *= Time.deltaTime;
        float rotation = Input.GetAxis ("Horizontal") * turnSpeed;// AD or L/Right
        rotation *= Time.deltaTime;

        transform.Translate (0, 0, w_Input);
        transform.Rotate (0, rotation, 0);

        if (Input.GetKeyDown ("space")) {
            rb.velocity = new Vector3 (0, jumpStrength, 0);
        } //END IF

    }
    // End Update
}
  //EOC
1 Like

Ah, yes RIgidBody. Thanks a lot Eternal. I’ll go now and have some fun with this.