The Raycast Extention of ".add_exception" is known as a "Nonexistent function 'add_exception' in base 'Nil'." What?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Noob_Maker
:warning: Old Version Published before Godot 3 was released.

I want my Raycasts to not count the player so I typed

raycast.add_exception(self)

but for some weird reason when I added two more raycasts and typed the same thing(with different names of course or else it will be a different problem altogether) I get this error:

Invalid call. Nonexistent function ‘add_exception’ in base ‘Nil’.

And I don’t understand that because 1. that’s a legit thing; raycast.add_exception(self) and 2. this worked previously. What the hell is going on? Do I need to say instead of “self” I say the player object?

Here’s the code for the game at the moment:

extends RigidBody2D
#The variables
var s = 200
var c_s = Vector2(0,0)
var raycast = null
var raycastL= null
var raycastR=null
var jumpforce = 220
var pushoff = 100
#controls
var Right = Input.is_action_pressed("right")
var Left = Input.is_action_pressed("left")
var Jump = Input.is_action_pressed("jump")
#dashing mechanics variables

#Collition thingy so that I don't have to go crazy when the sprite changes and because it will crouch so yeah

#ground check(never thought I'll be using this)

#how to use raycasts(if I ever forget...again):if raycast_1.is_colliding():
   #if raycast_1.get_collider().get_name() == "object":
     # do_something
   #elif raycast_1.get_collider().get_name() == "other_object":
    # do_something_else
#raycast_1 = get_node("left_ray")
#raycast_2 = get_node("right_ray")

func is_touching_wall():
	if raycastR.is_colliding():
		if Input.is_action_pressed ("jump"):
			set_linear_velocity(Vector2 (pushoff, get_linear_velocity().y))
	
func is_on_ground():
	if raycast.is_colliding():
		return true
	else:
		return false
	
func _ready():
	CollisionShape = RectangleShape2D.new()
	raycast = get_node("RayCast2D")
	#raycast = get_node("RayCast2D_left")
	#raycast = get_node("RayCast2D_right")
	raycast.add_exception(self)
	raycastR.add_exception_rid(self)
	set_fixed_process(true)
	set_gravity_scale(3)
	
#movement(walking)
func _fixed_process(delta):
	Right = Input.is_action_pressed ("right")
	Left = Input.is_action_pressed ("left")
	Jump = Input.is_action_pressed ("jump")
	if Right == true:
		set_linear_velocity(Vector2 (s, get_linear_velocity().y))
	elif Left == true:
		set_linear_velocity(Vector2(-s, get_linear_velocity().y))
	else:
		set_linear_velocity(Vector2 (0, get_linear_velocity().y))
	if is_on_ground():
		if Jump: 
			set_axis_velocity(Vector2(0,-jumpforce))
	if is_touching_wall():
		if Jump:
			set_axis_velocity(Vector2(0,-pushoff))
	#dashing
	
	

I’m working with a rigid body so don’t give me advice SPECIFICALLY for kinematic bodies

Just a tip apart for the null reference explained on the answers:

If many things need to ignore others, maybe you need to work with different layers and masks instead.

eons | 2017-05-16 16:58

:bust_in_silhouette: Reply From: Zylann

You are getting this error because the variable you are calling this function on is null (hence “base Nil”).
I can’t tell why, you should show more of your code, but you should check why your variable could be null first.
Also make sure you have no errors in the debugger, AND in the system console (in red).

I added the code into the question so that you and others can look it up

Noob_Maker | 2017-05-16 20:05

raycast = get_node("RayCast2D")
The only case in which this returns null is if Godot was unable to find the node named “RayCast2D” from your Rigidbody. As I said, check the errors. What is your scene hierarchy?

But it’s possible that…

CollisionShape = RectangleShape2D.new()

I don’t think this even works because:

  1. CollisionShape is a class, not a variable (I don’t see it anywhere anyways) so using = will fail,
  2. should not be used in scripting because CollisionShape is editor-only according to the doc
  3. RectangleShape2D is a Shape2D, not a CollisionShape (also note it’s the 3D version), so even if you had a variable the result would be unexpected.
    You are not using it as well so I suggest you remove this line^^

Edit: I tested this and that’s actually running… but it looks like a bug, because doing this replaces CollisionShape with something that is an instance of RectangleShape2D, or how to troll a game project by swapping classes around xD

Zylann | 2017-05-16 23:00

wow, nice find, I wonder if was always like that or is a recent bug…
EDIT: tested on 2.0 and was possible there too X_x


Try to set a coding style that do not interfere with core api, like always variables in lowercase, only classes uppercase, I don’t like snake case but is useful here to not mess with API class names too.

eons | 2017-05-17 00:01

Thanks! I’ll keep that in mind:
variables → lowercase
classes → Uppercase(ONLY)

Edit: I got that I got everything working now(besides the fact that it’s not working with the if is_touching_wall(): if Jump: set_axis_velocity(Vector2(0,-pushoff)) for some weird reason)

Noob_Maker | 2017-05-17 22:59

why “rid” ? … raycastR.add_exception_rid(self)
maybe therefore doesn’t work…if is_touching_wall(): ?

Bishop | 2017-05-18 21:44

RID is a pointer to a Resource, not much useful in scripting tbh (AFAIK). I don’t know why it has been exposed.

Zylann | 2017-05-18 23:40

ahh, yes…Resource identification…I think so…confusing, I thought it is more importance…for GDscript novice like me :slight_smile:

Bishop | 2017-05-19 11:36

:bust_in_silhouette: Reply From: MrMonk

so the new raycasts you created, are not attached to the player as you think they are, or you are not calling them with the correct name. The error doesn’t tell you the player does not exist, it tells you the raycasts don’t exist :slight_smile:

That’s what happened when I thought that it would be easier if I gave the raycasts their own scripts. How do I tell Godot that they exist?

Noob_Maker | 2017-05-16 20:00