I have a 3D cube model that I’m using for my building system in Godot 4 (GridMap, and the block is within a node as a MeshLibrary). I’ve written a script (attached to the parent node, Node3D - Test_CreateMap) to dynamically change the block’s texture directly within the script. However, after changing the texture, the block’s collision disappears, preventing player interaction despite having a script for building and destroying blocks. How can I fix this to prevent the collision from disappearing?
*Test_CreateMap script where i selected texture for block
@export var atlas_path: String = "res://game_assets/test for more updates/test create map/BlockTextureSelectTest/textures/TestBlocks2Atlas.png"
@export var block_scene: PackedScene # Reference to the block scene (.tscn)
@onready var cube_mesh: MeshInstance3D = $"BlockTest/Куб"
@onready var Total_Block : int = 0
var textures: Array[Texture2D] = []
func _ready():
var atlas: CompressedTexture2D = load(atlas_path)
var atlas_image: Image = atlas.get_image()
var texture_width: int = 18
var texture_height: int = 18
var atlas_width: int = atlas_image.get_width()
var atlas_height: int = atlas_image.get_height()
var num_textures_x: int = atlas_width / texture_width
var num_textures_y: int = atlas_height / texture_height
for y in num_textures_y:
for x in num_textures_x:
var rect: Rect2i = Rect2i(x * texture_width, y * texture_height, texture_width, texture_height)
var sub_image: Image = atlas_image.get_region(rect)
var sub_texture: ImageTexture = ImageTexture.create_from_image(sub_image)
textures.append(sub_texture)
print("Texture added at:", x, y)
if cube_mesh and textures.size() > 0:
cube_mesh.material_override.albedo_texture = textures[Total_Block]
else:
printerr("MeshInstance3D or textures not found.")```
*GridMap script
```extends GridMap
@export var block_scene: PackedScene # Reference to your block scene (.tscn)
var block_names = {} # Dictionary to store block names by coordinates
func destroy_block(world_coordinate):
var map_coordinate = local_to_map(world_coordinate)
if block_names.has(map_coordinate):
var block_name = block_names[map_coordinate]
var cell_content = get_node(block_name)
if cell_content:
cell_content.queue_free()
block_names.erase(map_coordinate) # Remove the name from the dictionary
set_cell_item(map_coordinate, -1) # Remove the block from GridMap
func place_block(world_coordinate, block_index):
var map_coordinate = local_to_map(world_coordinate)
# If there's already a block at this coordinate, remove it
if block_names.has(map_coordinate):
destroy_block(world_coordinate)
# Create an instance of the block scene:
var block_instance = block_scene.instantiate()
# Move the block to the correct position
block_instance.global_transform.origin = world_coordinate
# Give the block a name so we can delete it
var block_name = "block_" + str(map_coordinate.x) + "_" + str(map_coordinate.y) + "_" + str(map_coordinate.z)
block_instance.name = block_name
# Add the block to the scene
add_child(block_instance)
# Store the block name in the dictionary
block_names[map_coordinate] = block_name
# Set the cell item in GridMap
set_cell_item(map_coordinate, 0) # Set the cell item value to something other than -1```
*Part of the player's script for building
``` func _physics_process(delta: float) -> void:
if Input.is_action_just_pressed("left_click") or destroy_button.is_pressed():
if ray_blocks_create.is_colliding():
var collider = ray_blocks_create.get_collider() # Get the collider
if collider.has_method("destroy_block"):
print("Found destroy_block")
# Check that the method is actually called, and what happens when it's called
collider.destroy_block(ray_blocks_create.get_collision_point() -
ray_blocks_create.get_collision_normal())
else:
print("destroy_block NOT found on the collider!")
else:
print("The ray did NOT collide with anything when trying to destroy") # Check if a collision occurs at all
if Input.is_action_just_pressed("right_click") or create_button.is_pressed():
if ray_blocks_create.is_colliding():
var collider = ray_blocks_create.get_collider()
if collider.has_method("place_block"):
print("Found place_block")
# Check that the method is actually called, and what happens when it's called
collider.place_block(ray_blocks_create.get_collision_point() +
ray_blocks_create.get_collision_normal(), 0)
else:
print("place_block NOT found on the collider!")
else:
print("The ray did NOT collide with anything when trying to create") # Check if a collision occurs at all```
Thank you so much in advance for help!