Making instances have unique textures/next_pass textures in GDScript

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

Hi,
So I’m attempting some sort of card game that totally isn’t a rip-off of Uno.
Anyway to save on making 108 different textures I’ve instead made a base card texture, textures of 4 colours and a multicolour for the middle layer, and textures of numbers 0-9, “wild”, “+2” and “+4” for the top layer.
This reduces it to 19 textures. Much nicer :slight_smile:

I can apply these fine in the editor by stacking Next Pass in the mesh material and setting the render priority and the transparent flag where appropriate, but for the life of me I can’t generate cards properly in code.

I’m actually facing 2 issues here:
1) How do I do stacked next_pass properly in GDScript?

2) How do I make each of the cards generated have unique materials?

So, on question 1, I have a scene that is just a CGSMesh named “Card” with a quad primitive in it that’s card-shaped, that mesh has a SpatialMaterial with the base card texture applied that I want to be common to all cards. The layered textures/next_pass Spatialmaterials are all applied inside here This is fine looking at, and editing, it in the editor. This is my existing code attached to that CGSMesh named “Card”:

extends CSGMesh

var color_name
var card_type

# Called when the node enters the scene tree for the first time.
func _ready():
	pass # Replace with function body.

func init(color_name, color_tex, card_type, card_type_tex):
	self.color_name = color_name
	self.card_type = card_type

	var type_mat = SpatialMaterial.new()
	type_mat.flags_transparent = true
	type_mat.albedo_texture = card_type_tex
	type_mat.render_priority = 2
	
	var color_mat = SpatialMaterial.new()
	color_mat.flags_transparent = true
	color_mat.albedo_texture = card_type_tex
	color_mat.render_priority = 1
	
	color_mat.set_next_pass(type_mat)
	mesh.material.set_next_pass(color_mat)

Note I have also tried to swap these last 2 lines for
mesh.material.set_next_pass(color_mat)
mesh.material.next_pass.set_next_pass(type_mat) with no change to the outcome.

This init() is summoned by the _read() func of the sscript that lives in the root node of the main scene (I’ll later replace this with an actual deck generator instead of whatever this test nonsense is):

func _ready():
	var base_card = load("res://Card.tscn")
	var color_texs = {
		"yellow": load("res://CardTextures/YellowLayer.png")
		# - snip for brevity -
	}
	var types = {
		"0": load("res://CardTextures/0Layer.png"),
		"1": load("res://CardTextures/1Layer.png"),
		"2": load("res://CardTextures/2Layer.png"),
		"3": load("res://CardTextures/3Layer.png"),
		"4": load("res://CardTextures/4Layer.png")
		# - snip for brevity -
	}
	for i in range(5):
	# generate 5 multicoloured cards 0-4 as a test :)
		var new_card = base_card.instance()
		new_card.translation.y = i
		new_card.init("yellow", color_texs["multi"], str(i), types[str(i)])
		add_child(new_card)

So for whatever reason this just doesn’t work right. I already know I’m missing whatever I need to make the cards unique but even with all the cards being the same this fails to layer the textures correctly.
The “type” e.g. the numbers renders correctly above the base layer but for whatever reason the coloured layer doesn’t show up to the party. Switching the render priority values did nothing.

See here the result of that:
enter image description here
The number and boarder line are of course separate textures. I’m just missing the in-between layer.

Question 2 is of course, having fixed the above, how do I go about making each instance of the cards generated in code have a unique set of textures? A question that has been asked many times I’m sure, so I apologise for that, but I couldn’t get other answers working and as such have removed my attempts from the code here.

Thank you :slight_smile:

You could try duplicate the node and apply different next_passes.

sairam123 | 2021-02-21 16:44