2016-08-03 32 views
8

Pracuję nad bardzo prostą przewijaniem pionowym dla Unity iOS. W mojej grze występują niespójne drgania. Przeszukałem internet w poszukiwaniu rozwiązania bez żadnego szczęścia. Używam wersji Unity 5.3.4 f1.Niespójny jitter w grze na iOS

The Game

Gameplay screenshot

  • Postać spada. Używamy kontrolera znaków Unity do przesuwania znaku w mnożeniu Update() (Time.deltaTime).
  • Kamera podąża za postacią w LateUpdate() (za pomocą Vector3.Lerp() do naśladowania).
  • Ponieważ postać porusza się w dół, przeszkody wydają się przesuwać w górę ekranu.
  • W scenie jest 1 światło kierunkowe, ustawienie cienia w czasie rzeczywistym. Jakość cieni to wysokie i twarde cienie.
  • Na scenie nie ma sztywnych ciał. I nie ma większych skoków w profilerze.
  • Mamy bardzo prostą geometrię i bardzo mało połączeń wywołań/zestawów połączeń wychodzących (średnio 7 zestawów połączeń).
  • Mamy stałe 60 fps.
  • Ponieważ pracujemy na iOS, vSync jest domyślnie włączony i nie można go wyłączyć.

problem

  • elementów tła/przeszkody (drzewa, skały itp) zaczynają drgania bez wyraźnego powodu. Zachowanie jest niespójne, czasami drży, a czasami nie.
  • Nawet gdy nie występuje drgania, pojawia się małe zacinanie, gdy użytkownik podaje dane za pośrednictwem dotyku.

Co staraliśmy

  • Próbowaliśmy wszystkie kombinacje Update(), LateUpdate(), FixedUpdate(), Time.deltaTimeTime.smoothDeltaTime, Lerp, zmniejszając sceny do kilku kostek i wyprowadzenie wszystkich collidery i wyzwala.
  • Przebadaliśmy już następujące wątki: Link1, Link2, Link3 oraz niezliczone inne wątki.
  • Początkowo nasza gra działała z domyślnym 30 fps. Ale po kilku badaniach wydawało się, że nasz problem wynika z różnicy między "Szybkością klatek" a "Szybkością odświeżania ekranu". (aby zrozumieć ten problem, zobacz następujący LINK). Ponieważ urządzenia z systemem iOS mają częstotliwość odświeżania 60 Hz, ustawiliśmy docelową liczbę klatek na 60, a nasza gra utrzymuje stałą 60 fps.
  • Po ustawieniu docelowej liczby klatek na 60, jitter się poprawił, ale teraz jest niespójny.

Nie mam pomysłów. Każda pomoc lub wskaźnik będą bardzo cenne.

Z góry dziękuję.

+0

Ile świateł czasu rzeczywistego znajduje się na scenie i czy możesz podzielić się kodem ruchu kamery? –

+0

Brat Chussu. Jest tylko jedno kierunkowe Światło. I używam 'Vector3.Lerp()', aby przesunąć kamerę. Przetestowałem ruch kamery i to nie jest problem. Zaktualizuję też post i dodam w nim tę informację. –

+0

Witamy w StackOverflow! byłby bardziej przydatny, jeśli zaktualizujesz pytanie, dodając ** trochę kodu **. A jeśli jeszcze go nie czytałeś, [Dokumenty] (https://docs.unity3d.com/ScriptReference/Application-targetFrameRate.html) mówią tak: ** Pamiętaj, że ustawienie targetFrameRate nie gwarantuje tej szybkości klatek. Mogą występować wahania ze względu na specyfikę platformy lub gra może nie osiągnąć liczby klatek na sekundę, ponieważ komputer jest zbyt wolny. ** Plus, chciałbyś udostępnić zrzut ekranu Profiler z włączonym profilem __deep i bez ograniczania targetfps. –

Odpowiedz

1

To może być spowodowane przez wiele różnych przyczyn, a nie widząc żadnego kodu mogę tylko zrobić kilka sugestii, które przychodzą do głowy:

1. Błąd precyzja punkt Float

  • Czy postać ciągle spada?
  • Czy błąd występuje po tym, jak postać opadnie na chwilę?

Wskazuje to na błąd precyzji zmiennoprzecinkowej. zamiast upuszczania postaci, przesuwaj obiekty dookoła postaci spod widoku ekranu do widoku z góry ekranu, aby wszystko odbywało się w pobliżu miejsca pochodzenia.

2. instancji często lub inny lag kolce

  • Czy instancji obiektów lub łącząc je?
  • Czy wykonujesz jakieś długie obliczenia?
  • Czy masz dużo pętli for/foreach/?

Wywoływanie spowoduje skok opóźnienia i utworzenie garabage, które spowoduje, że śmieciarz będzie działał częściej. Ponieważ liczba klatek na sekundę jest stała, gdy pojawia się powolna operacja, zauważysz pewne drżenie.

Zamiast uruchamianiu i destorying obiektami, gdy gracz idzie na pewną odległość, należy Instantiate pula GameObjects po załadowaniu sceny, należy je nieaktywna z gameObject.SetActive(false), i zapisać je w postaci listy, tablicy itp i kiedy trzeba do Instatiate nowy obiekt, po prostu chwyć jeden z puli i zmień jego Transform.position i gameObject.SetActive(true), gdy jest to potrzebne.

3. śmieci kolektor działa często

Ten jest mało prawdopodobne, aby być problem, ale jeszcze o tym wspomnieć. wziąć ten przykładowy kod:

void Update() 
{ 
    Vector3 someVector = new Vector3(0,0,0); 
    float distance = someVector.magnitude; 
    if (distance > 5.0f) 
     Vector3 someNewVector = someVector + transform.position; 
    else 
     Vector3 someNewVector = Vector3.zero; 
} 

Everytime Update działa, tworzy nowe zmienne i przydziela pamięć dla nich. Następnym razem zaktualizuj funkcje runs, it creates new variables, and allocates more memory. Eventually, the memory usage sets off the garbage collector, which goes around and frees up the memory used by all the previous Update. Zamiast tego należy przydzielić pamięć na początku, a następnie ponownie użyć zmiennych.

void Start() 
{ 
    Vector3 someVector = new Vector3(0,0,0); 
    Vector3 someNewVector = new Vector3(0,0,0); 
    float distance = 0f; 
} 
void Update() 
{ 
    someVector = Vector3.zero; 
    float distance = someVector.magnitude; 
    if (distance > 5.0f) 
     Vector3 someVector += transform.position; 
    else 
     Vector3 someVector = Vector3.zero; 
} 

Aby to zdiagnozować, trzeba by dołączyć debugera profil i obejrzeć i sprawdzić, czy są one zgodne z jitter garbage collector.

Mam nadzieję, że coś tutaj może ci pomóc. Najlepszym sposobem na znalezienie źródła jittera jest użycie profilera.Oto instrukcje dla iOS:

Połącz urządzenie z systemem iOS do sieci WiFi (local/adhoc sieć WiFi jest używany przez profilera wysłać profilowania danych z urządzenia do Jedności editor). Zaznacz pole "Autoconnect Profiler" w oknie dialogowym ustawień Unity w wersji . Podłącz urządzenie do komputera Mac za pomocą kabla, zaznacz pole wyboru "Development Build" w oknie dialogowym ustawień Unity i naciśnij "Build & Run" w Unity Editor. Gdy aplikacja uruchamia się na urządzeniu otwórz okno profilera w Unity Editor (Window-> Profiler).

Więcej informacji: The Profiler Window

1

Dziękuję wszystkim za poświęcony czas.

  1. Nie, to nie jest błąd precesji zmiennoprzecinkowej.
  2. Obiekty są tworzone w czasie wykonywania, ale gdy wystąpił problem, przełączaliśmy się na łączenie obiektów, ale nie pomogło.
  3. Zrobiłem dokładne profilowanie, a nawet zdalne profilowanie na urządzeniu i odśmiecaczu też nie było problemem.

Po dalszych badaniach natknąłem się na BLOG POST, ci faceci mieli do czynienia z podobnym problemem, a rozwiązanie działa w moim scenariuszu.

W skrócie, problem polegał na tym, że ramka jedności nie synchronizowała się z szybkością rysowania ramki urządzenia. Kiedy Unity zajmuje trochę więcej czasu, aby wyrenderować swoją ramkę, pętla renderowania urządzenia nie będzie czekać na zakończenie jedności i narysuje pustą ramkę, która powoduje drgania. Ale, jak już wspomniałem w tytule postu "Niespójny jitter", blog również zgłasza to samo i tak nie dzieje się przez cały czas.

Skąd wiadomo, że to ten sam problem? Cóż, zobaczysz spęki w profilerze (chociaż mieliśmy bardzo minimalistyczną geometrię). Będzie wyglądać bardziej tak, jak Render będzie szaleć.

Chociaż na blogu chodzi bardziej o Input, który jest opóźniony, ale pomógł mi także w moim scenariuszu. Niektórzy mogą nie rozumieć, jak dokładnie rozwiązać ten problem dla nich, polecam ten POST, który przedstawia bardzo jasne rozwiązanie.

Aby kontynuować naukę, rozpocznij czytanie, gdy użytkownik o nazwie "cgJames" przeskoczy do CONVERSATION.

Mam nadzieję, że to pomoże także innym.

0

Niedawno spotkałem się z tym samym problemem. Dokładnie ... Pionowy scroller w Unity, z prostą grafiką, niespotykanie niespójną ilość klatek na sekundę w systemie iOS, czasem może być powiązany z danymi wejściowymi, może nie.

W końcu znalazłem, skąd się bierze problem. Spróbuj zmienić silnik renderowania na iOS z Metal na OpenGL ES 2 lub 3.

Mam nadzieję, że rozwiąże to twój problem.

+0

Dzięki za odpowiedź. Na pewno spróbuję tego i skontaktuję się z Tobą, jeśli to zadziała. –