You need to give your class a unique name (don’t call your class “This” but something more meaningful). Also, you can simply refer to the transform directly.
Transform trf;
void Start ()
{
trf = transform;
}
The MonoBehaviour knows about Transforms or GameObjects connected to it. No need for GetComponent.
BTW why do you need to call a GetComponent outside a method?
Thanks for your reply, @sstrong !
I faced the issue with a different class name before; I only named the class “This” as a placeholder for just anything to get the error message for this issue within a test project that I deleted afterwards; I don’t normally call a class like that.
About .GetComponent(): I cannot access all components by their name directly and I just want to keep it consistent.
I don’t necessarily need to call it outside of a method. I could just put the code in Awake(). But it would be handy to be able to initialize a variable like that.
EDIT:
Just to confirm:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class nawelkawlkenlka : MonoBehaviour {
Transform trf = this.gameObject.GetComponent<Transform>();
}
shows the error “Assets/nawelkawlkenlka.cs(5,17): error CS0027: Keyword ‘this’ is not available in the current context”
MonoBehaviour already has the property transform. You don’t need to use the this keyword either.
You cannot initialize a class scoped field using GetComponent. GetComponent is meant for runtime use, not compile time.
You can use a property instead of a field. Implement the get with a GetComponent.
public ExampleClassA MyProperty
{
get => gameObject.GetComponent<ExampleClassA>();
}
public void Start()
{
MyProperty.Field = 1f;
}
but if you do it like this, it’s just a performance waste. Everytime you access the property it has to get the component.
You’d be better off just creating a public field and just serialize this in the scene.
Yes, since this refers to the current instance of the class. We fill our local cache variables with components in the Awake method.
public class This : MonoBehaviour {
Transform trf;
private void Awake () {
trf = gameObject.GetComponent<Transform>();
// Although here the trf = transform; is more than okay.
}
}
Just to make one thing clear: You originally tried to access your class inside a field initializer. The field initializers are actually executed before the constructor of the class. So the class is not even yet constructed. You can not access any instance members (fields, properties or methods) inside a field initializer. You can access static members since they don’t belong to a particular instance.
Apart from this wrong initialization order, you can’t even access any of the Unity properties like gameObject, transform or GetComponent inside the class constructor since Unity has to initialize the link to the native class after the managed class has been created. So besides the fact that the construction of the class may even happen on a seperate thread which will make those calls even less possible, during the normal managed construction phase (field initializers and class constructor) the class is not initialized yet and none of the properties that link to the native code counterpart would work.
Some more details
Every UnityEngine.Object derived type has a native C++ counterpart. This is actually referenced through the internally stored pointer of the UnityEngine.Object class. When you call a method or access a property that is actually defined in native code, you implicitly send a reference to your managed class with that call as the first parameter. That’s generally how OOP works. All method code is static code. Instance methods just have an implicit first parameter that references the instance which you can access through “this” inside that method.
The native method will grab that pointer from the managed class that was passed with the call in order to access the actual native object. As I said above, during the construction of the managed class those fields are not set yet.
@MaskedMouse
Yeah I guess Awake is still the way to go then. Don’t want any performance hits on things I call a lot.
@
Alright, makes sense! I just try to declare any self references as fast as possible to avoid any unnecessary timing issues. And I figured initializing is faster than Awake. And it safes some lines of code.
@Bunny83
Thanks for the clear answer! This was very helpful! That explains why “this” doesn’t work, yet I can do the following:
public static class Ids {
public static int shaderCutoutVal = Shader.PropertyToID("_CutoutVal");
}
Sure because “Shader.PropertyToID” is a static method that does not belong to this or any object at all. It may simply use a static dictionary in combination with a static List so they can simply map a string to an ID and back internally. As the documentation says the IDs are not unique across runs or on different platforms. So they most likely just create that lookup table “on the fly”.