Orbit Camera Around Player And Add Force

I’m a beginner to unity, but I am liking what I have seen so far. I’ve started working on a project based off of the Roll-A-Ball tutorial in the Learn section, but I’m stuck!



I want the camera to rotate around the ball so players can get a better view of the area, but at the same time, have the ball move in the same direction as the camera. Right now I have a simple script the rotates the camera around, but when I press the up arrow key to move forward the ball looks like it’s rolling sideways. I have been trying to make a C# script that uses addForce to move it in the right direction, but have failed miserably.

I’m sorry if i’m not being specific enough, and would really be very grateful for any help

CameraRotate↓

using UnityEngine;
using System.Collections;

public class CameraRotate : MonoBehaviour{
	
	public Transform target;
	public float distance = 10.0f;
	public float sensitivity = 3.0f;
	
	private Vector3 offset; 
	
	void Start ()  {
		offset = (transform.position - target.position).normalized * distance;
		transform.position = target.position + offset;
	}
	
	void Update () {
		Quaternion q = Quaternion.AngleAxis(Input.GetAxis ("Mouse X") * sensitivity, Vector3.up);
		offset = q * offset;
		transform.rotation = q * transform.rotation;
		transform.position = target.position + offset;
	}
}

PlayerController↓

using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour {
	
	public float speed;
	
	private Rigidbody rb;
	
	void Start ()
	{
		rb = GetComponent<Rigidbody>();
	}
	
	void FixedUpdate ()
	{
		float moveHorizontal = Input.GetAxis ("Horizontal");
		float moveVertical = Input.GetAxis ("Vertical");
		
		Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
		
		rb.AddForce (movement * speed);
	}
}

At the moment, your “movement” Vector3 is strictly defined in world coordinates. If you want your control scheme to change with your camera’s perspective, you’re going to need to take the camera itself into account.

Therefore, in your PlayerController script, you’ll want to make a few adaptations:

public float speed;

// ADDED -- This will keep track of the direction your camera is looking
public Transform cam;

private Rigidbody rb;

// ...

// CHANGED -- This limits movement speed so you won't move faster when holding a diagonal. It's just a pet peeve of mine
Vector2 inputDirection = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
if(inputDirection.sqrMagnitude > 1)
{
	inputDirection = inputDirection.normalized;
}

// CHANGED -- This takes the camera's facing into account and flattens the controls to a 2-D plane
Vector3 newRight = Vector3.Cross(Vector3.up, cam.forward);
Vector3 newForward = Vector3.Cross(newRight, Vector3.up);
Vector3 movement = (newRight * inputDirection.x) + (newForward * inputDirection.y);

rb.AddForce(movement * speed);

Okay, now let’s break down the changes I made:

First, I added the camera’s transform to the script. It should be a simple drag-and-drop.

Second, I put a limit on the input. As I described in the commented script, it’s just my personal preference there.

Most importantly, third, I rebuilt a few axes. I created a guaranteed right-facing vector by calculating the vector perpendicular to the camera’s forward vector and the world’s up vector. While this would almost definitely result in the same vector as “cam.right” would, I use it to account for the possibility that the camera itself leans. This flattens the angle to a (near-) guaranteed “right” from the camera, relative to the world.

Then, I do the same for the forward vector. The “right” vector is now defined, so I make use of that to calculate a new forward, flat against the ground. The camera’s pitch is no longer relevant and will not be a factor in moving the ball.

Finally, I implement the new right and forward directions by multiplying them by the two-dimensional inputs. the horizontal axis input (x) is multiplied by the new “right” and the vertical axis input (y) is multiplied by the new “forward” to apply that input to those specific axes.

I can’t drag the camera to the player even though I defined transform called camera that’s why the player cannot build its new movement axes depending on the camera

Is there a way to stop the camera from going through walls with this script, and/or make it so you can control the camera’s Y-axis? @Eno-Khaon