2016-10-31 3 views
0

Я использую это:Единства 5: Как замедлить Rigidbody естественно вместо внезапной остановки

void Update(){ 
    if(leftJoystick){ 
     rb.AddRelativeForce(0, 0, 400f, ForceMode.Impulse); 
    } 
} 

переместить свой персонаж вперед в воздухе (с использованием ранца). Когда я отпускаю джойстик, мой персонаж немедленно останавливается. Я хочу, чтобы персонаж продолжал двигаться вперед после отпускания джойстика и со временем замедлялся и постепенно останавливался. Это выглядит глупо, что мой персонаж останавливается, как будто он ударился о стену. Какую силу/скорость/преобразование я должен использовать, чтобы физика замедляла мой характер после того, как я отпустил джойстик?

Мои Rigidbody настройки:

  • Масса: 100
  • Drag: 0
  • Угловая сопротивление: 0,05
  • использует силу тяжести
  • Не кинематической
  • Interpolate: интерполировать
  • Столкновение обнаружение: Дискретный
  • Замораживания положение: нет
  • Замораживания вращения: все

Характер также имеет капсульный коллайдер, который не вызывает и не имеет физический материала.

EDIT: вот полный код, так что вы можете увидеть, если есть какие-либо конфликты в моем коде

using UnityEngine; 
using System.Collections; 
using UnityStandardAssets.CrossPlatformInput; 

public class JetpackController : MonoBehaviour{ 

    Rigidbody rb; 

    // controller axes 
    [SerializeField] 
    public string speedAxis = "Vertical"; 
    public string rotateAxis = "HorizontalRotate"; 

    [SerializeField] 
    public float forwardSpeed; 
    public float upSpeed; 
    public float rotateSpeed; 
    public float rotationIgnoreZone; 
    public float MAX_HEIGHT; 

    float speedInput; 
    float rotateInput; 
    public bool leftJoystick; 
    public bool rightJoystick; 

    ParticleSystem jetpackFire1; 

    Vector3 originalGravity; 

    // access Joystick script in Standard assets to detect when right joystick is held down 
    Joystick joystick_left; 
    Joystick joystick_right; 

    void Start() { 
     if (GetComponent<Rigidbody>()) { 
      rb = GetComponent<Rigidbody>(); 
     } else { 
      Debug.LogError ("Player needs to have a rigidbody."); 
     } 

     // get Joysticks 
     if (GameObject.Find ("MobileJoystick_left").GetComponent<Joystick>()) { 
      joystick_left = GameObject.Find ("MobileJoystick_left").GetComponent<Joystick>(); 
     } else { 
      Debug.LogError ("Either gameobject with name 'MobileJoystick_right' does not exist in the scene or it does not have script called Joystick.cs attached to it."); 
     } 
     if (GameObject.Find ("MobileJoystick_right").GetComponent<Joystick>()) { 
      joystick_right = GameObject.Find ("MobileJoystick_right").GetComponent<Joystick>(); 
     } else { 
      Debug.LogError ("Either gameobject with name 'MobileJoystick_right' does not exist in the scene or it does not have script called Joystick.cs attached to it."); 
     } 

     jetpackFire1 = GameObject.Find("JetpackFire1").GetComponent<ParticleSystem>(); 
     jetpackFire1.playbackSpeed = 5.0f; 

     originalGravity = Physics.gravity; 
    } 

    void FixedUpdate() { 

     GetInput(); 

     // move forward and backward according to left joysticks input 
     if(leftJoystick){ 
      // left joystick held down 
      rb.AddRelativeForce(0, 0, forwardSpeed*speedInput, ForceMode.Impulse); 
     } 

     // if right joystick is used 
     if (rightJoystick) { 
      jetpackFire1.Play(); 

     if (transform.position.y < MAX_HEIGHT) { 
      // allow going up 
      //rb.AddRelativeForce (0, upSpeed, 0, ForceMode.Impulse); 
      rb.AddForce(transform.forward * forwardSpeed); 
     } else if (transform.position.y >= MAX_HEIGHT) { 
      // prevent player to go any further up and also falling 
      Physics.gravity = Vector3.zero; // no gravity to prevent player from falling 
      rb.velocity = Vector3.zero; 
     } 
      // rotate 
      // always keep rotating (player can go past look at joystick dir) 
      if (rotateInput >= rotationIgnoreZone || rotateInput <= -rotationIgnoreZone) { 
       transform.Rotate(Vector3.up * rotateInput, Time.deltaTime * rotateSpeed); 
      } 
    } else { 
      jetpackFire1.Stop(); 
      // if right joystick is released 
      Physics.gravity = originalGravity; // normal gravity -> player can fall 
     } 

    } 

public void GetInput(){ 
    speedInput = CrossPlatformInputManager.GetAxis (speedAxis); 
    rotateInput = CrossPlatformInputManager.GetAxis (rotateAxis); 
    // access Joystick.cs script to grab wether right joystick is pressed or not 
    leftJoystick = joystick_left.leftJoystickPressed; 
    rightJoystick = joystick_right.rightJoystickPressed; 
} 

}

+1

Единственное место, где я вижу вас, может остановить ваше твердое тело, когда 'transform.position.y> = MAX_HEIGHT'. Можете ли вы проверить, как-то введено это заявление? – Serlite

+0

Я добавил Debug.Log («Вы меня видите?») В инструкции if, чтобы проверить, когда он запускается. Как и ожидалось, это только срабатывает, если позиция игроков превышает 15 (MAX_HEIGHT = 15f). Если я отпустите джойстик, прежде чем превышать y позицию 15, проблема остается. – Jonathan

+2

Вы останавливаете скорость, когда они идут выше MAX_HEIGHT.Возможно, вам нужно ускорить скорость движения Lerp Y, когда они достигнут максимальной высоты, и позволяют горизонтальную скорость продолжать нормально. Лерп смоделировал бы «недостаток кислорода» для упаковки и предотвратил бы такое же ощущение «Хит стены», когда достигнет максимальной высоты. –

ответ

0

Вы могли бы сделать простой линейной замедлиться.

void Update(){ 
    if(leftJoystick){ 
     rb.AddRelativeForce(0, 0, 400f, ForceMode.Impulse); 
    } 

    if(noJoystick){ 
     rb.velocity = rb.velocity * 0.9; 
    } 
} 

Обратите внимание, что функция обновления вызывается при обновлении кадров, поэтому я хотел бы предложить положить это в функции FixedUpdate() таким образом низкая скорость не будет зависеть от частоты кадров.

+0

Пробовал это и, к сожалению, не работает. Кажется, что после отпускания джойстика скорость сразу становится равной 0, поэтому нет ничего, чтобы размножаться. – Jonathan

1

не могу комментировать еще

Как J.Small сказал, вы могли бы умножить скорость с числом около 0,95 медленно замедлить Rigidbody вниз. Если вы поместите умножение в метод обновления, я предлагаю вам умножить число ~ 0.95 на Time.deltaTime, поэтому уменьшение скорости будет пропорционально прошедшему времени.

void Update(){ 
    if(leftJoystick){ 
     rb.AddRelativeForce(0, 0, 400f, ForceMode.Impulse); 
    } 

    if(noJoystick){ 
     rb.velocity = rb.velocity * 0.95 * Time.deltaTime; 
     //Or: rb.velocity.x 
    } 
} 

Вы также можете нанести небольшое количество силы, вместо умножения скорости, если вы хотите, чтобы замедлить Rigidbody более настраиваемым способом (сумма должна быть основана на Time.deltaTime, если поместить его в Update - который вызывается после кадра), но метод выше проще.

Смежные вопросы