Search code examples
c#cameraunity-game-engine

Camera shake on collision in unity 3d


http://answers.unity3d.com/questions/212189/camera-shake.html I've followed the question's answer above to try and get a camera shake working for my first person camera. But I've tried to modify it so that the camera shakes from an invisible collision box.

So far my camera shake script looks like this;

public bool Shaking; 
private float ShakeDecay;
private float ShakeIntensity;   
private Vector3 OriginalPos;
private Quaternion OriginalRot;

void Start()
{
Shaking = false;   
}

void OnTriggerEnter(Collider collision)
{
if(collision.gameObject.name == "ShakeTrigger")
{
    DoShake();  
    Debug.Log("The camera trigger has hit");
}
}


void Update () 
{
if(ShakeIntensity > 0)
{
    transform.position = OriginalPos + Random.insideUnitSphere * ShakeIntensity;
    transform.rotation = new Quaternion(OriginalRot.x + Random.Range(-ShakeIntensity, ShakeIntensity)*.2f,
                              OriginalRot.y + Random.Range(-ShakeIntensity, ShakeIntensity)*.2f,
                              OriginalRot.z + Random.Range(-ShakeIntensity, ShakeIntensity)*.2f,
                              OriginalRot.w + Random.Range(-ShakeIntensity,     ShakeIntensity)*.2f);

   ShakeIntensity -= ShakeDecay;
}
else if (Shaking)
{
   Shaking = false;  
}

}


void OnGUI() {

 if (GUI.Button(new Rect(10, 200, 50, 30), "Shake"))
   DoShake();
   //Debug.Log("Shake");

}     

public void DoShake()
{
OriginalPos = transform.position;
OriginalRot = transform.rotation;

ShakeIntensity = 0.3f;
ShakeDecay = 0.02f;
Shaking = true;
}   

I know the code works 100% via the gui button. This script is attached to the camera on the first person controller. An invisible collision box with the tag ShakeTrigger is in the game. However, the debug log doesn't get called at all and I'm unsure why.

If anyone needs any more information just let me know.

Thanks in advance :)


Solution

  • If the script is attached to your camera, then OnTriggerEnter is looking at the camera for a trigger call, not the collision box.

    One thing you could do is stick the OnTriggerEnter into a new script and put that inside the collision box. Then have that do a SendMessage along these lines:

    GameObject.Find("Camera").SendMessage("DoShake");

    EDIT: To answer Jerdak's questions.

    The code bellow would be within the TriggerBox:

    void Start()
    {
        ...   
    }
    
    void OnTriggerEnter(Collider collision)
    {
        if(collision.gameObject.name == "ShakeTrigger")
    {
        GameObject.Find("Camera").SendMessage("DoShake");  
        Debug.Log("The camera trigger has hit");
    }
    }...
    

    and this would be within the Camera:

    void Start()
    {
        ...  
    }
    
    public void DoShake()
    {
        OriginalPos = transform.position;
        OriginalRot = transform.rotation;
    
        ShakeIntensity = 0.3f;
        ShakeDecay = 0.02f;
        Shaking = true;
    }... 
    

    This way, triggerbox is responsible for detecting triggers and only ever sends a message to the camera when right kind of object goes through it. The camera is then responsible for doing the shaking.