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, 2021 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, 2021 at 15:17

1 Answer 1

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, 2021 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, 2021 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, 2021 at 13:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .