Алгоритм генерации «линейного» объекта в Unity - PullRequest
0 голосов
/ 29 мая 2018

Я создаю базовый симулятор в Unity для своего проекта A-level Computer Science.В настоящий момент пользователь может нарисовать объект в виде ящика (ящика), выбрав соответствующий инструмент, щелкнув и перетащив его, чтобы определить два противоположных угла ящика, определив его размеры.

Коробка состоит из одного префаба, который создается и имеет соответственно измененный размер.Код для него выглядит следующим образом:

void Start () {
    boxAnim = boxButton.GetComponent<Animator>();
}

// Update is called once per frame
void Update()
{   
    //sets the mouseDown and mouseHeld bools and the mouse position Vector3
    mouseDown = Input.GetMouseButtonDown(0);
    mouseHeld = Input.GetMouseButton(0);
    mousePosition = Input.mousePosition;
    //checks if the user has started to draw
    if (mouseDown && !draw)
    {
        draw = true;
        originalMousePosition = mousePosition;

    }
    //checking if the user has released the mouse
    if (draw && !mouseHeld)
    {
        finalMousePosition = mousePosition;
        draw = false;
        if (boxAnim.GetBool("Pressed") == true) //if the box draw button is pressed
        {
            boxDraw(originalMousePosition, finalMousePosition); //draws crate
        }
    }
}

void boxDraw(Vector3 start, Vector3 end)
{
    //asigns world coordinates for the start and end mouse positions
    worldStart = Camera.main.ScreenToWorldPoint(start);
    worldEnd = Camera.main.ScreenToWorldPoint(end);
    if (worldStart.y >= -3.2f && worldEnd.y >= -3.2f)
    { 
        //determines the size of box to be drawn
        boxSize.x = Mathf.Abs(worldStart.x - worldEnd.x);
        boxSize.y = Mathf.Abs(worldStart.y - worldEnd.y);
        //crate sprite is 175px wide, 175/50 = 3.5 (50px per unit) so the scale factor must be the size, divided by 3.5
        boxScaleFactor.x = boxSize.x / 3.5f;
        boxScaleFactor.y = boxSize.y / 3.5f;
        //initial scale of the box is 1 (this isn't necessary but makes reading program easier)
        boxScale.x = 1 * boxScaleFactor.x;
        boxScale.y = 1 * boxScaleFactor.y;
        //creates a new crate under the name newBox and alters its size
        GameObject newBox = Instantiate(box, normalCoords(start, end), box.transform.rotation) as GameObject;
        newBox.transform.localScale = boxScale;
    }
}

Vector3 normalCoords(Vector3 start, Vector3 end)
{
    //takes start and end coordinates as position coordinates and returns a world coordinate coordinate for the box
    if(end.x > start.x)
    {
        start.x = start.x + (Mathf.Abs(start.x - end.x) / 2f);
    }
    else
    {
        start.x = start.x - (Mathf.Abs(start.x - end.x) / 2f);
    }
    if(end.y > start.y)
    {
        start.y = start.y + (Mathf.Abs(start.y - end.y) / 2f);
    }
    else
    {
        start.y = start.y - (Mathf.Abs(start.y - end.y) / 2f);
    }
    start = Camera.main.ScreenToWorldPoint(new Vector3(start.x, start.y, 0f));
    return start;
}

Аналогичным образом я хочу, чтобы можно было создать объект «рампа», чтобы пользователь мог щелкнуть и перетащить, чтобы определитьширину базы, затем щелкните еще раз, чтобы определить угол возвышения / высоты (рампа всегда будет прямоугольным треугольником.) Проблема заключается в том, что я хочу, чтобы рампа была спрайтом, который я создал, а не простоосновной цвет блока.Однако один спрайт будет иметь только один угол возвышения, и никакое преобразование не сможет изменить это (насколько я знаю). Очевидно, я не хочу создавать разные спрайты для каждого угла, поэтомуМогу ли я что-нибудь сделать?

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

РЕДАКТИРОВАТЬ: просто чтобы прояснить, что это 2D-среда, код включает в себя Vector3s только потому, что это то, что я привык к

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

У меня есть решение части проблемы с использованием сеток и полигонального коллайдера.Теперь у меня есть функция, которая создаст прямоугольный треугольник с заданной шириной и высотой, и коллайдер в форме этого треугольника:

using UnityEngine;
using System.Collections;

public class createMesh : MonoBehaviour {

    public float width = 5f;
    public float height = 5f;

    public PolygonCollider2D polyCollider;

    void Start()
    {
        polyCollider = GetComponent<PolygonCollider2D>();
    }

    // Update is called once per frame
    void Update () {
        TriangleMesh(width, height);
    }

    void TriangleMesh(float width, float height)
    {
        MeshFilter mf = GetComponent<MeshFilter>();
        Mesh mesh = new Mesh();
        mf.mesh = mesh;

        //Verticies
        Vector3[] verticies = new Vector3[3]
        {
            new Vector3(0,0,0), new Vector3(width, 0, 0), new Vector3(0, 
height, 0)
        };

        //Triangles
        int[] tri = new int[3];

        tri[0] = 0;
        tri[1] = 2;
        tri[2] = 1;

        //normals
        Vector3[] normals = new Vector3[3];

        normals[0] = -Vector3.forward;
        normals[1] = -Vector3.forward;
        normals[2] = -Vector3.forward;

        //UVs
        Vector2[] uv = new Vector2[3];

        uv[0] = new Vector2(0, 0);
        uv[0] = new Vector2(1, 0);
        uv[0] = new Vector2(0, 1);

        //initialise
        mesh.vertices = verticies;
        mesh.triangles = tri;
        mesh.normals = normals;
        mesh.uv = uv;

        //setting up collider
        polyCollider.pathCount = 1;

        Vector2[] path = new Vector2[3]
        {
            new Vector2(0,0), new Vector2(0, height), new Vector2(width, 0)
        };

        polyCollider.SetPath(0, path);

    }
}

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

0 голосов
/ 29 мая 2018

Вы упоминаете Sprite, который является 2D-объектом (ну, на самом деле он очень похож на Quad, который считается как 3D), но вы ссылаетесь на полное 3D в других частях вашего вопроса и в вашем коде, который, я думаю, сбивал людей с толку, потому чтоСоздание текстуры для спрайта - это совсем другая проблема.Я предполагаю, что вы упомянули Sprite по ошибке, и вы на самом деле хотите 3D-объект (в любом случае Unity в большинстве случаев является трехмерным), у него может быть только одна сторона, если вы хотите

Вы можете создавать 3D-фигуры из кода noпроблемы, хотя вам необходимо ознакомиться с классом Mesh, и освоение создания треугольников на лету требует некоторой практики

Вот пара хороших отправных точек

https://docs.unity3d.com/Manual/Example-CreatingaBillboardPlane.html https://docs.unity3d.com/ScriptReference/Mesh.html

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