Wszystkie obiekty które zapisaliśmy na scenie są standardowo wczytywane u każdego klienta, który tą scenę wczyta. Nie oznacza to jednak, że te obiekty są wspólne dla wszystkich klientów, wręcz przeciwnie - każdy klient posiada osobną scenę i każdy klient wczytuje ją osobno. Jeśli na scenie znajdowałby się skrypt generujący obiekty o losowych pozycjach, to prawie zawsze ta sama scena wyglądałaby inaczej na każdym z klientów. Podobną sytuację zaobserwujemy, jeśli posiadamy skrypt tworzący obiekty po kliknięciu lpm - obiekty utworzone na jednym kliencie nie będą tworzone na pozostałych klientach.
Jeśli sieć nie ma dedykowanego serwera, to rolę serwera przejmuje jeden z klientów, tzw. host.
Na scenie hosta znajdują się zarówno obiekty które powinny znajdować się na jego kliencie, jak i obiekty znajdujące się na serwerze, które niestety są niewidoczne na pozostałych klientach. Momentami może to być kłopotliwe dla nowych programistów, ponieważ podczas testowania gry na klientach zdalnych (innych niż host) może się okazać, że nie działają tam rzeczy testowane dotychczas na hoście.
Jeśli chcemy, aby jakiś obiekt miał odblokowane różne opcje związane z sieciami, musimy dodać do niego komponent NetworkIdentity. Stwórzmy więc na scenie pusty GameObject, dodajmy do niego ten komponent, a następnie zaznaczmy w nim opcję ServerOnly. Dzięki tej opcji obiekt nie będzie tworzony na żadnym z klientów i zostanie utworzony tylko na serwerze, w chwili rozpoczęcia połączenia. Jest to przydatne jeśli chcemy, aby w całej sieci istniała tylko jedna kopia jakiegoś elementu i była dostępna na serwerze.
Utworzony skrypt przypiszmy do obiektu, który ma znajdować się tylko na serwerze. Uzupełnijmy też folder Resources o potrzebny do tego skryptu prefab, oraz dodajmy go do skryptu NetworkMenager. W rezultacie po uruchomieniu gry obiekt istniejący tylko na serwerze utworzy dla każdego klienta
Mimo iż wszystkie te obiekty są powiązane, to osobnymi obiektami i na każdym kliencie mogą mieć inne właściwości, np. pozycję. W razie potrzeb możemy jednak wysyłać na serwer nowe informacje na temat tego obiektu, lub pobierać takie informacje, więc w zależności od naszych wymagań poszczególne elementy mogą być synchronizowane, lub mogą pozostać unikalne. W wielu grach można to wykorzystać np. do barwienia postaci, gdzie popularnym motywem jest barwienie sojuszniczych postaci na zielono, a dla każdej drużyny inne postacie są uznawane za przyjazne. Inny przykład zastosowania: możemy zredukować częstotliwość komunikowania się z serwerem, aby go nie przeciążać.
PlayerPrefab podobnie jak spawnowane obiekty nie jest automatycznie synchronizowany ze swoimi odpowiednikami na innych klientach. Gracz będący właścicielem takiego obiektu posiada nad nim Authority, czyli może wysyłać z niego polecania na serwer, jednak obiekty pozostałych graczy pozostają poza tą kontrolą. W razie potrzeb istnieje też możliwość nadania autorytetu także innym obiektom.
Na scenie hosta znajdują się zarówno obiekty które powinny znajdować się na jego kliencie, jak i obiekty znajdujące się na serwerze, które niestety są niewidoczne na pozostałych klientach. Momentami może to być kłopotliwe dla nowych programistów, ponieważ podczas testowania gry na klientach zdalnych (innych niż host) może się okazać, że nie działają tam rzeczy testowane dotychczas na hoście.
Jeśli chcemy, aby jakiś obiekt miał odblokowane różne opcje związane z sieciami, musimy dodać do niego komponent NetworkIdentity. Stwórzmy więc na scenie pusty GameObject, dodajmy do niego ten komponent, a następnie zaznaczmy w nim opcję ServerOnly. Dzięki tej opcji obiekt nie będzie tworzony na żadnym z klientów i zostanie utworzony tylko na serwerze, w chwili rozpoczęcia połączenia. Jest to przydatne jeśli chcemy, aby w całej sieci istniała tylko jedna kopia jakiegoś elementu i była dostępna na serwerze.
Spawn
Utwórzmy teraz nowy skrypt, który wypełnijmy następującym schematem:
using
UnityEngine;
using
System.Collections;
using
UnityEngine.Networking;
public
class
HostScript
: NetworkBehaviour
{
}
Do standardowego schematu skryptu dodaliśmy nową bibliotekę: UnityEnginie.Networking, która daje nam dostęp do narzędzi związanych z siecią, oraz zamieniliśmy MonoBehaviour na NetworkBehaviour, co także jest dla nas konieczne. Jeśli do jakiegoś obiektu przypiszemy skrypt zawierający te elementy, to automatycznie ten obiekt otrzyma także skrypt NetworkIdentity, co jest całkiem wygodne. Sama nazwa klasy może być dowolna.
Teraz wypełnijmy tą klasę następującą funkcją:
public override void OnStartServer () {
NetworkServer.Spawn (Instantiate (Resources.Load ("PreMObject")) as GameObject);
}
Funkcja ta aktywuje się w chwili startu serwera. Zawiera ona w sobie znaną nam już funkcję Instantiate, która w tym przypadku powoduję utworzenie instancji prefabu o nazwie "PreMObject" znajdującego się w katalogu o nazwie "Resources", a wszystko to zawiera się w funkcji NetworkServer.Spawn (), która może być uruchomiona tylko na serwerze i powoduje utworzenie wybranego prefabu na każdym kliencie. Warto pamiętać, że aby skorzystać z tej opcji nasz prefab musi być dodany do tabeli możliwych do spawnowania obiektów, która znajduje się w skrypcie NetworkManager. Wszystko to sprawi, że nasz obiekt pojawia się na scenie wszystkich klientów i wszystkie te kopie obiektu będą powiązane z serwerem, co w przyszłości pozwoli nam na łatwiejszą wymianę informacji, bowiem Unity oferuje nam możliwość tworzenie zmiennych o atrybucie [SyncVar], o której rozpiszę się później.
Utworzony skrypt przypiszmy do obiektu, który ma znajdować się tylko na serwerze. Uzupełnijmy też folder Resources o potrzebny do tego skryptu prefab, oraz dodajmy go do skryptu NetworkMenager. W rezultacie po uruchomieniu gry obiekt istniejący tylko na serwerze utworzy dla każdego klienta
Mimo iż wszystkie te obiekty są powiązane, to osobnymi obiektami i na każdym kliencie mogą mieć inne właściwości, np. pozycję. W razie potrzeb możemy jednak wysyłać na serwer nowe informacje na temat tego obiektu, lub pobierać takie informacje, więc w zależności od naszych wymagań poszczególne elementy mogą być synchronizowane, lub mogą pozostać unikalne. W wielu grach można to wykorzystać np. do barwienia postaci, gdzie popularnym motywem jest barwienie sojuszniczych postaci na zielono, a dla każdej drużyny inne postacie są uznawane za przyjazne. Inny przykład zastosowania: możemy zredukować częstotliwość komunikowania się z serwerem, aby go nie przeciążać.
Player Prefab
Kolejnym omawianym elementem będzie PlayerPrefab, który możemy wybrać w skrypcie NetworkManager. Prefab ten wymaga komponentu NetworkIdentity i będzie tworzony na serwerze za każdym razem gdy nowy gracz dołączy się do sieci i pojawi się na każdym kliencie, a po rozłączeniu się gracza obiekt ten jest usuwany ze wszystkich klientów.PlayerPrefab podobnie jak spawnowane obiekty nie jest automatycznie synchronizowany ze swoimi odpowiednikami na innych klientach. Gracz będący właścicielem takiego obiektu posiada nad nim Authority, czyli może wysyłać z niego polecania na serwer, jednak obiekty pozostałych graczy pozostają poza tą kontrolą. W razie potrzeb istnieje też możliwość nadania autorytetu także innym obiektom.
Brak komentarzy:
Prześlij komentarz