0

This doesn't accomplish what I want really. It basically just rotates around an empty until it hits a max. When I use this code, it moves fine. The "maximum" angle changes based on which way you decide to move first. Is there a way to set a maximum rotate around angle?

 using UnityEngine;
using System.Collections;

public class CameraMovement : MonoBehaviour {
    Transform rotAround;
    public float maxRotation = 0;
    // Use this for initialization
    void Start () {
        rotAround = GameObject.Find ("CamRotation").GetComponent <Transform> ();
    }

    // Update is called once per frame
    void Update () {
        if (Input.GetKey (KeyCode.D) && maxRotation < 52.0f) {
            transform.RotateAround (rotAround.position, Vector3.down, 100 * Time.deltaTime);
            maxRotation += 1;
        }
        if (Input.GetKey (KeyCode.A) && maxRotation > -52.0f) {
            transform.RotateAround (rotAround.position, Vector3.up, 100 * Time.deltaTime);
            maxRotation -= 1;
        }
    }
}
Danny Herbert
  • 2,002
  • 1
  • 18
  • 26
Mike Smith
  • 45
  • 1
  • 9
  • 100 * Time.deltaTime doesn't equal to 1, its a wrong assumption. Infact you can never tell what Time.deltaTime will be next frame, but its roughly 1 / 60, so 0.016667. – yes May 07 '16 at 09:33
  • @MikeSmith you should never count on `Time.deltaTime` being constant though. It's just the amount of time that has passed between the current and last frames. This makes it useful for regulating calculations with an irregular frame rate. – Danny Herbert May 07 '16 at 12:50
  • @yes Mm, sorry but I didn't. I thought it was the frame rate time, which can vary. I used 100 because at my original 50, the camera movement was too slow. Unless you were commenting to someone else. – Mike Smith May 07 '16 at 16:21
  • @MikeSmith but why did you only add 1 to rotation then. 100 / 60 is about 1.66667 and not 1. Also yes, Time.deltaTime is the time between 2 frames and it varies. But refer to gjttt1s answer, im sure it works ... – yes May 07 '16 at 16:45
  • @yes I didn't actually add 1 to any type of rotation. it's more like my fake bounds because I couldn't figure out how to set max rotate around angles. When the game starts, the cam is at default position and maxRotation, a pointless variable, is at 0. What it basically did was add 1 every time you moved. when it ran the Update() loop, it checked if the maxRotation variable was still within it's "bounds" if it was, you could move on that frame. but, for example, if you were greater than 90 or less than -90 the if statement would be false and you could not move in that direction anymore. – Mike Smith May 08 '16 at 07:47

2 Answers2

0

You are adding 1 to maxRotation each frame. You need to add Time.deltaTime instead otherwise your maxRotation will be reached at different times depending on your framerate. Just changing this should make your GameObject stop at the same angle no matter what way they turn.

That is the quick and simple way to do it. The other is to do some maths. finding the arctan (using Mathf.Atan2) of the difference of the rotateAround transform.position and the camera's start transform.position and then subtracting that from the camera's current transform.position minus the rotateAround position would give you the current angle (example below). You could then use this value to check if rotation should continue. See this answer for more info on how Atan2 works.

Note that Mathf.Atan2 returns the angle (in radians) between the vector passed to it and the X-axis (you probably don't want this). I think to find the angle between three vectors (which I think you do want) you will have to take the difference of their respective arctans (I've not checked this and it's pseudo-code for brevity). Like so:

float angle = 
Atan2(cameraStartPos.y - rotatePointPos.y, cameraStartPos.x - rotatePointPos.x) -
Atan2(cameraCurrentPos.y - rotatePointPos.y, cameraStartPos.x - rotatePointPos.x);

Even better than that, have unity do all that for you! use Vector3.Angle:

float angle = Vector3.Angle(rotateAround.position - cameraStart.position,  
                            rotateAround.position - cameraEnd.position));

Your final code could look something like:

public class CameraMovement : MonoBehaviour {

    Transform rotAround;
    private Vector3 startPosition;
    public float maxRotation = 0; // set this to the maximum angle in degrees

    void Start () 
    {
        rotAround = GameObject.Find ("CamRotation").GetComponent <Transform> ();
        startPosition = transform.position;
    }


    void Update () 
    {

        float currentAngle = Vector3.Angle(rotAround.position - startPosition,
                                           rotAround.position - transform.position));

        if (Input.GetKey (KeyCode.D) && maxRotation < currentAngle) 
        {
            transform.RotateAround (rotAround.position, Vector3.down, 100 * Time.deltaTime);
        }

        if (Input.GetKey (KeyCode.A) && maxRotation < currentAngle) 
        {
            transform.RotateAround (rotAround.position, Vector3.up, 100 * Time.deltaTime);
        }
    }
}

Note that the angle returned from Vector3.Angle will 'flip' when it reaches 180 so you can set your max angle to any value under 180 and it will stop at the same point on both sides.

Community
  • 1
  • 1
Danny Herbert
  • 2,002
  • 1
  • 18
  • 26
-1

Why don't you use the Random.Range(min,max) for the Maximum and Minimum Range, and then assign that angle in the Rotation.

  • even though the above code currently probably shows a seemingly random behavior, the OP didnt ask for random bounds, so how is random going to help? – yes May 07 '16 at 09:14