Como aplainar o terreno sob um objeto de jogo?

10

Eu tenho um script que cria um objeto de terreno e o pinta com texturas, mas estou tendo um problema. Quando tento colocar objetos de jogo (como o objeto de água simples que a unidade fornece), uso um Raycast para determinar a altura correta para colocar o objeto de jogo, mas isso apenas garante que ele seja colocado corretamente naquele ponto específico.

Como eu aplainaria o terreno sob o objeto de jogo para que ele não entre no terreno ou fique no ar no caso de colinas?

Rapida
fonte
3
Encontre todos os vértices que formam os triângulos do terreno sob o objeto do jogo. Faça a coordenada y de todos esses vértices da mesma forma.
Michaelhouse

Respostas:

6

Como eu disse no meu comentário, você encontrará todos os vértices que compõem os triângulos sob o objeto do jogo e definirá o valor de y para o mesmo valor.

Expandirei meu comentário com etapas mais detalhadas. Eu não estou muito familiarizado com o Unity, por isso não conheço as melhores ferramentas para usar no trabalho, mas acredito que posso ajudá-lo a começar o caminho certo.

Método de força bruta:

  1. Lance uma grade de raios diretamente do seu objeto de jogo. A grade deve ser firme o suficiente para garantir que não falte nenhum triângulo na superfície do terreno.
  2. Para cada raio que atinge algo, você pode obter o triângulo na malha do terreno com o seguinte:

    RaycastHit hit;
    if (!Physics.Raycast(camera.ScreenPointToRay(Input.mousePosition), out hit))
        return;
    
    MeshCollider meshCollider = hit.collider as MeshCollider;
    if (meshCollider == null || meshCollider.sharedMesh == null)
        return;
    
    Mesh mesh = meshCollider.sharedMesh;
    Vector3[] vertices = mesh.vertices;
    int[] triangles = mesh.triangles;
    Vector3 p0 = vertices[triangles[hit.triangleIndex * 3 + 0]];
    Vector3 p1 = vertices[triangles[hit.triangleIndex * 3 + 1]];
    Vector3 p2 = vertices[triangles[hit.triangleIndex * 3 + 2]];
  3. p0, p1 e p2 são todas as posições dos três vértices que compõem o triângulo atingido. Você deseja ajustar cada uma dessas posições dos vértices para ter o mesmo yvalor. Você pode coletar todos os vértices e defini-los com um yvalor médio ou usar o yvalor escolhido inicial encontrado ao colocar seu objeto de jogo.

Otimizações:

  • Em vez de apenas lançar uma grade de raios, você pode varrer um colisor do objeto de jogo e coletar os pontos de contato das colisões entre o colisor de objetos do jogo e a malha de colisão do terreno. Em seguida, para cada um desses pontos de contato, execute as etapas acima para obter os vértices que você deseja mover.

  • Crie seu terreno de tal maneira que cada vértice xe zvalores estejam alinhados a uma grade e variem apenas em seu yvalor. Agora você pode facilmente obter os limites do seu objeto de jogo e alterar todos os valores y dos vértices dentro desses limites.

Essa última otimização é realmente um método alternativo que provavelmente seria fácil de implementar e bastante eficaz.

MichaelHouse
fonte
Pelo que posso dizer, o objeto Terrain ( docs.unity3d.com/Documentation/ScriptReference/Terrain.html ) possui um TerrainCollider ( docs.unity3d.com/Documentation/ScriptReference/… ) e não um MeshCollider ( docs.unity3d.com/Documentation / ScriptReference /… ), portanto, falta uma propriedade sharedMesh que você tenta usar na etapa 2. Supus que seria necessário algum tipo de lógica para modificar o mapa de altura que a propriedade terrainData armazena.
Rapida
Você pode verificar aqui: forum.unity3d.com/threads/… Além disso, parece que o objeto terreno tem uma malha regular, portanto a segunda otimização pode ser sua melhor aposta.
MichaelHouse
1

Normalmente, o solo sob o objeto deve ser plano e o solo imediatamente ao redor dele ser suavizado.

Se o terreno é feito de uma grade e o edifício é alinhado aos eixos, isso é muito mais fácil.

No caso geral, subdivide os triângulos em que a construção se assenta e, em seguida, define o y de todos os vértices nos triângulos em que a construção se assenta com o mesmo y e, em seguida, efetua um deslocamento no ponto médio para todos os vértices a uma certa distância, não eles mesmos debaixo de um edifício.

Eu usei essa abordagem para colocar estradas em um terreno 3D.

Você normalmente deseja impor uma separação mínima entre prédios para ter terreno suficiente para suavizar. Ou você pode executar o algoritmo provisoriamente antes da colocação e ver se algum limite de inclinação é excedido e, portanto, policiar onde o usuário pode colocar edifícios.

Vai
fonte