How to change or add a shader to an object when the ray cast collides?

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

I did draw a toon outline but I wanted to it change its color to white when the ray cast collides, so it shows that the object can be selected

:bust_in_silhouette: Reply From: Ron0Studios

you should use a uniform variable.
For example:

uniform vec4 toon_outline : hint_color

remember to use hint_colour, because it will make setting shader params VERY EASY

:bust_in_silhouette: Reply From: njamster

You didn’t mention if you’re working in 2D or 3D, so I’ll assume 2D:

if $RayCast2D.is_colliding():
    var collider = $RayCast2D.get_collider()
    collider.material.set_shader_param("outline_color", Color(1., 1., 1., 1.))

That assumes your shader has a parameter outline_color defined:

uniform vec4 outline_color

that you’re using to set the outlines color.

I am using 3d.

jm4rcos | 2020-05-29 15:31

I am using 3d.

Alright, then it’s RayCast instead of RayCast2D - everything else stays the same.

njamster | 2020-05-29 16:57

i am getting this error:
Invalid get index ‘material’ (on base: ‘StaticBody’).

if ray.is_colliding():
	var interact = ray.get_collider()
	interact.material.set_shader_param("albedo", Color(255, 0, 0, 0))

i tried outline_color (created the uniform and changed ALBEDO = albedo.rgb) but also get the same error
my outline is in the next pass as a shader. just wanted to change its color of black to white in the runtime

jm4rcos | 2020-05-30 21:27

i am getting this error: Invalid get index ‘material’ (on base: ‘StaticBody’).

That means the node your RayCast is colliding with (the collider you save into the variable interact) is a StaticBody. Which (unlike it’s 2D-counterpart StaticBody2D) does not have the material-property you’re trying to access.

So you need to adapt the path to your scene tree and the location of your shader material. If it’s on a direct MeshInstance-child of interact it would be:

interact.get_node("MeshInstance").mesh.material

njamster | 2020-05-31 23:45