Jump to content
Unity Insider Forum

Problem mit Root Motion


TheSky

Recommended Posts

Hallo,

ich versuche gerade eine 2D-Charakter zu animieren, und bin dabei auf ein kleines Problem gestoßen.
Bisher habe ich Bewegungen mittels Unitys Physiksystem realisiert (z.B. über Rigidbody2d.velocity).
Das hat bei den bisherigen Animationen auch gut geklappt.
Nun soll der Charakter jedoch auf ein Objekt klettern. Mit dem Physiksystem schien das nicht so gut zu funktionieren,
daher dachte ich, ich benutze root-Motion. In der Editor-Vorschau sah das auch ganz gut aus.
Das Problem ist nun, dass sobald ich diese Animation zum Animator hinzufüge, Physikalische Kräfte
nicht mehr richtig zu funktionieren scheinen, selbst wenn die besagte Animation in dem Moment gar nicht aktiv ist.
Horizontale Kräfte, also in x-Richtung scheinen ignoriert zu werden, vertikale, wir für Sprünge und Gravitation scheinen aber noch zu funktionieren.
"Generate root motion curves" wurde für die Animation aktiviert, "Apply root motion" ebenfalls.
Kann es sein, dass root-Motion und das Physiksystem an ein und den selben Objekt einfach nicht funktionieren,
oder übersehe ich etwas.

Falls jemand Ratschläge hat, wäre ich sehr dankbar.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Kann gut sein, daß wenn eine Root-Animation in XY aktiv ist, die Bewegung des RBs durch die Physik überschrieben wird. Es kann helfen den RB auf kinematic zu setzen (+ Animate Physics) aber das Thema ist sehr komplex und ein Mischen von Animation und Physik ist nie unkompliziert.

Hier ist ein ganz interessanter Artikel zum Thema, evtl. kann er dir ein paar Ideen geben:
https://grovecodeblog.wordpress.com/2013/10/30/combining-physics-and-animation-in-unity/
 

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Zer0Cool

Danke, ich werd mir den Artikel durchlesen.

 

vor 46 Minuten schrieb Zer0Cool:

Es kann helfen den RB auf kinematic zu setzen (+ Animate Physics)

Du meinst isKinematik zu aktivieren, während die root-Animation läuft?

Das würde funktionieren, wenn das Problem nur auftreten würde, während die root-Animation abgespielt wird.

Das Problem ist jedoch, dass das Problem auch auftritt, wenn die root-Animation gar nicht abgespielt wird.

Das Problem tritt auf sobald die root-Animation dem Animator hinzugefügt wurde, selbst wenn es gar keine Transition zu der Animation gibt.

Mir scheint root-Animation und Physiksystem vertragen sich nicht besonders. :wacko:

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe mal eine Testszene aufgebaut und bei mir gibt es keine Probleme.
Das einzige Problem was ich hatte, war daß man die Rotation des RBs fixieren muss. Wenn man die Rotation des RBs nicht fixiert, dann rotiert der RB unkontrolliert umher und somit wirkt die Rootmotion in XZ in unterschiedliche Richtungen.

Testszene:
- ein Terrain erzeugt
- Eine Animation für einen Cube erstellt der einen Cube in X um 300 Einheiten bewegt
- Diese Animation zu einer Rootmotion gemacht
- dem Cube einen RB verpasst (mit Gravitation und Masse)
- am RB des Cubes Freeze Rotation in XYZ aktiviert
- am Animator 2 Zustände erstellt, die den Cube hin- und herbewegt.
=> Ergebnis
Der Cube wandert über das Terrain in X-Richtung

- einen 2. Cube erstellt den ich in Scale X vergrößert habe (eine Art Schaufel die den anderen Cube wegdrücken soll)
- 2. Cube RB verpasst (mit Gravitation und Masse)
- 2. Cube ein Skript verpasst:

using UnityEngine;

public class MoveRB : MonoBehaviour {

    private Rigidbody myrb;
    public float speed = 5f;

    // Use this for initialization
    void Start () {
        myrb = GetComponent<Rigidbody>();
	}
	
	// Update is called once per frame
	void FixedUpdate () {
        Vector3 pos = myrb.transform.position;
        pos.z = pos.z - speed * Time.deltaTime;
        myrb.MovePosition(pos);
	}
}

=> Ergebnis
Der 2. Cube drückt den 1. Cube weg.

Hier wie das Ganze dann aussieht:
https://streamable.com/di3ka

Ich denke du hast irgendwo ein anderes Problem in deinem Aufbau.

Hier noch eine 2. Kollision (die Ruckler kommen vom Video nicht vom Game):
https://streamable.com/9lzbj

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe auch mal eine kleine Testszene gebaut, um zu sehen, ob das Problem reproduzierbar ist.

Testszene:

-neues 2D-Projekt erstellt

-ein Sprite über Assets-->create-->Sprites-->square erzeugt

-Sprite einen Rigidbody2D (masse auf 0 gesetzt) und einen Animator gegeben

-ein einfaches Skript geschrieben, dass das Sprite durch druck auf A und D nach links oder rechts bewegt. (Code siehe unten)

-eine einfache sich wiederholende Animation erstellt, die den Sprite rotiert (keine root Animation) und als Default-State gesetzt.

Diese Szene habe ich dann erstmal getestet. Alles funktioniert. Der Sprite dreht sich, und bewegt sich bei druck auf A oder D nach links oder rechts.

Ich habe dann folgendes ergänzt:

-eine root-Animation erstellt, ber der der Sprite seine Position verändert.

-die Animation dem Animator hinzugefügt. (ohne Transition. Die Animation wird also zu keinem Zeitpunkt abgespielt)

-"Generate root Motion Curves" für die root-Animation und "Apply root Motion" und "Animate Physics" im Animator aktiviert

Diese Szene habe ich dann wieder getestet.

Nun bewegt sich gar nichts mehr. Es werden keine Kräft mehr bei Druck auf a oder d ausgeübt. Auch die Default-Animation, die den Sprite rotiert wird nun nicht mehr abgespielt.

Naja, laut der Anzeige im Animator läuft die Default-Animation, aber der Sprite rotiert einfach nicht mehr.

 

 

Der Code zum Bewegen des Sprite:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Move : MonoBehaviour {

    private Rigidbody2D rigidb;

	void Start () {
        rigidb = GetComponent<Rigidbody2D>();
	}
	
	void Update () {
        if(Input.GetKey("a")) {
            rigidb.velocity = Vector2.left * 10;
        } else if(Input.GetKey("d")) {
            rigidb.velocity = Vector2.right * 10;
        }else {
            rigidb.velocity = Vector2.zero;
        }
    }
}

 

Das Problem ist also reproduzierbar. Ich habe das ganze auch mal mit der Funktion MovePosition probiert. Dasselbe ergebnis (funktioniert wunderbar ohne root-Animation, aber mit root-Animation bewegt sich nichts). Vielleicht muss ich mir einfach was anderes überlegen.

 

Edit:

Da es bei dir zu funktionieren schien, habe ich das ganze mal mit einem Rigidbody statt einem Rigidbody2D probiert. Damit funktioniert alles bestens.

Das Problem ist also offenbar, dass die root-Animation ein Problem mit der Rigidbody2D-Komponente hat.

 

Edit2:

Ich denke ich kann auch ein rigidbody, statt eines Rigidbody2D nutzen. Das Problem scheint also erstmal umgangen.

Ich hoffe nur, dass der Performaceunterschied nicht zu groß ist, das mein Projekt für Smartphones gedacht ist.

@Zer0Cool

Danke für deine Hilfe. Deine Testszene hat für mich die Lösung gebracht, um das Problem zu umgehen.

Falls aber noch jemand eine Lösung für das eigentliche Problem hat, immer nur her damit. ^_^

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe deine Testszene mal nachgestellt.

Das Ergebnis:
Wenn man eine Animation in den Animator packt der KEINE "Root Motion Curves" besitzt (und "Apply Root Motion" auf on), dann blockiert man sämtliche Bewegungen.
Also entweder "Apply Root Motion" aus oder ALLE Animtationen mussen "Root Motion Curves" haben.
(scheinbar ändert sich auch was in der Animation, wenn man 1x die Motion Curves erzeugt und dann wieder entfernt, da ich nun auch eine Konstellation erzeugen kann, wo die Bewegungsanimation keine Root Motion besitzt und es trotzdem funktioniert)

Vielleicht müssen alle Animationen 1x eine Root Motion verpasst bekommen (auch wenn man sie danach wieder entfernt), damit es wie erwartet funktioniert?

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Zer0Cool

Habs mal getestet. Auch wenn in der Testszene alle Animationen root-Motion Animationen sind, werden die Physikalischen Kräfte blockiert.

Man mus sich wohl im Moment damit abfinden, dass root motion und rigidbody2d zusammen nicht funktionieren.

Ich hoffe das wird zukünftig noch geändert. Zumindest in meinem Fall gibt es noch alternativen.

Ich werde keinen Rigidbody, sondern weiterhin ein Rigidbody2D benutzen. Mit einen Rigidbody müsste ich auch alle anderen Collider und Trigger im Spiel anpassen und die Skripte ändern. Das größte Problem wäre aber wohl die Performance . Stattdessen, habe ich inzwischen die Hirarchie der Körperteile meines Charakters etwas verändert.

Mit der neuen Hirarchie kann ich die notwendigen Positionsänderungen auch ohne root motion vornehmen. Allerdings musste ich zusätzlich noch die ganzen .anim-Dateien mit dem Editor bearbeiten, damit ich die bisher erstellten Animation weiternutzen kann.

Ziemlich lästig, aber es funktioniert.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 15 Minuten schrieb TheSky:

@Zer0Cool

Habs mal getestet. Auch wenn in der Testszene alle Animationen root-Motion Animationen sind, werden die Physikalischen Kräfte blockiert.

Man mus sich wohl im Moment damit abfinden, dass root motion und rigidbody2d zusammen nicht funktionieren.

Ich hoffe das wird zukünftig noch geändert. Zumindest in meinem Fall gibt es noch alternativen.

Ich werde keinen Rigidbody, sondern weiterhin ein Rigidbody2D benutzen. Mit einen Rigidbody müsste ich auch alle anderen Collider und Trigger im Spiel anpassen und die Skripte ändern. Das größte Problem wäre aber wohl die Performance . Stattdessen, habe ich inzwischen die Hirarchie der Körperteile meines Charakters etwas verändert.

Mit der neuen Hirarchie kann ich die notwendigen Positionsänderungen auch ohne root motion vornehmen. Allerdings musste ich zusätzlich noch die ganzen .anim-Dateien mit dem Editor bearbeiten, damit ich die bisher erstellten Animation weiternutzen kann.

Ziemlich lästig, aber es funktioniert.

Komisch bei mir hat's funktioniert, ich hab ja deinen Test komplett nachgestellt.

Hier kannst du alle Einstellungen usw. sehen:
https://streamable.com/tjoc7

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ah, ich hatte noch was vergessen. Ich hatte das move-Skript etwas bearbeitet um zu sehen ob das ganze vielleicht mit rigidbody2d.moveposition statt rigidbody.velocity korrekt funktioniert.

Habs auf den ursprünglichen Zustand zurückgesetzt.

Wenn alle Animationen root-Motions sind, dann funktioniert es tatsächlich mit rigidbody2d.velocity. (allerdings nicht mit movePosition).

Damit ergibt sich natürlich eine weitere Möglichkeit, das Problem zu lösen:

Einfach zu jeder Animation einen Parameter (rotation, oder position) des root-parents hinzufügen (Erst dann erscheint offenbar die Einstellung "Generate root motion curves"), und bei allen Animationen "Generate root motion curves" aktivieren.

Das sollte eine gute Möglichkeit sein, das Problem zu umgehen. Hm, da hätte ich mir die Mühe mit der Änderung der .anim-Dateien ja vorhin sparen können. ^^

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was den Fehler betrifft, weiß ich nun in etwa, wo das Problkem ist, und wie man es umgehen kan.
Das Problem ist nähmlich ein anderes als ich zuerst dachte. (@sascha hat mich in einem anderen Thread auf die Lösung gebracht)
Das Problem ist nicht, dass das Physik2D-System nicht funktioniert, wenn root-Motion aktiviert ist. Das Physik2D-System funktioniert gut.
Das Problem ist, dass aus irgend einem Grund rigidbody2D.velocity überschrieben wird, wenn root-Motion aktiviert ist.
Da das Problem wohl irgendwie von der Animator-Komponente ausgeht, lässt sich das Problem simpel umgehen. Ich habe ein zusätzliches Skript erstellt.
Für dieses Skript muss unter edit-->"Project Setting"-->"Skript Execution Order" eingestellt werden, dass es nach der Default-Time ausgewertet wird. (auf diese Weise wird das Skript erst ausgeführt, wenn alle anderen Skripte ihre Sachen erledigt haben)
Ich speichere rigidbody.velocity nun in der Update-Methode und weise der rigidbody.velocity Komponente den gespeicherten Wert in der Late-Update-Methode (welche nach der Animator-Komponente ausgewertet wird) wieder zu.
Ich weiß nicht warum rigidbody2D.velocity überschrieben wird, aber zumindest ist das Problem somit gelöst.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich vermute es wird überschrieben, da die Root-Motion die Position des Transforms verändert und damit indirekt die Velocity des Rigidbodies ebenfalls. Die Root-Motion des Transforms wird zwischen Update und LateUpdate der Animator-Komponente berechnet.
Im Detail denke ich wurde vergessen, einen "Funktions-Einsprungspunkt" für die Rootmotions in ein neu erzeugtes Animationsfile zu packen. Da dieser bei einem neu erzeugten Animationsfile dann nicht vorhanden ist und man aber "Apply Root Motions" aktiviert, greift der Animator quasi ins Leere und verliert dabei das Delta der bereits existierenden Transformbewegung (und damit auch die vorhandene Velocity des RBs). Ist aber nur eine abstrakte Beschreibung des Fehlers in Unity ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...