Question

So I'm trying to create a realistic trampoline jump instead of the player falling through the trampoline and then slingshotting back up, whilst instead allowing the player to instantly shoot upon contact with the trampoline and come down a relative gravity.

Where am I going wrong and what can I do to fix it?

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);

    }

}

}

Was it helpful?

Solution

A trampoline reacts like a spring device. Let's assume gravity is in Y direction and the trampoline surface is positionied in the X,Z plane.

Then your Y coordinate y is proportional to a sine function during OnTriggerStay. Velocity v in Y direction as 1st derivative of y is then a cosine function, while X and Z velocity remain constant.

y (t) = yMax * sin (f * t)
v (t) = yMax * f * cos (f * t)

Considering conservation of energy, we have:

E = 0.5 * m * vMax² = 0.5 * k * yMax²
=> yMax = ± SQRT (k / m) * vMax

  • vMax := speed in Y direction when hitting the trampoline. ± because for landing and starting
  • yMax := maximum amplitude when v == 0, i.e. hwo deep should the player sink before returning
  • k := spring constant defining trampoline behaviour i.e. how strong it is
  • m := player's mass
  • f := SQRT (k / m)

So all you need to do is playing around with the spring constant and have something like this in your Update method:

Vector3 velocity = rigidbody.velocity;
float elapsedTime = Time.time - timestampOnEnter;
velocity.y = YMax * FConst * Mathf.cos (FConst * elapsedTime);
rigidbody.velocity = velocity;

Member var timestampOnEnter is taken in OnTriggerEnter, FConst is the constant we called f in the maths part.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top