TJBaldy
TJBaldy

Reputation: 23

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

Upvotes: 2

Views: 10840

Answers (3)

Aakash Solanki
Aakash Solanki

Reputation: 11

To shake your camera on the collision or Trigger you need to first Make function of Your Shake that you can also call from other scripts

Something like

public class ShakeCamera : MonoBehavior
{
    public bool canShake;
    
    private void Update()
    {
       if(canShake)
       DoShake()
    }
    public void DoShake()
    {
        // Shake Logic
    }
    public void StartShake()
    {
       canShake = true;
    }
    public void StopShake()
    {
       canShake = false;
    }
}

And from your other script whenever you trigger the target object you can call it like this

    public class TriggerScript: MonoBehavior
        {
            public ShakeCamera shakeCamera;

            private void Start()
            {
                shakeCamera = FindObjectOfType<ShakeCamera>();
            }

            void OnTriggerEnter(Collider collision)
            {
                 if(collision.gameObject.tag == "targetTag")// Change Tag accroding to your requirement
                    {
                      
                        cameraShake.StartShake();
                    } 
             }
            void OnTriggerExit(Collider collision)
            {
                 if(collision.gameObject.tag == "targetTag")// Change Tag accroding to your requirement
                    {
                        cameraShake.StopShake();
                    } 
             }
        }

I am attaching one reference video for you, May be it would help you in better camera shake. Hope it was helpful.

You can refer to this video I made https://youtu.be/9X_JXexwfR4

Upvotes: 1

Sayatan Majumder
Sayatan Majumder

Reputation: 1

If you have set up rigidbody then change the interpolate from none to interpolate.

Upvotes: -1

Steven Mills
Steven Mills

Reputation: 2381

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.

Upvotes: 2

Related Questions