简体   繁体   English

Unity:无法让游戏对象生成

[英]Unity: Unable to get GameObject to spawn

I am trying to get my GameObject (asteroid) to spawn continuously in the game.我试图让我的游戏对象(小行星)在游戏中不断产生。 I looked up and followed this tutorial: https://pressstart.vip/tutorials/2018/09/25/58/spawning-obstacles.html .我查看并遵循了本教程: https://pressstart.vip/tutorials/2018/09/25/58/spawning-obstacles.html To make the asteroid move, I created this script (AsteroidObject) and to spawn the objects, I created this script (DeployAsteroids).为了让小行星移动,我创建了这个脚本(AsteroidObject)并生成了对象,我创建了这个脚本(DeployAsteroids)。 There are no errors and the Debug.Log appears in the console.没有错误,Debug.Log 出现在控制台中。 But the asteroid game object cannot be seen and will not spawn.但是小行星游戏 object 看不到也不会生成。 Anyone can help?任何人都可以帮忙吗? Thanks in advance!提前致谢!

Asteroid Object Codes:小行星 Object 代码:

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");
        }
    }
}

DeployAsteroid codes:部署小行星代码:

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");
        }
    }
}

You even say it yourself你甚至自己说

the Debug.Log appears in the console. Debug.Log 出现在控制台中。

Well, you log in the moment you destroy your object => it is already gone.好吧,您在销毁 object 的那一刻登录 => 它已经消失了。

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

Unless you mean the out commented log after the spawn method.除非您的意思是在 spawn 方法之后的 out 注释日志。 You still immediately destroy the object.您仍然会立即销毁 object。 I think you would spot it immediately if you would use useful logs and not twice the same one如果您使用有用的日志而不是两次相同的日志,我认为您会立即发现它

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

and

Debug.Log("Destroyed an object");

So what exactly is happening then?那么到底发生了什么?

You immediately destroy the new spawned objects!您立即销毁新生成的对象!

  1. you do你做

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

    which stores the position at the right border of the screen.它将 position 存储在屏幕的右边框

    Let's say eg somewhere at x = 2;假设例如x = 2; (total random imaginary example number). (总随机虚构示例数)。

  2. Then right after spawning you set it to然后在生成后立即将其设置为

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

    So for the x you set it to (using our example value) x = -4;因此,对于 x 您将其设置为(使用我们的示例值) x = -4;

    This is not even the left boarder of the screen but even beyond!这甚至不是屏幕的左边界,甚至更远!

  3. Additionally you tell the asteroid to move另外你告诉小行星移动

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

    so assuming the value speed is positive even more into negative x direction.所以假设speed值是正的,甚至更多地进入负 x 方向。

  4. And finally you do最后你做到了

     // 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"); }

    => This condition will always be true and immediately destroys your objects in the next frame. => 这个条件永远成立,并在下一帧立即销毁你的对象。


So what should I do instead?那么我应该怎么做呢?

I assume you are trying to spawn the asteroid at the right boarder.我假设您正试图在正确的边界生成小行星。

And want to destroy it after it passed the left boarder.并想在它通过左边界后将其摧毁。 So it should probably be所以应该是

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;
}

And in the asteroid而在小行星

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

Note: Typed on smartphone but I hope the idea gets clear注意:在智能手机上输入,但我希望这个想法很清楚

Go to the scene hierarchy and check if the asteroids can be seen there. Go 到场景层级并检查那里是否可以看到小行星。 May be you do not see them within the game or the scene camera, but if they are in the scene they are spawn somewhere.可能你在游戏或场景摄像机中看不到它们,但如果它们在场景中,它们就会在某个地方生成。 It would be interesting info to update in the question.在问题中更新将是有趣的信息。

I did not dig into the code but if they are there, you need to check or set the position in which they are spawned respect to the camera, for the asterioids to be in the field of view.我没有深入研究代码,但如果它们在那里,您需要检查或设置 position,它们在相机中产生,以便小行星进入视野。

Check the posistion given in this line: a.transform.position = new Vector2(screenBounds.x * -2, Random.Range(-screenBounds.y, screenBounds.y));检查此行中给出的位置: a.transform.position = new Vector2(screenBounds.x * -2, Random.Range(-screenBounds.y, screenBounds.y)); and if it fits in the camera field of view.如果它适合相机的视野。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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