How to extend repeating texture towards point

Godot Version

v4.7.stable.official [5b4e0cb0f]

Question

I’m trying to create an attack animation for a turn-based battle game in a 3D environment but with 2D sprites and all battlers are on the same plane. The animation involves extending a long, tongue-like projection from the player sprite towards an enemy, then retracting and pulling the enemy towards the player. The tongue consists of a base sprite, a repeating middle sprite, and a tip sprite. I’ve tried to find tutorials online of extending ropes or beams but everything I’ve seen pertains to physics ropes or particle effects. This doesn’t need physics, it just needs to extend in a line while repeating a middle-section sprite of constant size. How can I do this? What type of node (presumably a MeshInstance3D) is appropriate and what commands can stretch out the tongue in the desired direction over the course of a given amount of time (ex: 1 second)?

Are your sprites in 3D space or are they in a CanvasLayer/Control? If they’re in a canvas layer, you can use a ninePatchPanel

All the characters in the game are Sprite3Ds. The tongue itself doesn’t have to be a sprite3D it could be a mesh or something. I’ll keep that in mind for 2D stuff though!

Scale the UVs proportionally to object scaling.

How do I access the UV scales in the code, like if I wanted to lerp them?

It’s a property of the standard material.

Thank you for the quick response! I figured out how to access those variables, however, I’m not sure I’m able to visually nail it. In the code below I’m trying to grow the mesh size and the uv1_scale.x at the same time and rate while simultaneously moving the object’s position towards the midpoint of the player and the target. The issue now appears to be that the UV scale and the size are growing at different paces so the size of one tongue-section sprite is not constant, and midsection of the tongue outpaces and moves past the tip of the tongue, which is a different sprite. What’s the correct way to proportionally scale the UV scale of the tongue sprite to the scale of the tongue mesh?

extends MeshInstance3D

@export var length: float
@export var start = Vector3(-1.618,-0.906,0.0)
@export var end = Vector3(3,3,0)
var half_or_full = 1
var duration
var elapsed = 0.0
var moving = false
var target_length
var mat = mesh.material

func _ready():
	tongue = mesh.duplicate()
	mesh = tongue
	
	mat = tongue.material.duplicate()
	
	tongue.material = mat
	#mat.cull_mode = BaseMaterial3D.CULL_DISABLED
	tongue.size = 0.0
	mat.uv1_offset.x = 0.0

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	if moving:
		elapsed += delta
		var t = clamp(elapsed / duration, 0.0, 1.0)
		
		
		mesh.size = lerp(mesh.size, target_length, t)
		mat.uv1_offset.x = lerp(mat.uv1_offset.x, target_length, t)
		global_position = start.lerp(end, t/half_or_full)
		if t >= 1.0:
			moving = false
			emit_signal("movement_finished")

func start_moving_time(destination1: Vector3, destination2: Vector3, time: float, journey : String = "half"):
	start = destination1
	end = destination2
	duration = time
	elapsed = 0.0
	moving = true
	match journey:
		"full":
			half_or_full = 1
		"half":
			half_or_full = 2
	
	target_length = start.distance_to(end)

Scale the mesh instance instead of changing mesh size.