Как сделать так, чтобы Physics2D.IgnoreLayerCollision игнорировал только физические жесткие столкновения и не запускал столкновения?

#c# #unity3d #collision-detection

Вопрос:

Я только что обнаружил, как игнорировать столкновения, и это действительно полезно. Я хочу этого, потому что хочу, чтобы в моей игре было какое-то сокровище, в котором был бы как физический жесткий коллайдер, так и триггер, когда мой игрок касается его. Я не хочу, чтобы мой игрок физически столкнулся с сокровищем, но я хочу, чтобы мое сокровище физически столкнулось с землей и не провалилось.

К сожалению, когда я использовал Physics2D.IgnoreLayerCollision его, он также игнорирует мой триггерный коллайдер, который я использую, когда мой игрок подходит к сокровищу, чтобы забрать его. Я хочу, чтобы триггерный коллайдер был включен, а физический жесткий коллайдер был отключен.

Вот мой код:

 public class colliderTreasureScript : MonoBehaviour
{
    public Rigidbody2D rb;
    public float jumpforce;
    public float speed;
    public LayerMask playerlayer; // 8
    public LayerMask treasurelayer; // 9
    // Start is called before the first frame update
    void Start()
    {
        Physics2D.IgnoreLayerCollision(8, 9, true);
        Physics2D.IgnoreLayerCollision(9, 8, true);
        Physics2D.IgnoreLayerCollision(9, 9,true);
        rb = GetComponent<Rigidbody2D>();
        rb.AddForce(Vector2.up * jumpforce * Time.deltaTime, ForceMode2D.Impulse);
    }
 

Вот еще один сценарий для сбора сокровищ

 public class GenericTreasureScript : MonoBehaviour
{
    public float rotatespeed;
    private Player playerscript;
    public int treasurevalue;
    public Transform movetowardsposition;
    public float speed;
    public bool touched;
   // public CircleCollider2D heavycollider;
    // Start is called before the first frame update
    void Start()
    {
        movetowardsposition = GameObject.Find("ScorePositionUpdated").transform;
        touched = false;
        playerscript = FindObjectOfType<Player>();
        //rotatespeed = Random.Range(140, 155.3f);
        speed = Random.Range(18, 22);
    }

    // Update is called once per frame
    void Update()
    {
        if (touched == true)
        {

            transform.position = Vector2.MoveTowards(transform.position, movetowardsposition.position, speed * Time.deltaTime);
        }
        if (Vector2.Distance(transform.position, movetowardsposition.position) < .2f)
        {
            destroy();
        }
}

 private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {


            playerscript.score  = treasurevalue;
            touched = true;
            StartCoroutine("destroyBackup");
        }


    }
 

Ответ №1:

Я не хочу, чтобы мой игрок физически столкнулся с сокровищем, но я хочу, чтобы мое сокровище физически столкнулось с землей и не провалилось

Если вы хотите разделить физический и триггерный коллайдер, чтобы он все равно срабатывал при контакте с игроком, но не вызывал столкновения.

Вы можете либо:

  1. Удалите RigidBody2D полностью, объект, который запускается, не нужен, а RigidBody2D только игрок в вашем случае и удалите физический коллайдер
  2. Оставьте RigidBody2D , но установите значение gravityScale 0 и удалите физический коллайдер
  3. Добавьте еще один дополнительный слой и переместите физический коллайдер на другой родительский игровой объект с помощью этого слоя , например "treasurephysicallayer" , затем отключите столкновение только между этим слоем и игроком вместо слоя, на котором находились оба коллайдера

Пример № 3:

 public LayerMask playerlayer; // 8
public LayerMask treasurelayer; // 9
public LayerMask treasurephysicallayer; // 10

// Start is called before the first frame update
void Start() {
    Physics2D.IgnoreLayerCollision(8, 8, true);
    Physics2D.IgnoreLayerCollision(8, 10, true);
    Physics2D.IgnoreLayerCollision(10, 8, true);
    Physics2D.IgnoreLayerCollision(9, 9, true);
    Physics2D.IgnoreLayerCollision(9, 10, true);
    Physics2D.IgnoreLayerCollision(10, 9, true);
    Physics2D.IgnoreLayerCollision(10, 10, true);
}
 

Дополнительно устанавливаем слои через. код возможен, но установить их в Physics2D PlayerSettings гораздо проще.

Вы можете просто отметить галочкой или включить соответствующее столкновение, которое вы в данный момент устанавливаете с помощью кода.

Матрица столкновений

Комментарии:

1. Я просто хотел бы сказать, что вы абсолютный гений! Не могу поверить, что я об этом не подумал. Мне все еще нужно жесткое тело и коллайдер, поэтому я выбрал номер три, но вместо этого я сделал коллайдер детским объектом. Все работает отлично. Ты настоящий гений, ха-ха, большое тебе спасибо!

2. @Джон, почему вы вообще настраиваете это с помощью кода, а не просто в матрице столкновений на уровне Physics2D ?