Tratamento de colisão com física padrão (2D)

Página atualizada :
Data de criação de página :

Ambiente de verificação

Windows
  • Janelas 11
Unity Editor
  • 2021.3.3f1
Pacote do sistema de entrada
  • 1.3.0

Pré-requisitos para esta dica

As configurações a seguir foram feitas com antecedência como premissa para a descrição desta dica.

Inicialmente

Essa dica coloca dois objetos para que você possa implementar o comportamento de manipular um objeto e usar a física padrão do Unity para empurrar o outro quando ele entra em contato com o outro.

A propósito, a maioria das configurações são as mesmas do procedimento descrito no artigo anterior "Determinando se os objetos colidem entre si (2D)".

Preparação

O procedimento aqui é quase o mesmo das dicas anteriores , então vamos fluir sem problemas.

Depois de criar o projeto, prepare duas imagens de sprite que serão objetos e adicione-as. Os nomes são "UnityTips" e "UnityTips_2", respectivamente.

Adicione dois arquivos de imagem soltando-os na exibição.

Adicione um script para mover o objeto esquerdo com o teclado. O nome Player do script é .

using UnityEngine;
using UnityEngine.InputSystem;

public class Player : MonoBehaviour
{
  // 一定時間ごとに呼ばれます
  void FixedUpdate()
  {
    // キーボードの情報を取得
    var keyboard = Keyboard.current;

    // スプライトの移動処理
    if (keyboard.leftArrowKey.isPressed)
    {
      transform.Translate(-0.1f, 0, 0, Space.World);
    }
    if (keyboard.rightArrowKey.isPressed)
    {
      transform.Translate(0.1f, 0, 0, Space.World);
    }
    if (keyboard.upArrowKey.isPressed)
    {
      transform.Translate(0, 0.1f, 0, Space.World);
    }
    if (keyboard.downArrowKey.isPressed)
    {
      transform.Translate(0, -0.1f, 0, Space.World);
    }
  }
}

Anexe ao objeto no qual você deseja executar o script.

Execute o jogo e verifique se ele funciona com as teclas do cursor no teclado.

Finalmente, coloque um objeto de texto para exibir o status de detecção de colisão. O nome do TextState objeto é .

Configurações de manipulação de colisão

A partir daqui, você pode definir as configurações relacionadas a colisões.

Primeiro, selecione o objeto que deseja mover, "UnityTips", e clique em "Add Component" no inspetor. Physics 2D Selecione na lista. Physics é um objeto 3D, então não se engane.

Physics 2DBox Collider 2D Selecione a partir de . Como esse sprite é retangular, Box é selecionado, mas se ele estiver em forma de círculo, por exemplo, selecione outras formas, como Circle.

Da última vez, eu queria obter informações apenas sobre se eu acertei ou não, então marquei "Fazer disparar", mas desta vez não vou. Isso permite o manuseio de colisões na física.

Rigidbody 2D Em seguida, adicione os componentes do . Você pode adicioná-lo a partir de "Physics 2D -> Rigidbody 2D". Rigidbody dá informaçõesCollider físicas ao objeto e também pode determinar colisões com objetos que têm .

Defina a Escala de Gravidade como 0 para evitar queda livre abaixo.

Da mesma forma, adicione um componente ao outro objeto "UnityTips_2" para marcar Box Collider 2D acertos.

Além disso, desta vez é necessário se movimentar com a força do adversário,Rigidbody 2D então adicione. A escala de gravidade deve ser 0.

É só isso. Nenhum programa é necessário no momento. Execute o jogo e tente tocar em outro objeto.

Acho que você pode confirmar que, se você empurrar o adversário assim, o adversário vai se comportar como se fosse empurrado. É muito fácil usar a física da função padrão porque nenhum programa é necessário.

Impedir que objetos girem

Você pode ver quando você toca nele, mas se o ponto de acerto mudar mesmo que ligeiramente, cada objeto irá girar. Como um jogo, muitas vezes se torna antinatural, então você precisa configurá-lo para que ele não gire.

Rigidbody 2D O componente tem um item chamado "Rotação fixa" em "Restrições", então marque Z. Agora você pode trabalhar para que ele não gire. Tente configurá-lo para dois objetos e executar o jogo para verificá-lo.

Acho que você pode ter certeza de que ele não gira, não importa de que ângulo você o empurre.

Faça algo quando os objetos se atingirem uns aos outros

Por exemplo, você pode querer implementar uma bala que atinja um inimigo enquanto empurra o oponente enquanto reduz a saúde do inimigo. Isso é o mesmo que as dicas anteriores , pois o evento ocorrerá, para que você possa lidar com ele.

Player Abra o script e adicione cada campo e método usando o seguinte:

using System;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class Player : MonoBehaviour
{
  /// <summary>状態表示用テキストオブジェクト。</summary>
  [SerializeField] private Text TextState;

  // 中略

  /// <summary>衝突した瞬間に呼ばれます。</summary>
  /// <param name="partner">衝突した相手のコリジョン情報。</param>
  private void OnCollisionEnter2D(Collision2D partner)
  {
    TextState.text = $"OnCollisionEnter2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
  }

  /// <summary>衝突している間呼ばれます。ただしスリープモードになった場合は呼ばれません。</summary>
  /// <param name="partner">衝突した相手のコリジョン情報。</param>
  private void OnCollisionStay2D(Collision2D partner)
  {
    TextState.text = $"OnCollisionStay2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
  }

  /// <summary>衝突状態でなくなったタイミングで呼ばれます。</summary>
  /// <param name="partner">衝突した相手のコリジョン情報。</param>
  private void OnCollisionExit2D(Collision2D partner)
  {
    TextState.text = $"OnCollisionExit2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
  }
}

Como queremos exibir informações sobre se ele foi atingido ou não, faremos com que seja possível exibi-lo em um objeto de texto da seguinte maneira.

/// <summary>状態表示用テキストオブジェクト。</summary>
[SerializeField] private Text TextState;

O processo de detecção de colisão é descrito a seguir.

/// <summary>衝突した瞬間に呼ばれます。</summary>
/// <param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionEnter2D(Collision2D partner)
{
  TextState.text = $"OnCollisionEnter2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}

/// <summary>衝突している間呼ばれます。ただしスリープモードになった場合は呼ばれません。</summary>
/// <param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionStay2D(Collision2D partner)
{
  TextState.text = $"OnCollisionStay2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}

/// <summary>衝突状態でなくなったタイミングで呼ばれます。</summary>
/// <param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionExit2D(Collision2D partner)
{
  TextState.text = $"OnCollisionExit2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}

Semelhante às dicas anteriores------, mas o nome do método agora é "OnCollision------2D" em vez de "OnTrigger2D".

Rigidbody 2D Cada um dos eventos acima ocorre quando um objeto que colide com outro objeto Collider 2D que tem . Isso permitirá que você determine e processe se está correto ou não.

Há três eventos, cada um dos quais é chamado no momento seguinte.

OnCollisionEnter2D Quando os objetos batem uns nos outros
OnCollisionStay2D Enquanto os objetos estão batendo uns nos outros
OnCollisionExit2D Quando os objetos saem do estado de colisão

Em ambos os casos, o objeto do oponente recebe o objeto do oponente como um argumento, então você pode obter o objeto do Collision2D oponente procurando Collider2D.gameObject o tipo de alvo atingido por (inimigo, item, Collider2D.collider.tag etc.).

Dos OnCollisionEnter2D três eventos acima, e OnCollisionExit2D são chamados uma vez por colisão.

OnCollisionStay2D é chamado de cada quadro durante a colisão, mas o evento não é mais chamado depois de um certo período de tempo desde que ambos os objetos pararam. Isso ocorre porque é considerado ter entrado em um estado de sono, e é considerado um desperdício de processamento calcular colisões a cada quadro com algo que não está se movendo.

Se você Rigidbody 2D não quiser que ele entre em suspensão, altere o modo de suspensão do parâmetro para "Não dormir".

Depois de alterar o código, defina o texto para exibir informações.

Execute o jogo e mova o objeto com o teclado para tocar em outro sprite. Você pode ver que três funções são chamadas para cada uma.

A propósito, se você tocar em um objeto e, em seguida, parar de se mover, o método será chamado por OnCollisionStay2D um curto período de tempo. Você deve ser capaz de ver que o método não é mais chamado após OnCollisionStay2D um certo período de tempo.

Isso indica que você entrou em um estado de suspensão, mas se quiser alterar o tempo até entrar nessa suspensão, poderá alterá-lo selecionando "Física 2D" nas configurações do projeto e especificando o parâmetro "Tempo de suspensão" em segundos. Ele não pode ser definido como 0, mas se for OnCollisionStay2D definido como infinitamente pequeno, o método em si não será chamado.