Why i'm getting exception InvalidCastException: Cannot cast from source type to destination type ?

What i want to do is to create for example 20 unitToInstantiate and 20 Range and to put the 20 unitToInstantiate in the center of the 20 Range.

So each created unitToInstantiate will be in the center of a Range.

unitToInstantiate is Prefab and Range is GameObject.

It’s creating only one instead of 20. One unitToInstantiate in the center of one Range. But it should create 20.
Instead i’m getting exception:

InvalidCastException: Cannot cast from source type to destination type.

On the line:

Transform unitInstantiated = Instantiate(unitToInstantiate, new Vector3(i * 2.0F, 0, 0), Quaternion.identity);

And this is the script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InstantiateUnits : MonoBehaviour
{
    public Transform Range;
    public Transform unitToInstantiate;
    public int numberOfUnits;

    // Use this for initialization
    void Start ()
    {
        for (int i = 0; i < numberOfUnits; i++)
        {
            Transform unitInstantiated = Instantiate(unitToInstantiate, new Vector3(i * 2.0F, 0, 0), Quaternion.identity);
            Transform rangeInstantiated = Instantiate(Range, new Vector3(i * 2.0F, 0, 0), Quaternion.identity);
            unitInstantiated.SetParent(rangeInstantiated.transform);
            unitInstantiated.localPosition = Vector3.zero;
        }
    }
   
    // Update is called once per frame
    void Update ()
    {
       
    }
}

You say unitToInstantiate is a prefab and Range is a GameObject, but you are declaring them as type Transform. Try declaring them as type GameObject, and then your code that accesses their transforms you do as unitInstantiated.transform.blahblah. Same with your declarations of unitInstantiated and rangeInstantiated. See if that works for you.

Something like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InstantiateUnits : MonoBehaviour
{
    public GameObject Range;
    public GameObject unitToInstantiate;
    public int numberOfUnits;

    // Use this for initialization
    void Start ()
    {
        for (int i = 0; i < numberOfUnits; i++)
        {
            GameObject unitInstantiated = Instantiate(unitToInstantiate, new Vector3(i * 2.0F, 0, 0), Quaternion.identity);
            GameObject rangeInstantiated = Instantiate(Range, new Vector3(i * 2.0F, 0, 0), Quaternion.identity);
            unitInstantiated.transform.SetParent(rangeInstantiated.transform);
            unitInstantiated.transform.localPosition = Vector3.zero;
        }
    }
  
    // Update is called once per frame
    void Update ()
    {
      
    }
}
1 Like

The non generic version of Instantiate returns a UnityEngine.Object. You are far better off using the generic version, which will return the same type you pass in.

1 Like