Help me understand this part of the WaveConfig

In Lecture 100. WaveConfig For Path & Speed, our goal is to move the pathing and the enemy speed to the Wave ScriptableObjects. I will not address the speed since I’ve already understood it.

So, Previously we had a WaveConfig serialize field in the enemypathing that was attached to the enemy gameobject, and we used it to attach a Wave ScriptableObject to it so the enemy can recognize which wave to follow. Now, we want to move that process to the enemySpawner script, so we delete the Serialized field part of the Waveconfig wave config ( I decided to comment it out):

public class Enemypathing : MonoBehaviour
{
    /*[SerializeField]*/  WaveConfig waveConfig;
   /* [SerializeField] */ List<Transform> Waypoints;
   /* [SerializeField] */ float moveSpeed = 2f;
    int waypointIdex = 0; 

then we wrote this method

 public void SetWaveConfig(WaveConfig EP_waveConfig)
    {
       this.waveConfig = EP_waveConfig ;


    }

I guess what we did here is create a public method that refers to a waveconfig variable in this case (EP_waveConfig) that for some reason had to be identified as waveconfig using this.waveConfig = EP_waveConfig ; which I also don’t understand it’s function, does it return or identify the waveConfig as EP_waveConfig, and if so why do we need it for the next step?

var newEnemy = Instantiate(waveConfig.GetenemyPrefab(), waveConfig.GetWaypoints()[0].transform.position, Quaternion.identity);
            newEnemy.GetComponent<Enemypathing>().SetWaveConfig( waveConfig);

Then, we had to get component which I get, but then we called out the waveConfig variable in the EnemyPathing as in WaveConfig waveConfig; not the EP_waveConfig variable in the SetWaveConfig public method. another thing I don’t understand is when we already have access to the WaveConfig class in the enemySpawner, why do we need to get the variable waveconfig of type Waveconfig by using a public method from the Enemy Pathing. Help me make sense of it all because I did not understand what does what and why we wrote it.

Hi Hue,

I guess what we did here is create a public method that refers to a waveconfig variable in this case (EP_waveConfig) that for some reason had to be identified as waveconfig using this.waveConfig = EP_waveConfig ;

When we use EP_waveConfig here, we assign the value of that variable to this.waveConfig. The EP_waveConfig parameter acts as a container for the reference to a WaveConfig object. By executing this.waveConfig = EP_waveConfig;, we give the Enemypathing object a “link” (reference) to a WaveConfig object so it does not have to look for such an object itself.

The EP_waveConfig exists only within the scope of the SetWaveConfig method. The Instantiate method could not access it because it is executed in a different scopt. However, since we assign the reference to the WaveConfig object which was “transported” by EP_waveConfig to this.waveConfig, and since this.waveConfig exists in the scope of the instance/object, we can access this.waveConfig in all methods within the class code block.

Did that clear it up for you?

Hi Nina,

Just couple questions

So the point of the method SetWaveConfig and this.waveConfig = EP_waveConfig; is to allow WaveConfig object to contain or gain access to all of the EnemyPathing
code and information so we can reference them in other scripts like what we just did in the EnemySpawner script, correct?

and by the “reference”, you mean waveconfig that is at the top of the public class in the enemy pathing that is using WaveConfig class?

The other way round. this.waveConfig is part of our EnemyPathing instance*. The EnemyPathing instance is supposed to access a WaveConfig object. We assign that WaveConfig object (or rather the reference) to this.waveConfig so we can reuse the reference.

After the SetWaveConfig executed its code block, the EP_waveConfig variable gets destroyed and information gets lost. To keep this information, we assign the “content” of the variable to our instance variable waveConfig. waveConfig exists as long as the EnemyPathing instance exists.

and by the “reference”, you mean waveconfig that is at the top of the public class in the enemy pathing that is using WaveConfig class?

A reference is something like a link to an object. The object resides somewhere in the memory, and we usually access objects via references assigned to variables.

We are not using the WaveConfig class in our EnemyPathing object but a WaveConfig object. The difference is important in C#. A class usually acts as a blueprint for objects. Imagine you had a blueprint of a car. You cannot drive a blueprint, so you’ll have to create a car object first. The car can be driven. The same applies to C# objects. Create objects to do something.


* “Instance” and “object” are synonyms.

Sorry, but I have more questions. I will use photos this time to make sure I ask the right questions

image

The one with the red line under it is called “Object” and not “class” correct? and the one with the green line (the variable) is the “reference” to that object. I will refer to them as red and green.

What I previously thought is that the the Object(red) and the variable/reference (green) is what gave the enemypathing script access to the WaveConfig.cs or the object, which is why we were able to use waveconfig.GetmoveSpeed. But what we want to do, is store the enemypathing.cs information(speed and waypoints) in the object(red) using the public method that we created public void SetWaveConfig(WaveConfig EP_waveConfig) so we can reference them( call them out) in another script (enemySpawner) like what is shown down below:

newEnemy.GetComponent<Enemypathing>().SetWaveConfig( waveConfig); 

but it seems my understanding of the whole thing was wrong, because the waveconfig in this code is referring to the local waveconfig in the EnemySpawner not the one in the Enemypathing (the green one). So we’re using a GetComponent to callout a public method in the eneympathing script and reference the local variable waveconfig in the enemySpawner, and that somehow gives the instantiate method access to all of the enemypathing information, which is why I’m even more confused by this whole operation, and I felt that I asked you the wrong questions.

why would Enemy pathing need access to a Waveconfig object when WaveConfig waveconfig; (the red and green) already gave the enemypathing that access?

and why would we want to reference the local enemyspawner waveconfig parameters in the .GetComponent<Enemypathing>().SetWaveConfig( waveConfig); if what we’re trying to do is call out the information from the enemy pathing?

and when you said " We assign that WaveConfig object (or rather the reference) to this.waveConfig so we can reuse the reference ."

“we give the Enemypathing object a “link” (reference) to a WaveConfig object so it does not have to look for such an object itself.”

" since we assign the reference to the WaveConfig object which was “transported” by EP_waveConfig to this.waveConfig , and since this.waveConfig"

What was the reference in this case? was it the code inside the public method, was it the WaveConfig(red) or the wavconfig (green)?

Sorry for bothering you too much, it just that I have been stuck here for 3 days replaying the lecture and reading other threads trying to understand this lecture.

WaveConfig waveConfig is a variable declaration, not an object. In C#, each variable must be defined with a type. The type, in this case, is WaveConfig because your class is named WaveConfig. waveConfig is the variable name.

In pure C#, we would create an object like this: new WaveConfig();. And this is how we would assign an object to a variable: WaveConfig waveConfig = new WaveConfig();.

Since we are working with the Unity framework, we often must not create objects ourselves because that would result in conflicts. If we tried to do that anyway, Unity would complain via a warning or error message in the Console. Unity creates objects itself, and we assign them to fields in the Inspector, or we create objects via the Instantiate method.

why would Enemy pathing need access to a Waveconfig object when WaveConfig waveconfig; (the red and green) already gave the enemypathing that access?

variable != object

If you need an analogy: Assuming you have a mobile phone, and your best friend is named Rick. You create a new contact. There is a field named “mobile”. Are you able to call Rick without having typed something into the “mobile” field? No, you are not because the “mobile” field is not the number but a field. You have to assign his number to the field first, then you can click on a button to call him. When Rick changes his number, you edit the “mobile” field.

If you had to write your own “contacts” feature with C#, you would create a variable named “mobile”, and it would be of type int because that field is supposed to accept integers only.

and why would we want to reference the local enemyspawner waveconfig parameters in the .GetComponent<Enemypathing>().SetWaveConfig( waveConfig); if what we’re trying to do is call out the information from the enemy pathing?

We are not referencing any variables but values. That’s a huge difference. See my example at the bottom of my answer.

If you meant “why don’t we access the waveConfig variable of the Enemypathing object directly to gain access to the referenced object”, the answer is: We follow the principles of object-oriented programming. One of them says that we do not want to make variables accessible to the outside because everything that has a reference to the object could modify the value of the variable. I covered that case in my example at the bottom of my answer.

What was the reference in this case?

We cannot see the reference. However, this.waveConfig and EP_waveConfig can both hold a reference to a WaveConfig object.

I mentioned the mobile phone, the contacts and the “mobile” field. The “mobile” field is supposed to contain an integer. That integer could be regarded as a reference to a specific mobile phone.

I don’t know how the equivalent looks in C#. I assume it’s some address in memory where the object can be found.

Sorry for bothering you too much, it just that I have been stuck here for 3 days replaying the lecture and reading other threads trying to understand this lecture.

No worries. I know that this lecture is fairly complex because a lot is going on there. We are dealing with different objects, moving data from one object to another. It is difficult to see the underlying concept, so please do ask questions. :slight_smile:


In C#, we usually do not work with objects directly. Instead, we use variables and treat them as if they were our object.

Due to the many different names we use in our scripts, the idea of referencing the same object could be a bit confusing. Let me give you an example with a badly written class named Test. For simplicity, we create objects from it ourselves and ignore Unity for a moment.

public class Test
{
    public string name = "Rick";
}

public class EnemySpawner: MonoBehaviour
{
    Test myTest; // default value is null (no reference)

    void Awake()
    {
        myTest = new Test(); // we create an object and assign it to 'myTest'
    }

    public Test GetTestObject()
    {
        Debug.Log("this.myTest.name: " + this.myTest.name); // Output 1
        return this.myTest;
    }
}

public class Enemy : MonoBehaviour
{
    [SerializeField] EnemySpawner spawner; // we assign the EnemySpawner object in the Inspector
    
    void Start()
    {
        Test test1 = spawner.GetTestObject();
        Debug.Log("test1.name: " + test1.name);  // Output 2
        test1.name = "Ben";
        
        Test test2 = new Test();
        Debug.Log("test2.name: " + test2.name);  // Output 3
        Debug.Log("test1.name: " + test1.name);  // Output 4
    }

}

If you can tell what the output in the console is without testing the code in Unity, you understood the underlying concept of references.


By the way, if you are interested in a free C# course, I can recommend Bob Tabor’s. If you feel you are getting stuck in each of Rick’s video because you didn’t understand what he was trying to explain, take a break from the Unity course, follow Bob’s C# course and proceed with Unity. You’ll realise that the C# stuff is not as difficult as it looks. It just feels difficult because you are doing so much at once at the moment: dealing with Visual Studio, typing code, moving stuff around in Unity, adjusting values in Unity.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms