Topic was automatically imported from the old Question2Answer platform.
Asked By
Skipperro
Hi,
I have a 3D isometric scene where player can sometimes disappear behind a wall. I would like to dynamically make a hole in a wall that stand between player and the camera or even better - make this wall half-transparent, to have a “see through walls” effect.
For a start, you need a way to recognize when your character moves behind an obstacle, or a way to figure out what lies between the camera and the character. Then, it is a matter of changing the material of the obstacle into a semi-transparent material.
One way you can acquire the obstacle is by casting a ray. I suggest you look it up by yourself, because as far as I know, there are multiple ways to work with rays in Godot. Choose the one that best fits your needs.
Take a look at the following sources:
Having said that, I have tested the following minimal example and it works: I have attached a script to the Camera node. This script casts a ray from the position of the Camera to 1000 units in the z direction of the Camera (again, there are other ways of casting rays that are more efficient, check the docs). If said ray detects a collision object (such as an Area or RigidBody), then it acquires the collider’s MeshInstance using the collider method. Afterwards, The script sets the collider’s MeshInstance’s material into another semi-transparent material using the set_surface_material(0, mat) method.
extends Camera
onready var wall = get_node("/root/Spatial/Invisible_wall/Invisible_wall_mesh") # our obstacle
onready var mat = preload("res://Materials/orange.tres")# our second, transparent material
func _ready():
pass
func _physics_process(delta):
var space_state = get_world().direct_space_state
var result = space_state.intersect_ray(translation, Vector3(translation.x, translation.y, translation.z-1000)) # Cast a ray from camera
if result: # if collision is found
print(result.collider)
result.collider.get_node("Invisible_wall_mesh").set_surface_material(0, mat)
print(mat) #get the collider's MeshInstance and change its material
A few notes:
Raycasting works with Area and Rigidbody nodes
I have hardcoded everything in the example, but you can avoid that easily
A more efficient way to do this might be to attach the script on the colliders instead of the Camera node. That way you can set the logic in such a way that once the ray no longer collides with your obstacles, your obstacles can have their previous material.