I want to make a 2d directional knockback effect.

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By davedabomb

I am making a 2D platformer where the player has a shotgun that’s rotation follows the mouse position. I actually want to add a “knockback” effect to the player whenever the shotgun is fired that is directional and can actually be used like a small jump boost if the player is aiming down. I know how to create basic player movement/jumping and I know how to add the shotgun that aims to the mouse position but I don’t know how to make the player move in the direction of any specific direction besides left, right, up and down.

Here is my code:

extends KinematicBody2D

var motion = Vector2()
var UP = Vector2(0,-1)

var speed = 400
var acceleration = 20
var gravity = 20
var jump_height = 400

func _physics_process(delta):
move_and_slide(motion,UP)
Gravity()
Move()
Jump()

func Move():
if Input.is_action_pressed(“move_left”) and not Input.is_action_pressed(“move_right”):
motion.x = max(motion.x - acceleration, -speed)
elif Input.is_action_pressed(“move_right”) and not Input.is_action_pressed(“move_left”):
motion.x = min(motion.x + acceleration, speed)
else:
motion.x = lerp(motion.x, 0, 0.2)
if Input.is_action_just_pressed(“shoot”):
pass

func Gravity():
if is_on_floor():
motion.y = 0
else:
motion.y += gravity

func Jump():
if Input.is_action_just_pressed(“move_up”):
motion.y -= jump_height

You can format the code by highlighting it and clicking the { } button

Magso | 2020-04-25 19:04

:bust_in_silhouette: Reply From: Magso

You need a reference to your shotgun and use the basis_xform() method to get the local direction of the shotgun.

var pushback : Vector2
motion += shotgun.global_transform.basis_xform(pushback)

Thanks for this info!

You’ll have to forgive me because I’m a beginner and I’m a bit confused. I have the shotgun as its own scene which is Just a sprite and a raycast2d that follow the mouse position and then I instanced it as a child of my player.

I tried to add the var pushback = Vector2() with my other variables at the top of my script and then I wrote this function:

func shoot():
	if Input.is_action_just_pressed("shoot"):
		motion += $shotgun.global_transform.basis_xform(pushback)

When I open the game and shoot It crashes and says "Invalid get index ‘global_transform’ (on base: ‘null instance’)

davedabomb | 2020-04-28 20:58

I really want to understand this stuff too, if you recommend any specific resources for learning I would love to check them out.

davedabomb | 2020-04-28 22:30

Is the shotgun a child of the node the script is on?

> player node (script)
   > shotgun

I couldn’t recommend any learning resources as I mostly learnt Godot using my prior knowledge of Unity but there’s tutorials on YouTube by GDQuest, KidsCanCode and many others. As you learn about datatypes (int, float, etc), properties, methods/functions, classes and inheritance you’ll get to a point where you’ll mostly just look at the docs instead of following a video or guide and luckily Godot is one of the easier engine’s to learn from.

Magso | 2020-04-29 00:52

The shotgun scene is a child of the player node. The shotgun scene has its own script simply to point toward the mouse position and this is the script for the player node:

extends KinematicBody2D

var motion = Vector2()
var UP = Vector2(0,-1)

var speed = 400
var acceleration = 20
var gravity = 20
var jump_height = 400
var pushback = Vector2()


func _physics_process(delta):
	move_and_slide(motion,UP)
	Gravity()
	Move()
	Jump()
	shoot()



func Move():
	if Input.is_action_pressed("move_left") and not Input.is_action_pressed("move_right"):
		motion.x = max(motion.x - acceleration, -speed)
	elif Input.is_action_pressed("move_right") and not Input.is_action_pressed("move_left"):
		motion.x = min(motion.x + acceleration, speed)
	else:
		motion.x = lerp(motion.x, 0, 0.2)



func Gravity():
	if is_on_floor():
		motion.y = 0
	else:
		motion.y += gravity


func Jump():
	if Input.is_action_just_pressed("move_up"):
		motion.y -= jump_height


func shoot():
	if Input.is_action_just_pressed("shoot"):
		motion += $shotgun.global_transform.basis_xform(pushback)

davedabomb | 2020-04-29 15:23

You need to get the reference to the shotgun.
Have you made shotgun a child of the player? If so is it called “shotgun”? If not you’ll have to reference up to the parent and down to the shotgun get_node("../shotgun")

Magso | 2020-04-29 16:03