(C#) Как вырезать игровые объекты в unity 3d - PullRequest
0 голосов
/ 09 июля 2020

Моя цель - построить средневековые дома из реальных данных (через openstreetmap, 3D-объекты из блендера). Стены уже построил (исправно работают). Но проблема в этажах (я использую плоскости): они уже находятся в правильном положении и вращении, но масштаб неправильный. С обычными прямоугольными домами я могу легко масштабировать его, но более сложный (прямоугольник в прямоугольнике). Вот несколько важных переменных: way.NodeIds - это массив с идентификаторами (в openstreetmap они используют идентификаторы, которые вы можете сравнить с узлов в файле openstreetmap xml; map.nodes - это массив, в котором расположена информация о точках; в переменной paths есть такая информация, как дорога, здание и т. д .; мне нужно вычесть map.bounds В некоторых местах центр, потому что обычно точки действительно далеко. Мой код пока что:

using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;

[RequireComponent(typeof(MapReader))]
class BuildingMaker : InfrastructureBehaviour
{

    public GameObject[] stonewall;

    public GameObject woodenfloor;


    private IEnumerator Start()
    {
        while (!map.IsReady)
        {
            yield return null;
        }
        GameObject buildings = new GameObject();
        buildings.transform.name = "Buildings";
        buildings.transform.parent = map.transform;
        foreach (var way in map.ways.FindAll((w) => { return w.IsBuilding && w.NodeIDs.Count > 1; }))
        {

            GameObject building = new GameObject();
            Vector3 localOrigin = GetCentre(way);
            building.transform.position = localOrigin;
            building.transform.parent = buildings.transform;
            building.transform.name = way.Name;
            Vector3[] vertices = new Vector3[way.NodeIDs.Count];
            float longestDistance = 0;
            //floor.transform.localScale = new Vector3(100f, 0f, 100f);
            for (int i = 1; i < way.NodeIDs.Count; i++)
            {

                OsmNode p1 = map.nodes[way.NodeIDs[i - 1]];
                OsmNode p2 = map.nodes[way.NodeIDs[i]];
                vertices[i - 1] = map.nodes[way.NodeIDs[i - 1]];
                Vector3 v1 = new Vector3(p1.X, 0f, p1.Y);
                Vector3 v2 = new Vector3(p2.X, 0f, p2.Y);
                float dist = Vector3.Distance(v1, v2);
                int j = (int)dist * 44 < 445 ? (int)dist * 44 : 444;
                int wallCount = (int)dist / 10;

                if (longestDistance <= Vector3.Distance(localOrigin, new Vector3(v1.x - map.bounds.Centre.x, 0f, v1.z - map.bounds.Centre.z)))
                {
                    longestDistance = Vector3.Distance(localOrigin, new Vector3(v1.x - map.bounds.Centre.x, 0f, v1.z - map.bounds.Centre.z));
                }
                else if (longestDistance <= Vector3.Distance(localOrigin, new Vector3(v2.x - map.bounds.Centre.x, 0f, v2.z - map.bounds.Centre.z)))
                {
                    longestDistance = Vector3.Distance(localOrigin, new Vector3(v2.x - map.bounds.Centre.x, 0f, v2.z - map.bounds.Centre.z));
                }

                double x = (p1.X + p2.X) / 2 - map.bounds.Centre.x;
                double y = (p1.Y + p2.Y) / 2 - map.bounds.Centre.z;
                Vector3 v3 = v2 - v1;
                Quaternion quaternion = Quaternion.FromToRotation(Vector3.right, v3) * Quaternion.Euler(0f, 0f, 90f);
                if (wallCount >= 1)
                {
                    GameObject wall2 = Instantiate(stonewall[j], LerpByDistance(v1, v2, 5) - map.bounds.Centre, quaternion);
                    wall2.transform.parent = building.transform;
                    for (int k = 1; k < wallCount; k++)
                    {
                        GameObject wall = Instantiate(stonewall[j], LerpByDistance(v1, v2, k * 10 + 5) - map.bounds.Centre, quaternion);
                        wall.transform.parent = building.transform;
                    }
                } else if (wallCount == 0)
                {
                    GameObject wall = Instantiate(stonewall[j], new Vector3(Convert.ToSingle(x), 0f, Convert.ToSingle(y)), quaternion);
                    //wall.transform.position = LerpByDistance(v1, v2, 5) - map.bounds.Centre;
                    wall.transform.parent = building.transform;
                }
                if (!(dist % 10 == 0) & wallCount >= 1)
                {

                    j = ((int)dist - wallCount * 10) * 44 < 445 ? ((int)dist - wallCount * 10) * 44 : 444;
                    GameObject wall = Instantiate(stonewall[j], LerpByDistance(v1, v2, (wallCount * 10) + (j != 0 ? (45f / 4430f) * j + 0.5f - (45f / 4430f) : 0.5f)) - map.bounds.Centre, quaternion);
                    wall.transform.parent = building.transform;
                }
            }

            GameObject floor = Instantiate(woodenfloor, building.transform.position, Quaternion.FromToRotation(Vector3.right, new Vector3(map.nodes[way.NodeIDs[1]].X - map.bounds.Centre.x, 0f, map.nodes[way.NodeIDs[1]].Y - map.bounds.Centre.z) - new Vector3(map.nodes[way.NodeIDs[0]].X - map.bounds.Centre.x, 0f, map.nodes[way.NodeIDs[0]].Y - map.bounds.Centre.z)) * Quaternion.Euler(-90f, 0f, 0f));
            floor.transform.parent = building.transform;
            floor.transform.localScale = new Vector3(longestDistance*100f, longestDistance*100f, longestDistance*100f);
            
            yield return null;
        }
    }
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...