Код единства батута не работает
Поэтому я пытаюсь создать реалистичный прыжок на батуте, вместо того, чтобы игрок провалился через батут, а затем выстрелил назад, одновременно позволяя игроку мгновенно выстрелить при контакте с батутом и снизить относительную гравитацию.
Куда я иду не так и что я могу сделать, чтобы это исправить?
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(CharacterController))]
public class small_bounce_script: MonoBehaviour {
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
private Vector3 moveDirection = Vector3.zero;
private Vector3 bounce = Vector3.zero;
void Update() {
CharacterController controller = GetComponent<CharacterController>();
if (controller.isGrounded) {
if (bounce.sqrMagnitude > 0) {
moveDirection = bounce;
bounce = Vector3.zero;
} else {
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
}
if (Input.GetButton("Jump"))
moveDirection.y = jumpSpeed;
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
}
void OnTriggerEnter(Collider other) {
Debug.Log ("Controller collider hit");
Rigidbody body = other.attachedRigidbody;
// Only bounce on static objects...
if ((body == null || body.isKinematic) && other.gameObject.controller.velocity.y < -1f) {
float kr = 0.5f;
Vector3 v = other.gameObject.controller.velocity;
Vector3 n = other.normal;
Vector3 vn = Vector3.Dot(v,n) * n;
Vector3 vt = v - vn;
bounce = vt -(vn*kr);
}
}
}
1 ответ
Батут реагирует как пружинное устройство. Давайте предположим, что сила тяжести находится в направлении Y, а поверхность батута расположена в плоскости X,Z.
Тогда ваша координата Y у пропорциональна функции синуса во время OnTriggerStay
, Скорость v в направлении Y в качестве 1-й производной от y является функцией косинуса, в то время как скорость X и Z остается постоянной.
y (t) = yMax * sin (f * t)
v (t) = yMax * f * cos (f * t)
Учитывая сохранение энергии, имеем:
E = 0,5 * м * vMax² = 0,5 * k * yMax²
=> yMax = ± SQRT (к / м) * vMax
- vMax: = скорость в направлении Y при попадании на батут. ± потому что для посадки и запуска
- yMax:= максимальная амплитуда при v == 0, т. е. глубина hwo, если игрок утонет перед возвратом
- k:= пружинная константа, определяющая поведение батута, т.е. насколько она сильна
- m:= масса игрока
- f:= SQRT (к / м)
Так что все, что вам нужно сделать, это поиграть с пружинной константой и иметь нечто подобное Update
метод:
Vector3 velocity = rigidbody.velocity;
float elapsedTime = Time.time - timestampOnEnter;
velocity.y = YMax * FConst * Mathf.cos (FConst * elapsedTime);
rigidbody.velocity = velocity;
Член вар timestampOnEnter
взят в OnTriggerEnter
, FConst - это константа, которую мы назвали f в математической части.