• Announcements

    • Lars

      Allgemeine Forenregeln   03/13/2017

      Forenregeln Nimm dir bitte einen Moment um die nachfolgenden Regeln durchzulesen. Wenn du diese Regeln akzeptierst und die Registration fortsetzen willst, klick einfach auf den "Mit der Registrierung fortfahren"-Button. Um diese Registration abzubrechen, klick bitte einfach auf den "Zurück" Button deines Browsers. Wir garantieren nicht für die Richtigkeit, Vollständigkeit und Brauchbarkeit der Nachrichten und sind auch nicht dafür verantwortlich. Die Beiträge drücken die Meinung des Autors des Beitrags aus, nicht zwangsläufig das, wofür die Forensoftware steht. Jeder Nutzer, der denkt, dass ein veröffentlichter Beitrag unzulässig bzw. störend ist, ist aufgefordert uns unverzüglich per E-Mail zu kontaktieren. Wir haben das Recht störende Beiträge zu löschen und bemühen uns, das in einem realistischem Zeitraum zu erledigen (sofern wir beschlossen haben, dass die Löschung notwendig ist). Du akzeptierst, durchgehend während der Nutzung dieses Services, dass du dieses Forum nicht dazu missbrauchen wirst, Inhalte zu veröffentlichen, welche bewusst falsch und/oder verleumderisch, ungenau, beleidigend, vulgär, hasserfüllt, belästigend, obszön, sexuell belästigend, bedrohlich, die Privatsphäre einer Person verletzend oder in irgend einer Art und Weise das Gesetz verletzen. Des Weiteren akzeptierst du, dass du keine urheberrechtlich geschützte Inhalte ohne Erlaubnis des Besitzers in diesem Forum veröffentlichst. Mit dem Klick auf den "Mit der Registrierung fortfahren"-Button, akzeptierst du zudem unsere Datenschutzerklärung und stimmst der Speicherung deiner IP-Adresse und personenbezogenen Daten zu, die dafür benötigt werden, um dich im Falle einer rechtswidrigen Tat zurückverfolgen zu können bzw. permanent oder temporär aus dem Forum ausschließen zu können. Es besteht keine Pflicht zur Abgabe der Einwilligung, dies erfolgt alles auf freiwilliger Basis.   Zusatzinformationen Der Forenbetreiber hat das Recht, Nutzer ohne Angabe von Gründen permanent aus dem Forum auszuschließen. Des Weiteren hat er das Recht, Beiträge, Dateianhänge, Umfrage, Blogeinträge, Galleriebilder oder Signaturen ohne Angabe von Gründen zu entfernen. Mit der Registrierung verzichtest du auf alle Rechte an den von dir erstellten Inhalten, bzw. treten diese an das Unity-Insider.de und Unity-Community.de ab. Dies bedeutet im Klartext, dass das Unity-Insider.de und Unity-Community.de frei über deine Texte verfügen kann, sofern diese nicht wiederum die Rechte anderer verletzen. Es besteht weiterhin kein Anspruch von registrierten Nutzern bzw. ehemaligen registrierten Nutzern darauf, dass erstellte Inhalte und/oder die Mitgliedschaft (User) wieder gelöscht werden (Erhaltung der Konsistenz dieses Forums).   Einwilligungserklärung Wenn du mit der Speicherung deiner personenbezogenen Daten sowie den vorstehenden Regeln und Bestimmungen einverstanden bist, kannst du mit einem Klick auf den Mit der Registrierung fortfahren-Button unten fortfahren. Ansonsten drücke bitte Zurück. Stand: 07.03.2011
J3nsis

Motorrad Physik/Movement (C#)

10 posts in this topic

Hallo Ich bin gerad dabei ein Motorrad Movement zu erstellen und der Script dafür sieht bis jetzt so aus:

 




    void FixedUpdate()
    {
        movement();
    
    }

    void movement()
    {
        if (Input.GetKey("w"))
        {

            if (powerSpeed <= maxSpeed)
            {
                powerSpeed += beschleunigung;
            }

            
        }
        else
        {

            
            if (powerSpeed >= normalSpeed)
            {
                powerSpeed -= auslauf;
            }
            
                

            
        }

        if (Input.GetKey("s"))
        {
            if (powerSpeed >= miniSpeed)
            {
                powerSpeed -= bremse;
            }

        }
        else if (powerSpeed <= normalSpeed)
        {
            powerSpeed += beschleunigungnachminiSpeed;
           
        }

        currentSpeed = Mathf.Round(powerSpeed); 
        slider.value = Mathf.Round(powerSpeed);
        transform.Translate(Vector3.forward * powerSpeed * Time.deltaTime);

       

        if (Input.GetKey("a"))
        {
            transform.Rotate(Vector3.down * turnSpeed * Time.deltaTime);
        }

        if (Input.GetKey("d"))
        {
            transform.Rotate(Vector3.down * -turnSpeed * Time.deltaTime);
        }


        


Ich habe auch schon probiert das sich das Bike wie ein echtes in richtung Boden in der Kurve zu rotieren aber dann lag es die ganze Zeit nur auf der Seite.

Das Problem ist momentan das wenn man über eine Rampe fährt man sehr lange sehr weit nach oben bewegt wird und Ich weis nicht wie man das Fixen soll (liegt denke Ich mal am Auslauf bzw. das man in der Luft immernoch nach vorn gedrückt wird aber nach oben wegen Rampen Rotation). Außerdem wenn man schräg von einer Rampe springt wird man schräg Landen bzw. das Bike liegt dann auf dem Boden und man kann nichts mehr machen. 

Meine Rigidbody Settings:Unbenannte.PNG.198316b6104a622b0fbe46a6be0b4a4a.PNG

 

Gibt es irgendeine Methode eine bessere Bike Physik zu bekommen oder was muss ich ändern damit es so echt wie möglich ist? (Das Bike ist einfach nur ein Motorrad Modell was sich bewegt ohne Räder oder so)

 

MfG J3nsis

 

Share this post


Link to post
Share on other sites

Ich würde dafür 2 Wheelcollider verwenden. Es gibt dafür bereits etliche Skripte und Tutorials, wie man damit eine Fahrzeugphysik (mit 4 Rädern) implementiert:
https://docs.unity3d.com/Manual/WheelColliderTutorial.html

Ich würde hier "einfach" mal 2 Räder herausnehmen und diese Räder mittig unter dem Fahrzeugcollider zentrieren. Alles andere wäre dann ein Feintuning dieser 3 Komponenten (2 Wheel Collider und einen Box Collider für das Fahrzeuggestell).

Hier ist noch ein Projekt, welches vermutlich bereits ein Bike realisiert hat:
https://github.com/RandomationGames/Randomation-Vehicle-Physics

2 people like this

Share this post


Link to post
Share on other sites
Zitat

Ich würde dafür 2 Wheelcollider verwenden. Es gibt dafür bereits etliche Skripte und Tutorials, wie man damit eine Fahrzeugphysik (mit 4 Rädern) implementiert:
https://docs.unity3d.com/Manual/WheelColliderTutorial.html

Ich würde hier "einfach" mal 2 Räder herausnehmen und diese Räder mittig unter dem Fahrzeugcollider zentrieren. Alles andere wäre dann ein Feintuning dieser 3 Komponenten (2 Wheel Collider und einen Box Collid

Danke aber leider kann man bei diesem Script nicht nur zwei Räder benutzen. Wenn man versucht die 4 Räder ziemlich dicht an einander zu machen geht es auch nicht weil das Bike dann immer in Kurven umkippt. Und Ich verstehe diesen Code nicht genug um ihn für 2 Räder abzuändern. 

 

Share this post


Link to post
Share on other sites

2 WheelCollider und Z-Axis Rotation Constraint beim Rigidbody sollte gehen. Das Neigen würde ich dann über den Child des Rigidbody animieren, nicht über den RB selbst.

1 person likes this

Share this post


Link to post
Share on other sites

Ich habe mich mal dran gesetzt und einen einfachen Bikecontroller aus dem Unity Tutorial gebastelt. Wichtig war hierbei einen Masseschwerpunkt hinzuzufügen, sonst kippt das Bike gleich beim 1. Lenkvorgang um. Nach dem Lenken neigt sich das Bike nun in eine Richtung und pendelt nach weiterem Geradeausfahren noch einige Zeit hin und her. Ich denke hier müsste man den Masseschwerpunkt nach einer Lenkung leicht in die entgegengesetzte Richtung verschieben, damit das Bike zu pendeln aufhört und stabiler wird. Das habe ich allerdings erst einmal nicht gemacht, da ich nicht weiß, was für ein Verhalten du möchtest. Vielleicht gibt es auch noch andere Möglichkeiten das Pendeln in den Griff zu bekommen, mit dem Luftwiderstand des Rigidbody habe ich es nicht geschafft. Die andere Variante wäre - diese Idee kommt von Sascha und hat super funktioniert :) - die Rotation des Rigidbodies in Z zu beschränken, dann neigt sich das Fahrzeug durch die Physikengine überhaupt nicht, dies funktioniert mit dem unten stehenden Code ebenfalls:
 

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

/// <summary>
/// Simple Bike Controller by zer0f0rce (skype) for the Unity Insider Forum.
/// "Center of Mass" should be a child gameObject with a centered position below the vehicle on the ground.
/// To completely prevent the swinging of the vehicle add a constraint "freeze rotation Z" to the rigidbody.
/// Missing Feature: Move the center of mass to the opposite direction of the steering process.
/// Relating to:
/// https://docs.unity3d.com/Manual/WheelColliderTutorial.html
/// </summary>
[System.Serializable]
    public class AxleInfoSingle
    {
        public WheelCollider wheel;
        public bool motor;
        public bool steering;
    }

    public class SimpleBikeController : MonoBehaviour
    {
        public List<AxleInfoSingle> axleInfos;
        public float maxMotorTorque;
        public float maxSteeringAngle;
        public Transform centerOfMass;
        public float steerDamping = 5.0f;
        private Rigidbody bikeRigidbody;

    void Start()
        {
          bikeRigidbody = GetComponent<Rigidbody>();
          bikeRigidbody.centerOfMass = centerOfMass.localPosition;
        }
    
        // finds the corresponding visual wheel
        // correctly applies the transform
        public void ApplyLocalPositionToVisuals(WheelCollider collider)
        {
            if (collider.transform.childCount == 0)
            {
                return;
            }

            Transform visualWheel = collider.transform.GetChild(0);

            Vector3 position;
            Quaternion rotation;
            collider.GetWorldPose(out position, out rotation);

            visualWheel.transform.position = position;
            visualWheel.transform.rotation = rotation;
        }

        public void FixedUpdate()
        {
             // dampen the steering of the rigidbody
             float step = steerDamping * Time.deltaTime * bikeRigidbody.velocity.magnitude;
             Quaternion targetRotation = Quaternion.Euler(bikeRigidbody.rotation.eulerAngles.x, bikeRigidbody.rotation.eulerAngles.y, 0);
             Quaternion currentRotation = Quaternion.RotateTowards(bikeRigidbody.rotation, targetRotation, step);
             bikeRigidbody.MoveRotation(currentRotation);

            float motor = maxMotorTorque * Input.GetAxis("Vertical");
            float steering = maxSteeringAngle * Input.GetAxis("Horizontal");

            foreach (AxleInfoSingle axleInfo in axleInfos)
            {
                if (axleInfo.steering)
                {
                    axleInfo.wheel.steerAngle = steering;
                }
                if (axleInfo.motor)
                {
                    axleInfo.wheel.motorTorque = motor;
                }
                ApplyLocalPositionToVisuals(axleInfo.wheel);
            }
        }
    }

Bike.png

Die Werte für das CenterofMass-Transform sind (es liegt zentriert am tiefsten Punkt unter dem Fahrzeug):
x=0 y=-0.663 z=0

Für die visuelle Darstellung der Reifen erzeugst du ein leeres Child-Gameobjekt direkt unter dem jeweiligen Wheelcollider mit folgenden Werten:
x0= y=-0.15 z=0  (Rotation 0/0/0 Scale 1/1/1)
Unter diesem wiederum ein Child-Zylinder-Gameobjekt:
x0= y=0 z=0  Rotation: 0/0/-90 Scale: 1/0.15/1

Wenn du einfach das ganze Projekt haben möchtest, schreib mich an.

Share this post


Link to post
Share on other sites
vor 54 Minuten schrieb Zer0Cool:

Ich habe mich mal dran gesetzt und einen einfachen Bikecontroller daraus gebastelt. Wichtig war hierbei einen Massenschwerpunkt hinzuzufügen, sonst kippt das Bike gleich beim 1. Lenkvorgang um. Nach dem Lenken neigt sich das Bike nun in eine Richtung und pendelt nach weiterem Geradeausfahren noch einige Zeit hin und her. Ich denke hier müsste man den Masseschwerpunkt nach einer Lenkung leicht in die entgegengesetzte Richtung verschieben, damit das Bike zu pendeln aufhört. Das habe ich allerdings erst einmal nicht gemacht, da ich nicht weiß, was für eine Verhalten du möchtest. Vielleicht gibt es auch noch andere Möglichkeiten das Pendeln in den Griff zu bekommen, mit dem Luftwiderstand des Rigidbody habe ich es nicht geschafft:
 


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

/// <summary>
/// Simple Bike Controller by zer0f0rce (skype) for the Unity Insider Forum.
/// Missing Feature: Move the center of mass to the opposite direction of the steering process.
/// Relating to:
/// https://docs.unity3d.com/Manual/WheelColliderTutorial.html
/// </summary>
[System.Serializable]
    public class AxleInfoSingle
    {
        public WheelCollider wheel;
        public bool motor;
        public bool steering;
    }

    public class SimpleBikeController : MonoBehaviour
    {
        public List<AxleInfoSingle> axleInfos;
        public float maxMotorTorque;
        public float maxSteeringAngle;
        public Transform centerOfMass;

        void Start()
        {
            Rigidbody rb = GetComponent<Rigidbody>();
            rb.centerOfMass = centerOfMass.localPosition;
        }
    
        // finds the corresponding visual wheel
        // correctly applies the transform
        public void ApplyLocalPositionToVisuals(WheelCollider collider)
        {
            if (collider.transform.childCount == 0)
            {
                return;
            }

            Transform visualWheel = collider.transform.GetChild(0);

            Vector3 position;
            Quaternion rotation;
            collider.GetWorldPose(out position, out rotation);

            visualWheel.transform.position = position;
            visualWheel.transform.rotation = rotation;
        }

        public void FixedUpdate()
        {
            float motor = maxMotorTorque * Input.GetAxis("Vertical");
            float steering = maxSteeringAngle * Input.GetAxis("Horizontal");

            foreach (AxleInfoSingle axleInfo in axleInfos)
            {
                if (axleInfo.steering)
                {
                    axleInfo.wheel.steerAngle = steering;
                }
                if (axleInfo.motor)
                {
                    axleInfo.wheel.motorTorque = motor;
                }
                ApplyLocalPositionToVisuals(axleInfo.wheel);
            }
        }
    }

 

Danke schonmal, allerdings kippt bei mir das Bike direkt beim ersten Lenkvorgang um (Ich habe in die Mitte ein Würfel gesetzt und es dem Centre of Mass zugeordnet, war das richtig??). Außerdem, Ich weiß nicht ob es an mir liegt aber die Visuellen Räder drehen sich bei mir nicht beim lenken obwohl das doch eigentlich hier passieren sollte oder?:

 

Transform visualWheel = collider.transform.GetChild(0);

        Vector3 position;
        Quaternion rotation;
        collider.GetWorldPose(out position, out rotation);

        visualWheel.transform.position = position;
        visualWheel.transform.rotation = rotation;

Aber trotzdem schonmal danke!

 

MfG J3nsis

 

Share this post


Link to post
Share on other sites

Das Center of Mass muss ganz unten auf den Boden verschoben werden (geht auch unter den Boden), ist es zu hoch, dann kippt das Bike ganz leicht um.

Ja die Räder schlagen ein und drehen sich, aber ich vermute bei dir einen Fehler im Aufbau der GameObjects. Wie ich oben schrieb, muss das eigentliche Mesh des Rades noch einmal in ein leeres Gameobjekt (der als Contrainer dient) gepackt werden. 
Für das Mesh des Rades einen Cylinder nehmen (wie oben beschrieben einstellen) und hier den Collider entfernen (hatte ich noch vergessen)!
Dieses Mesh ist dann wiederum ein Child den Gameobjektes, also der Aufbau ist wie folgt:
Vorderes Rad:
- front Wheel (WheelCollider): Position: 0 0 1 Rotation: 0 0 0 Scale: 1 1 1
---- GameObject (Container): Position: 0 -0.15 0 Rotation: 0 0 0 Scale: 1 1 1
-------- Cylinder (Mesh): Position: 0 0 0 Rotation: 0 0 -90 Scale: 1 0.15 1

Hinteres Rad:
- rear Wheel (WheelCollider): Position: 0 0 -1 Rotation: 0 0 0 Scale: 1 1 1
---- GameObject (Container): Position: 0 -0.15 0 Rotation: 0 0 0 Scale: 1 1 1
-------- Cylinder (Mesh): Position: 0 0 0 Rotation: 0 0 -90 Scale: 1 0.15 1

Ich bin gerade noch dabei in das Skript eine Dämpfung für die Neigung des Bikes einzubauen...

1 person likes this

Share this post


Link to post
Share on other sites

Ich habe das obere Skript noch einmal geändert und eine Dämpfung der Pendelbewegung eingebaut (das Pendeln in die Gegenrichtung habe ich dabei komplett entfernt). Das Bike richtet sich nun je nach Dämpfung und Geschwindigkeit von allein wieder auf.

1 person likes this

Share this post


Link to post
Share on other sites

Hier nochmal der aktuelle Code, falls den Thread noch jemand verfolgt:

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

/// <summary>
/// Simple Bike Controller by zer0f0rce (skype) for the Unity Insider Forum.
/// "Center of Mass" should be a child gameObject with a centered position below the vehicle on the ground.
/// To completely prevent the swinging of the vehicle add a constraint "freeze rotation Z" to the rigidbody.
/// Missing Feature: Move the center of mass to the opposite direction of the steering process.
/// Relating to:
/// https://docs.unity3d.com/Manual/WheelColliderTutorial.html
/// </summary>
[System.Serializable]
public class AxleInfoSingle
{
    public WheelCollider wheel;
    public bool motor;
    public bool steering;
}

public class SimpleBikeController : MonoBehaviour
{
    public List<AxleInfoSingle> axleInfos;
    public float maxSpeed = 20.0f;
    public float maxMotorTorque;
    public float maxSteeringAngle;
    public Transform centerOfMass;
    public float steerDamping = 10.0f;
    public float timeToZAlignment = 0.75f;
    private Rigidbody bikeRigidbody;
    private AudioSource bikeAudio;
    private string consoleLog = "";
    private float lastSteer = 0;
    private float lastSteerDelta = 0;


    void Start()
    {
        bikeRigidbody = GetComponent<Rigidbody>();
        bikeRigidbody.centerOfMass = centerOfMass.localPosition;
        bikeAudio = GetComponent<AudioSource>();
    }

    // finds the corresponding visual wheel
    // correctly applies the transform
    public void ApplyLocalPositionToVisuals(WheelCollider collider)
    {
        if (collider.transform.childCount == 0)
        {
            return;
        }

        Transform visualWheel = collider.transform.GetChild(0);

        Vector3 position;
        Quaternion rotation;
        collider.GetWorldPose(out position, out rotation);

        visualWheel.transform.position = position;
        visualWheel.transform.rotation = rotation;
    }

    public void FixedUpdate()
    {
        lastSteerDelta = Time.time - lastSteer;
        if ((Mathf.Abs(Input.GetAxis("Horizontal")) > 0.00001f))
        {
            lastSteer = Time.time;
        }

        Vector3 localAngularVelocity = bikeRigidbody.transform.InverseTransformDirection(bikeRigidbody.angularVelocity);
        Vector3 localRotation = bikeRigidbody.transform.localRotation.eulerAngles;
        if ((lastSteerDelta > timeToZAlignment) ||
            (localRotation.z > 0 && localRotation.z < 60) && (Input.GetAxis("Horizontal") > 0) ||
            (localRotation.z > 300 && localRotation.z < 360) && (Input.GetAxis("Horizontal") < 0))
        {
            consoleLog = "Aufrichten aktiv";
            float step = steerDamping * Time.deltaTime * bikeRigidbody.velocity.magnitude * 0.25f; //geschwindigkeit von aufrichten
            Quaternion targetRotation = Quaternion.Euler(bikeRigidbody.rotation.eulerAngles.x, bikeRigidbody.rotation.eulerAngles.y, 0);
            Quaternion currentRotation = Quaternion.RotateTowards(bikeRigidbody.rotation, targetRotation, step);
            bikeRigidbody.MoveRotation(currentRotation);

        }
        else
        {
            consoleLog = "";
        }

        // Some Infos about values:
        // Rigidbody localAngularVelocity: if z - then the bike is rolling to the right ...  if z + then to the left
        // Input.GetAxis("Horizontal"): if player directs to the left then value is -  ... if to the right then + 
        // Transform localRotation: if z is between 0-60 then the bike is on the left side ... if between 300-360 then on the right

        if (bikeAudio != null)
        {
            bikeAudio.volume = bikeRigidbody.velocity.magnitude * 0.1f;
            bikeAudio.pitch = bikeRigidbody.velocity.magnitude * 0.1f;
        }

        float motor;
        if (bikeRigidbody.velocity.magnitude < maxSpeed)
        {
            motor = maxMotorTorque * Input.GetAxis("Vertical");
        }
        else
        {
            motor = 0;
        }

        float steering = maxSteeringAngle * Input.GetAxis("Horizontal");

        foreach (AxleInfoSingle axleInfo in axleInfos)
        {
            if (axleInfo.steering)
            {
                axleInfo.wheel.steerAngle = steering;
            }
            if (axleInfo.motor)
            {
                axleInfo.wheel.motorTorque = motor;
            }
            ApplyLocalPositionToVisuals(axleInfo.wheel);
        }
    }

    void OnGUI()
    {
        GUI.TextArea(new Rect(10, Screen.height - 70, Screen.width - 10, Screen.height - 10), consoleLog);
    }
}


So sieht das Ganze dann aus:
Bikescene.png

Bikescene2.png

1 person likes this

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now