init commit

This commit is contained in:
2025-04-26 10:41:46 -05:00
commit 8a1166fc19
94 changed files with 4374 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
@tool
extends RefCounted
const _Result = preload("../result.gd").Class
const _Common = preload("../common.gd")
const _Options = preload("../options.gd")
class ImportResult:
extends _Result
var resource: Resource
var resource_saver_flags: ResourceSaver.SaverFlags
func _get_result_type_description() -> String:
return "Import"
func success(
resource: Resource,
resource_saver_flags: ResourceSaver.SaverFlags = ResourceSaver.FLAG_NONE
) -> void:
_success()
self.resource = resource
self.resource_saver_flags = resource_saver_flags
var __options: Array[Dictionary] = [
_Options.create_option(_Options.DEFAULT_ANIMATION_NAME, "default",
PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT),
_Options.create_option(_Options.DEFAULT_ANIMATION_DIRECTION, _Common.AnimationDirection.FORWARD,
PROPERTY_HINT_ENUM, ",".join(_Common.ANIMATION_DIRECTIONS_NAMES), PROPERTY_USAGE_DEFAULT),
_Options.create_option(_Options.DEFAULT_ANIMATION_REPEAT_COUNT, 0,
PROPERTY_HINT_RANGE, "0,,1,or_greater", PROPERTY_USAGE_DEFAULT),
_Options.create_option(_Options.AUTOPLAY_ANIMATION_NAME, "",
PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT),
_Options.create_option(_Options.ATLAS_TEXTURES_REGION_FILTER_CLIP_ENABLED, false,
PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT),
]
var __name: String
var __resource_type: StringName
var __save_extension: String
func _init(
name: String,
resource_type: String,
save_extension: String,
options: Array[Dictionary] = []) -> void:
__name = name
__resource_type = resource_type
__save_extension = save_extension
__options.append_array(options)
func get_name() -> String:
return __name
func get_resource_type() -> StringName:
return __resource_type
func get_save_extension() -> String:
return __save_extension
func get_options() -> Array[Dictionary]:
return __options
func import(
source_file_path: String,
atlas: Texture2D,
sprite_sheet: _Common.SpriteSheetInfo,
animation_library: _Common.AnimationLibraryInfo,
options: Dictionary,
save_path: String) -> ImportResult:
assert(false, "This method is abstract and must be overriden.")
var result: ImportResult = ImportResult.new()
result.fail(ERR_UNCONFIGURED, "This method is abstract and must be overriden.")
return result

View File

@@ -0,0 +1 @@
uid://cnw6e1ikxkc4j

View File

@@ -0,0 +1,14 @@
@tool
extends "_.gd"
func _init(
name: String,
resource_type: String,
save_extension: String,
options: Array[Dictionary] = []
) -> void:
options.append_array([
_Options.create_option(_Options.ROOT_NODE_NAME, "",
PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT),
])
super(name, resource_type, save_extension, options)

View File

@@ -0,0 +1 @@
uid://bsmnxi7wqyckj

View File

@@ -0,0 +1,64 @@
@tool
extends "_node.gd"
class TrackFrame:
extends RefCounted
var duration: float
var value: Variant
func _init(duration: float, value: Variant) -> void:
self.duration = duration
self.value = value
static func _create_animation_player(
animation_library_info: _Common.AnimationLibraryInfo,
track_value_getters_by_property_path: Dictionary
) -> AnimationPlayer:
var animation_player: AnimationPlayer = AnimationPlayer.new()
animation_player.name = "AnimationPlayer"
var animation_library: AnimationLibrary = AnimationLibrary.new()
for animation_info in animation_library_info.animations:
var animation: Animation = Animation.new()
var frames: Array[_Common.FrameInfo] = animation_info.get_flatten_frames()
for property_path in track_value_getters_by_property_path.keys():
__create_track(animation, property_path,
frames, track_value_getters_by_property_path[property_path])
animation.length = 0
for frame in frames:
animation.length += frame.duration
animation.loop_mode = Animation.LOOP_LINEAR if animation_info.repeat_count == 0 else Animation.LOOP_NONE
animation_library.add_animation(animation_info.name, animation)
animation_player.add_animation_library("", animation_library)
if animation_library_info.autoplay_index >= 0:
animation_player.autoplay = animation_library_info \
.animations[animation_library_info.autoplay_index].name
return animation_player
static func __create_track(
animation: Animation,
property_path: NodePath,
frames: Array[_Common.FrameInfo],
track_value_getter: Callable # func(f: FrameModel) -> Variant for each f in frames
) -> int:
var track_index = animation.add_track(Animation.TYPE_VALUE)
animation.track_set_path(track_index, property_path)
animation.value_track_set_update_mode(track_index, Animation.UPDATE_DISCRETE)
animation.track_set_interpolation_loop_wrap(track_index, false)
animation.track_set_interpolation_type(track_index, Animation.INTERPOLATION_NEAREST)
var track_frames = frames.map(func (frame: _Common.FrameInfo):
return TrackFrame.new(frame.duration, track_value_getter.call(frame)))
var transition: float = 1
var track_length: float = 0
var previous_track_frame: TrackFrame = null
for track_frame in track_frames:
if previous_track_frame == null or track_frame.value != previous_track_frame.value:
animation.track_insert_key(track_index, track_length, track_frame.value, transition)
previous_track_frame = track_frame
track_length += track_frame.duration
return track_index

View File

@@ -0,0 +1 @@
uid://c5tklyam00r8k

View File

@@ -0,0 +1,27 @@
@tool
extends "_node_with_animation_player.gd"
const ANIMATION_STRATEGIES_NAMES: PackedStringArray = [
"Animate sprite's region and offset",
"Animate single atlas texture's region and margin",
"Animate multiple atlas textures instances",
]
enum AnimationStrategy {
SPRITE_REGION_AND_OFFSET = 0,
SINGLE_ATLAS_TEXTURE_REGION_AND_MARGIN = 1,
MULTIPLE_ATLAS_TEXTURES_INSTANCES = 2,
}
func _init(
name: String,
resource_type: String,
save_extension: String,
options: Array[Dictionary] = []
) -> void:
options.append_array([
_Options.create_option(_Options.ANIMATION_STRATEGY, AnimationStrategy.SPRITE_REGION_AND_OFFSET,
PROPERTY_HINT_ENUM, ",".join(ANIMATION_STRATEGIES_NAMES), PROPERTY_USAGE_DEFAULT),
_Options.create_option(_Options.SPRITE_CENTERED, false,
PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT),
])
super(name, resource_type, save_extension, options)

View File

@@ -0,0 +1 @@
uid://jpcaxy1f6srb

View File

@@ -0,0 +1,45 @@
@tool
extends "_node.gd"
const _SpriteFramesImporter = preload("sprite_frames.gd")
var __sprite_frames_importer: _SpriteFramesImporter
func _init() -> void:
super("AnimatedSprite2D", "PackedScene", "scn")
__sprite_frames_importer = _SpriteFramesImporter.new()
func import(
res_source_file_path: String,
atlas: Texture2D,
sprite_sheet: _Common.SpriteSheetInfo,
animation_library: _Common.AnimationLibraryInfo,
options: Dictionary,
save_path: String
) -> ImportResult:
var result: ImportResult = ImportResult.new()
var sprite_frames_import_result: ImportResult = __sprite_frames_importer \
.import(res_source_file_path, atlas, sprite_sheet, animation_library, options, save_path)
if sprite_frames_import_result.error:
return sprite_frames_import_result
var sprite_frames: SpriteFrames = sprite_frames_import_result.resource
var animated_sprite: AnimatedSprite2D = AnimatedSprite2D.new()
var node_name: String = options[_Options.ROOT_NODE_NAME].strip_edges()
animated_sprite.name = res_source_file_path.get_file().get_basename() \
if node_name.is_empty() else node_name
animated_sprite.sprite_frames = sprite_frames
if animation_library.autoplay_index >= 0:
if animation_library.autoplay_index >= animation_library.animations.size():
result.fail(ERR_INVALID_DATA, "Autoplay animation index overflow")
return result
animated_sprite.autoplay = animation_library \
.animations[animation_library.autoplay_index].name
var packed_scene: PackedScene = PackedScene.new()
packed_scene.pack(animated_sprite)
result.success(packed_scene,
ResourceSaver.FLAG_COMPRESS | ResourceSaver.FLAG_BUNDLE_RESOURCES)
return result

View File

@@ -0,0 +1 @@
uid://byeghoxxqevfp

View File

@@ -0,0 +1,42 @@
@tool
extends "_node.gd"
const _SpriteFramesImporter = preload("sprite_frames.gd")
var __sprite_frames_importer: _SpriteFramesImporter
func _init() -> void:
super("AnimatedSprite3D", "PackedScene", "scn")
__sprite_frames_importer = _SpriteFramesImporter.new()
func import(
res_source_file_path: String,
atlas: Texture2D,
sprite_sheet: _Common.SpriteSheetInfo,
animation_library: _Common.AnimationLibraryInfo,
options: Dictionary,
save_path: String
) -> ImportResult:
var result: ImportResult = ImportResult.new()
var sprite_frames_import_result: ImportResult = __sprite_frames_importer \
.import(res_source_file_path, atlas, sprite_sheet, animation_library, options, save_path)
if sprite_frames_import_result.error:
return sprite_frames_import_result
var sprite_frames: SpriteFrames = sprite_frames_import_result.resource
var animated_sprite: AnimatedSprite3D = AnimatedSprite3D.new()
var node_name: String = options[_Options.ROOT_NODE_NAME].strip_edges()
animated_sprite.name = res_source_file_path.get_file().get_basename() \
if node_name.is_empty() else node_name
animated_sprite.sprite_frames = sprite_frames
if animation_library.autoplay_index >= 0:
animated_sprite.autoplay = animation_library \
.animations[animation_library.autoplay_index].name
var packed_scene: PackedScene = PackedScene.new()
packed_scene.pack(animated_sprite)
result.success(packed_scene,
ResourceSaver.FLAG_COMPRESS | ResourceSaver.FLAG_BUNDLE_RESOURCES)
return result

View File

@@ -0,0 +1 @@
uid://bg331u3nm4w8o

View File

@@ -0,0 +1,94 @@
@tool
extends "_sprite_with_animation_player.gd"
func _init() -> void:
super("Sprite2D with AnimationPlayer", "PackedScene", "scn")
func import(
res_source_file_path: String,
atlas: Texture2D,
sprite_sheet: _Common.SpriteSheetInfo,
animation_library: _Common.AnimationLibraryInfo,
options: Dictionary,
save_path: String
) -> ImportResult:
var result: ImportResult = ImportResult.new()
var sprite_size: Vector2i = sprite_sheet.source_image_size
var sprite: Sprite2D = Sprite2D.new()
var node_name: String = options[_Options.ROOT_NODE_NAME].strip_edges()
sprite.name = res_source_file_path.get_file().get_basename() \
if node_name.is_empty() else node_name
sprite.centered = options[_Options.SPRITE_CENTERED]
var filter_clip_enabled: bool = options[_Options.ATLAS_TEXTURES_REGION_FILTER_CLIP_ENABLED]
var animation_player: AnimationPlayer
match options[_Options.ANIMATION_STRATEGY]:
AnimationStrategy.SPRITE_REGION_AND_OFFSET:
sprite.texture = atlas
sprite.region_enabled = true
animation_player = _create_animation_player(animation_library, {
".:offset": func(frame: _Common.FrameInfo) -> Vector2:
return \
Vector2(frame.sprite.offset) - 0.5 * (frame.sprite.region.size - sprite_size) \
if sprite.centered else \
frame.sprite.offset,
".:region_rect": func(frame: _Common.FrameInfo) -> Rect2:
return Rect2(frame.sprite.region) })
AnimationStrategy.SINGLE_ATLAS_TEXTURE_REGION_AND_MARGIN:
var atlas_texture: AtlasTexture = AtlasTexture.new()
atlas_texture.filter_clip = filter_clip_enabled
atlas_texture.resource_local_to_scene = true
atlas_texture.atlas = atlas
atlas_texture.region = Rect2(0, 0, 1, 1)
atlas_texture.margin = Rect2(2, 2, 0, 0)
sprite.texture = atlas_texture
animation_player = _create_animation_player(animation_library, {
".:texture:margin": func(frame: _Common.FrameInfo) -> Rect2:
return \
Rect2(frame.sprite.offset,
sprite_size - frame.sprite.region.size) \
if frame.sprite.region.has_area() else \
Rect2(2, 2, 0, 0),
".:texture:region": func(frame: _Common.FrameInfo) -> Rect2:
return Rect2(frame.sprite.region) if frame.sprite.region.has_area() else Rect2(0, 0, 1, 1) })
AnimationStrategy.MULTIPLE_ATLAS_TEXTURES_INSTANCES:
var atlas_textures: Array[AtlasTexture]
var empty_atlas_texture: AtlasTexture = AtlasTexture.new()
empty_atlas_texture.filter_clip = filter_clip_enabled
empty_atlas_texture.atlas = atlas
empty_atlas_texture.region = Rect2(0, 0, 1, 1)
empty_atlas_texture.margin = Rect2(2, 2, 0, 0)
animation_player = _create_animation_player(animation_library, {
".:texture": func(frame: _Common.FrameInfo) -> Texture2D:
if not frame.sprite.region.has_area():
return empty_atlas_texture
var region: Rect2 = frame.sprite.region
var margin: Rect2 = Rect2(
frame.sprite.offset,
sprite_size - frame.sprite.region.size)
var equivalent_atlas_textures: Array = atlas_textures.filter(
func(t: AtlasTexture) -> bool: return t.margin == margin and t.region == region)
if not equivalent_atlas_textures.is_empty():
return equivalent_atlas_textures.front()
var atlas_texture: AtlasTexture = AtlasTexture.new()
atlas_texture.atlas = atlas
atlas_texture.filter_clip = filter_clip_enabled
atlas_texture.region = region
atlas_texture.margin = margin
atlas_textures.append(atlas_texture)
return atlas_texture})
sprite.add_child(animation_player)
animation_player.owner = sprite
var packed_scene: PackedScene = PackedScene.new()
packed_scene.pack(sprite)
result.success(packed_scene,
ResourceSaver.FLAG_COMPRESS | ResourceSaver.FLAG_BUNDLE_RESOURCES)
return result

View File

@@ -0,0 +1 @@
uid://dbik163y6wqp

View File

@@ -0,0 +1,97 @@
@tool
extends "_sprite_with_animation_player.gd"
func _init() -> void:
super("Sprite3D with AnimationPlayer", "PackedScene", "scn")
func import(
res_source_file_path: String,
atlas: Texture2D,
sprite_sheet: _Common.SpriteSheetInfo,
animation_library: _Common.AnimationLibraryInfo,
options: Dictionary,
save_path: String
) -> ImportResult:
var result: ImportResult = ImportResult.new()
var sprite_size: Vector2i = sprite_sheet.source_image_size
var sprite: Sprite3D = Sprite3D.new()
var node_name: String = options[_Options.ROOT_NODE_NAME].strip_edges()
sprite.name = res_source_file_path.get_file().get_basename() \
if node_name.is_empty() else node_name
sprite.centered = options[_Options.SPRITE_CENTERED]
var filter_clip_enabled: bool = options[_Options.ATLAS_TEXTURES_REGION_FILTER_CLIP_ENABLED]
var animation_player: AnimationPlayer
match options[_Options.ANIMATION_STRATEGY]:
AnimationStrategy.SPRITE_REGION_AND_OFFSET:
sprite.texture = atlas
sprite.region_enabled = true
animation_player = _create_animation_player(animation_library, {
".:offset": func(frame: _Common.FrameInfo) -> Vector2:
return Vector2( # spatial sprite offset (the Y-axis is Up-directed)
frame.sprite.offset.x,
sprite_size.y - frame.sptite.offset.y -
frame.sprite.region.size.y) + \
# add center correction
((Vector2(frame.sprite.region.size - sprite_size) * 0.5)
if sprite.centered else Vector2.ZERO),
".:region_rect": func(frame: _Common.FrameInfo) -> Rect2:
return Rect2(frame.sprite.region) })
AnimationStrategy.SINGLE_ATLAS_TEXTURE_REGION_AND_MARGIN:
var atlas_texture: AtlasTexture = AtlasTexture.new()
atlas_texture.filter_clip = filter_clip_enabled
atlas_texture.resource_local_to_scene = true
atlas_texture.atlas = atlas
atlas_texture.region = Rect2(0, 0, 1, 1)
atlas_texture.margin = Rect2(2, 2, 0, 0)
sprite.texture = atlas_texture
animation_player = _create_animation_player(animation_library, {
".:texture:margin": func(frame: _Common.FrameInfo) -> Rect2:
return \
Rect2(frame.sprite.offset,
sprite_size - frame.sprite.region.size) \
if frame.sprite.region.has_area() else \
Rect2(2, 2, 0, 0),
".:texture:region": func(frame: _Common.FrameInfo) -> Rect2:
return Rect2(frame.sprite.region) if frame.sprite.region.has_area() else Rect2(0, 0, 1, 1) })
AnimationStrategy.MULTIPLE_ATLAS_TEXTURES_INSTANCES:
var atlas_textures: Array[AtlasTexture]
var empty_atlas_texture: AtlasTexture = AtlasTexture.new()
empty_atlas_texture.filter_clip = filter_clip_enabled
empty_atlas_texture.atlas = atlas
empty_atlas_texture.region = Rect2(0, 0, 1, 1)
empty_atlas_texture.margin = Rect2(2, 2, 0, 0)
animation_player = _create_animation_player(animation_library, {
".:texture": func(frame: _Common.FrameInfo) -> Texture2D:
if not frame.sprite.region.has_area():
return empty_atlas_texture
var region: Rect2 = frame.sprite.region
var margin: Rect2 = Rect2(
frame.sprite.offset,
sprite_size - frame.sprite.region.size)
var equivalent_atlas_textures: Array = atlas_textures.filter(
func(t: AtlasTexture) -> bool: return t.margin == margin and t.region == region)
if not equivalent_atlas_textures.is_empty():
return equivalent_atlas_textures.front()
var atlas_texture: AtlasTexture = AtlasTexture.new()
atlas_texture.atlas = atlas
atlas_texture.filter_clip = filter_clip_enabled
atlas_texture.region = region
atlas_texture.margin = margin
atlas_textures.append(atlas_texture)
return atlas_texture})
sprite.add_child(animation_player)
animation_player.owner = sprite
var packed_scene: PackedScene = PackedScene.new()
packed_scene.pack(sprite)
result.success(packed_scene,
ResourceSaver.FLAG_COMPRESS | ResourceSaver.FLAG_BUNDLE_RESOURCES)
return result

View File

@@ -0,0 +1 @@
uid://c3vtlehm0qj6s

View File

@@ -0,0 +1,64 @@
@tool
extends "_.gd"
func _init() -> void: super("SpriteFrames", "SpriteFrames", "res")
func import(
res_source_file_path: String,
atlas: Texture2D,
sprite_sheet: _Common.SpriteSheetInfo,
animation_library: _Common.AnimationLibraryInfo,
options: Dictionary,
save_path: String
) -> ImportResult:
var result: ImportResult = ImportResult.new()
var sprite_frames: SpriteFrames = SpriteFrames.new()
for animation_name in sprite_frames.get_animation_names():
sprite_frames.remove_animation(animation_name)
var filter_clip_enabled: bool = options[_Options.ATLAS_TEXTURES_REGION_FILTER_CLIP_ENABLED]
var atlas_textures: Array[AtlasTexture]
var empty_atlas_texture: AtlasTexture
for animation in animation_library.animations:
sprite_frames.add_animation(animation.name)
sprite_frames.set_animation_loop(animation.name, animation.repeat_count == 0)
sprite_frames.set_animation_speed(animation.name, 1)
var previous_texture: Texture2D
for frame in animation.get_flatten_frames():
var atlas_texture: AtlasTexture
if frame.sprite.region.has_area():
var region: Rect2 = frame.sprite.region
var margin: Rect2 = Rect2(
frame.sprite.offset,
sprite_sheet.source_image_size - frame.sprite.region.size)
var equivalent_atlas_textures: Array = atlas_textures.filter(
func(t: AtlasTexture) -> bool: return t.margin == margin and t.region == region)
if not equivalent_atlas_textures.is_empty():
atlas_texture = equivalent_atlas_textures.front()
if atlas_texture == null:
atlas_texture = AtlasTexture.new()
atlas_texture.filter_clip = filter_clip_enabled
atlas_texture.atlas = atlas
atlas_texture.region = region
atlas_texture.margin = margin
atlas_textures.push_back(atlas_texture)
else:
if empty_atlas_texture == null:
empty_atlas_texture = AtlasTexture.new()
empty_atlas_texture.filter_clip = filter_clip_enabled
empty_atlas_texture.atlas = atlas
empty_atlas_texture.region = Rect2(0, 0, 1, 1)
empty_atlas_texture.margin = Rect2(2, 2, 0, 0)
atlas_texture = empty_atlas_texture
if atlas_texture == previous_texture:
var last_frame_index: int = sprite_frames.get_frame_count(animation.name) - 1
sprite_frames.set_frame(animation.name, last_frame_index, atlas_texture,
sprite_frames.get_frame_duration(animation.name, last_frame_index) + frame.duration)
continue
sprite_frames.add_frame(animation.name, atlas_texture, frame.duration)
previous_texture = atlas_texture
result.success(sprite_frames,
ResourceSaver.FLAG_COMPRESS | ResourceSaver.FLAG_BUNDLE_RESOURCES)
return result

View File

@@ -0,0 +1 @@
uid://7divemm1kjo6

View File

@@ -0,0 +1,83 @@
@tool
extends "_.gd"
const __ANIMATION_MERGE_EQUAL_CONSEQUENT_FRAMES_OPTION: StringName = "animation/merge_equal_sonsequent_frames"
const __ANIMATION_FLATTEN_REPETITION_OPTION: StringName = "animation/flatten_repetition"
func _init() -> void: super("Sprite sheet (JSON)", "JSON", "res", [
_Options.create_option(__ANIMATION_MERGE_EQUAL_CONSEQUENT_FRAMES_OPTION, true,
PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT),
_Options.create_option(__ANIMATION_FLATTEN_REPETITION_OPTION, true,
PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT),
])
func import(
res_source_file_path: String,
atlas: Texture2D,
sprite_sheet: _Common.SpriteSheetInfo,
animation_library: _Common.AnimationLibraryInfo,
options: Dictionary,
save_path: String
) -> ImportResult:
var result: ImportResult = ImportResult.new()
var unique_indixes_by_sprites: Dictionary
var unique_sprite_index: int = 0
var sprites: Array[Dictionary]
for sprite in sprite_sheet.sprites:
if not unique_indixes_by_sprites.has(sprite):
unique_indixes_by_sprites[sprite] = unique_sprite_index
sprites.push_back({
region = sprite.region,
offset = sprite.offset
})
unique_sprite_index += 1
var flatten_animation_repetition: bool = options[__ANIMATION_FLATTEN_REPETITION_OPTION]
var merge_equal_consequent_frames: bool = options[__ANIMATION_MERGE_EQUAL_CONSEQUENT_FRAMES_OPTION]
var animations: Array[Dictionary]
for animation in animation_library.animations:
var frames_data: Array[Dictionary]
var frames: Array[_Common.FrameInfo] = \
animation.get_flatten_frames() \
if flatten_animation_repetition else \
animation.frames
var previous_sprite_index: int = -1
for frame in frames:
var sprite_index: int = unique_indixes_by_sprites[frame.sprite]
if merge_equal_consequent_frames and sprite_index == previous_sprite_index:
frames_data.back().duration += frame.duration
else:
frames_data.push_back({
sprite_index = sprite_index,
duration = frame.duration,
})
previous_sprite_index = sprite_index
animations.push_back({
name = animation.name,
direction =
_Common.AnimationDirection.FORWARD
if flatten_animation_repetition else
animation.direction,
repeat_count =
mini(1, animation.repeat_count)
if flatten_animation_repetition else
animation.repeat_count,
frames = frames_data,
})
var json: JSON = JSON.new()
json.data = {
sprite_sheet = {
atlas = atlas,
source_image_size = sprite_sheet.source_image_size,
sprites = sprites,
},
animation_library = {
animations = animations,
autoplay_index = animation_library.autoplay_index,
},
}
json.get_parsed_text()
result.success(json, ResourceSaver.FLAG_COMPRESS)
return result

View File

@@ -0,0 +1 @@
uid://cpbdxtrpuluxc

View File

@@ -0,0 +1,98 @@
@tool
extends "_node_with_animation_player.gd"
const ANIMATION_STRATEGIES_NAMES: PackedStringArray = [
"Animate single atlas texture's region and margin",
"Animate multiple atlas textures instances",
]
enum AnimationStrategy {
SINGLE_ATLAS_TEXTURE_REGION_AND_MARGIN = 1,
MULTIPLE_ATLAS_TEXTURES_INSTANCES = 2
}
func _init() -> void:
super("TextureRect with AnimationPlayer", "PackedScene", "scn", [
_Options.create_option(_Options.ANIMATION_STRATEGY, AnimationStrategy.SINGLE_ATLAS_TEXTURE_REGION_AND_MARGIN,
PROPERTY_HINT_ENUM, ",".join(ANIMATION_STRATEGIES_NAMES), PROPERTY_USAGE_DEFAULT),
])
func import(
res_source_file_path: String,
atlas: Texture2D,
sprite_sheet: _Common.SpriteSheetInfo,
animation_library: _Common.AnimationLibraryInfo,
options: Dictionary,
save_path: String
) -> ImportResult:
var result: ImportResult = ImportResult.new()
var texture_rect: TextureRect = TextureRect.new()
var node_name: String = options[_Options.ROOT_NODE_NAME].strip_edges()
texture_rect.name = res_source_file_path.get_file().get_basename() \
if node_name.is_empty() else node_name
texture_rect.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
var sprite_size: Vector2i = sprite_sheet.source_image_size
texture_rect.size = sprite_size
var filter_clip_enabled: bool = options[_Options.ATLAS_TEXTURES_REGION_FILTER_CLIP_ENABLED]
var animation_player: AnimationPlayer
match options[_Options.ANIMATION_STRATEGY]:
AnimationStrategy.SINGLE_ATLAS_TEXTURE_REGION_AND_MARGIN:
var atlas_texture: AtlasTexture = AtlasTexture.new()
atlas_texture.atlas = atlas
atlas_texture.filter_clip = filter_clip_enabled
atlas_texture.resource_local_to_scene = true
atlas_texture.region = Rect2(0, 0, 1, 1)
atlas_texture.margin = Rect2(2, 2, 0, 0)
texture_rect.texture = atlas_texture
animation_player = _create_animation_player(animation_library, {
".:texture:margin": func(frame: _Common.FrameInfo) -> Rect2:
return \
Rect2(frame.sprite.offset,
sprite_size - frame.sprite.region.size) \
if frame.sprite.region.has_area() else \
Rect2(2, 2, 0, 0),
".:texture:region" : func(frame: _Common.FrameInfo) -> Rect2:
return \
Rect2(frame.sprite.region) \
if frame.sprite.region.has_area() else \
Rect2(0, 0, 1, 1) })
AnimationStrategy.MULTIPLE_ATLAS_TEXTURES_INSTANCES:
var atlas_textures: Array[AtlasTexture]
var empty_atlas_texture: AtlasTexture = AtlasTexture.new()
empty_atlas_texture.filter_clip = filter_clip_enabled
empty_atlas_texture.atlas = atlas
empty_atlas_texture.region = Rect2(0, 0, 1, 1)
empty_atlas_texture.margin = Rect2(2, 2, 0, 0)
animation_player = _create_animation_player(animation_library, {
".:texture": func(frame: _Common.FrameInfo) -> Texture2D:
if not frame.sprite.region.has_area():
return empty_atlas_texture
var region: Rect2 = frame.sprite.region
var margin: Rect2 = Rect2(
frame.sprite.offset,
sprite_size - frame.sprite.region.size)
var equivalent_atlas_textures: Array = atlas_textures.filter(
func(t: AtlasTexture) -> bool: return t.margin == margin and t.region == region)
if not equivalent_atlas_textures.is_empty():
return equivalent_atlas_textures.front()
var atlas_texture: AtlasTexture = AtlasTexture.new()
atlas_texture.atlas = atlas
atlas_texture.filter_clip = filter_clip_enabled
atlas_texture.region = region
atlas_texture.margin = margin
atlas_textures.append(atlas_texture)
return atlas_texture})
texture_rect.add_child(animation_player)
animation_player.owner = texture_rect
var packed_scene: PackedScene = PackedScene.new()
packed_scene.pack(texture_rect)
result.success(packed_scene,
ResourceSaver.FLAG_COMPRESS | ResourceSaver.FLAG_BUNDLE_RESOURCES)
return result

View File

@@ -0,0 +1 @@
uid://dqo2tgxc28q6l