Professional Documents
Culture Documents
Unity i c#. Podstawy Programowania Gier Pełna Wersja
Unity i c#. Podstawy Programowania Gier Pełna Wersja
Wstęp ................................................................................................................. 9
O czym jest książka? ................................................................................................................... 9
Ale czy na pewno przeciętna osoba bez wrodzonych cech programisty
może się nauczyć programować? ........................................................................................ 11
Struktura książki ....................................................................................................................... 11
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje
były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie,
ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz
Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody
wynikłe z wykorzystania informacji zawartych w książce.
Wydawnictwo HELION
ul. Kościuszki 1c, 44-100 GLIWICE
tel. 32 231 22 19, 32 230 98 63
e-mail: helion@helion.pl
WWW: http://helion.pl (księgarnia internetowa, katalog książek)
Drogi Czytelniku!
Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres
http://helion.pl/user/opinie/unityc
Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.
ISBN: 978-83-283-4390-0
Printed in Poland.
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
if (X > 10)
X += 1;
else
X += 2;
if (X > 10)
{
X += 1;
Y = 0;
}
else
{
X += 2;
Y = -1;
}
> lub <, czyli operatory większości i mniejszości, np. A > B zwraca true, tylko jeśli A
jest większe niż B;
>= lub <=, czyli operatory „większy lub równy” oraz „mniejszy lub równy”, np. A <= B
zwraca true, tylko jeśli A jest mniejsze lub równe B.
Operatory te można bez przeszkód stosować na typach prostych takich jak int czy bool,
ale na typach obiektowych można stosować tylko operatory == i !=, które sprawdzają,
czy dwie zmienne mają przypisany dokładnie ten sam obiekt.
Specjalną wartością dla zmiennych obiektowych jest null. Oznacza ona, że nie jest przy-
pisany żaden obiekt. Uwaga: próba wywołania funkcji dla zmiennej obiektowej o wartości
null zawsze skończy się błędem wykonania programu. Dobrą praktyką jest więc spraw-
dzanie, czy taka wartość jest przypisana do zmiennej, zawsze kiedy nie ma co do tego ab-
solutnej pewności — jak np. na listingu 4.3.
Zadanie
Zadaniem kursanta jest utworzenie prostej gry (można wykorzystać jeden z projektów
z lekcji 1.), w której będzie się znajdować kilka brył 3D mających jeden z trzech kom-
ponentów:
komponent z polem typu całkowitego,
komponent z polem typu zmiennoprzecinkowego,
komponent z polem typu bool.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if(ObiektZLiczbaCalkowita != null)
{
int wartosc = ObiektZLiczbaCalkowita.Liczba;
Debug.Log("Trafiony ma typ z liczbą całkowitą: " + wartosc.ToString());
Suma = Suma + wartosc;
} else if (ObiektZLiczbaZmiennoprzec != null)
{
int wartosc = (int)ObiektZLiczbaZmiennoprzec.Liczba;
Debug.Log("Trafiony ma typ z liczbą zmiennoprzecinkową, zmieniamy ją na: " +
wartosc.ToString());
Suma = Suma + wartosc;
}
else if (ObiektZPoleBool != null)
{
int wartosc = 0;
if(ObiektZPoleBool.PoleBool == true )
{
wartosc = 1;
Debug.Log("Trafiony ma typ z polem bool o wartości true, dodajemy 1 do sumy");
} else Debug.Log("Trafiony ma typ z polem bool o wartości false");
Suma = Suma + wartosc;
}
Debug.Log("Suma wynosi: " + Suma.ToString());
}
}
Plik KomponentZLiczbaCalkowita.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZLiczbaZmiennoprzecinkowa.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemBool.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część I
Czas: około 45 – 60 minut.
Zadanie
W lekcji 2. jedno z zadań dodatkowych związane było z projektem o nazwie ProjektRosliny.
Kursant miał za zadanie utworzenie dokumentacji projektowej do takiej właśnie gry.
Nadszedł teraz czas na utworzenie rozwiązania dla pierwszej wersji tej gry.
Celem gry jest podniesienie sadzonek (po jednej) i zaniesienie ich do doniczek. Kliknięcie
w doniczkę, gdy gracz niesie sadzonkę, powoduje zasadzenie drzewa. Gra kończy się, gdy
gracz zasadzi poprawnie co najmniej 3 drzewa.
Podpowiedź
Utwórz komponenty Doniczka, Sadzonka i Gracz. Niech komponent Gracz będzie przypi-
sany do obiektu FPSRigidbodyController i niech zapamiętuje, czy gracz niesie sadzonkę,
za pomocą publicznej zmiennej typu Sadzonka. Komponent Doniczka może reagować na
dotknięcie swojego obiektu na scenie uruchomieniem funkcji OnCollisionEnter i wprowa-
dzeniem odpowiednich zmian związanych z obiektami sadzonek i roślin. Powiąż sadzonkę
z odpowiadającą jej rośliną, dodając w klasie Sadzonka publiczne pole typu GameObject.
Do pola typu GameObject w edytorze Unity możesz przypisać dowolny obiekt, posiadający
dowolną liczbę i typ komponentów.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ProjektRosliny — część II
Czas: około 90 minut.
Zadanie
Grę utworzoną w poprzednim zadaniu, ProjektRosliny, rozbuduj do drugiej wersji. W kilku
miejscach na ziemi powinny leżeć konewki. Gracz może podnieść konewkę i nieść ją
równocześnie z sadzonką. Dotknięcie doniczki, gdy gracz niesie sadzonkę, powinno spowo-
dować posadzenie sadzonki (w doniczce powinna pojawić się mała roślina), a dotknięcie
doniczki, gdy jest w niej sadzonka i gracz niesie konewkę, powinno powodować, że wy-
rośnie drzewo. Warunki zwycięstwa nie zmieniają się, ale gracz może też przegrać — za-
blokuje się, jeżeli weźmie więcej niż jedną konewkę naraz.
Podpowiedź
Rozmiar kodu źródłowego rośnie i niektóre jego fragmenty są coraz bardziej rozbudo-
wane albo wykonywane kilka razy. Przykładowo, z pewnością trzeba będzie kilka razy
zmieniać ustawienie, czy sadzonka jest widoczna, czy nie. W takich przypadkach do do-
brych praktyk należy przeniesienie fragmentu kodu, który za dane działanie odpowiada,
do osobnej funkcji. Dobrym miejscem jest klasa Sadzonka. Takie modyfikacje kodu źró-
dłowego pod wpływem nowych wymagań są typowe dla programowania zwinnego i na-
zywają się refaktoryzacją.
Gra zawiera już sporo logiki działań i nie jest całkowicie liniowa. Może się zdarzyć, że
źle zakodujesz któryś z warunków i w trakcie testowania gry pojawi się błąd spowodo-
wany odwołaniem do pola w obiekcie null. Unity wyświetla wówczas w konsoli szcze-
gółową informację o tym, w którym pliku źródłowym i w której jego linii wystąpił błąd, np.:
NullReferenceException: Object reference not set to an instance of an object
Doniczka.OnCollisionEnter(UnityEngine.Collision collision) (at Assets/Doniczka.cs:22)
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Doniczka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Sadzonka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik Konewka.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Zadanie
Projekt JakimJestemTypem należy rozbudować o nowy komponent, który zamiast pola
z typem prostym będzie zawierał trzy pola z typami obiektowymi. Tymi typami będą klasy,
które utworzyliśmy w trakcie lekcji (a więc komponenty z typami prostymi).
KomponentzPolemObiektowym powinien mieć funkcję, która sama wyznaczy sumę dla po-
siadanych przez niego obiektów.
Podpowiedź
Pola obiektowe uzupełnij w edytorze (w przyszłości dowiesz się, jak tworzyć nowe obiekty
w kodzie). Aby to zrobić, najpierw musi istnieć obiekt na scenie z odpowiednim kom-
ponentem. Utwórz kilka ukrytych obiektów bez reprezentacji graficznej, które będą po-
siadały wyłącznie komponent Transform i ten z komponentów z lekcji, który chcesz za-
stosować i przypisać do pola obiektowego.
Rozwiązanie
Plik Gracz.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Plik KomponentZPolemObiektowym.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
B F
FPS, frame per second, 100
biblioteka, 59
funkcja, 31, 69
błędy, 147
OnCollisionEnter, 31
breakpoint, 147
OnGUI, 100
C Parse, 146
Update, 100, 101
cykl życia
funkcje
obiektu, 133
prywatne, 71
projektu, 54
publiczne, 71
D G
debugowanie, 64
gra MicroAbrix, 130
breakpoint, 147
GUI, 102
kontynuacja wykonania programu, 149
modyfikacja wartości zmiennych, 148 H
podgląd wartości zmiennych, 148
hierarchia obiektów, 102
w Visual Studio, 146
deklaracja I
tablic, 113
indeks, 113
zmiennych, 67
informacja, 45
destruktor, 134
instalacja
diagram klas, 57
Unity, 13
dodanie
Visual Studio, 13
parametru do komponentu, 29
instrukcja
własnego komponentu, 28
break, 143
dokumentacja, 53
continue, 144
fabuła gry, 57
switch, 143
mechanika gry, 56
instrukcje warunkowe, 75, 95
projektowa, 56
K O
klasa, 30, 32, 89 obiekty, 32, 72
GameObject, 103 aktywność, 103
OpelAstra, 72 na scenie, 32
String, 145 obracanie, 64
StringBuilder, 145 tworzenie, 92
klasy zwracanie, 139
dziedziczenie, 89 okna Unity
ogólne, 89 główne, 18
szczegółowe, 89 podstawowe, 22
kolejność obliczeń, 96 okno
kolekcje, 113 hierarchii obiektów, 18
komentarze, 29 inspektora, 18, 24
kompilacja projektu, 34 kompilacji, 59
w Unity, 58 widoku sceny, 18
w Visual Studio, 61 operator
komponent, 30, 32 !, 96
Collider, 27 !=, 76
Renderer, 27 ||, 68
Rigidbody, 27 <, 76
Transform, 26 <=, 76
komponenty ==, 76
ogólne, 25 >, 76
Unity, 100 >=, 76
konstruktor, 133 &&, 68
domyślny, 134 as, 94
przeciążanie, 135 is, 95
konwersja liczb, 146 otwieranie projektu, 20
M P
metoda ToString, 146 pętla
metodologia for, 115, 116, 125
Scrum, 54 foreach, 119, 126
tradycyjna, 54 while, 123, 126
zwinna, 54 pętle
metody, 71 instrukcja break, 144
przeciążanie, 134 instrukcja continue, 144
klasy String, 145 pierwszy
modyfikacja komponent, 28
obiektów, 24 projekt, 17
wartości zmiennych, 148 skrypt, 28
modyfikator platforma .NET, 17
out, 139, 140 plik
ref, 140 DoDestrukcji.cs, 131
Doniczka.cs, 80, 106, 128, 159
GlownySkrypt.cs, 150, 152
GlownySkryptPoprawnie.cs, 151, 154
Gracz.cs, 77, 79, 82, 86, 98, 105, 127, 131 pseudokod, 53
Jablko.cs, 99 pułapka w kodzie, 147, Patrz także
Klikacz.cs, 122, 125 debugowanie
KomponentGracza.cs, 109, 119, 121
KomponentZLiczbaCalkowita.cs, 78 R
KomponentZLiczbaZmiennoprzecinkowa.cs, ramki graficzne, 100
78 refaktoryzacja, 82
KomponentZPolemBool.cs, 78 rola
KomponentZPolemObiektowym.cs, 87 Analityk, 54
Konewka.cs, 85, 108 Designer, 55
Owoc.cs, 99 Dokumentalista, 55
Pojemnik.cs, 110 Lider zespołu, 56
Sadzonka.cs, 80, 84, 107, 155 Menedżer, 56
pliki Programista, 55
bibliotek, 59 Projektant, 55
projektu, 60 Tester, 55
podgląd wartości zmiennych, 148 Wdrożeniowiec, 55
pola klasy, 71 rozciąganie obiektu, 64
dostępność, 138 rozwiązania, 60
statyczne, 141 rzutowanie
String, 145 typów, 66
użycie, 137 typów obiektowych, 94
widoczność, 138 typu enum, 162
pomoc techniczna, 163 zmiennych, 69
prefabrykaty, 23, 32
programowanie S
ekstremalne, 54 scena, 23
komponentów Unity, 100 3D, 63
projekt otwieranie, 36
FixMe1, 150 przesuwanie, 63
FixMe2, 152 zmiana pozycji obiektu, 102
ObjectClicker, 122 schemat blokowy, 51, 52
ProjektRosliny, 79, 104, 126, 155 Scrum, 54
Tanks!, 169 skalowanie obiektu, 64
przeciążanie skok warunkowy, 143
konstruktorów, 135 słowo kluczowe
metod, 134 break, 143
przekazanie parametrów do funkcji, 70, 139 continue, 144
modyfikator out, 139 if, 75
modyfikator ref, 140 new, 92
przestrzenie nazw, 142 null, 76, 93
przesuwanie private, 91
obiektu, 63 protected, 91
sceny, 63 public, 91
przybornik narzędzi, 63 static, 141
przyciąganie podczas przesuwania, 64 this, 93
przypadki użycia, 57 using, 142
T V
tablice, 113 Visual Studio, 17
deklaracja, 113
sortowanie elementów, 117 W
użycie, 114 wartość null, 76, 93
tworzenie warunek, 75
gier i programów, 53 widoczność
obiektów, 92 metod i pól, 91
projektu, 17 zmiennych, 136
typ danych wyszukiwanie błędów, 147
bool, 66, 68 wyszukiwarka zasobów, 166
float, 66, 67 wywołania
enum, 161 przeciążonej metody, 135
int, 66 wielokrotne, 92
obiektowy, 92
string, 144 Z
typy zagnieżdżanie warunków, 95
proste, 66 zakładka Project, 19
wyliczeniowe, 161 zakup zasobów, 165
zasoby, 23, 32
U zmienne, 66
UML, Unified Modeling Language, 57 modyfikacja wartości, 148
Unity, 17 podgląd wartości, 148
Unity Asset Store, 165 typu obiektowego, 73
uruchomienie użycie, 67
gry, 25 zwracanie obiektu, 139
Visual Studio, 19
uzyskiwanie pomocy, 165
użycie
dokumentacji technicznej, 163
funkcji OnCollisionEnter, 31
gotowego kodu, 167
instrukcji break, 144
instrukcji continue, 144
instrukcji switch, 143
klasy StringBuilder, 146
modyfikatora out, 140
pętli for, 117
pętli while, 123
pola klasy, 72, 137
Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje
były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie,
ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz
Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody
wynikłe z wykorzystania informacji zawartych w książce.
Wydawnictwo HELION
ul. Kościuszki 1c, 44-100 GLIWICE
tel. 32 231 22 19, 32 230 98 63
e-mail: helion@helion.pl
WWW: http://helion.pl (księgarnia internetowa, katalog książek)
Drogi Czytelniku!
Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres
http://helion.pl/user/opinie/unityc
Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.
ISBN: 978-83-283-4390-0
Printed in Poland.