Search Unity

Camera script like in EVE online

Discussion in 'Scripting' started by sicKTouch, Apr 6, 2015.

  1. sicKTouch

    sicKTouch

    Joined:
    Mar 29, 2015
    Posts:
    10
    Hi, i'm having troubles making a script for my camera, I need something like in EVE online but i can't make that work, i need my camera to stay in the same position even if my game object moves up or down, and i need to zoom in or out, can anyone help me with this?
     
  2. Cherno

    Cherno

    Joined:
    Apr 7, 2013
    Posts:
    515
    What do you mean by "stay in the same position even if my game object moves up or down"? Should it follow the game object, or not? If yes, then just make it a child of the GO. As for zooming, you would need to set the camera's http://docs.unity3d.com/ScriptReference/Camera-fieldOfView.htmlfield of view variable (increase or decrease it when the mouse wheel is turned up or down, for example).

    Also, what have you tried so far? Please show us your script.
     
  3. sicKTouch

    sicKTouch

    Joined:
    Mar 29, 2015
    Posts:
    10
    yes it should follow the object, but the script i made ,when i turn right, the camera turns right too...i want my camera only to rotate if i move my mouse if you understand me :)
     
  4. Cherno

    Cherno

    Joined:
    Apr 7, 2013
    Posts:
    515
    Take a look at the SmoothFollow script included with the Standard Assets, it will make the camera look at a target position of your liking at al times.
     
  5. sicKTouch

    sicKTouch

    Joined:
    Mar 29, 2015
    Posts:
    10
    It's good but i need the one where i can rotate it with the mouse
     
  6. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
  7. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    The only way to achieve this is to have a container for the player and move that around. When you play say a jump animation only the child objects move and not the parent. Then you camera will not move when the player jumps. When you jump however the parent collider must be offset based on the jump so it can move around terrain / obstacles and then you can reset the position once you have completed the jump. All of this can be done via animations. As far as the camera goes, I suggest moving the camera via spherical coordinates. If you try to relate x,y,z into making a circle you will have so many headaches. Instead transform into spherical points to make things easier. This way you can control the 'zoom' level via the radius of the sphere, and keep everything equidistance since each component x, y, z depends on phi the angle from the Z axis (in unity it would be Y since that is what is facing upwards).

    I made two scripts SphericalMovement.cs and Mouse.cs. SphericalMovement should be placed on the object you want to move around some given target like a camera for instance. The Mouse.cs is not necessary but is only needed to call the methods on SphericalMovement.cs to move the object around. These two scripts needs to be on the same object. By adding the Mouse.cs to the camera the SphericalMovement.cs component will also be added automatically.

    SphericalMovement.cs
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class SphericalMovement : MonoBehaviour {
    5.     [SerializeField] Transform target; // Target assinged via inspector.
    6.     [SerializeField] string targetTag; // Target to be found if the target to move about is not yet in the scene.
    7.     [SerializeField] float targetFindDelay = 0.1f; // Delay before searching for the target.
    8.     [SerializeField] float minDistance = 2.0f; // Minimum zoom distance.
    9.     [SerializeField] float maxDistance = 10.0f; // Maximum zoom distance.
    10.     [SerializeField] float rotateSpeed = 15.0f; // The speed the look rotation.
    11.     [SerializeField] float movementSpeed = 15.0f; // The speed of positioning via the spherical bounds.
    12.     [SerializeField] float thetaSteps = 2.0f; // The amount of degrees to move via each request.
    13.     [SerializeField] float phiSteps = 10.0f; // the amount of degree to move via each request.
    14.     [SerializeField] float upperBound = 0.0f; // Upper bound of the Phi angle from the Y axis.
    15.     [SerializeField] float lowerBound = 145.0f; // Lower bound of the Phi angle form the Y Axis.
    16.     [SerializeField] float zoomSpeed = 15.0f; // The speed at which the radius will change.
    17.  
    18.  
    19.     float r = 1.0f; // Distance from the target.
    20.     float thetaAngle = 0.0f; // Theta angle for horizontal rotations.
    21.     float phiAngle = 0.0f; // Phi angle for vertical rotations
    22.  
    23.     void Start() {
    24.         this.phiAngle = (this.lowerBound - this.upperBound) / 2.0f; // Set the Phi angle between the lower and upper bound
    25.         this.r = (this.maxDistance - this.minDistance) / 2.0f; // Set the starting radius between the min and max distance.
    26.  
    27.         // Check if the target is null.
    28.         if(this.target == null) {
    29.             // Check if the target tag is null or empty
    30.             if(string.IsNullOrEmpty(this.targetTag) == true) {
    31.                 // If the tag is empty throw a warning and destroy the component.
    32.                 UnityEngine.Debug.LogWarning(typeof(SphericalMovement).ToString() + " - Start(): 'targetTag' is empty ensure the field matches the tag of the GameObject you are looking for.");
    33.  
    34.                 Object.Destroy(this);
    35.             } else {
    36.                 // Find the target with the given tag.
    37.                 this.StartCoroutine(this.FindTarget());
    38.             }
    39.         }
    40.     }
    41.  
    42.     /// <summary>
    43.     /// Finds the target witht he given tag based on some delay via the inspector.
    44.     /// This perfect when the player has not yet spawned.
    45.     /// </summary>
    46.     IEnumerator FindTarget() {
    47.         // Wait before trying to find the target.
    48.         yield return new WaitForSeconds(this.targetFindDelay);
    49.  
    50.         // Look for the target.
    51.         GameObject t = GameObject.FindGameObjectWithTag(this.targetTag);
    52.  
    53.         // Check if the target is null
    54.         if(t == null) {
    55.             // Throw and error, could not find the target with the given tag.
    56.             UnityEngine.Debug.LogError(typeof(SphericalMovement).ToString() + " - FindTarget(): Could not find target with tag '" + this.targetTag + "'!");
    57.         } else {
    58.             // Assign the transform of the found target.
    59.             this.target = t.transform;
    60.             // Set the theta angle to be behind the forward facing of the target.
    61.             this.thetaAngle = this.BehindPosition;
    62.         }
    63.     }
    64.  
    65.     /// <summary>
    66.     /// Gets the Z position in rectanglular coordinates from spherical coordinates
    67.     /// </summary>
    68.     /// <value>The Z position.</value>
    69.     float ZPosition {
    70.         get {
    71.             return this.r * Mathf.Sin(this.thetaAngle * (Mathf.PI / 180.0f)) * Mathf.Sin(this.phiAngle * (Mathf.PI / 180.0f)) + this.target.position.z;
    72.         }
    73.     }
    74.  
    75.     /// <summary>
    76.     /// Gets the Y position in rectanglular coordinates from spherical coordinates
    77.     /// </summary>
    78.     /// <value>The Y position.</value>
    79.     float YPosition {
    80.         get {
    81.             return this.r * Mathf.Cos(this.phiAngle * (Mathf.PI / 180.0f)) + this.target.position.y;
    82.         }
    83.     }
    84.  
    85.     /// <summary>
    86.     /// Gets the X position in rectanglular coordinates from spherical coordinates
    87.     /// </summary>
    88.     /// <value>The X position.</value>
    89.     float XPosition {
    90.         get {
    91.             return this.r * Mathf.Cos(this.thetaAngle * (Mathf.PI / 180.0f)) * Mathf.Sin(this.phiAngle * (Mathf.PI / 180.0f)) + this.target.position.x;
    92.         }
    93.     }
    94.  
    95.     /// <summary>
    96.     /// Gets the behind positional angle.
    97.     /// </summary>
    98.     /// <value>The behind position.</value>
    99.     float BehindPosition {
    100.         get {
    101.             return (360.0f - this.target.eulerAngles.y) - 90.0f;
    102.         }
    103.     }
    104.  
    105.     void Update() {
    106.         if(this.target == null) return;
    107.  
    108.         this.transform.position = Vector3.MoveTowards(this.transform.position, this.TargetPosition, this.movementSpeed * Time.deltaTime);
    109.  
    110.         this.transform.rotation = Quaternion.Slerp(this.transform.rotation, Quaternion.LookRotation(this.target.position - this.transform.position), this.rotateSpeed * Time.deltaTime);
    111.     }
    112.  
    113.     /// <summary>
    114.     /// Sets this gameObject behind the forward facing of the target.
    115.     /// </summary>
    116.     public void SetBehindTarget() {
    117.         this.thetaAngle = this.BehindPosition;
    118.     }
    119.  
    120.     /// <summary>
    121.     /// Zoom in.
    122.     /// </summary>
    123.     public void ZoomIn() {
    124.         this.r -= this.zoomSpeed * Time.deltaTime;
    125.  
    126.         this.r = Mathf.Clamp(this.r, this.minDistance, this.maxDistance);
    127.     }
    128.  
    129.     /// <summary>
    130.     /// Zoom out.
    131.     /// </summary>
    132.     public void ZoomOut() {
    133.         this.r += this.zoomSpeed * Time.deltaTime;
    134.  
    135.         this.r = Mathf.Clamp(this.r, this.minDistance, this.maxDistance);
    136.     }
    137.  
    138.     /// <summary>
    139.     /// Reset zoom.
    140.     /// </summary>
    141.     public void ResetZoom() {
    142.         this.r = (this.maxDistance - this.minDistance) / 2.0f;
    143.     }
    144.  
    145.     /// <summary>
    146.     /// Moves the gameObject upward bounded by the sphereical coordinate system.
    147.     /// </summary>
    148.     public void MoveUp() {
    149.         this.phiAngle -= this.phiSteps;
    150.  
    151.         this.phiAngle = Mathf.Clamp(this.phiAngle, this.upperBound, this.lowerBound);
    152.         this.phiAngle = Mathf.Clamp(this.phiAngle, 0.1f, 179.9f);
    153.     }
    154.  
    155.     /// <summary>
    156.     /// Moves the gameObject downward bounded by the sphereical coordinate system.
    157.     /// </summary>
    158.     public void MoveDown() {
    159.         this.phiAngle += this.phiSteps;
    160.  
    161.         this.phiAngle = Mathf.Clamp(this.phiAngle, this.upperBound, this.lowerBound);
    162.         this.phiAngle = Mathf.Clamp(this.phiAngle, 0.1f, 179.9f);
    163.     }
    164.  
    165.     /// <summary>
    166.     /// Move the gameObject counter clockwise.
    167.     /// Reference Vector <1, 0, 1>
    168.     /// </summary>
    169.     public void CounterClockWise() {
    170.         this.thetaAngle += this.thetaSteps;
    171.  
    172.         if(this.thetaAngle >= 360.0f) {
    173.             this.thetaAngle = 0.0f;
    174.         }
    175.     }
    176.  
    177.     /// <summary>
    178.     /// Move the gameObject clockwise.
    179.     /// Reference Vector <1, 0, 1>
    180.     /// </summary>
    181.     public void ClockWise() {
    182.         this.thetaAngle -= this.thetaSteps;
    183.  
    184.         if(this.thetaAngle < 0.0f) {
    185.             this.thetaAngle = 360.0f;
    186.         }
    187.     }
    188.  
    189.     /// <summary>
    190.     /// Gets the target position.
    191.     /// </summary>
    192.     /// <value>The target position.</value>
    193.     public Vector3 TargetPosition {
    194.         get {
    195.             return new Vector3(this.XPosition, this.YPosition, this.ZPosition);
    196.         }
    197.     }
    198. }
    199.  
    Mouse.cs
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [RequireComponent(typeof(SphericalMovement))]
    5. public class Mouse : MonoBehaviour {
    6.     SphericalMovement sphericalMovement;
    7.  
    8.     void Start() {
    9.         this.sphericalMovement = this.GetComponent<SphericalMovement>();
    10.     }
    11.  
    12.     void Update() {
    13.  
    14.         if(Input.GetAxis("Mouse X") < -0.1f) {
    15.             this.sphericalMovement.CounterClockWise();
    16.         }
    17.  
    18.         if(Input.GetAxis("Mouse X") > 0.1f) {
    19.             this.sphericalMovement.ClockWise();
    20.         }
    21.  
    22.         if(Input.GetAxis("Mouse Y") > 0.1f) {
    23.             this.sphericalMovement.MoveDown();
    24.         }
    25.  
    26.         if(Input.GetAxis("Mouse Y") < -0.1f) {
    27.             this.sphericalMovement.MoveUp();
    28.         }
    29.  
    30.         if(Input.GetAxis("Mouse ScrollWheel") > 0.1f) {
    31.             this.sphericalMovement.ZoomIn();
    32.         }
    33.  
    34.         if(Input.GetAxis("Mouse ScrollWheel") < -0.1f) {
    35.             this.sphericalMovement.ZoomOut();
    36.         }
    37.  
    38.         if(Input.GetKeyDown(KeyCode.Mouse2) == true) {
    39.             this.sphericalMovement.ResetZoom();
    40.             this.sphericalMovement.SetBehindTarget();
    41.         }
    42.     }
    43. }
    44.  
     
    Last edited: Apr 7, 2015
  8. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,913
    All you have to do is change the Transform components Rotation (transform.localEulerAngles) value when you move the mouse and set it's Position (transform.position) to where the ship is.

    Make an Empty GameObject called "CameraParent" and make Main Camera the child. Move Main Camera to 0,0,-10 position. Now just rotate CameraParent based on mouse movement and position it where the ship is.
     
  9. sicKTouch

    sicKTouch

    Joined:
    Mar 29, 2015
    Posts:
    10
    Thanks guys, i didn't wanted to post my script that i use now because it's ridiculous and i already deleted it ;)
     
  10. SmokyRetroSauce

    SmokyRetroSauce

    Joined:
    Oct 24, 2016
    Posts:
    1
    I just wanted to say THANK YOU for providing this code for all of us. It works beautifully and you deserve more credit, again, thank you!