Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

An object reference is required (solved)

Discussion in 'Scripting' started by ammenter, May 21, 2019.

  1. ammenter

    ammenter

    Joined:
    May 16, 2019
    Posts:
    10
    I'm trying to use the Transform.up.y module to detect rotation but I'm not sure how I need to reference it first as it says that "An object reference is required for the non-static field, method, or property 'Transform.up'

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class kaatunut : MonoBehaviour {
    7.  
    8.     // Use this for initialization
    9.     void Start () {
    10.  
    11.     }
    12.    
    13.     // Update is called once per frame
    14.     void Update () {
    15.         {
    16.             if (Transform.up.y < 0.4)
    17.             {
    18.                 Debug.Log("fallen");
    19.             }
    20.         }
    21.     }
    22. }
    23.  
    (unity 2018.2.21)
     
  2. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    779
    It should be 'transform' with lowercase 'T' - uppercase is the name of the class. Confusing, yes. but that's how they did it.

    You can make it less ambiguous if you prepend 'this' to indicate you want to access the script's GameObject's transform. E.g.

    Code (CSharp):
    1. this.transform.up.y = 0;
    2.  
    3. this.gameObject.transform.up.y = 0; // even more correct than above
    4.  
    5.  
     
  3. ammenter

    ammenter

    Joined:
    May 16, 2019
    Posts:
    10
    Thank you so much. I thought It was uppercase because it changed color when written in uppercase.
     
  4. ammenter

    ammenter

    Joined:
    May 16, 2019
    Posts:
    10
    I don't quite understand why and how this would be added
     
  5. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    779
    Just try it :)
     
  6. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    779
    To elaborate a little bit more:

    What is confusing is a somewhat unholy mix of Object-Oriented Programming (OOP), and Unity programmers believing they are doing the Unity community a favor.

    To start with OOP (you may want to revisit some tutorial on this, just the main parts): when you you have a class 'myClass' for which you have declared attributes, e.g. 'public int health = 100;' or 'public Vector3 myPosition'. In your methods, you can access these attributes in these objects using what some people call a "qualified path" - you've used that many times before. If, for example you have an object

    myClass testObject = new myClass();

    you can access health or myPosition my stringing together the various name bits that make up their structures: e.g.

    testObject.myPosition.y = 0;

    Now, if you access these properties in the class's own methods, you can't add the class object's name, so you normally omit the class object and directly access 'health' and 'myPosition'. However, to make clear and avoid ambiguity, you CAN (but don't have to) prepend the keyword 'this', meaning that you want to access this class instance's attribute.

    so, in a classes own method, the following are equivalent:

    this.health = 0;
    health = 0;

    So far so good.
    BUT, during design of Unity, the designers thought it wise to add some attributes to all components that implicitly give access to key attributes of the gameObject: these are the transform, name and game object itself (all by reference of course). They are accessible via 'name', 'gameObject' and 'transform' (note spelling and capitalization).

    So, when you in your script write

    transform.position.y = 0;
    name = 'Surprise!';

    This is a short form for

    this.gameObject.transform.position.y = 0;
    this.gameObject.name = 'Surprise!';

    and automatically gets resolved during compilation. This can be exceedingly confusing if you don't know what is going on behind the Scene (pun intendet), and leads many People to initially and erroneously believe that their script IS the game object. It's not. It's merely a component attached to a game object that has easy access to some of the game object's properties.

    But this will only confuse you for a while. So, for good measure, the Designers threw in another fine distraction, something that I regard as a very bad Habit amongst programmers: that of naming their variables exactly as their type, save for some capitalization:

    The type of the Transform class is 'Transform', capital 'T'. OF COURSE the Unity Designers thought it was a good idea to name the single most important attribute of your game object exactly that, save for the lower-case 't':

    public Transform transform;

    That's why you ran aground with the uppercase 'T'. you referenced the Type, not the Attribute. They did the same crime with the reference to the game object itself:

    public GameObject gameObject

    IMHO that is confusing, and very bad practice. Except now it's Gospel - everyone has to deal with it. I think it would have been better if they named these Attributes myTransform and myGameObject, respectively. But that strays into religious discussion territory, so I digress :)
     
    Last edited: May 22, 2019