Unity3d OneLine – problemy, które da się rozwiązać w jednej linii kodu. Dosłownie!

Linia: Dynamiczna zmiana opacity obrazka (Efekt Trafienia)

Efekt trafienia, był omawiany w kursie, który pisałem dość dawno temu. Od pojawienia się Untiy 5, często zgłaszano mi problemy z tym efektem. Problemem były zmiany w budowie Unity. Brak obiektów typu GUI, zmiany w animacjach etc. Dlatego dziś sobie z tym poradzimy, stosując metodę kodową. Czyli, oprzemy się na samym skrypcie, dzięki czemu nasza “animacja” zanikania tekstury, powinna być nieśmiertelna.

Żeby zacząć zabawę, potrzeba nam jakiejś fajnej tekstury krwi. Ja sobie jedną pobrałem od pana Sagacious z DevianArta – przy okazji go oznaczam, dopełniając warunków licencji.

Przejdźmy do rzeczy. Pierwszy krok to wrzucenie do naszego projektu pobranej tekstury i ustawienie jej opcji Texture Type, na GUI Editor and Legacy GUI.

Ustawiamy Texture Type
Ustawiamy Texture Type

Teraz tworzymy sobie nowy skrypt (u mnie OneLine_04_01.cs – tak, sprytnie wykorzystałem typ kursu, jego numer i numer skryptu). Cały skrypt dodajemy do obiektu MainCamera. Jak na OneLina, kodu mamy sporo. Wygląda on tak:

using UnityEngine;
using System.Collections;

public class OneLine_04_01 : MonoBehaviour {

	public Texture2D bloodTexture;
	private bool hit = false;
	private float opacity = 0.0f;

	void  OnGUI () {
		if (Input.GetKey (KeyCode.P)) {
			hit = true;
			opacity = 1.0f;
		}

		if(hit) {
			GUI.color = new Color(GUI.color.r, GUI.color.g, GUI.color.b, opacity);
			GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), bloodTexture, ScaleMode.ScaleToFit);
			StartCoroutine("waitAndChangeOpacity");
		}

		if (opacity <= 0) {
			hit = false;
		}
	}

	IEnumerator waitAndChangeOpacity()
	{
		yield return new WaitForEndOfFrame();
		opacity -= 0.05f;
	}
}

Zadeklarowane zmienne to kolejno: Nasza tekstura, flaga sprawdzająca czy mamy wyświetlić animowanie tekstury oraz licznik przeźroczystości (kanał alfa, albo z angielskiego opacity).

Teraz możesz na chwilę skoczyć do Unity i dodać sobie teksturę w odpowiednie miejsce – czyli wybrać obiekt MainCamera i przenieść na odpowiednie pole teksturę:

Ustawiamy Teksturę
Ustawiamy Teksturę

Teraz będę wrzucał fragmenty podanego wyżej kodu, aby je wyjaśnić. Zaczniemy od funkcji OnGUI:

if (Input.GetKey (KeyCode.P)) {
	hit = true;
	opacity = 1.0f;
}

To jest nasz trigger, czyli coś co wywoła wyświetlenie i animację tekstury. W normalnych warunkach będzie to trafienie przez przeciwnika, czy spadek z wysokości. Na potrzeby tego poradnika, zdarzenie wywołuje naciśnięcie klawisza P. W środku, oznaczamy flagę, wywołującą animację, oraz ustawiamy startową przeźroczystość na 1.0, czyli 100%.
[stextbox id=”info” defcaption=”true”]Kolory i przeźroczystość w Unity, jest podawana w sposób znormalizowany. Tzn. przyjmuje wartości z przedziału 0 do 1. W większości standardowych programów graficznych, kolory przyjmują wartości od 0 do 255. Wartość znormalizowaną, możemy rozumieć jako procent tych wartości. Tzn.: 0 = 0%, a 1 = 100%. Tak więc, np. 0.3 = 30% z maksymalnych 255.[/stextbox]

if(hit) {
	GUI.color = new Color(GUI.color.r, GUI.color.g, GUI.color.b, opacity);
	GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), bloodTexture, ScaleMode.ScaleToFit);
	StartCoroutine("waitAndChangeOpacity");
}

Kolejny if, jest w sumie odpowiedzialny za cały tutorial. Powyższy kod wykonuje się, gdy mamy oznaczaną naszą flagę hit. Pierwsze co robimy to ustalamy kolor GUI. Z racji, że konkretne ścieżki kolorów są tylko do odczytu, nie możemy sobie nadpisać samego opacity, tylko musimy nadać nowy kolor. Aby nie utracić reszty barw, pobieramy je z obecnego koloru, odpowiednio ze ścieżek: czerwonej (red), zielonej (green) i niebieskiej (blue), czyli klasycznego RGB. Jako przeźroczystość ustawiamy naszą zmienną.

Później rysujemy naszą teksturę. Najpierw używając prostokąta podajemy wymiar. Ja chciałem mieć teksturę na całym ekranie, dlatego jako punkt początkowy podałem początek układu współrzędnych, a jako rozmiar szerokość i wysokość ekranu użytkownika. Drugi parametr to sama tekstura. Ostatnim parametrem jest metoda skalowania. W podanym trybie, w razie potrzeby nieco pomniejszy teksturę, aby w całości zmieściła się na ekranie gracza.

Na koniec odczekujemy chwilę, aby zanikanie było dynamiczne, a nie jednorazowym skokiem. (odpowiedzialną za to funkcję omówię później).

if (opacity <= 0) {
	hit = false;
}

Ostatni if, odznacza naszą flagę, kiedy opacity będzie już zerowe lub nawet mniejsze. Dzięki temu, gdy tekstura przestanie być widoczna (będzie całkiem przeźroczysta), zrestartujemy sobie funkcjonalność, aby móc powtórzyć efekt.

Do omówienia została ostatnia funkcja:

IEnumerator waitAndChangeOpacity()
{
	yield return new WaitForEndOfFrame();
	opacity -= 0.05f;
}

Jest to nic innego jak… czekacz. Pierwsza linia funkcji wyczekuje do końca klatki, po czym rusza dalej (można by odczekać jakiś określony czas (w sekundach), ale wtedy animacja mogłaby być za długa). W drugim kroku pomniejszamy nieco opacity. Typ zwracany funkcji (IEnumerator) jest wymagany, aby móc korzystać z funkcji czekania czyli WaitForEndOfFrame.

Czas wrócić do Unity, odpalić grę i nacisnąć P.

Done!