NJL64 resources. You put the color as a resource, then upon you instantiate the scene you set the color.
You can premake the colors/materials and save them as resource .tres file and then preload and set it on the scene.
Add a script to the scene you instantiate and in _ready() function you set the colors you have in the exported vars.
As an example:
Make materials. I just change Albedo color and save as resource



Create scene. I just create coin mesh cylinder, animate so it rotates and up down.

Click on the premade materials, hold CTRL and drag n drop into the script and it will make preload() links for you.
extends Node3D
@onready var coin_mesh: MeshInstance3D = $CoinMesh
var colors_array:Array
@onready var animation_player: AnimationPlayer = $AnimationPlayer
const GREEN = preload("uid://qpxh3c0juaiv")
const ORANGE = preload("uid://c0m1ku1hxstnd")
const PURPLE = preload("uid://d3qywapf3ww4w")
const YELLOW = preload("uid://y0x76veic6lq")
func _ready() -> void:
colors_array = [GREEN,ORANGE,PURPLE,YELLOW]
var rnd_mat:Material = get_mat(colors_array)
coin_mesh.set_surface_override_material(0,rnd_mat)
animation_player.play("coin_rotate_updown") # Custom animation
func get_mat(_colors_array) -> Material:
var rnd = randi_range(0, 3)
return _colors_array[rnd]
Click on the premade coin scene, hold CTRL and drag n drop into the script and it will make preload() link for you.
Now add to player or whatever a key that trigger function:
const COIN = preload("uid://wu6fk2dw1p06")
func _process(delta):
if Input.is_action_just_pressed("k_interact"):
spawn_coin()
func spawn_coin():
print("Spawn coin")
var world:Node3D = self.owner # From My player character that is a child of my world scene
var new_coin:Node3D = COIN.instantiate()
new_coin.global_transform = self.global_transform
new_coin.position += Vector3(1,1,1)
world.add_child(new_coin)