• Godot Help3D
  • how to play sprite3D and set the frame speed thru code?

speed var doesn't do anything

im also getting this error

E 0:00:01:0214 _process: Index p_frame = 32 is out of bounds (int64_t(vframes) * hframes = 32).
<C++ Bron> scene/3d/sprite_3d.cpp:702 @ set_frame()
<Stack Trace> 3dspriteplay.gd:13 @ _process()

while hframes is 4
and vframes is 8 ,

@export var h = 0
@export var v = 0
@export var speed = 1.0

func _ready():
	frame = 0

func _process(_delta):
	if (frame <= h*v):
		frame += 1 * speed
	else:
		queue_free()```

also, is there a way to export files like scenes and assets between projects?

    DJM also, is there a way to export files like scenes and assets between projects?

    I have a plugin for this, but it doesn't work on windows yet.

    • DJM replied to this.

      spacecloud ive just copied the assets to the other project and its dependencies for now

      im trying to scroll thru a sprite sheet thru code which i will place on a mesh
      i have no clue on how to make it work
      its 4*8
      so im adjusting the UV offset of the material.
      how do i sample thru each row?

      
      @export var speed = 0.1
      @export var scaleU = 0.25
      @export var scaleV = 0.125
      var myMat = Material
      var uvscale = Vector3.ZERO
      var uvoffset = Vector3.ZERO
      var offsetU = 0.0
      var offsetV = 0.0
      var time = 0.0
      
      func _ready():
      	myMat = self.get_active_material(0)
      	uvscale = Vector3(scaleU,scaleV,1.0)
      	myMat.set_uv1_scale(uvscale)
      	uvoffset = Vector3(0.0,0.0,0.0)
      	myMat.set_uv1_offset(uvoffset)
      	offsetV = 0.0
      
      func _process(delta):
      	time += delta
      	if time > speed:
      		offsetU += scaleU
      		offsetV += scaleV
      	
      		time = 0.0
      		
      	uvoffset = Vector3(offsetU,offsetV,0.0)
      	myMat.set_uv1_offset(uvoffset)
      `

      is this right?
      Sprite3D

      @tool
      extends Sprite3D
      
      var time : float
      ## Seconds per frame.
      @export_range(0.0, 1.0, 0.01, &"or_greater") var speed : float = 0.1
      
      func _process(delta: float) -> void:
      	time += delta
      	if time >= speed:
      		frame = wrapi(frame + 1, 0, (hframes * vframes))
      		time = 0.0

      MeshInstance3D
      script:

      @tool
      extends MeshInstance3D
      
      var frame : int = 0 :
      	set(value):
      		material.set_shader_parameter("frame", Vector2i(value % frames.x, value / frames.x))
      		frame = value
      
      var total_frames : int
      
      var time : float = 0.0
      
      var material : ShaderMaterial
      ## seconds per frame.
      @export_range(0.0, 1.0, 0.1, &"or_greater") var speed : float = 0.1
      ## don't make either axis 0
      @export var frames := Vector2i.ONE :
      	set(value):
      		var a := Vector2i(clampi(value.x, 1, 512), clampi(value.y, 1, 512))
      		total_frames = a.x * a.y
      		material.set_shader_parameter("frames", a)
      		frames = a
      
      func _ready() -> void:
      	material = get_active_material(0)
      
      
      func _process(delta: float) -> void:
      	time += delta
      	if time >= speed:
      		frame = wrapi(frame + 1, 0, total_frames)
      		time = 0.0

      example shader:

      shader_type spatial;
      
      uniform sampler2D color;
      uniform ivec2 frame;
      uniform ivec2 frames;
      
      void fragment() {
      	vec2 frame_size = vec2(1.0) / vec2(frames);
      	vec2 uv = (UV * frame_size) + (frame_size * vec2(frame));
      	ALBEDO = texture(color, uv).rgb;
      	ALPHA = texture(color, uv).a;
      }
      • DJM replied to this.

        spacecloud tnx for your time !
        but i'm trying to animate a texture thru uv offset on a custom mesh , i cant use frames.
        i first thought using a sprite3d was a good idea but then i needed to disabled culling which is bad for performance . and also using the uv offset lets me use custom curved meshed etc.
        so i currently have a blood splat fx texture sheet thats 4* 8(32 frames) . so offset x should be 0.25 and offset y should be 0.125. im trying to figure out on how to iterate thru the whole sprite sheet by time using the offset of the spatial material.

        made it work
        heres' the script in case someone wants to do the same

        
        @export var speed = 0.1
        @export var framesH = 4.0
        @export var framesV = 8.0
        var myMat = Material
        var uvscale = Vector3.ZERO
        var uvoffset = Vector3.ZERO
        var offsetU = 0.0
        var offsetV = 0.0
        var time = 0.0
        
        func _ready():
        	myMat = self.get_active_material(0)
        	uvscale = Vector3(1.0/framesH,1.0/framesV,1.0)
        	myMat.set_uv1_scale(uvscale)
        	uvoffset = Vector3(0.0,0.0,0.0)
        	myMat.set_uv1_offset(uvoffset)
        	offsetV = 0.0
        
        func _process(delta):
        	time += delta
        	
        	if time > speed :
        		time = 0.0
        		offsetU += 1.0/framesH
        		
        		if offsetU == 1.0:
        			shiftrow()
        			if offsetV == 1 and offsetU == 1:
        				queue_free()
        			offsetU = 0.0
        	
        	uvoffset = Vector3(offsetU,offsetV,0.0)
        	myMat.set_uv1_offset(uvoffset)
        func shiftrow():
        	offsetV += 1.0/framesV