forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Физика (http://forum.boolean.name/forumdisplay.php?f=168)
-   -   Проблема физики двуколесного транспорта (http://forum.boolean.name/showthread.php?t=19978)

ІГРОГРАЙКО 03.09.2015 10:46

Проблема физики двуколесного транспорта
 
Вложений: 4
Привет
Я пробую делать мото гонки. Есть проблема с физикой, а конкретней с поведением мотоцикла на трасе.

Конструкция:
Вложение 21873
Персонаж, мотоцикл собраний с частей и 2 WheelCollider(а) на EmptyObject(ах):
Вложение 21874
Вертикальное положе (чтоб мотоцикл не падал) сделано с помощью Z rotation constraint в Ригид Боди.

Проблема:
При ускорении заднее колесо мотоцикла скользит по поверхности трасы, словно не происходит достаточного сцепления и сопровождается тряской и подпрыгиванием. Обороты колеса доходят до 40 000 RPM но мотоцикл движется со скоростью пешехода.

Вот так настроены WheelCollider(ы):
Вложение 21875

Что пробовал:
1. Параметры Forward и Sideways Friction.
Результат: скользит дальше. Если превысить значение Extremum или Asymptote Value больше 1 - скачеш как на коне, но скорости не прибавляется.
2. Вес мотоцикла.
Результат: скользит и скачет дальше. Если уменьшить до 1 - вообще нет сцепления, если повысить к 1000 - колесо скользит, тряска, не могу преодолеть 5% наклон дороги.

Вот настройки RigidBody:
Вложение 21876

Прошу помощи у вас!
Как сделать чтоб мотоцикл ездил нормально без тряски? Что я сделал не так?

pax 03.09.2015 10:56

Ответ: Проблема физики двуколесного транспорта
 
А силы как прикладываются? motorTorque для заднего колеса? Drag 0 смущает.

ІГРОГРАЙКО 03.09.2015 11:02

Ответ: Проблема физики двуколесного транспорта
 
Да.

Вот код мотоцикла:
Код:

using UnityEngine;
using System.Collections;

public class MotorbikeController : MonoBehaviour
{
        public enum State        {Idle, Braking, Accelerating};

        public State state = State.Idle;

        public Transform steeringWheel;
        public Transform frontWheelTransformer;
        public Transform rearWheelTransformer;

        public WheelCollider rearWheelCollider;
        public WheelCollider frontWheelCollider;

        public float maxSteerAngle = 30f;
        public float power = 50f;
        public float maxRpm = 40000;
        public float breakingCof = 2f;

        public float Speed {get; private set;}
        public float Steer {get; set;}

        private Vector3 prevPos;

        public void Accelerate(float effort)
        {
                state = State.Accelerating;
                rearWheelCollider.brakeTorque = 0;
                frontWheelCollider.brakeTorque = 0;
                if (rearWheelCollider.rpm < maxRpm) {
                        rearWheelCollider.motorTorque += effort * power;
                }
        }
       
        public void Brake(float frontEffort, float rearEffort)
        {
                state = State.Braking;
                rearWheelCollider.motorTorque = 0;
                rearWheelCollider.brakeTorque = breakingCof * rearEffort;
                frontWheelCollider.brakeTorque = breakingCof * frontEffort;
        }
       
        public void Turn(float balance = 0f)
        {
                //steeringWheel.localRotation = Quaternion.Euler(balance,0,0);
                frontWheelCollider.steerAngle = balance*maxSteerAngle;
        }

        void AcceleratorCullDown ()
        {
                if (rearWheelCollider.motorTorque < 0.001f) {
                        rearWheelCollider.motorTorque = 0;
                        return;
                }
                rearWheelCollider.motorTorque *= 0.99f;
        }

        void BrakesCullDown ()
        {
                if (rearWheelCollider.brakeTorque < 0.001f) {
                        rearWheelCollider.brakeTorque = 0;
                        return;
                }
                rearWheelCollider.brakeTorque *= 0.5f;
        }

        void FixedUpdate()
        {
                if (state == State.Idle) {
                        AcceleratorCullDown();
                        BrakesCullDown();
                }

                state = State.Idle;
                Speed = (transform.position - prevPos).magnitude/Time.fixedDeltaTime;
                prevPos = transform.position;
        }

        void Update()
        {
                Quaternion rotQuat;
                Vector3 pos;

                rearWheelCollider.GetWorldPose(out pos, out rotQuat);
                rearWheelTransformer.position = pos;
                rearWheelTransformer.rotation = rotQuat;

                frontWheelCollider.GetWorldPose(out pos, out rotQuat);
                frontWheelTransformer.position = pos;
                frontWheelTransformer.rotation = rotQuat;
        }
}

А это код персонажа:
Код:

using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour {

        public enum State {Stop,Riding,Crawling};
       
        public MotorbikeController motorbike;
        public PlayerInput input;

        public float brakesBalance = 0.6f;

        private bool ragDollMode = true;
        private Animator animator;
        public State state = State.Stop;
        private Rigidbody motorbikeBody;
        private float tiltAngle;

        Ray ray;

        float turn;

        void SetRagDollMode (bool enable)
        {
                if (ragDollMode == enable) {
                        return;
                }
                Physics.IgnoreLayerCollision(8,9,!enable);
                animator.enabled = !enable;
                var i = 0;
                foreach (var rBody in GetComponentsInChildren<Rigidbody> ())
                {
                        i++;
                        if (i == 1)
                        {
                                rBody.isKinematic = enable;
                                continue;
                        }
                        rBody.isKinematic = !enable;
                        rBody.detectCollisions = enable;
                }
                ragDollMode = enable;
        }

        // Use this for initialization
        void Start ()
        {
                animator = GetComponentInChildren<Animator>();
                motorbikeBody = motorbike.GetComponent<Rigidbody>();
                SetRagDollMode (false);
                ray = new Ray (transform.position, Vector3.down);

                motorbikeBody.centerOfMass = Vector3.up;
        }

        void Update()
        {
                ProcessInput();


        }

        void FixedUpdate()
        {
                var rotation = HelperFunctions.GetNonABSeulerValue(motorbikeBody.rotation.eulerAngles);

                RaycastHit hitInfo;
                Physics.Raycast(ray, out hitInfo, 3f);
               
                Debug.DrawRay(motorbike.transform.position, motorbike.transform.up);
                Debug.DrawRay(motorbike.transform.position, hitInfo.normal, Color.blue);
               
                var preTiltAngel = Vector3.Angle(motorbike.transform.up, hitInfo.normal);
                if (preTiltAngel != 90) {
                        tiltAngle = preTiltAngel;
                }

                if (state != State.Crawling)
                {
                        if (motorbike.Speed < 1.1f)
                        {
                                state = State.Stop;
                        }
                        else
                        {
                                state = State.Riding;
                        }
                }

                if (tiltAngle < ((int)motorbike.Speed | 10)) {
                        motorbikeBody.transform.Rotate(0,0,-input.Tilt);
                }

                if (state == State.Stop)
                {
                        if (tiltAngle > 5)
                        {
                                motorbikeBody.constraints = RigidbodyConstraints.FreezeRotationZ;
                                if (tiltAngle > 10) {
                                        var ideal = rotation;
                                        ideal.z = 0;
                                        motorbikeBody.rotation = Quaternion.Euler(Vector3.Lerp(rotation, ideal, 0.1f));
                                }
                        }
                        else
                        {
                                motorbikeBody.constraints = RigidbodyConstraints.None;
                        }
                }
                else if (state == State.Riding)
                {
                        motorbikeBody.constraints = RigidbodyConstraints.FreezeRotationZ;
                        if (input.Tilt == 0 || tiltAngle > ((int)motorbike.Speed | 10)) {
                                var ideal = rotation;
                                ideal.z = 0;
                                motorbikeBody.rotation = Quaternion.Euler(Vector3.Lerp(rotation, ideal, 0.1f));
                        }


                }
                else
                {
                        motorbikeBody.constraints = RigidbodyConstraints.None;
                }

                animator.SetFloat("speed", motorbike.Speed);
                animator.SetFloat("direction", rotation.z);


        }

        void OnTriggerEnter(Collider other) {
                if (other.gameObject.layer == LayerMask.NameToLayer("Default"))
                {
                        var holder = GetComponent<FixedJoint>();
                        Destroy(holder);
                        state = State.Crawling;
                        SetRagDollMode(true);
                }
        }
       
        void ProcessInput ()
        {
                turn = Mathf.Lerp(turn,input.Tilt,0.1f);
                motorbike.Turn(turn);
               
                if (input.Accelerating > 0) {
                        motorbike.Accelerate(input.Accelerating);
                }

                if (input.Braking > 0) {
                        motorbike.Brake(input.Braking * brakesBalance, input.Braking * (1f-brakesBalance));
                }
        }
}


pax 03.09.2015 11:04

Ответ: Проблема физики двуколесного транспорта
 
А еще другой вопрос - на колесах случаем нет меш коллайдеров?

ІГРОГРАЙКО 03.09.2015 11:06

Ответ: Проблема физики двуколесного транспорта
 
нет. только WheelCollider(ы)

pax 03.09.2015 11:09

Ответ: Проблема физики двуколесного транспорта
 
Ну и последний вопрос, у дороги есть физический материал? А вообще с физикой Unity 5 еще дела не имели, скоро предстоит.

pax 03.09.2015 11:14

Ответ: Проблема физики двуколесного транспорта
 
Еще что приглянулось:
Это точно не влияет?
PHP код:

motorbikeBody.rotation Quaternion.Euler(Vector3.Lerp(rotationideal0.1f)); 

Ну и ProcessInput выполняет физические функции в Update вместо FixedUpdate

ІГРОГРАЙКО 03.09.2015 11:17

Ответ: Проблема физики двуколесного транспорта
 
Вложений: 1
Вложение 21877
Нет по ходу...
Только меш колайдер.

Может знаете какие то туториалы по теме мотогонок с физикой WheelCollider (ов)?

pax 03.09.2015 11:18

Ответ: Проблема физики двуколесного транспорта
 
Еще вращать физические тела надо с помощью функции http://docs.unity3d.com/ScriptRefere...eRotation.html

UPD: оказывается теперь можно указывать вращение через свойства, не знал.

Туторов по мотоциклам не знаю к сожалению

ІГРОГРАЙКО 11.09.2015 12:06

Ответ: Проблема физики двуколесного транспорта
 
Вложений: 1
Цитата:

Сообщение от pax (Сообщение 299264)
Ну и ProcessInput выполняет физические функции в Update вместо FixedUpdate

Ага, исправил. Спасибо.

Многочисленные попытки дали результат :)
Моими главными ошибками были настройки WheelCollider_ов и неправильный центр масс.

1. Если вы настраивали WheelCollider_ы и обнаружили что после ваш мотоцикл трясет, или же он скачет как лошадь - скиньте параметры WheelCollider_ов к стандартным.
2. Если у вас все же мотоцикл почему то переворачивается на переднее колесо при езде - поверните WheelCollider на угол равный углу рулевой вилки мотоцикла.
Вложение 21890
3. Не трогайте центр масс мотоцикла! если же вам хочется наклонять мотоцикл выводя из равновесия, то делайте это персонажем, но лучше всего обойтись rigidbody.MoveRotation() P.S. rigidbody мотоцикла.

Благодарю за помощь и внимание.


Часовой пояс GMT +4, время: 16:15.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot