InvalidCastException when using Instantiate on a ParticleSystem
Hi all,
I'm using Unity 5.5.1f1 Personal Edition. In my script, I declared a ParticleSystem variable:
public ParticleSystem SmokeParticle;
and I'm assigning it from the editor. Then in the script I have:
var smokeEffect = Instantiate<ParticleSystem>(SmokeParticle, hit.point, Quaternion.FromToRotation(Vector3.up, hit.normal));
At runtime, every time this instruction is hit, I get the following exception in the console:
InvalidCastException: Cannot cast from source type to destination type. UnityEngine.Object.Instantiate[ParticleSystem] (UnityEngine.ParticleSystem original, Vector3 position, Quaternion rotation) (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:207)
I have this problem since I updated to Unity version 5.5.1f1, the previous version worked fine with this.
Can someone please explain me what I'm doing wrong?
Thank you all,
FOC
1) Check if the error log has a stack trace back to this line in your own code, just to be certain that this is the line that's tripping it up.
2) $$anonymous$$ake sure every function parameter is of the correct type.
3) Try declaring ParticleSystem smokeEffect
ins$$anonymous$$d of var smokeEffect
, I doubt that would help, but it wouldn't hurt.
If none of those help, we'll need to see more of your code, preferably the whole function that line is in.
Answer by FandangoOnCore · Mar 07, 2017 at 10:35 AM
Hi all, I had an answer from the unity staff: this is not a bug.
"Thanks for reporting the issue. This is not a bug of Unity though.
You should use GameObject type for a variable which you are using in Instantiate method if you are instantiating from a prefab. Changing line 66 to "public GameObject SmokeParticle;" and line 313 to "GameObject smokeEffect = Instantiate(SmokeParticle, hit.point, Quaternion.FromToRotation(Vector3.up, hit.normal));" should fix the issue."
I'm going to mark this as the solution. Thank you.
Hi, co$$anonymous$$g to this almost 5 years later I figured out a way to keep your custom data type.
public GameObject SmokeParticle;
...
ParticleSystem smokeEffect = Instantiate(SmokeParticle, hit.point, Quaternion.FromToRotation(Vector3.up, hit.normal)).GetComponent<ParticleSystem>();
What's happening here is that we're still using Instantiate legally by passing it a GameObject type, but then we're accessing the component "ParticleSystem" and returning it to SmokeEffect.
Bear in $$anonymous$$d that the ParticleSystem script should be attached to the prefab you are instantiating in this way.
Answer by FandangoOnCore · Mar 04, 2017 at 07:43 PM
Hi Commoble, thank you for your time. Here is the rest of the stack trace from the console:
InvalidCastException: Cannot cast from source type to destination type. UnityEngine.Object.Instantiate[ParticleSystem] (UnityEngine.ParticleSystem original, Vector3 position, Quaternion rotation) (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:207) WeaponController.ApplyHole (RaycastHit hit) (at Assets/Scripts/WeaponController.cs:313) WeaponController.Update () (at Assets/Scripts/WeaponController.cs:184)
Line 313 of WaponController.cs is this one:
var smokeEffect = Instantiate<ParticleSystem>(SmokeParticle, hit.point, Quaternion.FromToRotation(Vector3.up, hit.normal));
I alredy tried 2) as I know sometimes the keyword var can lead to some ambiguous behaviour, but no luck.
I checked the parameters:
SmokeParticle is of type ParticleSystem;
hit.Point is of type Vector3;
Quaternion.FromToRotation gives a Quaternion type
the signature of the generic method is this:
Instantiate<ParticleSystem>(ParticleSystem a, Vector3 b, Quaternion c)
so everything looks fine to me.
The whole method is:
private void ApplyHole(RaycastHit hit)
{
var hole = Instantiate(HoleTexture[0], hit.point, Quaternion.FromToRotation(-Vector3.forward, hit.normal)) as GameObject;
if (hit.rigidbody != null)
hole.transform.parent = hit.rigidbody.transform;
Destroy(hole, 8);
ParticleSystem smokeEffect = Instantiate(SmokeParticle, hit.point, Quaternion.FromToRotation(Vector3.up, hit.normal));
Destroy(smokeEffect, 2);
}
Do you need the Update routine code?
FOC
Answer by ifurkend · Mar 05, 2017 at 12:27 AM
Try instantiate the prefab and move/rotate the instance separately instead of handling all actions in instantiate.
Hi ifurkend, thank you. I followed your advice by changing the code this way:
var smokeEffect = Instantiate<ParticleSystem>(SmokeParticle);
smokeEffect.transform.position = hit.point;
smokeEffect.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
But the exception is still raised. The stack trace is now:
InvalidCastException: Cannot cast from source type to destination type.
UnityEngine.Object.Instantiate[ParticleSystem] (UnityEngine.ParticleSystem original) (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:202)
WeaponController.ApplyHole (RaycastHit hit) (at Assets/Scripts/WeaponController.cs:314)
WeaponController.Update () (at Assets/Scripts/WeaponController.cs:184)
Line 314 of WeaponController.cs is the one holding the Instantiate.
I have only seen that "C:/buildslave/unity/..." error in Unity 5.6 beta and it was neglected by me quickly. If your original code works in the older version of Unity Editor, you may want to file a formal bug report to Unity.
O$$anonymous$$. I'm reporting this right now. Upload will take some time as the project is quite big. I'll write again when they'll give me a bug ID and/or an answer.
Thank you all.
FOC
Your answer
Follow this Question
Related Questions
How to Instantiate a particle system at a certain prefab's position? 2 Answers
Get a Insantiate particle system follow a GameObject 1 Answer
How to Instantiate decals where particles from particle system hits? 1 Answer
Instantiate ParticleSystem prefab as ParticleSystem returns null. As GameObject returns the prefab 1 Answer