Stigma Posted February 27 Report Share Posted February 27 Hallo, ich versuche ein Objekt um ein anderes Objekt im Kreis mit einem gewissen Radius fahren zu lassen. Ich habe mir dafür ein Empty auf (0/0/0) gesetzt und mein anderes Objekt auf (0/0/-15). Und dann mit transform.RotateAround(emptyObjectTransform.position, Vector3.up, speed * Time.deltaTime); ums Objekt fahren lassen. Das funktioniert auch genau so, wie ich mir das vorgestellt habe. Nur leider funktioniert die Collision so ja gar nicht. Darum wollte ich das nun gerne mit dem CharacterController machen. Nur leider weiss ich nicht genau, wie ich die Rotation um das Objekt als MotionVector genau so berechnet bekomme, wie es transform.RotateAround macht. Hat da jemand eine Idee, wie man das mit dem CharacterController lösen kann? Oder vielleicht auch eine andere Lösung, bei der Collision funktioniert? Liebe Grüße Quote Link to comment Share on other sites More sharing options...
Sascha Posted February 27 Report Share Posted February 27 Moin! Du könntest zum Beispiel ein neues Objekt ohne Collider nehmen, das die Kreisbewegung macht, und dann deinem CC-Objekt sagen, dass es immer darauf zuhalten soll, aber dann eben mit CharacterController.Move. Quote Link to comment Share on other sites More sharing options...
Stigma Posted February 27 Author Report Share Posted February 27 Hey, danke für deine Antwort! Meinst du das so, dass ich ein Parent habe, welches ich mit transform.RotateAround rum fahren lassen und dann ein Child mit einem CC habe, welches dem Parent folgt? So in entwa? parent.transform.RotateAround(emptyObjectTransform.position, Vector3.up, speed * Time.deltaTime); Vector3 direction = parent.transform.position - child.transform.position; child.CharacterController.Move(direction); Nur sehe ich dann das Problem, dass wenn das Child kollidiert, dass der Parent einfach weiter fährt und das Child dann irgendwann durch den Collider glitcht. Oder habe ich dich falsch verstanden? Quote Link to comment Share on other sites More sharing options...
Sascha Posted February 27 Report Share Posted February 27 Naja, wenn dein CC ein Child des sich bewegenden Objekts ist, dann kommt er ja wieder mit, ohne sich eigenständig zu bewegen und wird Kollisionen erstmal wieder ignorieren. Das führende Objekt und der folgende CC sollten daher nicht übereinander in der Hierarchie sein. vor 38 Minuten schrieb Stigma: Nur sehe ich dann das Problem, dass wenn das Child kollidiert, dass der Parent einfach weiter fährt und das Child dann irgendwann durch den Collider glitcht. Oder habe ich dich falsch verstanden? Genau - wenn du sie einander unterordnest. Wenn du das aber nicht tust, wird der CC (zumindest aufgrund dieses Setups...) nicht irgendwo durch glitchen. Was aber in der Tat passiert ist, dass der Parent einfach immer weiter geht. Der kriegt von Kollisionen ja nix mit. An diesem Punkt musst du dir überlegen, was du eigentlich für ein Verhalten haben willst. Soll dein CC immer, unter allen Bedingungen, auf dem Kreis bleiben? Oder könnte er an einem Hindernis auch vorbei rutschen und kommt dann irgendwann wieder auf dem Kreis an? Quote Link to comment Share on other sites More sharing options...
Stigma Posted February 27 Author Report Share Posted February 27 Ok, ich verstehe was du meinst. Wenn es nicht untergeordnet wird, glitcht er zwar nicht durch, aber rutscht anhand des Winkels irgendwann am Obstacle vorbei. Das Verhalten soll schon so sein, dass wenn der CC kollidiert auch angehalten wird. Also das Objekt das im Kreis fährt und das der CC verfolgt, müsste eigentlich auch stehen bleiben. Man kann schon sagen, dass sie immer zusammen bleiben sollen. Hast du da eine Idee, wie ich das erreichen kann? Das Einzige was mir in den Sinn kommt, ist bei einer Kollision den Input zu disablen, damit das Objekt, welches im Kreis fährt auch stehen bleibt. Nur dann könnte ich nicht mehr in die andere Richtung fahren. Dann müsste ich mit einem Raycast gucken, ob die andere Seite frei ist oderso. Aber eigentlich wollte ich keine Raycasts benutzen. Quote Link to comment Share on other sites More sharing options...
Sascha Posted February 27 Report Share Posted February 27 Kreise können etwas problematisch sein, weil Bewegung immer linear ist. Wenn ein Objekt auf- und vorwärts geworfen wird, dann passiert in der Simulation keine "echte" Kurve, sondern Aneinanderreihung von ganz vielen kleinen Linien, die annähernd eine Kurve beschreiben. Deshalb bewegst du auch deinen CC nur so "halbwegs wirklich" auf einem Kreis - die Positionen, auf die du ihn in jedem Frame aufs neue schickst, liegen (hoffentlich) alle auf dem Kreis, aber wenn das Ding auf dem Weg von einem Punkt zum nächsten kollidiert, dann wäre diese Kollision halt nicht mehr auf dem Kreis. Da man meistens keinen Achtelkreis, sondern einen viel kleineren Weg am Stück zurück legt, ist er erst mal nicht so krass - aber da man das ganz oft pro Sekunde macht, kann sich diese kleine Abweichung schnell mit allen anderen Aufsummieren. Eine saubere Lösung geht mit diesem Problem also irgendwie um. Was du machen könntest wäre ein eigener Physik-Check. Du nimmst dir eine der Funktionen in Physics, z.B. Physics.CapsuleCast, welches eine imaginäre Kapsel (also genau die Form deines CC) durch die Gegend schießt und schaut, ob eine Kollision passieren würde. Du könntest ganz stumpf sagen dass, wenn das passiert, einfach keine Bewegung in diesem Frame passieren soll. Du könntest das mit der oberen Idee (die übrigens nicht unbedingt "die beste" ist!) kombinieren, indem du dann auch den "Vorangeher" anhältst, anstatt dass er sich weiter dreht. Er dreht sich also nur so lange, wie der CC auch folgen kann, und wartet ansonsten. Quote Link to comment Share on other sites More sharing options...
Stigma Posted February 27 Author Report Share Posted February 27 Vielen Dank für die genaue Erklärung! Genau das was du mit den Physics.CapsuleCast meinst, meinte ich auch. Nur halt mir einem Physics.RayCast. Aber so richtig glücklich bin ich mit dieser Lösung irgendwie nicht. Am liebsten hätte ich eine Methode, die mir einfach den Motion Vector zurück gibt und ich den einfach für CC.Move verwenden kann. Ich habe auch versucht die transform.TurnAround Funktion "nachzubauen". Aber leider stehe ich da Mathematisch völlig auf dem Schlauch. Die Frage ist, was ist an dieser Stelle "die beste" Lösung. Du scheinst da ja ziemlich Fit zu sein. Hast du noch eine Idee, wie man das sonst angehen könnte? Vielleicht auch ohne CC. Aber ich denke, dass ich mit einem Rigidbody und AddForce genau das selbe Problem haben werde. Quote Link to comment Share on other sites More sharing options...
Sascha Posted February 27 Report Share Posted February 27 Wenn du einfach einen Bewegungsvektor berechnen lässt, ihn in CC.Move reinsteckst und er dann auf dem Weg kollidiert, dann wird der CC halt nicht mehr auf dem Kreis sein. Und wenn das mehrere Frames hintereinander passiert, kann das auch durchaus sichtbar werden. Das war nach meinem Verständnis das, was du vermeiden wolltest. Du könntest jetzt mit Trigonometrie da ran und dir mit Sinus und Kosinus die nächste Position auf dem Kreis ausrechnen. Der Vorschlag mit dem leeren Objekt, dem gefolgt wird, war nur, um das zu vermeiden - Trigonometrie selber machen ist meh Du musst das Objekt auch nicht durchgehend weiter laufen lassen. Du kannst das Objekt auch in jedem Frame auf die Position des CCs setzen und von dort aus mit RotateAround weiterdrehen. Sollte nichts mit dem CC passieren, dann dreht sich das Ding die ganze Zeit, aber sollte er kollidieren, dann würde das Objekt immer wieder auf die Position des CCs zurückspringen, bevor er sich dreht. Irgendwie sowas: public Transform leader; public CharacterController characterController; private void FixedUpdate() { leader.position = characterController.position; leader.RotateAround( ... ); var direction = leader.position - characterController.transform.position; characterController.Move(direction); } Quote Link to comment Share on other sites More sharing options...
Stigma Posted February 27 Author Report Share Posted February 27 Ja genau, dass soll eigentlich nicht passieren. Der soll immer auf dem selben Kreis fahren und nicht abweichen. Wenn ich jetzt den leader immer auf die Position vom CC setze und dann gegen ein Obstacle komme und einfach immer weiter gegen fahre, verschiebt sich der CC ja auch und rutscht dann irgendwann einfach dran vorbei. Dann fährt er danach zwar weiter im Kreis. Nur leider nicht auf dem richtigen. Ich vermute das selbe Problem hätte ich auch, wenn ich das über Trigonometrie löse, da ich da ja den nächsten Punkt auf der Kurve anhand meiner aktuellen Position berechnen würde, wenn ich mich nicht irre. Und wenn durch die Kollision schon eine Verschiebung stattgefunden hat, wäre der nächste Punkt ja auch nicht akkurat. Quote Link to comment Share on other sites More sharing options...
Sascha Posted February 27 Report Share Posted February 27 vor 47 Minuten schrieb Stigma: Wenn ich jetzt den leader immer auf die Position vom CC setze Naja - du kannst den Leader auf den Kreis zurück setzen. Dafür musst du nur die Distanz zum Kreismittelpunkt nehmen, die Distanz normalisieren (auf Länge 1 bringen) und dann mit dem Kreisradius multiplizieren. Damit bewegt sich der Leader auf den Kreismittelpunkt zu bzw. davon weg, um wieder auf dem Kreis zu landen. var directionToCenter = leader.position - centerPosition; var directionOntoCircle = directionToCenter.normalized * circleRadius; leader.position = centerPosition + directionOntoCircle; Und wenn der Leader immer auf dem Kreis bleibt, egal was der CC macht, dann wird der CC auch immer wieder auf den Kreis zusteuern. Quote Link to comment Share on other sites More sharing options...
Stigma Posted February 28 Author Report Share Posted February 28 Ich habe das mal ausprobiert und das funktioniert soweit auch ganz gut. Vielen Dank dafür! Jetzt habe ich noch das Problem, dass bei der Kollision die Position des leaders wieder auf den Kreis gesetzt wird. Aber die Rotation nicht. Das habe ich so gelöst: Vector3 directionToCenter = leader.transform.position - origin.position; leader.transform.rotation = Quaternion.LookRotation(directionToCenter); Meinst das ist ok so, oder hast du da eine smartere Idee? Quote Link to comment Share on other sites More sharing options...
Sascha Posted February 28 Report Share Posted February 28 Wozu braucht denn der Leader eine bestimmte Rotation? Aber davon abgesehen ist das ne gute Lösung, wenn in die Mitte gucken okay für dich ist. Quote Link to comment Share on other sites More sharing options...
Stigma Posted February 28 Author Report Share Posted February 28 Der CC soll dem rechts Vektor vom Leader folgen. Ich gucke quasi von der Seite in die Mitte auf den CC, während er um den Zylinder fährt. Dabei nimm der CC dann die. characterController.transform.rotation = Quaternion.LookRotation(leader.transform.right); Wenn du verstehst, was ich meine. Quote Link to comment Share on other sites More sharing options...
Sascha Posted February 28 Report Share Posted February 28 Öh joa, kann man so machen. Du kannst aber auch einfach direkt den CC drehen, ohne den Leader zu involvieren. Aber wenn du den ganzen mehrstufigen Drehkram in eine Methode auslagerst, dann ist das schon okay so Quote Link to comment Share on other sites More sharing options...
Stigma Posted February 28 Author Report Share Posted February 28 Hast du Lust mir zu verraten, wie ich Rotation ohne den Leader machen kann? Ich komme irgendwie nicht drauf. Ich würde es eigentlich schöner finden, wenn der CC nicht so abhängig von dem Leader ist. Quote Link to comment Share on other sites More sharing options...
Sascha Posted February 28 Report Share Posted February 28 Was du suchst, ist das Kreuzprodukt von Vector3.up und dem Vektor vom CC zum Kreismittelpunkt. Ein Kreuzprodukt zweier Vektoren ist der Vektor, der senkrecht zu beiden Vektoren ist. Das wäre dann (ausgehend davon, dass dein Kreis horizontal ist) die Tangente des Kreises. var lookDirection = Vector3.Cross(Vector3.up, directionToCenter); characterController.transform.rotation = Quaternion.LookDirection(lookDirection); Wenn der Vektor in die falsche Richtung zeigen sollte, Parameter-Reihenfolge vertauschen oder bei einem von beiden ein Minus davor klatschen Quote Link to comment Share on other sites More sharing options...
Stigma Posted February 28 Author Report Share Posted February 28 Achja, das Kreuzprodukt. Lang lang ist es her. Das funktioniert soweit auf jeden Fall. Ich glaube ich komme so erstmal weiter. Vielen lieben Dank für deine Hilfe. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.