Sidescroller Bubble Feature

Hi,
I am working on a 2D-Sidescroller and I have problems with a feature.
The idea is that there is a bubble wich is flying in the air, and the player can jump into it. If he collides with the Bubble, his position is set to the center of the bubble. Then the player can either wait until the bubble explodes by itself after some time and sets the player free, or he can press space for “jump”, wich makes the bubble explode immediately and also makes the player jump from that spot.

At the moment I got 2 problems.

  1. The Player can’t jump, because he is not on the ground, (the exploding of the bubble and the jump should happen just once after pressing space)
  2. I tried to use “Vector3.Lerp” so that the Player moves very smooth into the Bubble if he collides with it. The lerp-function happens at every frame (its in Update()), and it should happen only once at the beginning, so I checked if the lerp has played before, if “yes”, it sets the player to the bubble position immediately.
    The problem is the script is updating it so fast, that now the player is set to the bubble position before the “lerp” has time to do it’s job :wink: Is there a better way to do this?

greetings
J.

the bubble script:

public class Seifenblase: MonoBehaviour {

    private Vector3 startPos;
    private Vector3 newPos;
    public float speed = 10f;

    bool inBubble = false;
    float StartTime;
    float TotalDistanceDestination;
    bool lerped = false;

   
    void OnTriggerEnter2D (Collider2D col)
    {
        if(col.gameObject.tag == "Player") // if Player collides with Bubble
        {
            inBubble = true;
        }
    }

    void Start () {
        startPos = transform.position;

        StartTime = Time.time;
        TotalDistanceDestination = Vector3.Distance (GameObject.Find ("Player").GetComponent<Player> ().transform.position, newPos);
    }

    void Update () {
        newPos = startPos;
        newPos.y = newPos.y + Mathf.PingPong(Time.time * speed, 6) - 3; 
        newPos.x = newPos.x + Mathf.PingPong(Time.time * speed, 1) - 3; 

        transform.position = newPos;

        //Bubble
        if (Input.GetKeyDown(KeyCode.Space)) { //if space pressed, set player free
            inBubble = false;
            //Player.Instance.Jump = true;
        }

        float currentDuration = Time.time - StartTime;
        float journeyFraction = currentDuration / TotalDistanceDestination;

        if (inBubble == true && lerped == false) {
            GameObject.Find ("Player").GetComponent<Player> ().transform.position = Vector3.Lerp (GameObject.Find ("Player").GetComponent<Player> ().transform.position, newPos, journeyFraction ); // moves player with bubble
            lerped = true;
        }
        if (inBubble == true && lerped == true){
            GameObject.Find ("Player").GetComponent<Player> ().transform.position = newPos;
        }

        //BubbleEnd
    }
}

and here the player-script:

public class Player : Charakter {

    private static Player instance;

    public static Player Instance{
        get{
            if(instance == null){
                instance = GameObject.FindObjectOfType<Player> ();
            }
            return instance;
        }
    }

    [SerializeField]
    private Transform[] groundPoints;
    [SerializeField]
    private float groundRadius;
    [SerializeField]
    private LayerMask whatIsGround;

    [SerializeField]
    private bool airControl;
    [SerializeField]
    private float jumpForce;

    public Rigidbody2D MyRigidbody {get;set;}
    public bool Jump {get;set;}
    public bool OnGround {get;set;}
    private Vector2 startPos;

    //public override bool IsDead     get{        return health <= 0;    }}

    public override void Start () {
       
        base.Start();
        startPos = transform.position;
        MyRigidbody = GetComponent<Rigidbody2D>();
    }


    void Update(){
       
        HandleInput();
    }

    void FixedUpdate () {

        float horizontal = Input.GetAxis ("Horizontal");

        OnGround = IsGrounded();
        HandleMovement (horizontal);
        Flip (horizontal);
        HandleLayers();
    }

    private void HandleMovement(float horizontal){

        if(MyRigidbody.velocity.y<0){
            MyAnimator.SetBool ("land", true);
        }
        if((OnGround || airControl)){
            MyRigidbody.velocity = new Vector2 (horizontal * movementSpeed, MyRigidbody.velocity.y);
        }
        if(Jump && MyRigidbody.velocity.y == 0){
            MyRigidbody.AddForce (new Vector2 (0, jumpForce));
        }
            MyAnimator.SetFloat ("speed", Mathf.Abs (horizontal));
       
    }


    private void HandleInput(){
        if(Input.GetKeyDown(KeyCode.Space)){
            MyAnimator.SetTrigger("jump");
        }

        if(Input.GetKeyDown(KeyCode.V)){
            ThrowKnife(0);
        }
    }

    private void Flip(float horizontal){
        if(horizontal > 0 && !facingRight || horizontal < 0 && facingRight){
            ChangeDirection();
        }
    }

    private bool IsGrounded(){
        if (MyRigidbody.velocity.y <= 0){
            foreach(Transform point in groundPoints){
                Collider2D[] colliders = Physics2D.OverlapCircleAll(point.position, groundRadius, whatIsGround);

                for(int i = 0; i< colliders.Length; i++){
                    if(colliders[i].gameObject != gameObject){
                       
                        return true;
                    }
                }
            }
        }
        return false;
    }


    private void HandleLayers(){
        if(!OnGround){
            MyAnimator.SetLayerWeight (1, 1);
        }
        else{
            MyAnimator.SetLayerWeight (1, 0);
        }
    }


}

I didn’t read your script at all, but I did read your question.
What I would try, in your situation, is to start a coroutine when you’ve hit the bubble and set that up so your player is moved smoothly into the center.

As for your jumping issue inside the bubble, I’d say you could solve that with a bool variable probably.
isInsideBubble = true; if(grounded || isInsideBubble) → allow jump, set isInsideBubble to false, explode bubble, carry on with the game … :wink:

1 Like