简体   繁体   中英

Is it possible to cast Unity GameObject to ScriptableObject class type?

I have created scriptable object custom class Card:

[CreateAssetMenu(fileName = "Card", menuName = "Card")]
public class Card : ScriptableObject
{
    public new string name;
    public string Description;
    public Sprite HeroImage;
    public int Attack;
    public int Health;
    public int XCoord;
    public int YCoord;
}

I have added plenty of such objects through Unity Editor, and instanced such objects as GameObjects on 2d Canvas:

for (int i = 0; i < 5; i++)
{
    GameObject go = Instantiate(CardPrefabTemplate, new Vector3(x_delt, 0, 0), Quaternion.identity) as GameObject;
    go.transform.SetParent(MPlayerOpenedCards.transform, false);
    go.gameObject.name = "CardUIPrefabOpened" + i;
    x_delt += (int)(CardPrefabTemplBackgrRect.rect.width * CardPrefabTemplateBackground.localScale.x) + x_card_margin;
}

After Raycast by mouse click I get current clicked Card GameObject :

GameObject RaycastOpenedCard(string prefabName)
{
    //Set up the new Pointer Event
    m_PointerEventData = new PointerEventData(m_EventSystem);
    //Set the Pointer Event Position to that of the mouse position
    m_PointerEventData.position = Input.mousePosition;
    //Create a list of Raycast Results
    List<RaycastResult> results = new List<RaycastResult>();
    //Raycast using the Graphics Raycaster and mouse click position
    m_Raycaster.Raycast(m_PointerEventData, results);

    if (Input.GetMouseButtonDown(0))
    {
        foreach (RaycastResult result in results)
        {
            if (result.gameObject.transform.parent != null && Regex.IsMatch(result.gameObject.transform.parent.name, prefabName))
            {
                Debug.Log("Hit " + result.gameObject.transform.parent.name);
                return result.gameObject.transform.parent.gameObject;
            }
        }
    }
    return null;
}

In other part of program, I have List<Card> ActiveCards list and I am not able to cast Raycasted GameObject to scriptableobject class Card :

GameObject g = RaycastOpenedCard("CardUIPrefabOpened");
if (g != null)
{
    if (ActiveCards != null && ActiveCards.Count < 5)
    {
        Mplayer.ActiveCards.Add(g.GetComponent<Card>());
    }
}

Is it possible to cast Unity GameObject to ScriptableObject class type?

Error:

ArgumentException: GetComponent requires that the requested component 'Card' derives from MonoBehaviour or Component or is an interface. UnityEngine.GameObject.GetComponent[T] () (at C:/buildslave/unity/build/Runtime/Export/Scripting/GameObject.bindings.cs:28) BoardManager.Update () (at Assets/Scripts/BoardManager.cs:202)

Simply put, no, it's not possible to cast a GameObject to ScriptableObject , nor the opposite for that matter. This is because GameObject doesn't inherit from ScriptableObject and neither does ScriptableObject from GameObject . Both of them directly inherit from Object however.

The reason the line GameObject go = Instantiate(CardPrefabTemplate, new Vector3(x_delt, 0, 0), Quaternion.identity) as GameObject; is because Instantiate that takes an Object as argument and that clones it, returning an Object . A ScriptableObject is an Object so that works. And you can cast an Object to an GameObject so that works too. But that doesn't achieve much as the only thing you'll keep by doing that is the Object part, so in your example, Object.name .

Now the reason GetComponent fails is because it can only look for a MonoBehaviour , which a ScriptableObject (Card) isn't. MonoBehaviour also inherit from Object a some point by the way.

So the real question is what were you trying to achieve in the first place ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM