【问题标题】:spawn obstacles c# and accessing from another script产生障碍 c# 并从另一个脚本访问
【发布时间】:2016-07-04 07:42:05
【问题描述】:

当我尝试在管理器类中实例化时出现错误。说 错误 CS1061:类型 UnityEngine.Object' does not contain a definition forGetComponent' 并且找不到扩展方法 GetComponent' of typeUnityEngine.Object'。您是否缺少程序集参考? (CS1061) (Assembly-CSharp)

【问题讨论】:

  • 抱歉对我太粗鲁了.. 完成了。

标签: c# unity3d unity5


【解决方案1】:

将此添加到您的 Obstacle 课程中:

void Start()
{
    manager = GameObject.FindWithTag("ObstacleManager").GetComponent<ObstacleManager>();
}

标签显然必须是管理器附加到的游戏对象的标签。

另外:总是以大写字母开头类名(我在 sn-p 中这样做了,请记住这一点,你会得到一个错误)。

也许你想稍微改变一下你的产卵。有两个列表,一个是免费的生成点,一个是被占用的。当您摧毁障碍物时,将位置传递给生成函数以将位置移动到空闲列表中。

编辑

创建引用的另一个选项是在生成时将其设置在您的ObstacleManager 中。为此,您需要获取对实例化障碍物的引用。我相信这应该可以在不实际抓取障碍游戏对象的情况下工作,但您也可以这样做。

Obstacle obs = ((GameObject)Instantiate(TypeOfObstacles[j], pointsAvailiable[pointsIndex].position, Quaternion.identity)).GetComponent<Obstacle>();
obs.SetManagerReference(this);

并在Obstacle 中添加

public void SetManagerReference(ObstacleManager obsManager)
{
    manager = obsManager;
}

对于空闲位置,您可以执行以下操作:

// in Obstacle.cs
public void OnMouseDown()
{
    manager.SpawnNewObstacle(transform.position);    // you might be able to actually pass the transform, but I'm not sure if it will get destroyed before used in the other function
    Destroy(gameObject);
}

在管理器中:

public  int noOfObsacles;

public float[] xPercent;
public GameObject[] TypeOfObstacles;

float y;

// to keep track of which spawn points are free and which aren't use these lists
private List<Transform> freePositions;
private List<Transform> occupiedPositions;

private void Start()
{
    freePositions = new List<Transform>(spawnPoints);
    occupiedPositions = new List<Transform>();

    SpawnObstacles();
}

private void SpawnObstacles()
{
    // just use this for initial obstacles
    // call Spawn as often as needed
    for(int i = 0; i < noOfObstacles; i++)
    {
        Spawn();
    }
}

// you call this function from the obstacle that gets destroyed
public void SpawnNewObstacle(Vector3 freePos)
{
    // find the spawnpoint in the occupied points
    // and move it to the free ones since the obstacle got destroyed
    for(int i = 0; i < occupiedPositions.Count; i++)
    {
        if(occupiedPositions[i].position == freePos)
        {
            freePositions.Add(occupiedPositions[i]);
            occupiedPositions.RemoveAt(i);
            break;
        }
    }
    // and call Spawn
    Spawn();
}

private void Spawn()
{
    y = Random.value;
    int pointsIndex = Random.Range (0, freePositions.Count); 

    for (int j =0; j<xPercent.Length; j++)
    {

        if ( y <  xPercent[j])
        {
            // these 4 lines are essential for the spawning
            Obstacle obs = ((GameObject)Instantiate(TypeOfObstacles[j], freePositions[pointsIndex], Quaternion.identity).GetComponent<Obstacle>();
            obs.SetManagerReference(this);
            occupiedPositions.Add(freePositions[pointsIndex]);
            freePositions.RemoveAt(pointsIndex);

            break;
        }
    }
}

【讨论】:

  • 我真的很困惑..你能解释一下吗...? :( 是否还有另一种使用 findWithtag 我真的不想使用它...
  • 您需要创建对其他类的引用。由于您的障碍物是在运行时产生的,因此您无法在编辑器中填充该变量。
  • 你可以使用 find 或者实际上你也可以在生成过程中设置它。
  • 我编辑了我的答案。这应该让您开始了解如何获得连接。我不确定您是否可以直接在Instantiate 上获取Obstacle obs,或者您是否首先需要游戏对象并在另一行中执行此操作。对于延迟生成,您可以执行 Invoke("Spawn", 5) 之类的操作。
  • 并且为示例简化了实例化。随心所欲地启动它。
【解决方案2】:

有一个括号问题!我的坏

障碍物 obs = ((GameObject)Instantiate(TypeOfObstacles[j], freePositions[pointsIndex].position, Quaternion.identity)).GetComponent();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    • 2021-10-11
    相关资源
    最近更新 更多