Camera shake

Hi all,

is there any possibility to make camera shake without animaing it ?. I want to simulate an earthquake in my game everytime an enemy explodes. Thanks in advance.

could you have several empties parented to the player just off it’s edges and have the camera quickly cycle through tracking to them?

hi Scalia, it sounds like a good idea. but it consumes memory for more game objects. I imagined to make a fast randomization of camera orientation, but im not sure if i can use Matrix3x3

Parent the camera to an empty. Use this empty for aiming and moving the camera. Give the camera a shake animation (or several blended) and play it each time you want the camera to shake.

animating it is a must? can it be just randomized everytime?

You can do it using python to move or rotate the camera, then set it back to the original position.

Sent from my LG-H440n using Tapatalk

Here you are sir :smiley:

Demo = press space

in game

change space bar to message sensor :smiley:

Brutality of shake = adjust the range in the random actuator

import bge



def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner


    own.alignAxisToVect(own.parent.worldOrientation.col[2],2,.25)
    own.alignAxisToVect(own.parent.worldOrientation.col[1],1,.25)
    own.alignAxisToVect(own.parent.worldOrientation.col[0],0,.25)
    if own['Time']>=1:
        own['Time']-=1
        Vec2 = own.getVectTo(own.parent.worldPosition)
        if own['Time']!=0:
            own.applyMovement(Vec2[1]*(Vec2[0]/own['Time']))
        else:
            own.worldOrientation=own.parent.worldOrientation
            own.worldPosition=own.parent.worldPosition
    else:
        if own['Shake']>=1:
            offset = -own['Shake']+bge.logic.getRandomFloat()*(own['Shake']*2)
            offset*=.125
            own.worldPosition.x+=offset
            offset2 = -own['Shake']+bge.logic.getRandomFloat()*(own['Shake']*2)
            offset2*=.125
            own.worldPosition.y+=offset2
            offset3 = -own['Shake']+bge.logic.getRandomFloat()*(own['Shake']*2)
            offset3*=.125
            own.worldPosition.z+=offset3
            offset4 = -own['Shake']+bge.logic.getRandomFloat()*(own['Shake']*2)
            offset4*=.0125
            Ang = own.parent.worldOrientation.to_euler()
            Ang.x +=4
            offset5 = -own['Shake']+bge.logic.getRandomFloat()*(own['Shake']*2)
            offset5*=.0125
            Ang.y+=offset5
            offset6 = -own['Shake']+bge.logic.getRandomFloat()*(own['Shake']*2)
            offset6*=.0125
            Ang.z+=offset6
            own['Shake']-=1
            own['Time']=int(bge.logic.getRandomFloat()*4) 
        else:
            own.worldOrientation=own.parent.worldOrientation
            own.worldPosition=own.parent.worldPosition
                
            
                
        


main()



Attachments

ShakeIt.blend (439 KB)

thanks BPR! Its very useful!

No problem - here it is with a few small fixes.

Attachments

ShakeIt_(SmallFix).blend (440 KB)

what is better? one animation or 50 lines of code?
should not also this effect be handled from an 2Dfilter? that require one line of code?
scene.add2Dfilter(“shake_camera”, time_max=1.0, max_shake=0.2)

this mean the filter is removed after 1.0 second without touch the camera.

yeah

if Shake!=0------------Run camera shake

will only run when needed if you set it that way,

and assigning Shake to 8 = up to 36 +more frames of shake (the time modifier)

and my script is truly ‘ad hoc’ so it’s not repetitive at all.

Attachments

ShakeIt_(SmallFix)_(NotRanUnlessShakeisNotZero).blend (440 KB)

not clear the task of “Time” , ie, in the bricks is not calculated and in the code even

code condensed: 8)


import bge
import random
from mathutils import Vector




def main():
   
    def get_rand_vec(size=1.0):
        return Vector([random.uniform(-size,size) for axis in range(3)])
    
    cont = bge.logic.getCurrentController()
    own = cont.owner
    
    if own['Shake']>0.0:
        own['Shake'] -= 0.016
        own.worldPosition = own.parent.worldPosition.lerp(own.worldPosition + get_rand_vec(own["Shake"]),0.05)
    else:
        own.worldOrientation=own.parent.worldOrientation
        own.worldPosition=own.parent.worldPosition
        own['Shake'] = 0.0


main()





time for the return of the camera to base world position before iterating again.

its randomly 1 , 2, 3, 4 or zero I think*

but the time is “time”, not a “tic”,(tic=integer that should rapresent the frame logic)
anyway the modification of orientation in my opinion is avoidable

i thank you both