Mr. Zelta previously had a code that instructed me to make the camera2D shake when fired. It works very well provided you are locking the camera2D according to the main character. But now the game I'm working on, I don't lock Node Camera2D according to the main character anymore. I just look with the viewport. So now how do I fix this code so that when any character in the game throws a grenade, the viewport will shake? Please help me. Thanks to everyone.
Shake viewport
- Edited
Well, because the camera is locked to the player, it's just following the player. You should be able to use that same code on the camera instead of the player. Just add a script to it. I could be wrong, of course. The ysorting shouldn't change so you should be able to forget the second script.
i think that too. if you change the path of the camera should work. set camera anchor to drag center and maybe you have to add this (line 17) to recover the default position after shaking, not sure.
get_node("Camera2D").set_offset(Vector2(0,0))
Actually it is camera2D's script. Not Player's script. Player's script has only emitt_signal task. But the important thing here is that in this game, there is no camera, so how do I shake the viewport. Because I tried making the camera can't shake, because basically this game doesn't need camera2D. It is only using the viewport. So how to shake the existing viewport.
- Edited
If you look at the script player script, it refers to global position. If it's on the camera, then it's moving the camera. That is the position of transform because it's on the script attached to the node. Line 10 on the script. lerp means linear interpolation which means it is moving it.
If you don't have a camera, then you should have a Node2d which is the root node. If you attach that script to it, and call the function, it will interpolate the position of the root node and everything else except the viewport should move because everything is parented to it. and look like a camera shake, except possibly reversed. I tried moving the root node when there was no camera in the scene and the sprite that was parented to the root node moved. So, it should shake with that script as far as I can tell. I couldn't copy the script and try it because it's an image. You should only need the first script, I think.
- Edited
Thank you fire7side! This is Camera2D's script:
extends Camera2D
var counter = 0
var cam_shake = false
var shake_amount = 4 # do chan dong (level shake)
onready var CAM = get_node(".")
func _process(delta):
if cam_shake:
CamShake(delta)
func CamShake(delta):
print("da Cam Shake")
counter += 1 * delta
CAM.set_offset(Vector2(rand_range(-1.0,1.0) * shake_amount,rand_range(-1.0,1.0) * shake_amount))
if counter >= 0.5: # time rung ngan hay dai (time shake short or long)
cam_shake = false
Parameter_Shake()
func Shake():
cam_shake = true
func Parameter_Shake():
shake_amount = 4 # reset lai do chan dong (reset shake)
counter = 0 # reset lai do lac (reset counter shake)
May you check and test it for me and and guide me what to do? Because my game doesn't need to lock camera2D on any character. So now I just need "when any character throws grenade, the viewport will shake".
Sincerely thank you very much! Best regards!
- Edited
-viewport (if you have) --Node2D ---Ysort ----character ----granades
-World --player
only those. How can?
World = Node2D
- Edited
OK, try putting this script on your world and then press spacebar for the shake.
extends Node2D
var time = 0
var can_shake = false
var counter = 2
func _process(delta):
if can_shake:
if time < counter:
time += delta
global_position.x += lerp(rand_range(-5,5),rand_range(-5,5),time/counter)
global_position.y += lerp(rand_range(-5,5),rand_range(-5,5),time/counter)
else: can_shake = false
func _input(event):
if event is InputEventKey and event.pressed:
if event.scancode == KEY_SPACE:
can_shake = true
time = 0
You'll have to fix line 10 and 11 because they got broken apart.
@fire7side said:
You'll have to fix line 10 and 11 because they got broken apart.
Not really, it's just rendered that way, but copy pasting it should be perfectly fine.
Yeah, it does vibrate. But there is another problem that occurs when the viewport after shaking will be skewed. Is there a way to make after shaking the viewport will return to the original position, Mr Fire7Side? That means no matter how much shaking, after the shaking stops, the viewport will still be in its original position.
- Edited
Try this:
var time = 0
var can_shake = false
var counter = 2
var startx = global_position.x
var starty = global_position.y
func _process(delta):
if can_shake:
if time < counter:
if global_position.x == startx:
time += delta
global_position.x += lerp(rand_range(-5,5),rand_range(-5,5),time/counter)
global_position.y += lerp(rand_range(-5,5),rand_range(-5,5),time/counter)
else:
time += delta
global_position.x = startx
global_position.y = starty
else:
can_shake = false
global_position.x = startx
global_position.y = starty
func _input(event):
if event is InputEventKey and event.pressed:
if event.scancode == KEY_SPACE:
can_shake = true
time = 0
SHAKE is OK. But what is this error message Mr. Fire7Side?
Please HELP!!!
Something is calling a node(to get it's transform) that isn't instanced in the scene tree. Putting an appropriate check to see if a node is in tree before getting it's transform should remove the 'error'.
Yeah change var startx to
onready var startx = global_position.x
onready var starty = global_position.y
Yeah, Well well well....it worked perfectly. Thank you very much for your enthusiastic help, Mr Fire7Side and thank you very much everyone. But I wonder it's not a node, so why put ONREADY in front?
- Edited
@Odin said: Yeah, Well well well....it worked perfectly. Thank you very much for your enthusiastic help, Mr Fire7Side and thank you very much everyone. But I wonder it's not a node, so why put ONREADY in front?
It's on a node. The script is derived from a node. That's why it says extends Node2d. Generally I just instantiate variables in the ready function, but I was altering someone else's code and didn't think of it. My bad. You can see that the other variables were all right until it needed a global position, which required the node to be in the scene. It's really just better to instantiate in the ready function as far as I'm concerned. Just giving them a number value is all right. The worst that can happen though is you get an error.
I'm glad it's working for you.
I mean usually when declaring a variable as a node, for example "preload(get...node...)" then use onready var ..., but here when declaring variable xxx = global_position.x why do you have to use "onready" to not have error? Excuse I am new to programming, hope you understand my slow understanding.