Oh, my bad. The coroutine itself is not null, but you have a null reference exception within the coroutine. You have the exception at line 18 in the Projectile class.
What do you mean when you say within the coroutine?
This is line 18 of the Projectile class:
_move.Perform(projectile, target, args.Power);
I added debugs and neither _move, projectile, target, nor args.Power are null so I’m not sure what’s going on.
_move.Perform just starts the real coroutine so I can have a bit nicer syntax and doesn’t actually modify the parameters.
At this line in the Projectile class throws a TypeInitializationException, which leads to a NullReferenceException, you need to resolved that type initialization exception.
It is caused by the call of projectile, target, args.Power or _move.Perform. You need to find out which one it is. You may e.g. do something like:
var power = args.Power;
If you do that for projectile and target too, you will find out whether it is one of them or _move.Perform. Check which line it is and you get one step closer to the cause.
So when I do find out which one it is, how would I even fix it?
I’m pretty sure it’s _move because the other parameters are being used in other statements but not causing errors.
Pretty sure is not enough in software development.
Before the _move.Perform, get all the values as I wrote in the example above. Like that you will be pointed to one of those lines, if they are the cause. Otherwise it will still throw the error at the line with _move.Perform.
This is why null checks and creating local variables can be handy. It might seem verbose and slightly obtuse to do:
if (args == null)
throw new ArgumentException("args");
if (_move == null)
throw new NullReferenceException("_move cannot be null");
var power = args.Power;
_move.Perform(projectile, target, power);
but it can sure make debugging a lot easier. You should also learn to use the inspectors and immediate window in the debugger. This will help you solve a lot of these kinds of issues.
If you do that, you will be able to further isolate the issue, without guessing:
var p = projectile;
var t = target;
var power = args.Power;
_move.Perform (p, t, power);
You can revert it when you found out what the actual cause is, but as you are not sharing more code at the moment, we can’t know what has which side effect. As soon you you know which of those four lines is causing the issue, we can continue the discussion, before that, it is just a waste of time.
Of course it does. Every class has a default constructor. You can’t remove it but you can override it or provide alternatives.
Besides that, a static constructor is a little different. Every class also has one of these and it is called only once (usually after the first reference of your class is hit but not necessarily. It can happen well before that or even after your instance constructor!)
Sorry what I meant was my class has no user-defined constructors because I can’t do anything with the compiler generated constructor. Didn’t know that bit about static constructors though I’ll have to do more research into it.
Anyway thanks guys. As soon as I get home I will try your suggestions and post more code.
I should correct myself a little bit: Not every class has a static constructor.
There are two steps that go into “setting up” a type. The first is a type initializer and the second (if defined) is the static constructor. The TypeInitializationError can be thrown by either of these.
If you want to know more about the weirdness I described in parentheses, see John Skeet’s article: C# and beforefieldinit
var a = projectile;
var b = args.Target;
var c = args.Power;
var d = _move;
d.Perform(new PerformArgs<Vector2>(a, b, c));
And the error points me to the last line (d.Perform). I’m not sure why. No coroutine is started or anything.
EDIT: Solved! I had renamed some game object in the scene and in my class I made use of a static variable that referenced that game object, but because I used GameObject.Find, it couldn’t find it (because I had renamed it) which caused the crash.