Jump to content
Unity Insider Forum

Individuelle Winkelwerte einem Rotations-Script übergeben


minuschki

Recommended Posts

Hallo zusammen

Ich bin blutiger Anfänger und komme bei einem Script-Problem nicht weiter.

Ich habe eine menschliche Figur in die Szene importiert. Mit Hilfe von mehreren Slidern kann man die einzelnen Körperteile bewegen (z.B. den Arm seitlich anheben oder ein Knie beugen). Dazu habe ich das unten stehende "Rotationsscript" jeweils an einen Körperteil angehängt und mit einem Slider verbunden. Die Bewegung aller Körperteile funktioniert so sehr gut, aber ohne Winkelbegrenzung. Das heisst, ein Knie kann beispielsweise übel überstreckt werden.

Um die Bewegung einzuschränken habe ich einen Startwinkel definiert (xxx). Mit einer "If else" Abfrage wird geprüft, ob eine Rotation ausgeführt werden darf oder ob die Grenzwerte (min 20° und max 140°) bereits erreicht sind. Das hat auch wunderbar funktioniert, aber eben nur für einen bestimmten Körperteil. Da jeder Körperteil aber seinen eigenen Startwinkel, Minimum und Maximum hat, müsste ich diese auch einzeln definieren können.

Also sinngemäss:

Wenn Slider 1 betätigt wird

ist der Startwinkel=45, min=20, max=140

wenn Slider 2 betätigt wird

ist der Startwinkel=80, min=35, max=80

u.s.w.....

 

Wie kann ich das scriptmässig bewerkstelligen?

Oder wie kann ich die individuellen Winkelwerte dem Rotationsscript übergeben?

Besten Dank für eure Hilfe!

 

 

using System.Collections;
using UnityEngine;


public class RotateCube : MonoBehaviour {

    public float speed1 = 0f;
    public float speed2 = 0f;
    public float speed3 = 0f;

    public float xxx = 45f;//Startwinkel
    public float yyy = 0f;
    public float zzz = 0f;


    void Update () {

        xxx = xxx + speed2 * Time.deltaTime;

        if(xxx < 140 && xxx > 20)
            
        {
            transform.Rotate (speed2 * Time.deltaTime, speed3 * Time.deltaTime, speed1 * Time.deltaTime);
        }
            
        else
            
        {
            xxx = Mathf.Clamp (xxx, 20, 140);
        }

    }
                    

    public void AdjustSpeed1(float newSpeed1)
    {
        speed1 = newSpeed1;
    }
        
    public void AdjustSpeed2(float newSpeed2)
    {
        speed2 = newSpeed2;
    }

    public void AdjustSpeed3(float newSpeed3)
    {
        speed3 = newSpeed3;
    }

}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Moin!

Hab man deine Formatierung repariert. Code ist wesentlich einfacher lesbar, wenn du den <>-Knopf über deinem Beitrag benutzt ;)

Aber zum Problem:

Grundsätzlich läuft etwas nicht richtig, wenn du beim Hinzufügen eines weiteren Köperteils erstmal den Code erweitern musst. Als Faustregel gilt daher bei mir: Wenn mehr als zwei deiner Felder oder Methoden bis auf die Nummer am Ende gleich heißen, sollten die Alarmglocken läuten.

Wie du aber schon richtig vermutest...

vor 34 Minuten schrieb minuschki:

Oder wie kann ich die individuellen Winkelwerte dem Rotationsscript übergeben?

...kann man seinen Code so bauen, dass man für jedes Körperteil andere Werte verwendet, der Code aber auch beim nächsten Mal nicht geändert werden muss.

Es gibt hier, wie so oft, verschiedene Wege. Aber ich empfehle ganz klar, auf jedes Körperteil eine Instanz desselben Scripts zu packen. Ich beschränke mich mal nur auf eine Achse:

public float minX;
public float maxX;
// ...

(Das geht auch ein bisschen hübscher, wenn du das hier verwendest. Wenn du's probieren willst, bei Problemen gerne Fragen.)

Mit dieser Komponente auf dem Körperteil kannst du das Körperteil einfach selektieren und dann die Grenzwerte dafür einstellen. Ich würde diese Werte auch als Offset behandeln wollen. Heißt: Du trägst nicht die tatsächlichen Grenzwerte für die Rotation ein, sondern den maximalen Winkel von der Ausgangsausrichtung aus. Dann kannst du dieselben Werte bei denselben Gelenken eintragen und musst da nicht groß rumrechnen, wie die Knochen unterschiedlich gedreht sind. Ein hast du Problem dann noch, wenn gleichartige Gelenke sich auf unterschiedlichen Achsen drehen müssen. Ist nichts, was sich nicht lösen ließe, aber dann wird's wieder ein bisschen komplizierter.

Jedenfalls geht das mit den Offsets so:

private Quaternion initialRotation;

private void Awake()
{
  initialRotation = tranform.rotation;
}

Damit speicherst du die Ausgangsausrichtung des Knochens. Wenn du später eine Rotation reingibst, dann rechnest du diese Rotation auf diesen gespeicherten Wert obendrauf. Wenn du dann "20°" sagst, dann bedeutet das "20° von der Ausgangsausrichtung aus", und das macht vieles einfacher. Das Draufrechnen geht dann so:

public void SetRotationOffset(Vector3 offset)
{
  offset.x = Mathf.Clamp(offset.x, minX, maxX);
  // Noch zwei weitere Clamps...
  
  transform.rotation = initialRotation * Quaternion.Euler(offset);
}

Wenn du die drei Achsen separat ansprechen können musst, dann sind drei Methoden dafür auch okay - du brauchst dann nur einen Vector3, den du dir speicherst:

private Vector3 currentOffset;

public void SetRotationOffsetX(float x)
{
  currentOffset.x = x;
  SetRotationOffset(currentOffset);
}

public void SetRotationOffsetY(float y)
{
  currentOffset.y = y;
  SetRotationOffset(currentOffset);
}

public void SetRotationOffsetZ(float z)
{
  currentOffset.z = z;
  SetRotationOffset(currentOffset);
}

Wenn du das machst, sollte SetRotationOffset um diese Zeile am Ende erweitert werden:

currentOffset = offset;

Ist ein bisschen viel auf einmal, aber hoffentlich hilft's :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...