Physics2D.OverlapCircleAll 未检测到其他游戏对象 [英] Physics2D.OverlapCircleAll not detecting other gameobjects

查看:95
本文介绍了Physics2D.OverlapCircleAll 未检测到其他游戏对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个敌人的预制件,它会在玩家周围的随机位置多次生成.但是,有时这会使一个敌人预制件与另一个敌人预制件重叠.

I have a prefab of a enemy that will spawn in a random position multiple times around the player. However, sometimes this can make one enemy prefab overlap another enemy prefab.

因此,我编写了一个脚本,它使用 Physics2D.OverlapCircleAll() 在实例化敌人预制件之前检测任何碰撞体,从而避免敌人预制件与现有敌人重叠.我的问题是 OverlapCircleAll() 没有检测到预制件的其他实例.

So, I wrote a script which uses Physics2D.OverlapCircleAll() to detect any colliders before instantiating the enemy prefab which avoids the enemy prefab from overlaping an existing enemy. My issue is that the OverlapCircleAll() didn't detect the other instances of the prefab.

我也已经尝试过 Physics2D.OverlapBoxAll.如果我生成超过 30 个这些敌人预制件",至少一个会与另一个敌人重叠

I already tried with Physics2D.OverlapBoxAll aswell. If I spawn more than 30 of these "enemy prefabs", at least one will overlap another enemy

这是用于检测重叠的代码:

public void SpawnEachEnemy(GameObject Enemy)
{
    Vector3 futurePosition = new Vector2(UnityEngine.Random.Range(UpperLeft.transform.position.x, DownRight.transform.position.x),
                                UnityEngine.Random.Range(UpperLeft.transform.position.y, DownRight.transform.position.y));
    bool correctPosition = false;
    while (!correctPosition)
    {
        Collider2D[] collider2Ds = Physics2D.OverlapCircleAll(futurePosition,0.2f);
        if (collider2Ds.Length > 0)
        {
            //re-spawning to prevent overlap
            futurePosition = new Vector2(UnityEngine.Random.Range(UpperLeft.transform.position.x, DownRight.transform.position.x),
                                UnityEngine.Random.Range(UpperLeft.transform.position.y, DownRight.transform.position.y));
        }
        else
        {
            correctPosition = true;
        }
    }

    GameObject b = Instantiate(Enemy) as GameObject;
    b.transform.position = futurePosition;
    b.transform.parent = this.transform;
}

推荐答案

Louis Garczynski 提到了一些可能性,但没有提到的是,如果这些都在单个帧的范围内实例化(基于猜测的在评论中说 SpawnEachEnemy 在循环中被调用),那么您可能需要在 Physics2D Settings 下启用 Auto Sync Transforms:

Louis Garczynski mentioned a few of the possibilities but one that wasn't mentioned is that if these are all instantiating in the span of a single frame (a guess based on a comment saying SpawnEachEnemy is called in a loop), then you may need to enable Auto Sync Transforms under Physics2D Settings:

这个最小可重现示例在新的 3D 项目场景中连接到相机时应该可以正常工作Auto Sync Transforms 已启用,禁用时将无法防止重叠.这可能是阻止它为您工作的原因:

This minimal reproducible example when attached to the camera in a new 3D project's scene should work as you intend with Auto Sync Transforms enabled and it will fail to prevent overlaps when it is disabled. It may be what is preventing it from working for you:

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

public class TestScript : MonoBehaviour
{
    Vector3 upperLeft;
    Vector3 downRight;

    GameObject prefab;

    // Start is called before the first frame update
    void Start()
    {
        transform.position = new Vector3(0, 0, -3);
        upperLeft = new Vector3(-1, -1);
        downRight = new Vector3(1, 1);

        prefab = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        DestroyImmediate(prefab.GetComponent<SphereCollider>());
        prefab.transform.localScale = 0.4f * Vector3.one;
        prefab.AddComponent<CircleCollider2D>();

        for (int i = 0; i < 12; i++)
        {
            SpawnEachEnemy(prefab);
        }

        prefab.SetActive(false);

    }


    public void SpawnEachEnemy(GameObject Enemy)
    {
        Vector3 futurePosition;
        Collider2D[] collider2Ds;

        do { 
            futurePosition = new Vector2(
                UnityEngine.Random.Range(
                    upperLeft.x,
                    downRight.x),

                UnityEngine.Random.Range(
                    upperLeft.y, 
                    downRight.y));

            collider2Ds = Physics2D.OverlapCircleAll(futurePosition, 0.2f)
        } 
        while (collider2Ds.Length > 0)

        GameObject b = Instantiate(Enemy) as GameObject;
        b.transform.position = futurePosition;
        b.transform.parent = this.transform;
    }
}

这篇关于Physics2D.OverlapCircleAll 未检测到其他游戏对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆