Can't move Camera Position using Script

Hello,

I’m making a simple Brick Breaker game and I’m trying to add a Camera Shake when a brick is destroyed.
Here’s my setup,

I have a Brick script that manages collision between my ball and my bricks, here’s the piece that manages collision,

void OnCollisionEnter2D (Collision2D collision) 
	{	
				
		int health = (damageSprites.Length + 1);
		// ADD if brick hits need debugging
		//Debug.Log("Brick Hit");
		damage++;
		
		if (isBreakable)
		{
			if (damage >= health)
			{
				mainCam.GetComponent<CameraShake>().Shake();
				AudioSource.PlayClipAtPoint(crack, transform.position);
				smoke.GetComponent<ParticleSystem>().startColor = brickColor;
				Instantiate(smoke, this.transform.position, Quaternion.identity);
				GameObject.Destroy(gameObject);
				brickCount--;
				//ADD if need to debug bricks being destroyed
				//Debug.Log("Brick Destroyed! Brick Count now, " + brickCount);
				levelManager.BrickDestroyed();
			}
			else
			{
				LoadSprite();
			}
		}
	}

I’m loading my mainCam variable in my start method,

		mainCam = GameObject.FindObjectOfType<Camera>();

I then have this CameraShake script attached to my MainCamera object in my scene,

using UnityEngine;
using System.Collections;

public class CameraShake : MonoBehaviour {
	
	public float shakeDuration;
	public float shakeMagnitude;
	
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	public void Shake()
	{	
		print ("shake");
		
		float elapsed = 0.0f;
		
		Vector3 originalCamPos = transform.position;
		
		while (elapsed < shakeDuration) 
		{
			print ("shake in while");
			elapsed += Time.deltaTime;          
			
			//			float percentComplete = elapsed / shakeDuration;         
			//			float damper = 1.0f - Mathf.Clamp(4.0f * percentComplete - 3.0f, 0.0f, 1.0f);
			
			// map value to [-1, 1]
			float x = Random.Range(-1.0f,1.0f);
			
			float y = Random.Range(-1.0f,1.0f);
			
			x *= shakeMagnitude; //* damper;
			y *= shakeMagnitude; //* damper;
			
			Vector3 newCamPos = new Vector3(x,y, originalCamPos.z);
			
			transform.position = newCamPos;
			
		}
		
		this.transform.position = originalCamPos;
	}
}

Unfortunately I have been unsuccessful in producing a shake with this setup. I have logged events for the following and confirmed that all are logging that they are functioning correctly,

  • Finding the camera object
  • Entering the shake script
  • The original camera position
  • Entering the while loop
  • The elapsed time (which correctly logged gradually from 0 to the shakeDuration)
  • The new Random floats (different for each different elapsed time)
  • The newCamPos (also different for each different elapsed time)
  • The transform.position also updated correctly
  • The reset to the original position after the while loop completed

All of this and no camera movement. I suspected it was a global project setting preventing the camera from moving, but couldn’t find anything.

Any help is greatly appreciated.

Your problem comes from the shake method : you do all your animation in a while loop without any rendering of frames. So when you go out of your shake method the position of the camera is set to the originalCamPos, you did your animation, but you cannot see it ^^.

what you should is when you call your shake method, initialize a bool to tell to shake, reset your ellapsed time to 0, then put the animation code in the update loop and count the time elapsed. When you are done set your bool to false. Something like :

Vector3 m_OriginalCamPos;
bool m_Shake;
double m_Elapsed;

// Update is called once per frame
 void Update () 
 {
	if (m_Shake)
	{
		if (elapsed < shakeDuration)
		{
			print ("shake in while");
			m_Elapsed += Time.deltaTime;          
			
			// map value to [-1, 1]
			float x = Random.Range(-1.0f,1.0f);
			
			float y = Random.Range(-1.0f,1.0f);
			
			x *= shakeMagnitude; //* damper;
			y *= shakeMagnitude; //* damper;
			
			Vector3 newCamPos = new Vector3(x,y, originalCamPos.z);
			
			transform.position = newCamPos;
		}
		else
		{
			this.transform.position = originalCamPos;
			m_Shake = false;
		}
	}
 }
 
 public void Shake()
 {    
	 print ("shake");         
	 m_Elapsed = 0.0f;         
	 m_OriginalCamPos = transform.position;		 
	 m_Shake = true;      
 }

You are a champion. Worked like a charm and makes total sense.

Thanks for your help!