"Do not create your own module instances" Warning for ParticleSystem with custom Inspector
I have a particle system set up, and a custom inspector panel that turns it into a "smart" asset by keeping some settings relative to each other.
So far it works, but it is giving me a warning that I dont understand. How do I fix this warning, and what does it mean? I am also trying to learn C# from a Python BG.
NullReferenceException: Do not create your own module instances, get them from a ParticleSystem instance
UnityEngine.ParticleSystem+EmissionModule.set_rateOverTime (UnityEngine.ParticleSystem+MinMaxCurve value) (at <b6edb49129684880865710f98e97a458>:0)
particle_customizer.ChangeParticleNum (System.Int32 num_particles) (at Assets/particle_customizer.cs:16)
particle_editor.OnInspectorGUI () (at Assets/Editor/particle_editor.cs:19)
UnityEditor.UIElements.InspectorElement+<>c__DisplayClass58_0.<CreateIMGUIInspectorFromEditor>b__0 () (at <1fe7a3c0284a456b9681b7a93141c89a>:0)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
Here are my 2 scripts. One is an Editor script and the other is a particle system with the script added as a component.
Component of ParticleSystem:
using UnityEngine;
[ExecuteInEditMode]
[RequireComponent(typeof(ParticleSystem))]
public class particle_customizer : MonoBehaviour
{
public ParticleSystem ps;
public void ChangeParticleNum( int num_particles)
{
ps = GetComponent<ParticleSystem>();
var emission = ps.emission;
emission.rateOverTime= num_particles;
}
}
Editor Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(particle_customizer))]
public class particle_editor : Editor
{
public int num_particles;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
num_particles = EditorGUILayout.IntField("Num Particles", num_particles);
particle_customizer ps_custom = (particle_customizer)target;
ps_custom.ChangeParticleNum(num_particles);
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
Answer by marek_PLH · Feb 10, 2021 at 04:42 PM
Problem is in this line:
var emission = ps.emission;
Explicit type of var
here is ParticleSystem.EmissionModule
, that is struct and passed by value, not reference. This means that it will create copy as an emission
variable and will not change values of ParticleSystem. All modules are in fact for usage of PS only and you should change anything by directly modifying fields and properties in its reference.
Your ChangeParticleNum
code should look like this (also added null-check for good practice):
public void ChangeParticleNum( int num_particles)
{
if(ps == null)
ps = GetComponent<ParticleSystem>();
ps.emission.rateOverTime = num_particles;
}