Snippets

michael b nium's 3d effect in godot

Created by michael b last modified
#######################################
# Simple implementation of layered sprites technique, to achieve a voxel-like
# isometric effect.
# More info about what inspired this at: http://michaelb.org/niums-3d-effect-in-godot/
#
# Public Domain - michaelb (http://michaelb.org/)
#######################################

# To use this, simply set it as a script on a Node2D.
# It could probably be optimized by pre-rendering each direction onto a texture.

# changing the direction will cause it to achieve the rotation effect
export(int, 0, 360) var direction = 0 setget set_direction

# set spritesheet to be a single (horizontal) spritesheet containing every layer
export(ImageTexture) var spritesheet = null setget set_spritesheet

# layer_count is the number of layers (e.g. frames) contained by the spritesheet
export(int, 0, 100) var layer_count = 0 setget set_layer_count

# offset is the number of pixels to offset each layer
export(int, 0, 100) var offset = 1 setget set_offset

var sprites = []
func set_direction(new_value):
    direction = new_value
    _refresh_direction()

func set_offset(new_value):
    offset = new_value
    _refresh_direction()

func set_layer_count(new_value):
    layer_count = new_value
    _refresh_sprites()
    _refresh_direction()

func set_spritesheet(new_value):
    spritesheet = new_value
    _refresh_sprites()
    _refresh_direction()

func _ready():
    _refresh_sprites()
    _refresh_direction()

func _refresh_sprites():
    sprites = []
    # First remove existing children
    for child in get_children():
        remove_child(child)

    # Then add new sprites
    for layer in range(layer_count):
        var sprite = Sprite.new()
        sprite.set_texture(spritesheet)
        sprite.set_hframes(layer_count)
        sprite.set_frame(layer)
        sprites.append(sprite)
        add_child(sprite)

func _refresh_direction():
    for layer in range(layer_count):
        if layer >= sprites.size():
            # layer_count hasn't yet been set
            return
        var sprite = sprites[layer]
        sprite.set_rotd(direction)
        sprite.set_pos(Vector2(0, layer * -offset))

Comments (0)