Pasek życia.
W tym temacie zajmiemy się zrobieniem prefabrykatu paska życia dla obiektu gracza lub każdego innego obiektu występującego na scenie 3D.
Poniższy krótki film przedstawia działanie paska. Przykładowo każdorazowe przejście prze portal zabiera 5% punktów życia (kliknij na obrazku aby obejrzeć film).
Zadania paska życia
Warunki jakie narzucimy na wygląd paska życia to:
- pasek ma być zlokalizowany tuż nad obiektem 3D
- pasek ma być zawsze zwrócony w stronę głównej kamery sceny
- pasek ma zmieniać rozmiar względem stan punktów życia obiektu
- pasek ma zawierać tekst z procentową skalą punktów życia
- pasek ma zawierać ikonę serca lub inny obrazek
- pasek ma oprawę graficzną w formie ramki
Ułożenie elementów tworzonego paska przy rozciągniętej osi głębokości przedstawia poniższa ilustracja
Czerwony pasek nie zmienia swojej długości, zielony tak. Ramka pełni rolę maski dla krawędzi pasków. W docelowym działaniu pasek prezentuje się jak poniżej.
Sprite 2D dla paska życia
Oprawę graficzną dla paska życia przygotujemy w programie GIMP w postaci zasobu grafiki o wymiarach 512x512 pikseli. W Unity wykorzystamy technikę tekstur 2D wycinanych jako sprite z jednego zasobu graficznego. Ważne aby zasób graficzny miał wymiary potęgi liczby 2 (64x64, 128x128, 512x512 itd.). Dla takich wymiarów uzyskuje się lepszą kompresję zasobów graficznych.
Przykład mojego zasobu dla tworzonego paska życia. Puste miejsca można w dalszym etapie tworzenia projektu wykorzystać na inne ikony (jedzenie, broń, narzędzia itp.)
Gotowy zasób graficzny zapisujemy w postaci pliku *.png z kanałem przezroczystości.
Przechodzimy do Unity. Tworzymy folder na grafikę 2D (u mnie folder nazwałem małą literą g). Do folderu importujemy utworzony plik *.png. Z zaimportowanego pliku tworzymy tekturę typu Sprite 2D, z ustawieniem właściwości Sprite Mode na Multiple. Patrz poniższe ilustracje
Jeżeli w Unity nie masz zainstalowanego rozszerzenia 2D Sprite Package to je zainstaluj.
Otwórz Sprite Edytor
W opcjach wybierz automatyczne wycinanie duszków
Wybrane zmiany zatwierdź klawiszem Apply
Jeżeli wszystko zostało zrobione prawidłowo, to w folderze z zasobami grafiki po kliknięciu na ikonę zaimportowanego pliku zobaczysz podział na osobne tekstury. Jednocześnie zasób został skompresowany.
Przygotowanie prefabrykatu paska życia
Do sceny dodajemy pusty obiekt (Create Empty). Na razie zostawiamy nazwę GameObject. Do pustego obiektu dodajemy komponenty: Canvas, Canvas Scaler, Graphic Raycaster. Patrz poniższe ustawienia.
Korzeń obiektu paska życia został utworzony. Korzeń jest ojcem dla paska czerwonego, paska zielonego, paska oprawy graficznej i serduszka.
Tworzymy pasek czerwony przez dodanie kolejnego pustego obiektu (Create Empty). Do obiektu dodajemy komponent Canvas Render, Image. Ustawiamy zakotwiczenie na środek lewego boku (patrz Rect Transform). W komponencie Image przypisujemy kolo czerwony. Patrz poniższa ilustracja.
Dwukrotnie duplikujemy dodany pusty obiekt. Dla GameObject (1) ustawiamy kolor zielony. Dla GameObject (2) w komponencie Image we właściwości Source Image osadzamy teksturę oprawy graficznej. Patrz poniższa ilustracja.
Dopasowujemy rozmiary obrazów
W pasku zielonym zmieniamy współrzędną X osi obrotu (Piwot)- ustawiamy na zero.
Po zmianie współrzędnej X osi obrotu musisz dopasować współrzędne zakotwiczenia paska. Jeżeli zmienisz skalę po osi X to zauważysz, że pasek skraca się lub wydłuża. I tę zmienną należy obsłużyć w skrypcie.
Do paska dodamy jeszcze ikonę serca. Duplikujemy pierwszy pasek (czerwony). Ustawiamy obraz na serduszko.
Zerujemy współrzędne Z
Dodajemy kolejny pusty obiekt na tekst. Podpinamy do niego komponent Text Mesh. Ustawiamy parametry tekstu- kolor, rozmiar itp. Zmieniamy odpowiednio nazwy obiektów. Patrz poniższa ilustracja.
Skrypt paska życia
Zmiana długości paska w podanym skrypcie odbywa się poprzez zmianę skali wzdłuż osi X. Zakres wartości skali to od 0 do 1. Gdzie 1 to 100% długości. Przykładowa zmiana długości w podanym przykładzie będzie odbywać się po każdorazowym przejściu przez portal. Stąd w skrypci pojawia się taki warunek
Wskazówka:
if (Instancja.fZabierz)
Patrz poniższy kod i komentarz.
Wskazówka:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class pasekZycia : MonoBehaviour
{
[Header("Options")]
[Range(0f, 100f)] public float maxHP = 100.0f;//max punkty zycia
[Range(0f, 100f)] public float hp = 100.0f;//biezace punkty zycia
[SerializeField] Image pasekZielony;
[SerializeField] TextMesh pasekTekstu;
void Start()
{
}
public void ZabierzHP(float ile)
{
hp -= ile;
if (hp < 0) hp = 0;
float skala = hp / maxHP;
//ustaw długośc paska zycia na podstawie skali,
//piwot w inspektorze jest wybrany na lewy bok
//co pozwala skracać pasek z prawgo boku
pasekZielony.transform.localScale = new Vector2(skala, pasekZielony.transform.localScale.y);
pasekTekstu.text = (skala * 100).ToString() + "%";
}
// Update is called once per frame
void LateUpdate()
{
if (Instancja.fZabierz)
{
ZabierzHP(Instancja.ileZabracZycia);
Instancja.fZabierz = false;
Instancja.ileZabracZycia = 0;
}
//obracaj pasek życia plaszczyzną do kamery
transform.LookAt(transform.position +
Camera.main.transform.rotation*Vector3.forward,
Camera.main.transform.rotation*Vector3.up);
}
}
Skrypt podpinamy do paska i ustawiamy jak poniżej.
Wykonujemy zmiany w skrypcie Instancja. Dopisujemy dwie zmienne ileZabracZycia oraz Zabierz. Patrz poniżej
Wskazówka:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Instancja : MonoBehaviour
{
//skrypt zachowujący kazdy obiekt przy przejsciu z jednej sceny do drugiej
public static Instancja instancja;
//nazwa tagu portalu przejścia z jednej sceny do innej
public static string tagPortal;
//zaznacz ze gracz się nie teleportował
public static bool fTeleportacja=false;
//zabierz punkty zycia przy teleportacji
public static float ileZabracZycia = 0.0f;
public static bool fZabierz = false;
private void Awake()
{
if (!instancja)
{
DontDestroyOnLoad(this.gameObject);
instancja = this;
}
else
{
Destroy(this.gameObject);
}
}
}
Przechodzimy do skryptu Portal. Dopisujemy dwie linijki kodu w metodzie OnTriggerStay(). Patrz poniższy kod (doszły dwie ostatnie linie kodu)
Wskazówka:
//gdy gracz jest wewnatrz portalu
private void OnTriggerStay(Collider other)
{
if (other.tag != "Player") return;
//nie było teleportacji to sie teleportuj
if (!Instancja.fTeleportacja)
{
//załaduj nowa scenę
Application.LoadLevel(nazwaScenyCelu);
//zaznacz ze gracz się teleportował
Instancja.fTeleportacja = true;
//zabierz punkty zycia przy telportacji
Instancja.ileZabracZycia = 5.0f;
Instancja.fZabierz = true;
}
}
To na tyle zmian w skryptach. Skrypty pochodzą z poprzedniej części (patrz link)
Z paska życia tworzymy prefabrykat i podpinamy do obiektu gracza.
Uruchom scenę i sprawdź zachowanie. Cały pasek powinien być zwrócony w stronę głównej kamery sceny.
Jeżeli przejdziesz przez portal, to za każdym razem zostanie zabrane 5% życia.