WaveConfig ScriptableObject referancing

Hi,

In the tutorials, we are setting some values of the Enemies(maxtime, mintime and proj.speed) through the enemy.cs and I would like to be able to set them through the scriptable object that we create for the waves that we want to spawn.

I have tried to set some public variables and tried to call them from the enemy.cs which did not work. (I tried to use FindObjectOfType) and I tried to make methods of which return these values but I could not manage to call these methods and set their values on the matching values in the enemy. cs.
Enemy.cs:

Blockquote

[SerializeField] public float health = 100f;
[SerializeField] float shotCounter;
[SerializeField] float minTimeBetweenShots;
[SerializeField] float maxTimeBetweenShots;
[SerializeField] GameObject enemyProjectile;
[SerializeField] float projectileSpeed;

WaveConfig waveConfig;

[SerializeField] private WhiteFlash whiteFlash;



[SerializeField] GameObject powerUp;
PowerUpManager pUpMan_E;
PowerUp pUp_E;

[SerializeField] GameObject shL, shR;

[SerializeField] GameObject explosion;
public Transform firePosition2;
public Transform firePosition1;

// Start is called before the first frame update
void Start()
{
  
   
   
    shotCounter = Random.Range(minTimeBetweenShots, maxTimeBetweenShots);
    pUpMan_E = FindObjectOfType<PowerUpManager>();
    pUp_E = FindObjectOfType<PowerUp>();
  

}

// Update is called once per frame
void Update()
{
    CountDownAndShoot();
}

private void CountDownAndShoot()
{
    shotCounter -= Time.deltaTime;
    if (shotCounter <= 0f)
    {
        Fire();
        
        shotCounter = Random.Range(minTimeBetweenShots, maxTimeBetweenShots);
    }
}

WaveConfig.cs:

Blockquote[CreateAssetMenu(menuName = “Enemy Wave Config”)]
public class WaveConfig : ScriptableObject

{
[SerializeField] GameObject enemyPrefab;

[SerializeField] GameObject pathPrefab;
[SerializeField] float timeBetweenSpawns = 0.5f;
[SerializeField] float spawnRendomFactor = 0.3f;
[SerializeField] int  numberOfEnemies = 5;
[SerializeField]  float moveSpeed = 2f;
[SerializeField] public  bool isMoveType1, isMoveType2;




public GameObject GetEnemyPrefab() {return enemyPrefab;}

public List<Transform> GetWaypoints()
{
    var waveWaypoints = new List<Transform>();
    foreach (Transform child in pathPrefab.transform)
    {
        waveWaypoints.Add(child);
    }

    return waveWaypoints;
}


public float GetTimeBetweenSpawns() { return timeBetweenSpawns; }
public float GetSpawnRendomFactor() { return spawnRendomFactor; }
public int GetNumberOfEnemies() { return numberOfEnemies; }
public float GetMoveSpeed() { return moveSpeed; }

}
How can I change these values(max-min_time,projectilespeed) through waveConfig scriptable object?
Any Ideas?Thanx in advance…Cheers=)

Hi,

What do you mean by “did not work”? Did you get any error messages?

For what exactly? FindObjectOfType returns the first object it fines, whatever Unity defines as first. If you have multiple instances of the same type in your scene, it might be that the method returns the same object, not necessarily the one you are looking for.

Do the same what you did in the WaveConfig class, analogous to:

[SerializeField] GameObject enemyPrefab;
public GameObject GetEnemyPrefab() { return enemyPrefab; }

See also:

I was getting NullReferanceExepction and I thought that was because I couldn’t create a reference to the scriptable object properly. That’s why I tried FindObjectOfType cause normally that’s the main way I know how to access the class that I need. But this being a scriptable object confused me a little.

So I created the methods as you suggested like this one :

    [SerializeField] float minTimeBetweenShots;
    [SerializeField] float maxTimeBetweenShots;
    [SerializeField] float projectileSpeed;
 
    public float GetMinTime() { return minTimeBetweenShots; }
    public float GetMaxTime() { return maxTimeBetweenShots; }
    public float GetProjectileSpeed() { return projectileSpeed; }

and assign them to variables at the Start() like this :

 void Start()
    {

         minTimeBetweenShots = waveConfig.GetMinTime();
         maxTimeBetweenShots = waveConfig.GetMGetMaxTime();
         projectileSpeed = waveConfig.GetProjectileSpeed();


        shotCounter = Random.Range(minTimeBetweenShots, maxTimeBetweenShots);
        pUpMan_E = FindObjectOfType<PowerUpManager>();
        pUp_E = FindObjectOfType<PowerUp>();
      

    }

This works in-game but I still get the NullReferanceExepction: Object reference not set to an instance of an object for the first line of Start().

Your code looks fine. The problem is a problem with references (“link” to an object).

To which line does the NullReferenceException error message refer? Double click on it.

The WaveConfig object is a scriptable object, isn’t it? If so, it cannot be found via FindObjectOfType as that method only looks for objects in the scene. Scriptable objects are not in the scene.

This is how I created the floats:

 [SerializeField] float minTimeBetweenShots, maxTimeBetweenShots, projectileSpeed;

The error is referring to the first line in Start() which is :

 void Start()
    {

         minTimeBetweenShots = waveConfig.GetMinTime();
         maxTimeBetweenShots = waveConfig.GetMGetMaxTime();
         projectileSpeed = waveConfig.GetProjectileSpeed();

I also thought this was a reference problem. And also when I remove the first line of the Start() and run the program, the error starts to refer to the next line. But I couldn’t manage to figure how to create a reference for scriptableObject properly and get rid of the error.

Is there a reason you aren’t using a serialize field attribute above your reference for your wave config asset? Like this:

[SerializeField] WaveConfig waveConfig;

Without it, it looks like the waveConfig variable is implicitly private, which means that it won’t show up in the inspector, which means that you can’t drag and drop your config in the inspector.

Well, since there would be a lot of waveConfig scriptable objects I didn’t know what to put on that field. Because different waveConfigs will have different variables. I might maybe add the waveConfig list that I already have on the spawner…?

There is an EnemySpawner gameObject which contains a list with different waveConfig scriptalble objects with different variables.

But even than, there will be different EnemySpawer gameObjects which will start at the same time. Should I than need to add all of them?

So that’s the reason you’re getting a null reference exception.
Hmm, so tell me if I’m understanding you correctly:

You have EnemySpawner GameObjects, each of which needs to spawn enemies according to a particular wave config. So EnemySpawner1 would have be associated with a particular config, and EnemySpawner2 would be associated with either the same of a different config.

Or are you trying to do this:
You have EnemySpawner GameObjects, each of which needs to spawn enemies according to a config selected from a list of configs.

Either way, each enemy needs to be injected with the information contained in a config housed in the spawner it came from?

Is this what you want?

public class Enemy
{
     //Other code.....
    public void Init(WaveConfig config)
    {
        this.waveConfig = config;
    }
}

Then, in the spawner that instantiates the enemy, right after you instantiate it, you can pass the config you want it to have using the Init() method:

var enemy = Instantiate(enemyPrefab,.....);
enemy.Init(config);

This.

I have different enemy prefabs and paths. I feed these to a waveConfig.And I feed the waveConfigs to a EnemySpawner , in a List. I plan to have multiple EnemySpawners.

Why I wanna do that is this:
I have the information for the fire rate of an enemy ship on Enemy.cs which is on the enemy prefabs. But I didnt want to create different versions of the enemies with different fare rates. Instead, I thought , I should manipulate the variables of the fire rate through waveConfig.

This is already there. In another script for the moving the enemy. But I think now I get what I should do. I’ll just try it.

Edit: Actually I thought wrong again…=) But I understood how it should go and now it works…=) What you suggested was right and I should have seen it sooner couse we did the same process for the moving part as I mentioned.
Thanx a lot…=)Cheers…=)

Right, so you want to have an enemy prefab have variable firerates that are determined not by variables within the enemy script that are stored in the prefab, but by config that is specified by an EnemySpawner when the enemy is instantiated at runtime.

So the enemy spawner, which is storing the info that the enemy needs, can pass the reference to the config that it wants the Enemy to have, such as through an Init() method like the one above.

No problem, I’m glad to help! Now you won’t forget it. :smile:

1 Like

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

Privacy & Terms