Skrypty w Unity


#1

Dzień dobry wszystkim,

jest to mój pierwszy post na tym forum wiec mam nadzieje, że mnie nie zjecie. Mam 23 lata i chce napisać pierwszą dopracowaną produkcje, mam kilka małych projekcików na moim koncie. Teraz chciałbym napisać coś większego i tutaj pojawia się moje pytanie:

Jakie zasady przyjąć przy pisaniu skryptów? Chodzi mi o odpowiedz w stylu np.:
Jeden główny skrypt sterujący główną mechaniką gry korzystający z reszty skryptów które pisane są pod konkretne elementy.
Czy lepiej tworzyć wiele skryptów które będą stosunkowo krótkie, czy raczej większe, ale mniej.

Czym wy się kierujecie? Mam też nadzieje, że wypowie się ktoś z branży GameDev i powie jak to wygląda u niego w firmie.

Za wszystkie odpowiedzi z góry dziękuje.
Pozdrawiam Dawiz147


#2

Cześć.
Pozwolę sobie skopiować moją wypowiedź z discroda na podobnie pytanie. :slight_smile:

Ogólnie to są zasady architektury projektu. Trzeba rozróżnić na start co to jest manager co to controller.
Unity Learn: https://learn.unity.com/tutorial/game-managers?projectId=5c5149c5edbc2a001fd5be95#
Tutaj link do filmu: https://youtu.be/T39tyyQjFSQ

I teraz tak. Skrypty powinny być rozbite na jak najprostsze tzn. Player powinien mieć InputController, MovementControler itd. Managery trzymają kontrolery wiec do tego jakiś jeden manager który to wszystko spina w całość. No i tutaj tez dochodzą zasady Clean Code, KISS, SOLID etc.

Ogólnie rzecz biorąc architektura projektu to dosyć skomplikowana sprawa i tak jak Gszak napisał często się różni od projektu. W małej grze mobilnej będziesz mieć jeden GameManager, a teraz sobie wyobraź taki Manager dla wiedźmina - nie ma opcji.


#3

Kod projektów growych nie różni się specjalnie w tym względzie od ogólnie sprawdzonych praktyk IT.

Zdecydowanie lepiej tworzyć wiele krótkich i dobrze nazwanych skryptów spełniających ściśle określone zadanie.

Ponadto warto zapoznać się z wzorcami projektowymi (szczególnie Observer), dbać o Clean Code, czystą architekturę, spróbować MVC (uniezależnienie warstwy wizualnej od danych), podejścia TDD, refaktoryzacji.
Pamiętać również o kilku zasadach: SOLID, DRY, KISS, YAGNI.

Projektowanie większych produkcji wymaga znajomości wielu dobrych praktyk co też przychodzi z doświadczeniem.


#4

Dziękuję za odpowiedzi, wiele to wyjaśnia po przejrzeniu linków chyba sam umiałbym odpowiedzieć na swoje kolejne pytanie. Jednak myślę, że dla całkowitej pewności korzystając z waszej dobroci opisze problem który teraz przyszedł mi do głowy.

Więc na studiach pisałem symulacje chińskiej restauracji gdzie każdy obiekt był w osobnej klasie z użyciem c++ style guida od googla. Zdaję to pytanie bo kiedyś naoglądałem się niezbyt profesjonalnych poradników na youtubie na temat tworzenia gier. Więc teraz na potrzeby pytania załóżmy, że tworzymy klikera gdzie przyjmujemy, że istnieją 3 surowce np. złoto, drewno i kamień. Tak więc jeśli się nie mylę każdy skrypt (klasa) powinien zajmować się jednym z tych surowców a w środku niego powinny znajdować się funkcję które zajmują się tylko i wyłącznie tym surowcem np. surowiec na sekundę, surowiec na kliknięcie, oraz zmniejszenie surowca o odpowiednią ilość kiedy coś ulepszamy.
Do tego wszystkiego wartości powinny być private i modyfikowane tylko za pomocą funkcji public void. Czy mam rację i na taki kod patrzy się dobrze?

Bo jeśli tak to bardzo by to mi ułatwiło pracę bo to takiego systemu jestem przyzwyczajony. Tak wynika z linków które otrzymałem, ale wolałbym się ostatecznie upewnić żeby pisać grę w spokoju, nie martwiąc się, że ktoś spojrzy na coś takiego z przerażeniem w oczach i myślą w głowie co ten człowiek właściwie tworzy. Jest to ostatnie pytanie reszta wątpliwości jest wyjaśniona.


#5

Może ktoś bardziej doświadczony się nie zgodzi, ale moim zdaniem jeżeli surowiec jest tylko liczbą to po co tworzyć dla niego osobną klasę.

No bo aby nie powielać kodu robisz klasę abstrakcyjną Material, po niej dziedziczyły by klasy Wood, Gold, Stone, które w zasadzeni dodawałyby nic od siebie poza informacją jestem czymś.

Chyba wygodniej byłoby utworzyć klasę ResourcesManager i w niej zamknąć ogarnianie surowców. Przy niewielkiej liczbie surowców, np.3, funkcje pobierały by po prostu 3 argumenty ( np. spendResources(Wood, Stone,Gold )), przy większej liczbie można to ogarnąć tablicami i enumeracją.

Z jednej strony jest to bardziej abstrakcyjne podejście. Z drugiej strony masz ogarnianie surowców w jednym miejscu, nie musisz np. pamiętać aby do przycisku podłączać kilka funkcji itd. No i masz jedną funkcję updateResurces().
Do tego jeżeli w klasie masz enumeracje, to jest w kodzie miejsce gdzie masz zapisane surowce występujące w grze, co jest łatwiejsze niż pamiętanie wszystkich klas

Do tego masz taki problem, że ilość surowca w danej rozgrywce jest jedna i trzeba uważać żeby gdzieś w kodzie nie była tworzona inna instancja klasy danego surowca. A w zasadzie w ogóle nie ma potrzeby tworzenia instancji klasy, bo można to ogarnąć na zmiennych statycznych
( o ile w grze występuje jeden gracz, bo dla kilku graczy trzeba jednak tworzyć asocjacje i tu jest problem aby przypadkiem nie stworzyć nowego obiektu. Do tego i tak masz Gracz->KlasaOgarniaczaSurowców->Surowiec i moim zdaniem ostatnia relacja jest zbędna jeżeli surowiec to tylko liczba całkowita ).

Inna sprawa, to gdyby surowiec istniał fizycznie jako obiekt w grze ( jak to jest np. w settlersach ) lub sytuacja gdzie surowce się w jakiś istotny sposób różnią, np. update() musiałaby z jakiegoś powodu wyglądać znacząco inaczej dla każdego surowca ( np. jeden surowiec przyrasta o wartość, inny o procent ).