There's no GetComponent... I need help for our School Project :(

I followed some Indonesian guy in YouTube on how to make a Word Scrabble. However, what really bugs me the most is the GetComponent Error and that error is shown above, highlighted. I already followed what he type (not says because I can’t understand bahasa and this is the only game that has close resemblance to PopCap’s Text Twist). Please help. :frowning:

Here’s the code for each CS:
WordScramble.CS

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

[System.Serializable]
public class Word
{
    public string word;
    [Header("leave empty if you want randomized")]
    public string desiredRandom;

    public string GetString()
    {
        if (!string.IsNullOrEmpty (desiredRandom))
        {
            return desiredRandom;
        }

        string result = word;

        while (result == word)
        {
            result = "";
            List<char> characters = new List<char> (word.ToCharArray ());
            while (characters.Count>0)
            {
                int indexChar = Random.Range(0, characters.Count - 1);
                result += characters[indexChar];
             
                characters.RemoveAt (indexChar);
            }
        }

        return result;
    }
}

public class WordScramble : MonoBehaviour {

    public Word[] words;

    [Header("UI REFERENCE")]
    public CharObject prefab;
    public Transform container;
    public float space;

    List<CharObject> charObjects = new List<CharObject>();
    CharObject firstSelected;

    public int currentWord;

    public static WordScramble main;

    void Awake()
    {
        main = this;
    }

    // Use this for initialization
    void Start () {
 
    }
 
    // Update is called once per frame
    void Update () {
 
    }

    void RepositionObject()
    {
        if (charObjects.Count == 0)
        {
            return;
        }

        float center = (charObjects.Count - 1) / 2;
        for (int i = 0; i < charObjects.Count;i++)
        {
            charObjects[i].rectTransform.anchoredPosition
                = new Vector2((i - center) * space, 0);
            charObjects[i].index=1;
        }
    }

    /// <summary>
    /// Shows a random word to the screen
    /// </summary>
    public void ShowScramble()
    {
        ShowScramble (Random.Range (0, words.Length - 1));
    }

    /// <summary>
    /// Show word from collection with desired index
    /// </summary>
    /// <param name="index">Index of the element</param>
    public void ShowScramble(int index)
    {
        charObjects.Clear ();
        foreach(Transform child in container)
        {
            Destroy(child.gameObject);
        }

        if (index > words.Length - 1)
        {
            Debug.LogError ("index out of range, please enter range betweeen 0-" + (words.Length - 1).ToString());
            return;
        }

        char[] chars = words[index].GetString().ToCharArray();
        foreach (char c in chars)
        {
            CharObject clone = Instantiate(prefab.gameObject).GetComponent<CharObject>();
            clone.transform.SetParent(container);

            charObjects.Add(clone.Init(c));
        }

        currentWord = index;
    }

    public void Swap(int indexA, int indexB)
    {
        CharObject tmpA = charObjects [indexA];

        charObjects [indexA] = charObjects [indexB];
        charObjects [indexB] = tmpA;

        charObjects [indexA].transform.SetAsLastSibling ();
        charObjects [indexB].transform.SetAsLastSibling ();
    }

    public void Select(CharObject charObject)
    {
        if (firstSelected)
        {
            Swap(firstSelected.index, charObject.index);

            //unselect
            firstSelected=null;
            firstSelected.Select();
            charObject.Select ();

        } else
        {
            firstSelected=charObject;
        }
    }

    public void Unselect()
    {
        firstSelected = null;
    }

    public bool Checkword()
    {
        string word = "";
        foreach (CharObject charObject in charObjects)
        {
            word += charObject.character;
        }

        if (word == words [currentWord].word)
        {
            currentWord++;
            ShowScramble(currentWord);

            return true;
        }

        return false;
    }
}

and CharObject.CS

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class CharObject : MonoBehaviour {

    public char character;
    public Text text;
    public Image image;
    public RectTransform rectTransform;
    public int index;

    [Header("Appearance")]
    public Color normalColor;
    public Color selectedColor;

    bool isSelected = false;

    public CharObject Init(char c)
    {
        character = c;
        text.text = c.ToString ();
        gameObject.SetActive (true);
        return this;
    }

    public void Select()
    {
        isSelected = !isSelected;

        image.color = isSelected ? selectedColor : normalColor;
        if (isSelected) {
            WordScramble.main.Select (this);
        } else
        {
            WordScramble.main.Unselect();
        }
    }
}

The error is coming from the pictures code. Instantiate returns a UnityEngine.Object not a GameObject. Object does not contain GetComponent as it is just a base object. You need to cast what is returned by Instantiate into a GameObject and your problem will be solved.

1 Like

Following on from what chris said heres how to do a cast in c#

CharObject charObj = (Instantiate(prefab.gameObject) as GameObject).GetComponent<CharObject>();

Or use the generic version, which is much cleaner and shorter.

1 Like

@HachimanHikigaya , everyone in this thread is a bit wrong! The code works as-is, and should compile. You probably have an outdated version of Unity. The generic version of Instantiate was introduced in Unity… 5.4? 5.5? Something like that. So if you have a somewhat old version of Unity, the code won’t work.

Download the latest version of the editor. Or, if the tutorial you’re following is using a specific version, download that exact version, as there won’t be differences. You can find older versions of Unity here.

@Suddoha , @lordconstant
The generic version will automatically be used by the compiler, as it’s more specific. When you have these two methods:

public static Object Instantiate(Object original)
public static T Instantiate<T>(T original) where T : Object

the compiler will pick the second one if original is of a type that derives from Object, like GameObject. It can instantiate a version of the generic method where the argument exactly matches the parameter, while picking the non-generic method requires a cast.

so @lordconstant 's code is casting a GameObject to a GameObject. The generic version is already used.

It’s actually wrong to say ‘the code works as-is’ when the version he’s using does not allow it. :smile:
Given the condition the tools are up to date, then it should.

Yes that’s true, it can infer the type, but just like you said, it’s still the generic version though.

Ever since Visual Studio started to provide recommendations regarding this specific simplification I’m a little annoyed, I should change the coloring or disable it. :smile: