I am making a moving-sphere game from scratch. For the camera, I decided to control it through transform instead of rigidbody. I’ve tried several kind of approaches, but using a circle function around the target has offered me the most accurate rotation and following.
Why I move cam through Transform rather than Rigidbody
The motive I decided to implement cam moving through transform is that no matter how fast the ball is moving, or which direction the cam is looking: operating cam coords directly makes sure the cam is always over a perfect circle around the sphere. Also, due to my approach sets the camera position relative to the target’s position (the sphere) in every frame, this way the relative positions of both the camera and the sphere remain the same, independent from the sphere’s rotation.
I just couldn’t figure out how to achieve the same without overriding cam’s physics (ALERT: I am assuming that any translation or rotation through transform overrides physics, but I am not sure if this assumption is completely true).
Other approaches I tried and failed (for the record)
My approach works well, but…
…it becomes a problem when avoiding that the cam goes through walls, though. I tried tracing rays out of the wall, but then the cam makes an annoying ‘inside-out’ alternative move.
What can I do to prevent the cam going inside the walls, but at the same time mantaing this “perfect orbit” system? (for the record, I’d throw away my cam’s beautiful code if necessary) In other words, i would like that the orbit’s arc that is inside the wall, becomes a straight line stuck to the wall’s collider. Any tips for a better approach are welcome.
The code
Here is the script(in Javascript) I attached to the cam, for the sake of completeness:
#pragma strict
public var target : Transform;
public var height: float = 1.0f;
public var cam_distance: float = 4.0f;
public var orbit_speed: float = 40.0f;
private var trans: Transform;
function Start () {
trans = GetComponent.<Transform>();
}
function Update () {
//Initial positioning: later we change it depending on cam's angle
trans.position.x = target.position.x;
trans.position.y = target.position.y + height;
trans.position.z = target.position.z - cam_distance;
//Rotate the cam with A and D keys
if(Input.GetKey(KeyCode.A)) {
trans.Rotate(Vector3.up, -orbit_speed * Time.deltaTime);
}
if(Input.GetKey(KeyCode.D)) {
trans.Rotate(Vector3.up, orbit_speed * Time.deltaTime);
}
var base_angle : float;
// First, we get the cam's angle and turn it 180º
base_angle = (trans.rotation.eulerAngles.y + 180) % 360;
// Using trigonometry to translate the cam to the corresponding orbit position depending on angle
trans.position.x = cam_distance * Mathf.Sin(base_angle * Mathf.Deg2Rad) + target.position.x;
trans.position.z = cam_distance * Mathf.Cos(base_angle * Mathf.Deg2Rad) + target.position.z;
}
