GetComponent无法将类型“类”隐式转换为GameController

时间:2019-07-18 16:28:12

标签: c# unity3d

我正在制作一个游戏系统,其中玩家使用吊索,当他击中目标并摧毁它时,他会获得得分,但是我无法将其他脚本转换成游戏对象。通过getcomponent。

我过去曾遇到过此问题,而更改FindGameObjectsWithTag可以更早地解决它,但现在却没有,我仍然不明白为什么会这样,因为我重新启动了一次并重新编写了WHOLE项目之后它工作得很好。但是我这次不想这样做。

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

public class GameController : MonoBehaviour
{
    public int Score { get; private set; }
    public Text ScoreText;
    private static GameController _instance;
    public static GameController Instance
    {
        get
        {
            if(_instance == null)
            {
                var obj = GameObject.FindWithTag("GameController");
                if (obj != null)
                {
                      _instance = obj.GetComponent<SlingBackController>();
                }
            }
            return _instance;
        }  
        set
        {
            _instance = value;
        }
    }
    void Awake()
    {
        Instance = this;
    }

    void Start()
    {
        Score = 0; 
    }

    public void AddToScore(int points)
    {
        if(points >0)
        {
            Score += points;
            ScoreText.text = Score.ToString();
        }
    }
}

错误在此行: _instance = obj.GetComponent();

它应该可以正常工作,没有任何问题,但是显然可以,而且我不太了解它们。

2 个答案:

答案 0 :(得分:0)

private static GameController _instance;更改为private static SlingBackController _instance;

问题是计算机需要GameController,但是您在_instance = obj.GetComponent<SlingBackController>();处为它分配了SlingBackController,这是行不通的。

答案 1 :(得分:0)

您正在尝试为类型为SlingBackController的字段分配GameController引用。

如前所述,您似乎只是将代码从SlingBackController复制到了GameController,却忘记了相应地排除GetComponent的类型。

应该是

public static GameController Instance
{
    get
    {
        if(!_instance)
        {
            var obj = GameObject.FindWithTag("GameController");
            if (obj)
            {
                  _instance = obj.GetComponent<GameController>();
            }
        }
        return _instance;
    }  
    private set
    {
        _instance = value;
    }
}

或更有效的使用FindObjectOfType

public static GameController Instance
{
    get
    {
        if(!_instance) _instance = FindObjectOfType<GameController>();

        return _instance;
    }  
    private set
    {
        _instance = value;
    }
}

但是,这就是所谓的“延迟初始化”,这意味着仅在需要时才执行。

由于无论如何都要在Awake中设置值,因此您实际上应该确保在Instance方法之前,没有类依赖于Start

我的黄金法则通常是:

  • 使用 Awake 初始化类自己的值和进行GetComponent调用。
  • 只要该类依赖于另一个首先初始化的类值,就使用 Start

有时候这是不可能的,那么您可以使用Script execution order settings来配置脚本执行的顺序,或者作为后备使用您的代码进行延迟初始化。