【问题标题】:Unity: Unable to get GameObject to spawnUnity:无法让游戏对象生成
【发布时间】:2021-02-04 16:20:32
【问题描述】:

我正在尝试让我的游戏对象(小行星)在游戏中不断生成。我查找并按照本教程进行操作:https://pressstart.vip/tutorials/2018/09/25/58/spawning-obstacles.html。为了让小行星移动,我创建了这个脚本(AsteroidObject)并生成了对象,我创建了这个脚本(DeployAsteroids)。没有错误,Debug.Log 出现在控制台中。但是小行星游戏对象是看不到的,也不会产生。任何人都可以帮忙吗?提前致谢!

小行星目标代码:

public class AsteroidObject : MonoBehaviour
{
    public float speed = 10.0f; //how fast the asteroid will move 
    private Rigidbody2D rb;
    private Vector2 screenBounds; //screenbounds calculation 

    // Start is called before the first frame update
    void Start()
    {
        rb = this.GetComponent<Rigidbody2D>(); //find rigidbody 2d and  set it to rb reference by using the getcomponent
        rb.velocity = new Vector2(-speed, 0); //moving the asteroid from right to left by setting the x value, leaving the y value 0 so that it will not move up and down 
        screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z)); //defines the boundaries of the screen on the x and y axis
    }

    // Update is called once per frame
    void Update()
    {
        //transform.position = new Vector3(Mathf.Clamp(transform.position.x, -9f, 9f),
        //Mathf.Clamp(transform.position.y, -4f, 4f), transform.position.z);

        if (transform.position.x < screenBounds.x) //check if it is moving to the left of the screen
        {
          Destroy(this.gameObject);
          Debug.Log("hello world");
        }
    }
}

部署小行星代码:

public class DeployAsteroids : MonoBehaviour
{
    public GameObject asteroidPrefab;
    public float respawnTime = 1.0f;
    private Vector2 screenBounds;

    // Start is called before the first frame update
    void Start()
    {
        screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));
        StartCoroutine(asteroidWave());
    }

    private void spawnEnemy()
    {
        GameObject a = Instantiate(asteroidPrefab) as GameObject;
        a.transform.position = new Vector2(screenBounds.x * -2, Random.Range(-screenBounds.y, screenBounds.y));
    }

    IEnumerator asteroidWave()
    {
        while (true)
        {
            yield return new WaitForSeconds(respawnTime);
            spawnEnemy();
            //Debug.Log("Hello World");
        }
    }
}

【问题讨论】:

  • 请谨慎标记您的问题。 Visual-Studio 与您的问题完全无关,请注意 unityscript 是一种 JavaScript 风格,类似于早期 Unity 版本中使用的自定义语言,现在早已弃用!你的脚本显然是c#
  • 主摄像头是透视模式还是正交模式?

标签: c# unity3d


【解决方案1】:

你自己也这么说

Debug.Log 出现在控制台中。

好吧,您在销毁对象的那一刻就登录 => 它已经消失了。

Destroy(this.gameObject);
Debug.Log("hello world");

除非你的意思是在 spawn 方法之后的 out 注释日志。您仍然会立即销毁该对象。如果您使用有用的日志而不是两次相同的日志,我认为您会立即发现它

Debug.Log("Spawned a new object");

Debug.Log("Destroyed an object");

那么到底发生了什么?

您会立即销毁新生成的对象!

  1. 你会的

     screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));
    

    将位置存储在屏幕的右边框

    比如说,例如x = 2; 某处(总随机虚构示例数)。

  2. 然后在生成后立即将其设置为

     a.transform.position = new Vector2(screenBounds.x * -2, Random.Range(-screenBounds.y, screenBounds.y));
    

    因此,对于 x,您将其设置为(使用我们的示例值)x = -4;

    这甚至不是屏幕的左边界,而是更远!

  3. 另外你告诉小行星移动

     rb.velocity = new Vector2(-speed, 0);
    

    所以假设值speed 是正的,甚至在负 x 方向上。

  4. 最后你做到了

     // Even without the Rigidbody this is already comparing
     // if(-2 * screenBounds.x < screenBounds.x)
     // Or with our example numbers
     // if(-4 < 2)
     if (transform.position.x < screenBounds.x)
     {
         Destroy(this.gameObject);
         Debug.Log("hello world");
     }
    

    =>此条件将始终为真,并立即销毁下一帧中的对象。


那我应该怎么做呢?

我假设你正试图在边界生成小行星。

并且想在它通过边界后摧毁它。所以应该是

private void spawnEnemy()
{
    GameObject a = Instantiate(asteroidPrefab);
    Vector3 rightEdgeWorldPoint = Camera.main.ScreenToWorldPoint( 
            new Vector3(Screen.width, Random.Range(0, Screen.height), 
            Camera.main.nearClipPlane);
    rightEdgeWorldPoint.z = 0f;
    a.transform.position = rightEdgeWorldPoint;
}

在小行星上

if (Camera.main.WorldToScreenPoint(transform.position).x < 0)
{
    Destroy(this.gameObject);
    Debug.Log("Left the screen -> destroyed");
}

注意:在智能手机上输入,但我希望思路清晰

【讨论】:

  • 是的,我正试图在对象离开屏幕后将其销毁。但是,游戏对象现在甚至不会在游戏视图/场景视图中生成。我可以知道是什么问题吗?
  • @johnny 我修改了一些代码,如果解决了请告诉我
【解决方案2】:

转到场景层次结构并检查那里是否可以看到小行星。可能你在游戏或场景摄像机中看不到它们,但如果它们在场景中,它们就会在某个地方生成。在问题中更新将是有趣的信息。

我没有深入研究代码,但如果它们在那里,您需要检查或设置它们相对于相机产生的位置,以便小行星进入视野。

检查此行中给出的位置:a.transform.position = new Vector2(screenBounds.x * -2, Random.Range(-screenBounds.y, screenBounds.y)); 以及它是否适合相机视野。

【讨论】:

  • 对于这行代码,我应该放什么推荐字段?
  • 任何适合相机视野的东西。我将调试赋予生成游戏对象的位置并检查其是否正确。您可以通过添加一个空的游戏对象或图元(立方体)来检查这一点,并检查您在游戏窗口中看到它们的立方体的位置,因为它在相机的视野范围内
猜你喜欢
  • 1970-01-01
  • 2021-02-06
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多