Prefabrykaty
Każdy obiekt, model 3D może być utworzony z obiektu rodzica (być jego klonem), który jest matrycą odwzorowania dla potomka. Taka matryca zwana jest prefabrykatem. Stosowanie prefabrykatów ułatwia dynamiczne tworzenie modeli 3D w trakcie działającej sceny.
Cel: Utwórz w scenie model lufy strzelającej pociskami w losowym kierunku.
Zmodyfikuj układ sceny z tematu Kolizje i wyzwalacze kolizji. Zmień ułożenie i wielkość obiektu o nazwie Cube. Dodaj do niego obiekt 3D typu Cylinder. Zmień mu nazwę na Lufa. Utwórz i przypisz nowy materiał do obiektu Lufa. Ustaw nowe parametry transformacji (pozycja, rotacja, skala). Patrz poniższy rysunek
Dodaj do sceny nowy obiekt 3D typu Shpere. Nadaj mu nazwę Pocisk, przypisz materiał, ustaw rozmiar- skalę. Dodaj komponent ciała fizycznego (Add Component/ Physics/ Rigidbody)
Załóż w projekcie nowy folder o nazwie Prefabrykaty.
Otwórz folder Prefabrykaty. W obszar otwartego folderu Prefabrykaty przeciągnij myszką z listy obiekt o nazwie Pocisk. Patrz poniższa ilustracja
Jest to najprostszy sposób tworzenia prefabrykatów. Do każdego z prefabrykatów można dodawać dowolne skrypty i inne właściwości. W omawianym przykładzie ograniczymy do najprostszego zastosowania. Usuń obiekt (Pocisk) ze sceny.
Dynamiczne tworzenie obiektów z prefabrykatów
Nasz model lufy będzie mieć zadanie wystrzeliwania pocisków w losowy sposób. Do jednego końca lufy dodamy pusty obiekt (Create Empty). Będzie to slot wystrzeliwujący pociski z wykorzystaniem prefabrykatu Pocisk.
Powyższa ilustracja pokazuje kolejne kroki, które należy wykonać aby obiektowi na scenie przypisać ikonę widoczności oraz Tag. Czynności te nie są wymagane w tworzeniu sceny, ale pomagają w przypadku używania pustych obiektów (Create Empty).
Otwieramy folder Skrypty i tworzymy skrypt o nazwie Strzelaj. Utworzony skrypt osadzamy w slocie na pociski
Wypełnij skrypt poniższym kodem
Wskazówka:
public class Strzelaj : MonoBehaviour
{
[SerializeField] private GameObject prefabPocisk;
[Header("Opcje")]
[Range(10.0f, 100.0f)]
[SerializeField] private float v = 15.0f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
Parametr [Header] utworzy w edytorze Unity nagłówek o nazwie Opcje. Do tych opcji będzie należeć zmienna v (współczynnik prędkości), który wstępnie będziemy zmieniać wartościami z przedziału od 10 do 100. Odpowiednią wartość ustalimy przy uruchomionej scenie. Do skryptu przenieś prefabrykat pocisku, tak jak pokazuje to poniższy rysunek.
Możemy przyjąć, że pocisk będzie wystrzeliwany po wciśnięciu spacji. Wektor prędkości ustalimy z wektora transformacji slotu. Tu należy uważać z doborem kierunku wektora strzału. W zależności jak wykonywane były przekształcenia budowy lufy należy odpowiednio dobrać kierunek do swojego projektu używając transform.up, transform.forward
Wskazówka:
void Update()
{
if(Input.GetKeyUp(KeyCode.Space))
{
Rigidbody rb = Instantiate(prefabPocisk,transform.position,transform.rotation);
rb.velocity= transform.up*v;
}
}
Skompiluj program i sprawdź efekt działania. Wynikiem będzie strzelanie, na scenie pojawi się tyle pocisków ile razy wciśnięto spację.
Dodajemy kręcenie się lufy wokół osi pionowej
Obrót możemy zrobić z wykorzystaniem nowego skryptu lub użyć już istniejący podpięty do slotu pocisku. Aby wykorzystać już istniejący skrypt należy odczytać właściciela slotu- czyli lufę. Jest to obiekt nadrzędny w stosunku do slotu. Pełni rolę ojca. Modyfikujemy skrypt Strzelaj do takiej postaci
Wskazówka:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Strzelaj : MonoBehaviour
{
[SerializeField] private Rigidbody prefabPocisk;
[Header("Opcje")]
[Range(10.0f, 100.0f)]
[SerializeField] private float v = 15.0f;
Transform ojciec;
// Start is called before the first frame update
void Start()
{
ojciec = transform.parent;
}
// Update is called once per frame
void Update()
{
ojciec.transform.Rotate(new Vector3(0,0,25)*Time.deltaTime);
if(Input.GetKeyUp(KeyCode.Space))
{
Rigidbody rb = Instantiate(prefabPocisk,transform.position,transform.rotation);
rb.velocity= transform.up*v;
}
}
}
Skompiluj program i sprawdź efekt działania. Lufa powinna się obracać. Po naciśnięciu spacji strzelamy w aktualnym kierunku.
Czas życia obiektu
Obiekty na scenie mogą żyć tak długo jak chcemy. Możliwość określenia czasu życia obiektu ma znaczenie na przykład dla pocisków. Nasze pociski będziemy uśmiercać po trzech sekundach życia. Aby to zrobić używa się funkcji Destroy(). Funkcja podana z jednym parametrem niszczy natychmiast. Jeżeli podamy z dwoma parametrami, to możemy zdecydować ile czasu na scenie ma żyć obiekt. Pierwszy parametr to uśmiercany obiekt, drugi parametr to czas w sekundach po którym obiekt zostaje zniszczony.
Przerabiamy skrypt Strzelaj
Wskazówka:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Strzelaj : MonoBehaviour
{
[SerializeField] private GameObject prefabPocisk;
[Header("Opcje")]
[Range(10.0f, 100.0f)]
[SerializeField] private float v = 15.0f;
Transform ojciec;
// Start is called before the first frame update
void Start()
{
ojciec = transform.parent;
}
// Update is called once per frame
void Update()
{
ojciec.transform.Rotate(new Vector3(0,0,25)*Time.deltaTime);
if(Input.GetKeyUp(KeyCode.Space))
{
GameObject p = Instantiate(prefabPocisk,transform.position,transform.rotation);
p.GetComponent<Rigidbody>().velocity= transform.up*v;
Destroy(p,3);
}
}
}
Po zmianach w skrypcie należy ponownie podpiąć do skryptu prefabrykat pocisku.
Skompiluj program i sprawdź efekt działania. Obiekty pocisków będą ginąć po zadanym przedziale czasu.