Bubble movement Issue coming / improvement needed. "H.E.L.P"

hii, i made a bubble spawn when i blow the air on my microphone.

I want to make their movement as natural as possible. Guide me improvement on my code

Currently, they move like this - https://everyplay.com/videos/780064?share=true

  1. Sometimes, they stuck at the corners like in the video above, what to do to get rid of this ?
  2. they should explode at different times, currently entire batch explode at ones
  3. once they are spawn, they should move in different directions and rotate left,right a bit

Can you help me with the moment please, here is my current code -

using UnityEngine;
using System.Collections;


public class BubbleMovement : MonoBehaviour
{
	private Vector3 _blowDirection = Vector3.up;
	
	private float _screenBoundTop;
	private float _screenBoundBottom;
	private float _screenBoundLeft;
	private float _screenBoundRight;
	
	GameObject spawnparticle,wandpos,bottle,wand;
	private Vector3 _originalSize;
	private bool _isBlowing = false;
	private bool _isBlow = false;
	private bool _isExploding = false;
	private Vector3 _driftVelocity = Vector3.zero;
	private Vector3 _maxDriftVelocity;
	private Vector3 _minDriftVelocity;
	private Vector3 _blowAcceleration;
		
	public ColorTypes color;
	public float maxSizeFactor = 3f;
	public float explosionThreshold = 1.4f;
	public float fillRate = 2f;
	public float minDriftSpeed = 0;
	public float maxDriftSpeed = 6f;
	public float driftAcceleration = 15f;
	public float driftDecceleration = 1f,spawntime;
	
	// Use this for initialization
	void Start ()
	{
		bottle = GameObject.Find("bottle");wand = GameObject.Find("wand_Big");
		gameObject.renderer.material.mainTexture = Resources.Load("Bubbles/"+wand.tag+"/"+bottle.tag+"Bubble")as Texture;
		maxSizeFactor = Random.Range(1.5f,4f);
		explosionThreshold = Random.Range(1.5f,3f);
		wandpos = GameObject.Find("Spawnposition").gameObject;
		spawnparticle = Resources.Load("Particles")as GameObject;
		var test = Camera.main.ScreenToWorldPoint(Vector3.zero);
		_screenBoundBottom = test.y;
		_screenBoundLeft = test.x;
		
		test = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, 0f));
		_screenBoundTop = test.y;
		_screenBoundRight = test.x;
		
		_minDriftVelocity = Vector3.one * minDriftSpeed;
		_maxDriftVelocity = Vector3.one * maxDriftSpeed;
		_originalSize = transform.localScale;		
	}
	
	// Update is called once per frame
	void Update ()
	{
		spawntime=Time.frameCount;
		// i think this is burst time
		if(spawntime > 2000)
		{
			StartCoroutine(NormalExplodeBubble());
		}
		
		if(!_isBlow)
		transform.position = wandpos.transform.position;
		if(!_isExploding)
		{
			PerformScaling();
			PerformMovement();
		}
	}
	
	private void PerformScaling()
	{
		
		if(MicrophoneManager.Instance.IsBlowing)
		{
			_isBlow = true;
			transform.localScale = Vector3.Lerp(transform.localScale, _originalSize * maxSizeFactor, fillRate * Time.deltaTime);//this.transform.parent = null;
			
		}
		
		if(transform.localScale.x > (_originalSize.x * explosionThreshold))
		{
			_isExploding = true;
			StartCoroutine(ExplodeBubble());
		}
		//StartCoroutine(NormalExplodeBubble());
	}
	
	private void PerformMovement()
	{
		if(MicrophoneManager.Instance.IsBlowing)
		{
			
			var incomingBlowPosition = new Vector3(_screenBoundRight/2, _screenBoundTop, 0f);
			var normalizedBlowVectorOnBubble = (transform.position - incomingBlowPosition).normalized;
			normalizedBlowVectorOnBubble = new Vector3(normalizedBlowVectorOnBubble.x * Random.Range(-9.0f,5f),normalizedBlowVectorOnBubble.y,normalizedBlowVectorOnBubble.z);
			_driftVelocity += normalizedBlowVectorOnBubble * driftAcceleration * Time.deltaTime;
			
		}
		else
		{
			_driftVelocity = Vector3.Lerp(_driftVelocity, _minDriftVelocity, driftDecceleration * Time.deltaTime);
		}
		_driftVelocity.z = 0;
		if((transform.position.x - renderer.bounds.extents.x) < _screenBoundLeft)
		{
			_driftVelocity = new Vector3(-_driftVelocity.x, _driftVelocity.y, 0f);
		}
		else if((transform.position.x + renderer.bounds.extents.x) > _screenBoundRight)
		{
			_driftVelocity = new Vector3(-_driftVelocity.x, _driftVelocity.y, 0f);
		}
		
		if((transform.position.y + renderer.bounds.extents.y) > _screenBoundTop)
		{
			if(_driftVelocity.y > 0)
			{
				_driftVelocity = new Vector3(_driftVelocity.x, -_driftVelocity.y, 0f);
			}
		}
		else if((transform.position.y - renderer.bounds.extents.y) < _screenBoundBottom)
		{
			_driftVelocity = new Vector3(_driftVelocity.x, -_driftVelocity.y, 0f);
		}
		
		this.transform.position += _driftVelocity * Time.deltaTime *Random.Range(0.2f,0.8f) * Random.Range(0.5f,1.5f);
		//transform.position = new Vector3( transform.position.x,transform.position.y*Random.Range(0.1f,1f),transform.position.z);
	}
	
	private IEnumerator ExplodeBubble()
	{
		var currentTime = Time.time + Random.Range(0.5f,1f);
		
		while(currentTime  > Time.time)
		{
			transform.localScale = Vector3.Lerp(transform.localScale, _originalSize * maxSizeFactor, fillRate * Time.deltaTime);
			yield return null;
		}
		yield return null;
		Debug.Log("Pop");
		Instantiate(spawnparticle,gameObject.transform.position,Quaternion.identity);
		Destroy(gameObject);
	}
		private IEnumerator NormalExplodeBubble()
	{
		yield return new WaitForSeconds (Random.Range(15f,18f));
		Instantiate(spawnparticle,gameObject.transform.position,Quaternion.identity);
		audio.Play();
		Destroy(this.gameObject);
	}
}

Regarding bubble motion, sin waves tend to look good. Here’s a quick snippet to play with… :slight_smile:

float _motionAngle = 0.0f;

private Vector3 GetBubbleMotion (float motionSpeed, float motionWidth, float motionGravity) {

   _motionAngle += Mathf.PI / 180.0f * motionSpeed;

   return new Vector3(Mathf.Sin(_motionAngle) * motionWidth, motionGravity, 0.0f);	
}

// store original x position
float _originalXPos ;

void Start () {

 _originalXPos = transform.position.x; 

}

Called per-frame:

_driftVelocity = GetBubbleMotion (3.0f, 200.0f, -1.0f);

// include current Y position to increment gravity. X position must not increment. Use original X if required (as shown above).
Vector3 bubblePos = new Vector3(_originalXPos, transform.position.y, 0.0f); 

transform.position = bubblePos +_driftVelocity * Time.deltaTime;
1 Like

With regards to them sticking to the edge, reflecting the vector usually works. Check your bound conditions, use the equal to operator “<=” instead of just “<” and check the condition after you’ve moved the object, not before, otherwise it could creep back outside the bounds.

Lastly, having watched the video I cannot see how the bubbles appear to explode. Looking at your code (with tired eyes) I notice that the random delay is half a second (max). Try increasing this threshold.