Search Unity

Problem with a struct

Discussion in 'Scripting' started by AndrAla, Mar 26, 2017.

  1. AndrAla

    AndrAla

    Joined:
    Mar 11, 2017
    Posts:
    18
    Problem solved. Here is the working script:
    Code (csharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class CameraScript : MonoBehaviour {
    6.  
    7.     public GameObject target;
    8.     public Transform cameraPosition;
    9.     [HideInInspector] public Orientation angle;
    10.     public float sensitivity = 1;
    11.     public float minDistance = 0.75f;
    12.     float distance;
    13.     private Rigidbody mRigidbody;
    14.  
    15.     void Start () {
    16.         distance = Vector3.Distance (transform.position, target.transform.position + Vector3.up * 1.75f);
    17.         angle = new Orientation((target.transform.position + Vector3.up * 1.75f) - transform.position);
    18.         mRigidbody = target.GetComponent<Rigidbody> ();
    19.     }
    20.  
    21.     void FixedUpdate () {
    22.         float x = Input.GetAxis ("Mouse X") * sensitivity;
    23.         float y = Input.GetAxis ("Mouse Y") * sensitivity;
    24.         float z = Input.GetAxis ("Mouse ScrollWheel") * sensitivity;
    25.         angle.Add (x, y);
    26.         if (angle.v > 70) {
    27.             angle.v = 70;
    28.         } else if (angle.v < -70) {
    29.             angle.v = -70;
    30.         }
    31.         distance += z;
    32.         if (distance <= minDistance) {
    33.             distance = minDistance;
    34.             transform.position = cameraPosition.position;
    35.             mRigidbody.MoveRotation (angle.HorizontalRotation());
    36.  
    37.         } else {
    38.             transform.position = target.transform.position + Vector3.up * 1.75f - angle.ToVector3 () * distance;
    39.         }
    40.         transform.rotation = angle.Rotation();
    41.     }
    42. }
    43.  
    44. public struct Orientation{
    45.     public float h; //horizontal
    46.     public float v; //vertical
    47.  
    48.     public Orientation(Vector3 vect){
    49.         vect.Normalize ();
    50.         v = Mathf.Asin (vect.y) * 180 / Mathf.PI;
    51.         vect.y = 0;
    52.         vect.Normalize ();
    53.         if (vect.z < 0) {
    54.             h = 180 - Mathf.Asin (vect.x) * 180 / Mathf.PI;
    55.         } else {
    56.             h = Mathf.Asin (vect.x) * 180 / Mathf.PI;
    57.         }
    58.     }
    59.  
    60.     public void Add(float x, float y){
    61.         h = (h + x) % 360;
    62.         v = (v + y) % 360;
    63.     }
    64.  
    65.     public static Orientation Sum(Orientation or1, Orientation or2){
    66.         Orientation or = or1;
    67.         or.h = (or.h + or2.h) % 360;
    68.         or.v = (or.v + or2.v) % 360;
    69.         return or;
    70.     }
    71.  
    72.     public Vector3 ToVector3(){
    73.         Vector3 vect = Vector3.zero;
    74.         vect.x = Mathf.Sin (h * Mathf.PI / 180) * Mathf.Cos (v * Mathf.PI / 180);
    75.         vect.y = Mathf.Sin (v * Mathf.PI / 180);
    76.         vect.z = Mathf.Cos (h * Mathf.PI / 180) * Mathf.Cos (v * Mathf.PI / 180);
    77.         return vect;
    78.     }
    79.  
    80.     public Quaternion Rotation(){
    81.         Vector3 vect = Vector3.zero;
    82.         vect.x = Mathf.Sin (h * Mathf.PI / 180) * Mathf.Cos (v * Mathf.PI / 180);
    83.         vect.y = Mathf.Sin (v * Mathf.PI / 180);
    84.         vect.z = Mathf.Cos (h * Mathf.PI / 180) * Mathf.Cos (v * Mathf.PI / 180);
    85.         return Quaternion.LookRotation (vect);
    86.     }
    87.  
    88.     public Quaternion HorizontalRotation(){
    89.         Vector3 vect = Vector3.zero;
    90.         vect.x = Mathf.Sin (h * Mathf.PI / 180);
    91.         vect.z = Mathf.Cos (h * Mathf.PI / 180);
    92.         return Quaternion.LookRotation (vect);
    93.     }
    94.  
    95.     public Quaternion VerticalRotation(){
    96.         Vector3 vect = Vector3.zero;
    97.         vect.y = Mathf.Sin (v * Mathf.PI / 180);
    98.         vect.z = Mathf.Cos (v * Mathf.PI / 180);
    99.         return Quaternion.LookRotation (vect);
    100.     }
    101.  
    102.     public static Orientation forward {
    103.         get{
    104.             return new Orientation ();
    105.         }
    106.     }
    107.  
    108.     public static Orientation back {
    109.         get{
    110.             return new Orientation (Vector3.back);
    111.         }
    112.     }
    113.  
    114.     public static Orientation up {
    115.         get {
    116.             return new Orientation (Vector3.up);
    117.         }
    118.     }
    119.  
    120.     public static Orientation down {
    121.         get{
    122.             return new Orientation (Vector3.down);
    123.         }
    124.     }
    125.  
    126.     public static Orientation left {
    127.         get {
    128.             return new Orientation (Vector3.left);
    129.         }
    130.     }
    131.  
    132.     public static Orientation right {
    133.         get{
    134.             return new Orientation (Vector3.right);
    135.         }
    136.     }
    137.  
    138.     public static bool operator == (Orientation or1, Orientation or2){
    139.         return or1.Equals (or2);
    140.     }
    141.  
    142.     public static bool operator != (Orientation or1, Orientation or2){
    143.         return !or1.Equals (or2);
    144.     }
    145. }
    146.  
    I also fixed some errors in the calculations, and added a bit more methods.
     
    Last edited: Mar 27, 2017
  2. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    I think its here:

    Code (CSharp):
    1.     private float m_x = 0;
    2.     private float m_y = 0;
    Because it's saying you can't assign values to those when they are declared.
     
    AndrAla likes this.
  3. AndyGainey

    AndyGainey

    Joined:
    Dec 2, 2015
    Posts:
    216
    The problem is with these two lines (double clicking on the error should have taken you here):
    Code (CSharp):
    1.     private float m_x = 0;
    2.     private float m_y = 0;
    The rules of C# syntax disallow assigning default values to fields in structs (probably so that certain assumptions can be made by the compiler, making its job easier or its output more efficient).

    Fortunately, fields are zero-initialized anyway, so you can safely remove the " = 0" part and it will still do exactly the same thing. If you needed to initialize them to some other value, you'd need to do so using a constructor (and not a parameterless constructor, as that is also disallowed for related reasons), or you could create a named static function or property that returns an instance of Oriantation, setting the values to the defaults you desire.

    Finally, minor quibble, but it's spelled with an 'e', not an 'a': Orientation.
     
    AndrAla, lordofduct and MD_Reptile like this.
  4. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    I saw, but resisted :p
     
  5. AndrAla

    AndrAla

    Joined:
    Mar 11, 2017
    Posts:
    18
    After removing the "= 0" I started getting other errors:
    "Field `Orientation.m_y' must be fully assigned before control leaves the constructor"
    "Field `Orientation.m_x' must be fully assigned before control leaves the constructor"
    "The `this' object cannot be used before all of its fields are assigned to"
    "Expression denotes a `type', where a `variable', `value' or `method group' was expected"
    (I renamed it to Orientation, with e, not with a)
    Edited the script in the original post (although not much was changed in it).
     
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    Structs need to be handled very specifically.

    They can not have initializers for the fields, because having initial values for them (like m_x = 0;) implies a constructor. If you create an array of length 1000, because structs are not nullable... you will end up with EVERY entry of the array having to run a constructor on itself.

    So instead, structs will initialize to their default values as if the entire memory it takes up is all 0's.

    That was your first problem.

    Your next problem is that IF there is a constructor defined. Then EVERY field must be initialized, directly.

    Not indirectly through a getter/setter, like you currently are.

    Currently you say:

    Code (csharp):
    1.  
    2.     public Orientation(Vector3 vect){
    3.         vect.Normalize();
    4.         x = Mathf.Asin (vect.y) * 180 / Mathf.PI;
    5.         y = Mathf.Asin (vect.x) * 180 / Mathf.PI;
    6.     }
    7.  
    You can't say that... you have to say:

    Code (csharp):
    1.  
    2.     public Orientation(Vector3 vect){
    3.         vect.Normalize();
    4.         m_x = Mathf.Asin (vect.y) * 180 / Mathf.PI;
    5.         m_y = Mathf.Asin (vect.x) * 180 / Mathf.PI;
    6.     }
    7.  
     
    MD_Reptile, AndyGainey and AndrAla like this.
  7. AndrAla

    AndrAla

    Joined:
    Mar 11, 2017
    Posts:
    18
    Okay, that helped. I stopped using get/set in this struct, and only 1 error left:
    "Assets/Scripts/CameraScript.cs(14,11): error CS0119: Expression denotes a `type', where a `variable', `value' or `method group' was expected"
    Again edited the code in the original post.

    EDIT: nevermind. I had forgotten the 'new', now it's working :)
     
    Last edited: Mar 26, 2017
    MD_Reptile likes this.