|
03.09.2015, 10:46
|
#1
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Проблема физики двуколесного транспорта
Привет
Я пробую делать мото гонки. Есть проблема с физикой, а конкретней с поведением мотоцикла на трасе.
Конструкция:
Персонаж, мотоцикл собраний с частей и 2 WheelCollider(а) на EmptyObject(ах):
Вертикальное положе (чтоб мотоцикл не падал) сделано с помощью Z rotation constraint в Ригид Боди.
Проблема:
При ускорении заднее колесо мотоцикла скользит по поверхности трасы, словно не происходит достаточного сцепления и сопровождается тряской и подпрыгиванием. Обороты колеса доходят до 40 000 RPM но мотоцикл движется со скоростью пешехода.
Вот так настроены WheelCollider(ы):
Что пробовал:
1. Параметры Forward и Sideways Friction.
Результат: скользит дальше. Если превысить значение Extremum или Asymptote Value больше 1 - скачеш как на коне, но скорости не прибавляется.
2. Вес мотоцикла.
Результат: скользит и скачет дальше. Если уменьшить до 1 - вообще нет сцепления, если повысить к 1000 - колесо скользит, тряска, не могу преодолеть 5% наклон дороги.
Вот настройки RigidBody:
Прошу помощи у вас!
Как сделать чтоб мотоцикл ездил нормально без тряски? Что я сделал не так?
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
03.09.2015, 10:56
|
#2
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Проблема физики двуколесного транспорта
А силы как прикладываются? motorTorque для заднего колеса? Drag 0 смущает.
|
(Offline)
|
|
03.09.2015, 11:02
|
#3
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Проблема физики двуколесного транспорта
Да.
Вот код мотоцикла:
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));
}
}
}
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
03.09.2015, 11:04
|
#4
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Проблема физики двуколесного транспорта
А еще другой вопрос - на колесах случаем нет меш коллайдеров?
|
(Offline)
|
|
03.09.2015, 11:06
|
#5
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Проблема физики двуколесного транспорта
нет. только WheelCollider(ы)
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
03.09.2015, 11:09
|
#6
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Проблема физики двуколесного транспорта
Ну и последний вопрос, у дороги есть физический материал? А вообще с физикой Unity 5 еще дела не имели, скоро предстоит.
|
(Offline)
|
|
03.09.2015, 11:14
|
#7
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Проблема физики двуколесного транспорта
Еще что приглянулось:
Это точно не влияет?
motorbikeBody.rotation = Quaternion.Euler(Vector3.Lerp(rotation, ideal, 0.1f));
Ну и ProcessInput выполняет физические функции в Update вместо FixedUpdate
|
(Offline)
|
|
03.09.2015, 11:17
|
#8
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Проблема физики двуколесного транспорта
Нет по ходу...
Только меш колайдер.
Может знаете какие то туториалы по теме мотогонок с физикой WheelCollider (ов)?
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
03.09.2015, 11:18
|
#9
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Проблема физики двуколесного транспорта
Еще вращать физические тела надо с помощью функции http://docs.unity3d.com/ScriptRefere...eRotation.html
UPD: оказывается теперь можно указывать вращение через свойства, не знал.
Туторов по мотоциклам не знаю к сожалению
|
(Offline)
|
|
11.09.2015, 12:06
|
#10
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Проблема физики двуколесного транспорта
Сообщение от pax
Ну и ProcessInput выполняет физические функции в Update вместо FixedUpdate
|
Ага, исправил. Спасибо.
Многочисленные попытки дали результат
Моими главными ошибками были настройки WheelCollider_ов и неправильный центр масс.
1. Если вы настраивали WheelCollider_ы и обнаружили что после ваш мотоцикл трясет, или же он скачет как лошадь - скиньте параметры WheelCollider_ов к стандартным.
2. Если у вас все же мотоцикл почему то переворачивается на переднее колесо при езде - поверните WheelCollider на угол равный углу рулевой вилки мотоцикла.
3. Не трогайте центр масс мотоцикла! если же вам хочется наклонять мотоцикл выводя из равновесия, то делайте это персонажем, но лучше всего обойтись rigidbody.MoveRotation() P.S. rigidbody мотоцикла.
Благодарю за помощь и внимание.
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
Эти 3 пользователя(ей) сказали Спасибо ІГРОГРАЙКО за это полезное сообщение:
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 01:15.
|