Kontroler postaci 2D w jedności (próba odzyskania oldschoolowych platformówek)


11

Obecnie próbuję stworzyć kontroler postaci 2D z jednością (za pomocą fizyki). Jestem dość nowy w silnikach fizycznych i naprawdę trudno jest uzyskać kontrolę, której szukam. Byłbym bardzo szczęśliwy, gdyby ktoś mógł zaproponować rozwiązanie problemu, który znajduję:

To jest teraz moja FixedUpdate:

public void FixedUpdate()
{
    Vector3 v=new Vector3(0,-10000*Time.fixedDeltaTime,0);
    _body.AddForce(v);

    v.y=0;
    if(state(MovementState.Left))
    {
        v.x=-_walkSpeed*Time.fixedDeltaTime+v.x;
        if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=-_maxWalkSpeed;
    }
    else if(state(MovementState.Right))
    {
        v.x= _walkSpeed*Time.fixedDeltaTime+v.x;
        if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=_maxWalkSpeed;
    }

    _body.velocity=v;

    Debug.Log("Velocity: "+_body.velocity);
}

Próbuję tu po prostu przesunąć sztywne ciało przy użyciu siły grawitacji i siły liniowej dla lewej i prawej. Mam ustawiony materiał fizyczny, który nie powoduje podskakiwania i 0 tarcia podczas ruchu i 1 tarcie przy bezruchu. Głównym problemem jest to, że mam zderzaki ze zboczami, a prędkość zmienia się od wchodzenia w górę (wolniej), schodzenia w dół zbocza (szybciej) i chodzenia po prostym zderzaku (normalny). Jak można to naprawić? Jak widać, zawsze stosuję tę samą prędkość dla osi x.

Dla gracza mam to ustawienie z kulą w pozycji stóp, która jest sztywnym ciałem, do którego przykładam siły.

Wszelkie inne wskazówki, które mogłyby ułatwić mi życie, są mile widziane :).

PD Wracając do domu zauważyłem, że mogę rozwiązać ten problem, stosując stałą siłę równoległą do powierzchni, po której idzie gracz, ale nie wiem, czy to najlepsza metoda.


4
Oldschoolowe platformówki wykorzystywały ręcznie dostosowaną „kreskówkową fizykę” do mechaniki skoków i bezpośrednią kontrolę prędkości (tj. Brak fizyki w ogóle) do poruszania się. Jeśli możesz przepisać kontroler postaci, zrób to, ponieważ ciężko będzie wcisnąć i wbić delikatną symulację fizyki w ostre ruchy, które miały stare gry szkolne.
— Patrick Hughes,

Problem pisania niestandardowego polega na tym, że utracono wykrywanie kolizji. I nie jest łatwo go odbudować bez użycia raycast (w zależności od środowiska itp. ... może to być kilka). Jak sobie z tym poradzić?
— Notbad

Podczas korzystania ze sztywnych nadwozi kinematycznych możesz mieć zderzaki na rzeczach, które nadal są niestandardowo animowane. Zapewniam, że w większości sytuacji tak naprawdę nie potrzebujesz fizyki / sił w świecie rzeczywistym do tego rodzaju zastosowań. Jeśli szukasz bardziej technicznego punktu widzenia, może
— zbadaj

1
Def fizyka rowów w tej sytuacji.
— Ray_Garner

Odpowiedzi:


7

Jeśli chcesz naśladować oldskulowe platformówki, pierwszym krokiem jest porzucenie fizyki. Skończysz walkę z systemem fizyki, aby uzyskać zdecydowanie nierealistyczny ruch starej szkolnej platformówki. Spójrz na tę zamiennik CharacterController, która całkowicie porzuca fizykę, aby uzyskać dobry pomysł na jeden ze sposobów jej wdrożenia.


3

Prawdopodobnie byłbyś szczęśliwszy, postępując zgodnie z zaleceniami mheona. Ale jeśli zamierzasz użyć fizyki Unity, prawdopodobnie prawdopodobnie chcesz to wykorzystać ForceMode.VelocityChange.

Przykład:

public void FixedUpdate()
{
    var v = Vector3.zero;
    if(state(MovementState.Left))
    {
        v.x=-_walkSpeed*Time.fixedDeltaTime+v.x;
        if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=-_maxWalkSpeed;
    }
    else if(state(MovementState.Right))
    {
        v.x= _walkSpeed*Time.fixedDeltaTime+v.x;
        if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=_maxWalkSpeed;
    }

    _body.AddForce(v, ForceMode.VelocityChange);

    Debug.Log("Velocity: "+_body.velocity);
}

Powinieneś również zastosować globalną grawitację w ustawieniach Fizyki swojego projektu, a do obiektów, które chcesz upaść szybciej, dodaj komponent Constant Force .

ForceMode.Impulsejest podobny, ale wpływa na niego masa ciała sztywnego. Utrudnia dostrojenie.


2

Nawet jeśli nie podoba ci się wbudowany kontroler postaci (tak jak ja), spójrz na przykładowy kod Unity dla samouczka rozgrywki 2D .

Kod implementuje pełną rozgrywkę 2D z ruchomymi platformami, wrogami i skrzynkami z kolizją, za pomocą kontrolera postaci.

Ale jeśli nawet nie chcesz rzucić okiem, sugeruję, aby zminimalizować użycie fizyki i spróbować skopiować jej zachowanie za pomocą własnego kodu. W zależności od rodzaju planowanej gry 2D może ona działać całkiem dobrze. Na przykład, zamiast przykładać siłę, aby Rigidbody.velocityporuszać postacią, możesz zadzierać bezpośrednio Transform.Translate(), która porusza obiekt w Transform.positionoparciu o jego oś. Możesz określić forwardi backzwiązany z samym obiektem, a może platformą lub podłogą Transform.up, dzięki czemu będziesz wiedział, czy jest to rampa i jakoś znasz jego kąt.

Również jeśli stworzysz coś w rodzaju atrybutu kontroli prędkości (np. Jak długo wciśnięty jest klawisz), możesz zastosować go razem z twoim kierunkiem podczas tłumaczenia, aby zapobiec twojemu bohaterowi chodzenia po czymś zbyt pochylonym bez pewnej prędkości, podobnie jak robili to Sonic the Hedgehog dla Genesis / Mega Drive.

Jeśli zdecydujesz się nadal używać fizyki, nie mogę ci w ogóle pomóc, ponieważ nie jestem w tym tak dobry, ale pamiętaj, że normalnym zachowaniem jest chodzenie wolniej, ponieważ ciało potrzebuje więcej siły, aby nadążyć , jak prawdziwe życie.


Pierwszą rzeczą, którą przeczytałem, kiedy połączyłem się, był samouczek. Problem polega na tym, że kontrola jest dość zła. Dlatego chciałem znaleźć własne rozwiązanie. Z drugiej strony, kiedy zaczynasz używać Transform.Translate (), nie jest tak łatwo robić zbocza i inne rzeczy. Musisz rzucić kilka razy promieniem (2 lub 3 na podłogę, więcej na kierunek, w którym się poruszasz, w zależności od wielkości bohatera). W przypadku urządzeń mobilnych raycast nie jest dobry, a mniej, jeśli masz zrobić 5..n na iterację wykrywania kolizji. Być może mogę się mylić, ale nie sądzę.
— Notbad

1

Co chcesz to wbudowany kontroler postaci . Ustawiając step offsetwłaściwość dla tego komponentu, możesz sprawić, że gracz będzie mógł łatwo poruszać się po zboczach.


Przepraszam, że nie komentowałem. Wiem, że istnieje Kontroler Postaci w jedności i że użyłem go kilka razy, ale nie podoba mi się jego zachowanie. Jest bardziej odpowiedni dla FPS, a nie gry platformowej, w której mechanika ruchu jest jedną z najważniejszych rzeczy.
— Notbad

Wydaje mi się, że kiedy będziesz majstrować przy ustawieniach kontrolera postaci, działa dobrze. Czego ci brakowało?
— NoobsArePeople2

Pierwszą rzeczą, która mi się nie podoba, jest to, że jest powolny w stosunku do zwykłych sztywnych ciał z pewnym promieniowaniem. Wiedząc, jak to osiągnąć, myślę, że mógłbym zrobić bardziej lekki kontroler. Innym problemem jest dziwne zachowanie kapsuły / kuli na krawędziach platformy (można to rozwiązać za pomocą kilku rzutów promieniujących). Właśnie dlatego chcę rzucić własne.
— Notbad

0

wprowadź opis zdjęcia tutajPrzypuszczam, że dzieje się tak, ponieważ siła nie jest równoległa do platformy, a wynik kończy się niższym wzrostem i większym spadkiem.

Jeśli zastosujesz siłę względną do układu współrzędnych

AddRelativeForce

Chcesz zachować maksymalną prędkość w „x” i porównać ją ze skalarem, pamiętaj, że prędkość jest wektorem i składa się z vx i vy, w płaskim terenie vy wynosi zero, ale koniecznie na zboczach jest większe niż zero.

Prędkość zmienia się zgodnie z kierunkiem ciała, a jej względne vx zmienia się w stosunku do ogólnego vx

Może to zmodyfikować twój V w sposób, którego nie chcesz:

if (Mathf.Abs (v.x)> _ maxWalkSpeed) v.x = _maxWalkSpeed;

utrzymywanie tego samego globalnego Vx może wydawać się dziwne dla oka. (Niepożądane przyspieszenia)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.