5corpio Posted November 9, 2008 Report Share Posted November 9, 2008 Nie mogę wykminić w czym źle pojmuje dlatego muszę napisać Sprawa wygląda tak: mam jakieś punkty kontrolne po, których ma chodzić postać reprezentację waypointów i połączeń mam załatwione etc. tylko mam problem z obrotem postaci "twarzą" na wprost do nowego waypointa. Chodzi o to, że postać dochodzi do punktu i obraca się twarzą w kierunku nowego punktu. Zaprezentuje graficznie o co kaman: Czyli w momencie dojścia do pkt. (a dokładnie do małego kwadratu) muszę obliczyć kąt i obrócić postać. No i niby tak robię i coś jest źle bo się obraca o zły kąt :/ Teraz kod: procedure TSIobject.UpdateSIState; var lookUpPoint : Vector2d; begin { Sprawdzamy czy postać znajdzie się w kwadracie dookoła waypointa jesli tak to:} if PointInRect2d(Vector2(fLinkedChr.Position.x, fLinkedChr.Position.z), fLinkedPath.fTollBox) then begin { Aktualny waypoint to ten który był następny } fPATHcontroller := fPATHnextController; { A następny punkt to następny } fPATHnextController := fLinkedPath.GetNextWaypoints(fPATHnextController); { Pobieramy pkt. w którym jest kolejny punkt i na który będziemy się mieć patrzeć } lookUpPoint := fLinkedPath.GetWaypoint(fPATHnextController).fData.fWPTPosition; { Ustawiam sobie taki mały kwadracik dookoła żeby mieć jakąś tolerancję } fLinkedPath.fTollBox.p1 := Vector2(lookUpPoint.x - toll, lookUpPoint.y - toll); fLinkedPath.fTollBox.p2 := Vector2(lookUpPoint.x + toll, lookUpPoint.y + toll); { Ta metoda ma obrócić postać tak żeby patrzyła prosto na żadany punkt } fLinkedChr.LookToPoint(lookUpPoint); end else begin lookUpPoint := fLinkedPath.GetWaypoint(fPATHnextController).fData.fWPTPosition; fLinkedChr.MoveForward(); // Idź na przód end; end; ...... //Teraz metoda LookToPoint(...) procedure TCharacter.LookToPoint(lookTo: Vector2d); var v1, v2 : Vector2d; rAngle : Single; begin { Pierwszy wektor zbudowany od pozycji postaci do celu patrzenia } v1 := Vector2(fPosition.x - lookTo.x, fPosition.y - lookTo.y); { Drugi wektor od postaci w dal czyli taki wektor w którą stronę idziemy } v2 := Vector2(fPosition.x + sin(RotateAngles.y * PI / 180), fPosition.y + cos(RotateAngles.y * PI / 180)); { Kąt między wektorami } rAngle := CalcDirAngleBetween(v1, v2); { Pomijając pare rzeczy ta metoda działa tak: KatObrotuY = KatObrotuY + rAngle } RotateCharacter(rAngle); end; ..... //A wyliczanie kata miedzy wektorami jest (niby tak:p wg. Tostera hehe) function dd(const v1,v2 : Vector2d) : real; var l1, l2, dProduct : real; begin l1 := VectorMagnitude(v1); //dl. wektora l2 := VectorMagnitude(v2); if (l1 = 0) or (l2 = 0) then begin Result := 0; exit; end; dProduct := DotProduct(v1, v2); result := RadToDeg(ArcCos(dProduct / (l1 * l2))); if v2.y < 0 then Result := 360 - Result; end; function CalcDirAngleBetween(const v1, v2 : Vector2d) : real; var a1, a2 : real; begin a1 := dd(Vector2(1,0), v1); a2 := dd(Vector2(1,0), v2); Result := a1 - a2; end; Na koniec wrzucę programik jak ktoś ma ochotę otworzyć exe i zobaczyć jak działa dokładnie. Ten czerwony kwadrat na środku olejcie Ten zielony mniejszy to jest waypoint do którego powinien dążyć postać natomiast te niebieskie linie pokazują te wyliczane wektory żeby lepiej zobrazować Kursorami można dodatkowo sterować postacią. Jak się wejdzie na waypoint to się pokazuje kolejny punkt do którego powinnien podążać (dokładnie są 3 punkty) Program Demonstracyjny:) Jak komuś będzie się chciało zerknąć to fajnie jak nie to i tak będe drążył co jest nie ten tegez :/ Pozdro 5corpio Ot taka mini-strona moja po godzinach http://www.wnetrzekuchni.pl Link to comment Share on other sites More sharing options...
Jason Posted November 9, 2008 Report Share Posted November 9, 2008 W moim projekcie coś takiego wymodziłem: if (pZ+jason.z<=0) { if (pX+jason.x>0) jason.ry=RadToDeg(atan(abs(pZ+jason.z)/abs(pX+jason.x)))-90; else if (pX+jason.x<0) jason.ry=-RadToDeg(atan(abs(pZ+jason.z)/abs(pX+jason.x)))+90; else jason.ry=0; } else { if (pX+jason.x>0) jason.ry=-RadToDeg(atan(abs(pZ+jason.z)/abs(pX+jason.x)))-90; else if (pX+jason.x<0) jason.ry=RadToDeg(atan(abs(pZ+jason.z)/abs(pX+jason.x)))+90; else jason.ry=180; } W ten sposób postać zawsze obraca się w stronę gracza (należy wziąć pod uwagę, że pX,pZ to nie jest rzeczywista pozycja postaci - niuanse z kamerą - dlatego funkcji abs podaję sumę, a nie różnicę). Może to Ci w czymś pomoże Link to comment Share on other sites More sharing options...
5corpio Posted November 11, 2008 Author Report Share Posted November 11, 2008 Dobra problem rozwiązany wyliczam sobie innaczej kąt już a mianowicie tworze prostą potem wyliczam kąt nachylenia i lekko modyfikuje go w zależności od X A dokładnie to tak: v1 := Vector2(lookTo.x, lookTo.y); v2 := Vector2(Position.x, Position.z); v3 := LineParamFromPoint2d(v1, v2); // Zwraca a i b prostej przechodzacej przez 2 punkty. a zapisuje do v3.x a b do v3.y angl := RadToDeg(ArcTan(v3.x)); if v1.x <= v2.x then angl := 90 - angl; if v1.x > v2.x then angl := 270 - angl; RotateCharacter(angl); Jeszcze tylko zamiast dodawania kąta do aktualnego zrobiłem ustawianie na wyliczony kąt i wszystko śmiga a dokładnie łazi po punktach Pozdro i Tyle hehe a jak ktoś jest ciekaw wyniku to tutaj jest demko z 2 postaciami korzystającymi z tej samej ścieżki: Demko]:-> Ot taka mini-strona moja po godzinach http://www.wnetrzekuchni.pl Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.