Hej, witajcie w drugiej części serii postów poświęconych generowaniu siatki w Unity. W tym poście stworzymy trójwymiarową bryłę oraz zajmiemy się stworzeniem mesh collidera, a więc nasz obiekt będzie mógł oddziałować fizycznie na świat!
Poprzednia nudna siatka |
Pamiętacie poprzednią siatkę którą stworzyliśmy? Nie ciekawy, dwuwymiarowy obiekt. Dzisiaj stworzymy coś znacznie ciekawszego, mianowicie trochę brył platońskich. No może nie trochę, a jedną ☺. Bowiem sam Platon mawiał: "Trójkąty są najprostszym elementem budulcowym, podstawową cegiełką, z której zbudowany jest Kosmos". Zaskakująco dobrze pasuje to do naszego przypadku. Trójkąty czyli poligony są podstawowym budulcem naszych obiektów!
W poprzednim poście poprosiłem czytelników by sami rozgryźli dlaczego raz poligon zwrócony jest w jedną stronę, a raz w drugą. Tutaj wytłumaczę o co chodzi.
rys.01 |
Jeżeli chcemy by tworzony poligon był widoczny z naszej strony, musimy dodać punkty składające się na poligon wedle wskazówek zegara. (rys.01)
I tak jak na dołączonym obrazku, jeżeli chcemy by nasz poligon był zwrócony w naszą stronę, musimy poszczególne punkty dodawać według wskazówek zegara, czyli po kolei: wpierw punkt o ID 1, potem 0 i na końcu 2. Równie dobrze mogło by być wpierw 0, potem 2 i na końcu 1. Chodzi tu bardziej o samą zasadę.
Kiedy to mamy już wytłumaczone, zabierzmy się do pracy.
rys.02 |
Na sam początek dobrym pomysłem będzie stworzenie sześcianu. (Taka bryła jak na drugim rysunku)
rys.03 |
Sześcian, jak widać to na rysunku trzecim, składa się z 8 punktów. Stwórzmy zatem tablice 8 elementową zawierającą punkty, oraz tablice o rozmiarze 36 przechowującą informacje o poligonach. (36 ponieważ: 6 ścian * 2 poligony * 3 punkty)
Vector3[] verticles = new Vector3[8];
verticles[0] = new Vector3(0, 0, 0);
verticles[1] = new Vector3(1, 0, 0);
verticles[2] = new Vector3(1, 1, 0);
verticles[3] = new Vector3(0, 1, 0);
verticles[4] = new Vector3(0, 0, 1);
verticles[5] = new Vector3(1, 0, 1);
verticles[6] = new Vector3(1, 1, 1);
verticles[7] = new Vector3(0, 1, 1);
Utwórzmy teraz poligony.
int[] triangles = new int[36];
//Przednia ściana
triangles[0] = 2;
triangles[1] = 1;
triangles[2] = 0;
triangles[3] = 0;
triangles[4] = 3;
triangles[5] = 2;
//Tylnia ściana
triangles[6] = 4;
triangles[7] = 5;
triangles[8] = 6;
triangles[9] = 6;
triangles[10] = 7;
triangles[11] = 4;
//Lewa ściana
triangles[12] = 0;
triangles[13] = 4;
triangles[14] = 7;
triangles[15] = 7;
triangles[16] = 3;
triangles[17] = 0;
//Prawa ściana
triangles[18] = 6;
triangles[19] = 5;
triangles[20] = 1;
triangles[21] = 1;
triangles[22] = 2;
triangles[23] = 6;
//Górna ściana
triangles[24] = 2;
triangles[25] = 3;
triangles[26] = 7;
triangles[27] = 7;
triangles[28] = 6;
triangles[29] = 2;
//Dolna ściana
triangles[30] = 5;
triangles[31] = 4;
triangles[32] = 0;
triangles[33] = 0;
triangles[34] = 1;
triangles[35] = 5;
Dodałem komentarze po to, by ładniej było widać która część kodu odpowiada za którą ścianę.Punktem odniesiania jest pierwsza "przednia ściana".
Tak prezentuje się nasza figura na scenie:
Prawda że wygląda pięknie? ☺
Teraz czas na wisienkę na torcie - kolizje.
Aby sprawić by figura reagowała fizycznie z otoczeniem, musi mieć collider. W naszym przypadku posłużymy się MeshColliderem. Dodajmy go zatem do wymaganych komponentów i uzyskamy do niego dostęp w kodzie.
I teraz cała magia, dodajmy do niego siatkę naszego obiektu. Dodatkowo przypiszmy polu convex wartość true. (Na razie nie będę wyjaśniał czemu, tak ma być i koniec 😈)
sharedMesh = meshToCollider;
meshCollider.convex = true;
I to wszystko. Teraz wystarczy dodać komponent RigidBody i możemy cieszyć się efektami naszej pracy ☺
Dodajmy jeszcze jakąś powierzchnie i możemy cieszyć się naszym sześcianem fizycznie reagującym z otoczeniem ☺
Tak prezentuje się cały kod:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshCollider))]
[RequireComponent(typeof(Rigidbody))]
public class Szescian : MonoBehaviour {
MeshRenderer meshRenderer;
MeshFilter meshFilter;
MeshCollider meshCollider;
Mesh mesh;
// Use this for initialization
void Start()
{
meshRenderer = gameObject.GetComponent();
meshFilter = gameObject.GetComponent();
meshCollider = gameObject.GetComponent();
mesh = new Mesh();
Vector3[] verticles = new Vector3[8];
verticles[0] = new Vector3(0, 0, 0);
verticles[1] = new Vector3(1, 0, 0);
verticles[2] = new Vector3(1, 1, 0);
verticles[3] = new Vector3(0, 1, 0);
verticles[4] = new Vector3(0, 0, 1);
verticles[5] = new Vector3(1, 0, 1);
verticles[6] = new Vector3(1, 1, 1);
verticles[7] = new Vector3(0, 1, 1);
int[] triangles = new int[36];
//Przednia ściana
triangles[0] = 2;
triangles[1] = 1;
triangles[2] = 0;
triangles[3] = 0;
triangles[4] = 3;
triangles[5] = 2;
//Tylnia ściana
triangles[6] = 4;
triangles[7] = 5;
triangles[8] = 6;
triangles[9] = 6;
triangles[10] = 7;
triangles[11] = 4;
//Lewa ściana
triangles[12] = 0;
triangles[13] = 4;
triangles[14] = 7;
triangles[15] = 7;
triangles[16] = 3;
triangles[17] = 0;
//Prawa ściana
triangles[18] = 6;
triangles[19] = 5;
triangles[20] = 1;
triangles[21] = 1;
triangles[22] = 2;
triangles[23] = 6;
//Górna ściana
triangles[24] = 2;
triangles[25] = 3;
triangles[26] = 7;
triangles[27] = 7;
triangles[28] = 6;
triangles[29] = 2;
//Dolna ściana
triangles[30] = 5;
triangles[31] = 4;
triangles[32] = 0;
triangles[33] = 0;
triangles[34] = 1;
triangles[35] = 5;
mesh.vertices = verticles;
mesh.triangles = triangles;
meshFilter.mesh = mesh;
meshCollider.sharedMesh = mesh;
meshCollider.convex = true;
}
}
Ten komentarz został usunięty przez autora.
OdpowiedzUsuńTen komentarz został usunięty przez autora.
OdpowiedzUsuń