x


Slowly orbit camera on keypress

I used the generic orbit camera script and tweaked it to only rotate 90 degrees when either the left or right arrow key are pressed. It works well, the only thing now is I'd like to get it to kind of swing around as opposed to instantly snapping to the position.

I've read most of the other questions regarding orbiting objects but I'm pretty new to unity and don't really know how to apply them to my situation. Here's the code:

 var target : Transform;
 var targetOffset = Vector3.zero;
 var distance = 4.0;

var lineOfSightMask : LayerMask = 0;
var closerRadius : float = 0.2;
var closerSnapLag : float = 0.2;

var xSpeed = 200.0;
var ySpeed = 80.0;

var yMinLimit = 45;
var yMaxLimit = 45;

private var currentDistance = 10.0;
private var x = 0.0;
private var y = 0.0;
private var distanceVelocity = 0.0;

function Start () {
    var angles = transform.eulerAngles;
    x = angles.y;
    y = angles.x;
    currentDistance = distance;

    if (rigidbody)
       rigidbody.freezeRotation = true;
}

function LateUpdate () {
    if (target) {
        if(Input.GetKeyDown(KeyCode.LeftArrow)){
            x += 90;
      }
      if(Input.GetKeyDown(KeyCode.RightArrow)){
            x -= 90;
      }

      y = ClampAngle(y, yMinLimit, yMaxLimit);

        var rotation = Quaternion.Euler(y, x, 0);
        var targetPos = target.position + targetOffset;
        var direction = rotation * -Vector3.forward;

        var targetDistance = AdjustLineOfSight(targetPos, direction);
       currentDistance = Mathf.SmoothDamp(currentDistance, targetDistance, distanceVelocity, closerSnapLag * .3);

        transform.rotation = rotation;
        transform.position = targetPos + direction * currentDistance;
    }
}

function AdjustLineOfSight (target : Vector3, direction : Vector3) : float
{
    var hit : RaycastHit;
    if (Physics.Raycast (target, direction, hit, distance, lineOfSightMask.value))
       return hit.distance - closerRadius;
    else
       return distance;
}

static function ClampAngle (angle : float, min : float, max : float) {
    if (angle < -360)
       angle += 360;
    if (angle > 360)
       angle -= 360;
    return Mathf.Clamp (angle, min, max);
}

@script AddComponentMenu("Third Person Camera/Mouse Orbit"

)

more ▼

asked Jun 13 '12 at 02:24 PM

Falantar gravatar image

Falantar
2 1 1 2

(comments are locked)
10|3000 characters needed characters left

1 answer: sort voted first

Add this to your camera:

var object : Transform;
private var lastRotation : Vector3;
var rotateSpeed : float;
private var swing : float;
var toRight : boolean = false;
var toLeft : boolean = false;

function Start(){
lastRotation = transform.eulerAngles;
}

function Update(){
//Always look at the object
transform.LookAt(object);

//rotate 90 degrees to right
if(Input.GetKeyDown("right") && toLeft==false){
toRight = true;}
if(toRight && toLeft==false && Mathf.RoundToInt(transform.eulerAngles.y) != Mathf.RoundToInt(lastRotation.y)-90){
swing = Mathf.Abs(Mathf.RoundToInt(lastRotation.y)-90-Mathf.RoundToInt(transform.eulerAngles.y));
transform.RotateAround(object.position, -transform.up, rotateSpeed * swing *Time.deltaTime);}
if(Mathf.RoundToInt(transform.eulerAngles.y) <= Mathf.RoundToInt(lastRotation.y)-90){
toRight = false;
lastRotation = transform.eulerAngles;}

//rotate 90 degrees to left
if(Input.GetKeyDown("left") && toRight==false){
toLeft = true;}
if(toLeft && toRight==false && transform.eulerAngles.y != lastRotation.y+90){
swing = Mathf.Abs(Mathf.RoundToInt(lastRotation.y)+90-Mathf.RoundToInt(transform.eulerAngles.y));
transform.RotateAround(object.position, transform.up, rotateSpeed * swing * Time.deltaTime);}
if(Mathf.RoundToInt(transform.eulerAngles.y) >= Mathf.RoundToInt(lastRotation.y)+90){
toLeft = false;
lastRotation = transform.eulerAngles;}
}

Good luck with the project!

more ▼

answered Jun 13 '12 at 07:09 PM

Sokco816 gravatar image

Sokco816
85 2 2 4

Works like a charm! Much appreciated. I'm going to try and read through it to make sure I understand what's going on.

Jun 13 '12 at 07:13 PM Falantar

No problem, it's my pleasure!

Jun 13 '12 at 07:40 PM Sokco816

I noticed that the angle (y-axis) slightly diminishes each time the camera rotates. You can test it better by setting the speed up higher, like to about 10. I also noticed that the camera will rotate twice occasionally. Any idea on what might be the issue?

Jun 13 '12 at 07:51 PM Falantar

The camera sometimes rotates twice because it is moving so quickly, that it actually misses it's goal rotation and has to move on to the next goal rotation. To get it more precise, you can try changing

 if(toLeft && toRight==false && transform.eulerAngles.y < lastRotation.y+90){

to

 if(toLeft && toRight==false && Mathf.RoundToInt(transform.eulerAngles.y) < Mathf.RoundToInt(lastRotation.y)+90){

and

 if(toRight && toLeft==false && Mathf.RoundToInt(transform.eulerAngles.y) > Mathf.RoundToInt(lastRotation.y)-90){

to

 if(toRight && toLeft==false && Mathf.RoundToInt(transform.eulerAngles.y) > Mathf.RoundToInt(lastRotation.y)-90){
Jun 14 '12 at 01:17 AM Sokco816
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x3460
x3001
x724
x101

asked: Jun 13 '12 at 02:24 PM

Seen: 704 times

Last Updated: Jun 14 '12 at 01:19 AM