实例化和销毁Unity预制体

huangapple go评论93阅读模式
英文:

Instantiating and destroying unity prefabs

问题

我正在尝试在Unity中创建一个平台游戏,并且有一个随机生成的平台。我能够生成平台对象,但无法销毁它。

关于创建/销毁预制体的任何帮助将不胜感激。

public GameObject platform;
private Vector2 screenBounds;

void Start()
{
    // 生成平台
    Vector2 spawnPosition = new Vector2();
    for (int i = 0; i < platformCount; i++)
    {
        spawnPosition.y = Random.Range(1f, 10f);
        spawnPosition.x = Random.Range(-2.0f, 2.0f);
        instance = Instantiate(platform, spawnPosition, Quaternion.identity);
    }
    screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));
}

void FixedUpdate()
{
    if (instance != null)
    {
        if (platform.transform.position.y < screenBounds.y * 5)
        {
            Destroy(instance);
        }
    }
}
英文:

I am trying to create a platformer in unity and have a platform that randomly generates. I am able to get the platform object to spawn but cannot get it to be destroyed.

Any help on creating / destroying prefabs would be highly appreciated.

public GameObject platform;
private Vector2 screenBounds;

void Start()
{    // Spawn the platforms
    Vector2 spawnPosition = new Vector2();
    for ( int i=0; i < platformCount; i++) 
    {
        spawnPosition.y = Random.Range(1f , 10f);
        spawnPosition.x = Random.Range(-2.0f, 2.0f);
        instance = Instantiate(platform, spawnPosition, Quaternion.identity);
    }
    screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));
}

void FixedUpdate()
{
    if (instance != null) 
    {
        if (platform.transform.position.y < screenBounds.y * 5) 
        {
            Destroy(instance);
        }
    }
}

答案1

得分: 1

以下是代码部分的中文翻译:

主要问题已经在评论中提到:

instance = Instantiate(platform, spawnPosition, Quaternion.identity);

这在循环中被重新分配,所以最终只会保留最后一次迭代的实例。

在检查中,您正在使用原始的预制体:

if (platform.transform.position.y < screenBounds.y * 5)

这是从您实例化的资源中的预制体,所以在场景中当然不会移动。


我建议将这分为自己的脚本,例如:

public class Spawner : MonoBehaviour
{
    [SerializeField] private OffScreenDestroy platformPrefab;

    void Start()
    {  
        for (int i = 0; i < platformCount; i++) 
        {
            var spawnPosition = new Vector2(Random.Range(1f, 10f), Random.Range(-2.0f, 2.0f));
            Instantiate(platformPrefab, spawnPosition, Quaternion.identity);
        }  
    }
}

// 将这个附加到您的平台预制体
public class OffScreenDestroy : MonoBehaviour
{
    private static Vector2? screenBounds;

    private void FixedUpdate()
    {
        if (screenBounds == null) screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));

        if (transform.position.y < screenBounds.Value.y * 5) 
        {
            Destroy(gameObject);
        }
    }
}

或者将它们保留在一个集合中,例如:

public class Spawner : MonoBehaviour
{
    [SerializeField] private GameObject platformPrefab;

    private readonly List<GameObject> instances = new();
    private Vector2 screenBounds;

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

        for (int i = 0; i < platformCount; i++) 
        {
            var spawnPosition = new Vector2(Random.Range(1f, 10f), Random.Range(-2.0f, 2.0f));
            instances.Add(Instantiate(platformPrefab, spawnPosition, Quaternion.identity));
        }  
    }

    private void FixedUpdate()
    {
        for (var i = instances.Count - 1; i >= 0; i--)
        {
            var instance = instances[i];
            if (instance.transform.position.y < screenBounds.Value.y * 5) 
            {
                Destroy(instance);
            }
        }
    }
}
英文:

The main issue was already mentioned in the comments:

instance = Instantiate(platform, spawnPosition, Quaternion.identity);

this is re-assigned in a loop so it will only end up with the very last iteration's instance.

Further in your check you are using the original prefab

if (platform.transform.position.y < screenBounds.y * 5)

this is the prefab from the assets you instantiate so of course it never moves in the scene at all.


I would either split this into its very own script and do e.g.

public class Spawner : MonoBehaviour
{
    [SerialzieField] private OffScreenDestroy platformPrefab;

    void Start()
    {  
        for ( int i=0; i < platformCount; i++) 
        {
            var spawnPosition = new Vector2(Random.Range(1f , 10f), Random.Range(-2.0f, 2.0f));
            Instantiate(platformPrefab, spawnPosition, Quaternion.identity);
        }  
    }
}

and

// Attach this to your platform prefab
public class OffScreenDestroy : MonoBehaviour
{
    private static Vector2? screenBounds;

    private void FixedUpdate()
    {
        if(screenBounds == null) screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));

        if(transform.position.y < screenBounds.Value.y * 5) 
        {
            Destroy(gameObject);
        }
    }
}

Or alternatively keep them in a collection and do e.g.

public class Spawner : MonoBehaviour
{
    [SerializeField] private GameObject platformPrefab;

    private readonly List<GameObject> instances = new();
    private Vector2 screenBounds;

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

        for ( int i=0; i < platformCount; i++) 
        {
            var spawnPosition = new Vector2(Random.Range(1f , 10f), Random.Range(-2.0f, 2.0f));
            instances.Add(Instantiate(platformPrefab, spawnPosition, Quaternion.identity));
        }  
    }

    private void FixedUpdate()
    {
        for(var i = instances.Count -1; i >= 0; i--)
        {
            var instance = instances[i];
            if(instance.tranform.position.y < screenBounds.Value.y * 5) 
            {
                Destroy(instance);
            }
        }
    }
}

huangapple
  • 本文由 发表于 2023年4月4日 09:45:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/75924903.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定