0
\$\begingroup\$

I just learned in a C# tutorial that we can declare var name = new ClassNameOfOtherScript(); to create a new class object, then use the object to call the function in that class, but it doesn't seem to be working in Unity.

Am I understanding it wrong or does it work differently in Unity?

I have a class Cube1 this is attached to an object with SpriteRenderer enabled. Then I have another script ClockController which is not attach to any object. When I run it, the color of cube does not change to red?

public class Cube1 : MonoBehaviour
{
    
    public void Rectangle()
    {
        GetComponent<SpriteRenderer>().color = Color.red;
    }

}
public class ClockController : MonoBehaviour
{
  
    void Start()
    {
        var cube1 = new Cube1();
        cube1.Rectangle();
    }
}
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Why would the colour of your existing Cube1 object change when you called the colour change function on a new Cube1 object? (ie. NOT the one that already exists in your scene/project) Did you try searching for past answers about how to get a reference to an existing object to call a method on it? \$\endgroup\$
    – DMGregory
    Jan 11 at 13:03
  • \$\begingroup\$ Tested both code and noticed the different, indeed putting the title getting a reference on(existing) object would be more appropriate. Been learning C# fundamental tutorial for sometime yet I do not realize I'm on the wrong direction regarding the usage of "new" operator. Thank again!! \$\endgroup\$
    – chuackt
    Jan 11 at 15:17
1
\$\begingroup\$

Well you are doing var cube1 = new Cube1(); which is how you would make an object in C#, but since it is Unity, and this is a MonoBehaviour, you are not supposed to make it like that.

Instead, make a new GameObject and attach the Cube1 script to it.


void Start()
{
    // make a new gameobject.
    GameObject gameObject = new GameObject();

    // adding a SpriteRenderer as your `Cube1` will try to access it.
    // -- please also see the bottom note of the answer. --
    gameObject.AddComponent<SpriteRenderer>();

    // attach a Cube1 script to it and store the reference to it in a var. 
    Cube1 cube = gameObject.AddComponent<Cube1>();

    // call the function on that cube.
    cube.Rectangle();
}

Sidenote, if you don't make an object in the scene that holds the ClockController, it won't execute the Start() method.


When you already have an existing GameObject (instead of making a new one) that has a script you want to access, you can use gameObject.GetComponent<Cube1>() , store it in a variable (if necessary) and access it that way. You just need to get that specific GameObject to begin with.


Extra info on component dependencies:

As pointed out by @DMGregory, cube.Rectangle() will try to find/access a SpriteRenderer on the cube object, which would have to be added first. You could add [RequireComponent(typeof(SpriteRenderer))] which means that whenever you add a Cube1 script to a GameObject, the required component is added aswell if it is not already there.

I'd suggest to take a look at the docs: https://docs.unity3d.com/ScriptReference/RequireComponent.html

Alternatives would probably be making sure in your Cube1 script that at some point a SpriteRenderer is attached, but that's all going off-topic I think.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Note that since Cube1.Rectangle() tries to get a reference to an attached SpriteRenderer component, it does not make sense to call this on a new object that has no SpriteRenderer on it, as shown in this answer. The as Cube1 is also unnecessary — the return type is already Cube1 \$\endgroup\$
    – DMGregory
    Jan 11 at 13:23
  • \$\begingroup\$ Ah thanks, I was not sure about the as Cube1 part so looked up the docs (and saw it there). Will update my answer. Sharp one on the SpriteRenderer, guess I was too focussed on only answering how to call the function. \$\endgroup\$
    – D.Kallan
    Jan 11 at 13:39
  • \$\begingroup\$ Note that the as is shown in the docs only for the overloads that take a type or string as an argument. It is not present in the example for the generic version that you're using here. \$\endgroup\$
    – DMGregory
    Jan 11 at 13:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.