2012-03-13 10 views
13

Mam problem z utrzymywaniem obiektów gry w zamkniętym obszarze. Kiedy dotrą do krawędzi, nastąpi chwilowe odepchnięcie, ale potem przejdą przez ścianę.Jak zapobiegać przechodzeniu przez siebie zderzaków?

Używam Zderzaka Pudełek na odtwarzaczu i Zderzaka Siatek dla ściany poziomu. Mam problemy zarówno z postacią gracza (statkiem kosmicznym), którą ruch kontroluje gracz. I za pomocą pocisków, które są ogniami i zapominają poruszać się ze stałą prędkością.

To jest mój kod ruchu dla mojego odtwarzacza. Jest uruchamiany w funkcji FixedUpdate().

//Movement 
    haxis = Input.GetAxis("Horizontal") * speed; 
    vaxis = Input.GetAxis("Vertical") * speed; 

    moveVector.x = haxis; 
    moveVector.z = vaxis; 

    if(moveVector.magnitude > 1) 
    { 
     moveVector.Normalize(); 
    } 

    rigidbody.MovePosition(transform.position + moveVector * speed); 

Za pomocą pocisków, otrzymują prędkość, a silnik oblicza ich filmy. Używają one Box Collider i jest ustawiony jako Trigger, więc nie mają fizyki. Ale używam OnTriggerEnter, aby je zniszczyć.

//Projectiles without physics collisiions 
function OnTriggerEnter (other : Collider) { 
    Destroy(gameObject); 
} 

Niektóre, ale nie wszystkie pociski zostaną zniszczone po uderzeniu w ścianę zderzacza siatki. Gracz czasami uderzy go i przestanie, ale zwykle może go przepchnąć. Jak za każdym razem można wykonać kolizje za pomocą narzędzia do sprawdzania siatki?

+0

Stworzyłem nawet prostszy zderzacz siatki z siatki ściany i to nie pomogło. – Chris

+0

Jak szerokie są zderzacze siatki używane na ekranie i jak szybko mogą pocisk i gracz podróżować? Jeśli pociski lub gracz mogą przesunąć odległość dłuższą niż zderzak w jednej klatce, masz ją. Poza tym unikałbym ręcznego przenoszenia sztywnego nadwozia. To tylko pomyli silnik fizyki i uniemożliwi jej optymalizację. Zamiast tego przenieś transformację obiektu gry. – Elideb

+0

@Elideb Zderzacze mają około 8 znaków i 20 pocisków. Nie przemieszczają się całkowicie przez zderzak w pojedynczej ramce. Jeśli przeniesiesz transformację, Unity zignoruje całą fizykę, rigidbody.MovePosition bierze pod uwagę fizykę. – Chris

Odpowiedz

9

Kolizja z szybko poruszającymi się przedmiotami jest zawsze problemem. Dobrym sposobem na wykrycie kolizji jest użycie funkcji Raycasting zamiast polegania na symulacji fizyki. Działa to dobrze w przypadku pocisków lub małych obiektów, ale nie przyniesie dobrych wyników dla dużych obiektów. http://unity3d.com/support/documentation/ScriptReference/Physics.Raycast.html

Pseudo-codeish (nie mam Podpowiedzi tu i słabą pamięć):

void FixedUpdate() 
{ 
    Vector3 direction = new Vector3(transform.position - lastPosition); 
    Ray ray = new Ray(lastPosition, direction); 
    RaycastHit hit; 
    if (Physics.Raycast(ray, hit, direction.magnitude)) 
    { 
     // Do something if hit 
    } 

    this.lastPosition = transform.position; 
} 
+0

Przesłano zmianę, ale powinna to być Ray (ostatnia pozycja, kierunek), w przeciwnym razie możesz znajdować się w zderzaczu siatki, a promień nie trafi z wnętrza zderzacza. Wygląda na to dobre podejście, sprawdzę to. – Chris

+0

Jedyny problem, jaki mogę tu sobie wyobrazić, to że możemy przyglądać się wielu ruchomym elementom i podejrzewam, że Raycast na wszystkich z nich będzie bardziej wydajny niż w przypadku zderzeń złożonych. Jeśli będę miał okazję przetestować to, dam ci znać, jaka jest różnica w wydajności. – Chris

+0

collider.Raycast sprawdza przeciwko pojedynczemu zderzaczowi - Edytowałem w Physics.Raycast. Jeśli chodzi o wydajność, nie sądzę, że będzie to duży hit, ale wymaga testów. Możesz użyć parametru layerMask w Physics.Raycast, aby upewnić się, że testowany jest tylko pod kątem tego, co chcesz (zobacz dokumenty). – Petrucio

1

Więc nie udało się uzyskać Mesh Zderzacze do pracy. Stworzyłem zderzacz złożony za pomocą prostych kolizji pudełkowych i działało dokładnie zgodnie z oczekiwaniami.

Inne testy z prostymi zderzaczami do siatki okazały się takie same.

Wygląda na to, że najlepszą odpowiedzią jest zbudowanie zderzacza złożonego z prostych zderzaków skrzynkowych/sferycznych.

W moim konkretnym przypadku napisałem kreatora, który tworzy zderzacz złożony w kształcie rury.

@script AddComponentMenu("Colliders/Pipe Collider"); 
class WizardCreatePipeCollider extends ScriptableWizard 
{ 
    public var outterRadius : float = 200; 
    public var innerRadius : float = 190; 
    public var sections : int = 12; 
    public var height : float = 20; 

    @MenuItem("GameObject/Colliders/Create Pipe Collider") 
    static function CreateWizard() 
    { 
     ScriptableWizard.DisplayWizard.<WizardCreatePipeCollider>("Create Pipe Collider"); 
    } 

    public function OnWizardUpdate() { 
     helpString = "Creates a Pipe Collider"; 
    } 

    public function OnWizardCreate() { 
     var theta : float = 360f/sections; 
     var width : float = outterRadius - innerRadius; 

     var sectionLength : float = 2 * outterRadius * Mathf.Sin((theta/2) * Mathf.Deg2Rad); 

     var container : GameObject = new GameObject("Pipe Collider"); 
     var section : GameObject; 
     var sectionCollider : GameObject; 
     var boxCollider : BoxCollider; 

     for(var i = 0; i < sections; i++) 
     { 
      section = new GameObject("Section " + (i + 1)); 

      sectionCollider = new GameObject("SectionCollider " + (i + 1)); 
      section.transform.parent = container.transform; 
      sectionCollider.transform.parent = section.transform; 

      section.transform.localPosition = Vector3.zero; 
      section.transform.localRotation.eulerAngles.y = i * theta; 

      boxCollider = sectionCollider.AddComponent.<BoxCollider>(); 
      boxCollider.center = Vector3.zero; 
      boxCollider.size = new Vector3(width, height, sectionLength); 

      sectionCollider.transform.localPosition = new Vector3(innerRadius + (width/2), 0, 0); 
     } 
    } 
} 
12

mam prototyp pinball, który dał mi wiele problemów w tych samych obszarach.Są to wszystkie kroki wziąłem do prawie (ale jeszcze nie całkowicie) rozwiązać te problemy:

Dla szybko poruszających się obiektów:

  • Ustaw interpolacji bryła sztywna do „Interpolate” (nie ma to wpływu faktyczna symulacja fizyki, ale poprawnie aktualizuje renderowanie obiektu - użyj tego tylko na ważnych obiektach z punktu widzenia renderowania, takich jak odtwarzacz lub pinball, ale nie dla pocisków)

  • Ustawienie wykrywania kolizji na ciągłe Dynamiczny

  • Dołącz skrypt do obiektu DontGoThroughThings (https://www.auto.tuwien.ac.at/wordpress/?p=260) do swojego obiektu. Ten skrypt sprytnie wykorzystuje rozwiązanie Raycasting, które opublikowałem w mojej drugiej odpowiedzi, aby wycofać obraźliwe obiekty przed punktami kolizji.

W Edit -> Project Settings -> Physics:

  • Set Min Penetracja na kary do bardzo niskiej wartości. Ustawiłem kopalnię na 0,001

  • Ustaw liczbę iteracji solwera na wyższą wartość. Ustawiłem kopalnię na 50, ale prawdopodobnie można zrobić ok, znacznie mniej.

Wszystko, co będzie miało karę w wykonaniu, ale to nieuniknione. Wartości domyślne są miękkie w działaniu, ale nie są przeznaczone do poprawnej symulacji małych i szybko poruszających się obiektów.

+0

Witam, nie mogę znaleźć skryptu DontGoThroughtThings Czy możesz go podać. może być użytkownik usunięty z powyższego linku. –

+0

Znalazłem link do DontGoThroughtThings Scripte http://code.google.com/p/lava-in-antarctica/source/browse/trunk/DontGoThroughThings.cs?spec=svn2&r=2 –

+0

Korzystam z Unity 5 i po przeczytaniu to, chociaż nie mogłem znaleźć "Min. penetracji dla kary", ale próbowałem zmienić "domyślne przesunięcie kontaktu" na 1. Teraz szybko się poruszające obiekty są wykrywane :) – Kunalxigxag

1
  • Edytuj ---> Ustawienia projektu ---> Czas ... zmniejsz wartość "Naprawiono czas". To rozwiąże problem, ale może negatywnie wpłynąć na wydajność.

  • Innym rozwiązaniem jest może być obliczyć współrzędne (na przykład, masz piłki i ściany. Ball trafi do ściany. Tak więc obliczyć współrzędne ściany i ustawić proces uderzenie według tych cordinates)

0

1.) Nigdy nie używaj MESH COLLIDER. Użyj kombinacji skrzynki i zderzacza kapsułek.

2.) Sprawdź ograniczenia w RigidBody. Jeśli zaznaczysz Zablokuj położenie X, niż przejdzie przez obiekt na osi X. (To samo dotyczy osi y).

0

Stare pytanie, ale może pomaga komuś.

Przejdź do Ustawienia projektu> Czas i spróbuj podzielić ustalony czas i maksymalny dozwolony czas przez dwa lub cztery.

Miałem problem, że mój gracz był w stanie przecisnąć się przez otwory mniejsze niż zderzacz zawodników i to rozwiązało. Pomaga także w zatrzymywaniu szybko poruszających się obiektów.

+0

Stara odpowiedź, ale dziękuję! – Deniss

Powiązane problemy