remove unused plugin
This commit is contained in:
parent
edd6ed0f4c
commit
47a983c085
13 changed files with 0 additions and 709 deletions
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 kyboon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -1,49 +0,0 @@
|
|||
# ModularSpriteAnimationFactory
|
||||

|
||||
|
||||
A Godot 4 plugin to generate animations for modular 2d sprites. Generated animations will have multiple tracks, one for each Sprite2D node.
|
||||
|
||||
## Installation
|
||||
1. Download the plugin from github and place the `addons` directory to your Godot project root folder. Alternatively, you can install it from the `AssetLib` in the Godot editor.
|
||||
2. In the Godot editor, go to `Project` > `Project Settings` > `Plugins` and enable `Modular Sprite Animation Factory`.
|
||||
|
||||
## Usage
|
||||
1. Prepare your sprites. Split it to different parts and convert them to white (or greyscale). Example below:
|
||||
|
||||
Original:
|
||||

|
||||
Head:
|
||||

|
||||
Body:
|
||||

|
||||
Eyes:
|
||||

|
||||
Outline:
|
||||

|
||||
|
||||
2. Setup your nodes, it has to be a `Node2D`, **contains an `AnimationPlayer` and at least a `Sprite2D`** among its children. It's recommended to name the `Sprite2D`s accordingly. Example below:
|
||||
|
||||
- `Node2D`
|
||||
- `AnimationPlayer`
|
||||
- `Sprite2D`
|
||||
- `Sprite2D`
|
||||
- ... more `Sprite2D`s
|
||||
|
||||

|
||||
3. Set the textures of the `Sprite2D`s with your sprites. And set the Hframes and Vframes (under the `Sprite2D > Animation` section), in the example it's a 4x4 spritesheet.
|
||||
|
||||

|
||||
|
||||
4. You can now customize your character by setting different colors to each part of the sprite. To do so, in the `CanvasItem > Visibility` section, change the modulate color. You can also change that via a script. Alternatively, you can also customize your character by changing the texture. For example, you can have a `Sprite2D` node named `Hat`, and you can change the character's hat to different styles, instead of just changing the hat color.
|
||||
|
||||

|
||||

|
||||
|
||||
5. When you select the root Node2D, a tab will apear on the right panel, named `MSAF`. You can then manage and generate animations using it.
|
||||
|
||||

|
||||
|
||||
6. The result of the generated animation:
|
||||
|
||||

|
||||
|
BIN
addons/modular_sprite_animation_factory/assets/checkbox-blank-circle.png
(Stored with Git LFS)
BIN
addons/modular_sprite_animation_factory/assets/checkbox-blank-circle.png
(Stored with Git LFS)
Binary file not shown.
|
@ -1,34 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://rwsj5eomxtuy"
|
||||
path="res://.godot/imported/checkbox-blank-circle.png-19ed1aa8d0ec722460ac308e98c5b30f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/modular_sprite_animation_factory/assets/checkbox-blank-circle.png"
|
||||
dest_files=["res://.godot/imported/checkbox-blank-circle.png-19ed1aa8d0ec722460ac308e98c5b30f.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
BIN
addons/modular_sprite_animation_factory/assets/checkbox-circle.png
(Stored with Git LFS)
BIN
addons/modular_sprite_animation_factory/assets/checkbox-circle.png
(Stored with Git LFS)
Binary file not shown.
|
@ -1,34 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ckdctfvm4f0t2"
|
||||
path="res://.godot/imported/checkbox-circle.png-3e5f3f4552812201969d5bcd3ec00ca7.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/modular_sprite_animation_factory/assets/checkbox-circle.png"
|
||||
dest_files=["res://.godot/imported/checkbox-circle.png-3e5f3f4552812201969d5bcd3ec00ca7.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
|
@ -1,246 +0,0 @@
|
|||
@tool
|
||||
extends Control
|
||||
|
||||
var sprite_node_names
|
||||
var selected_sprite_nodes: Array[bool] = []
|
||||
|
||||
var selected_library = ""
|
||||
var lib_names: Array[StringName] = []
|
||||
|
||||
var animation_parts: Array[MSAFPart] = []
|
||||
|
||||
var checked_tex = preload("res://addons/modular_sprite_animation_factory/assets/checkbox-circle.png")
|
||||
var unchecked_tex = preload("res://addons/modular_sprite_animation_factory/assets/checkbox-blank-circle.png")
|
||||
|
||||
var anim_player: AnimationPlayer
|
||||
|
||||
|
||||
func setup_dock(node_names, animation_player):
|
||||
anim_player = animation_player
|
||||
sprite_node_names = node_names
|
||||
|
||||
refresh_all()
|
||||
|
||||
func refresh_all():
|
||||
update_library_list()
|
||||
update_sprite_node_list()
|
||||
update_visible_anim()
|
||||
update_animation_list()
|
||||
%ChangeNotAppliedLabel.visible = false
|
||||
|
||||
func update_sprite_node_list():
|
||||
%SpriteNodeItemList.clear()
|
||||
selected_sprite_nodes.clear()
|
||||
|
||||
var existing_selected_nodes: Array[String] = []
|
||||
var lib = anim_player.get_animation_library(selected_library)
|
||||
var has_animation = false
|
||||
# Check the first animation in the library, to set the default selected state of the sprite nodes
|
||||
if lib:
|
||||
if lib.get_animation_list().size() > 0:
|
||||
var first_anim = lib.get_animation(lib.get_animation_list()[0])
|
||||
has_animation = true
|
||||
for i in first_anim.get_track_count():
|
||||
var path = first_anim.track_get_path(i)
|
||||
if path.get_subname_count() > 0 and path.get_subname(0) == "frame" and path.get_name_count() > 0:
|
||||
existing_selected_nodes.append(path.get_name(0))
|
||||
|
||||
for i in sprite_node_names.size():
|
||||
if !has_animation or existing_selected_nodes.has(sprite_node_names[i]):
|
||||
# If no animation in the library, default to true
|
||||
# Or existing animation contains the node track, then its true as well
|
||||
selected_sprite_nodes.append(true)
|
||||
%SpriteNodeItemList.add_item(sprite_node_names[i], checked_tex, true)
|
||||
else:
|
||||
selected_sprite_nodes.append(false)
|
||||
%SpriteNodeItemList.add_item(sprite_node_names[i], unchecked_tex, true)
|
||||
|
||||
%SpriteNodeItemList.set_item_icon_modulate(i, Color.WHITE)
|
||||
|
||||
func update_library_list():
|
||||
lib_names = anim_player.get_animation_library_list()
|
||||
%LibraryItemList.clear()
|
||||
|
||||
for i in lib_names.size():
|
||||
var item_string: String
|
||||
if lib_names[i] == "":
|
||||
item_string = "[Global]"
|
||||
else:
|
||||
item_string = lib_names[i]
|
||||
|
||||
if lib_names[i] == selected_library:
|
||||
%LibraryItemList.select(i)
|
||||
item_string += " (selected)"
|
||||
|
||||
%LibraryItemList.add_item(item_string, null, true)
|
||||
|
||||
func update_visible_anim():
|
||||
animation_parts.clear()
|
||||
var lib = anim_player.get_animation_library(selected_library)
|
||||
|
||||
if !lib:
|
||||
return
|
||||
|
||||
var visible_anims = lib.get_animation_list()
|
||||
|
||||
# convert all animation to MSAFPart
|
||||
for anim_name in visible_anims:
|
||||
var animation = lib.get_animation(anim_name)
|
||||
|
||||
var new_part = MSAFPart.new()
|
||||
new_part.animation_name = anim_name
|
||||
new_part.loop = animation.loop_mode != Animation.LOOP_NONE
|
||||
|
||||
if animation.get_track_count() > 0:
|
||||
var key_count = animation.track_get_key_count(0)
|
||||
if key_count > 1:
|
||||
new_part.start_index = animation.track_get_key_value(0, 0)
|
||||
new_part.end_index = animation.track_get_key_value(0, key_count - 1)
|
||||
new_part.fps = key_count / animation.length
|
||||
else:
|
||||
new_part.start_index = animation.track_get_key_value(0, 0)
|
||||
new_part.end_index = animation.track_get_key_value(0, 0)
|
||||
new_part.fps = 1
|
||||
else:
|
||||
new_part.start_index = -1
|
||||
new_part.end_index = -1
|
||||
new_part.fps = -1
|
||||
|
||||
animation_parts.append(new_part)
|
||||
|
||||
func update_animation_list():
|
||||
%AnimationItemList.clear()
|
||||
|
||||
for anim_part in animation_parts:
|
||||
var item_string = anim_part.animation_name
|
||||
if anim_part.loop:
|
||||
item_string += " (loop)"
|
||||
if anim_part.fps > 0:
|
||||
item_string += " [%d - %d]" % [anim_part.start_index, anim_part.end_index]
|
||||
item_string += " %.2f fps" % anim_part.fps
|
||||
else:
|
||||
item_string += " [? - ?] ? fps"
|
||||
|
||||
%AnimationItemList.add_item(item_string, null, true)
|
||||
|
||||
func _on_library_item_list_item_selected(index):
|
||||
var previously_selected_lib = selected_library
|
||||
|
||||
if index < lib_names.size():
|
||||
selected_library = lib_names[index]
|
||||
|
||||
if previously_selected_lib != selected_library:
|
||||
if selected_library == "":
|
||||
print("MSAF Selected library: [Global]")
|
||||
else:
|
||||
print("MSAF Selected library: ", selected_library)
|
||||
refresh_all()
|
||||
|
||||
func _on_sprite_node_item_list_item_selected(index):
|
||||
# toggle item
|
||||
if selected_sprite_nodes[index]:
|
||||
%SpriteNodeItemList.set_item_icon(index, unchecked_tex)
|
||||
else:
|
||||
%SpriteNodeItemList.set_item_icon(index, checked_tex)
|
||||
selected_sprite_nodes[index] = !selected_sprite_nodes[index]
|
||||
|
||||
|
||||
func _on_select_all_button_pressed():
|
||||
print("MSAF select all sprite nodes")
|
||||
for i in sprite_node_names.size():
|
||||
%SpriteNodeItemList.set_item_icon(i, checked_tex)
|
||||
selected_sprite_nodes[i] = true
|
||||
|
||||
func _on_select_none_button_pressed():
|
||||
print("MSAF select none sprite nodes")
|
||||
for i in sprite_node_names.size():
|
||||
%SpriteNodeItemList.set_item_icon(i, unchecked_tex)
|
||||
selected_sprite_nodes[i] = false
|
||||
|
||||
func _on_delete_anim_button_pressed():
|
||||
var selected_item_indexes = %AnimationItemList.get_selected_items()
|
||||
if selected_item_indexes.size() > 0:
|
||||
var selected_index = selected_item_indexes[0]
|
||||
print("MSAF deleted animation: ", animation_parts[selected_index].animation_name)
|
||||
animation_parts.remove_at(selected_index)
|
||||
update_animation_list()
|
||||
%ChangeNotAppliedLabel.visible = true
|
||||
|
||||
func _on_add_anim_button_pressed():
|
||||
print("MSAF added new animation")
|
||||
|
||||
if %AnimNameLineEdit.text == "" or %AnimNameLineEdit.text.contains("/"):
|
||||
$AcceptDialog.dialog_text = "Invalid animation name"
|
||||
%AcceptDialog.popup_centered()
|
||||
return
|
||||
|
||||
if !%StartFrameLineEdit.text.is_valid_int() or !%EndFrameLineEdit.text.is_valid_int():
|
||||
$AcceptDialog.dialog_text = "Start and end frame needs to be integer"
|
||||
%AcceptDialog.popup_centered()
|
||||
return
|
||||
|
||||
if !%FPSLineEdit.text.is_valid_float() and float(%FPSLineEdit.text) <= 0:
|
||||
$AcceptDialog.dialog_text = "Invalid FPS number"
|
||||
%AcceptDialog.popup_centered()
|
||||
return
|
||||
|
||||
var new_part = MSAFPart.new()
|
||||
new_part.animation_name = %AnimNameLineEdit.text
|
||||
new_part.loop = %LoopCheckButton.button_pressed
|
||||
new_part.start_index = int(%StartFrameLineEdit.text)
|
||||
new_part.end_index = int(%EndFrameLineEdit.text)
|
||||
new_part.fps = float(%FPSLineEdit.text)
|
||||
animation_parts.append(new_part)
|
||||
|
||||
update_animation_list()
|
||||
%ChangeNotAppliedLabel.visible = true
|
||||
|
||||
func _on_generate_button_pressed():
|
||||
var lib = anim_player.get_animation_library(selected_library)
|
||||
if !lib:
|
||||
$AcceptDialog.dialog_text = "No library selected"
|
||||
%AcceptDialog.popup_centered()
|
||||
return
|
||||
|
||||
if %OverwriteCheckBox.button_pressed: # overwrite is checked
|
||||
for existing_anim in lib.get_animation_list():
|
||||
lib.remove_animation(existing_anim)
|
||||
|
||||
for anim_part in animation_parts:
|
||||
if anim_part.fps <= 0:
|
||||
# invalid animation part, skip this one
|
||||
continue
|
||||
|
||||
if lib.has_animation(anim_part.animation_name): # if already exist
|
||||
if !%OverwriteCheckBox.button_pressed: # overwrite is not checked
|
||||
continue # skip this one
|
||||
|
||||
var animation = Animation.new()
|
||||
animation.length = float(anim_part.end_index - anim_part.start_index + 1) / anim_part.fps
|
||||
|
||||
if anim_part.loop:
|
||||
animation.loop_mode = Animation.LOOP_LINEAR
|
||||
else:
|
||||
animation.loop_mode = Animation.LOOP_NONE
|
||||
|
||||
for i in sprite_node_names.size():
|
||||
if !selected_sprite_nodes[i]:
|
||||
# this sprite node is not selected, skip it
|
||||
continue
|
||||
|
||||
# add a track for each sprite node
|
||||
animation.add_track(Animation.TYPE_VALUE)
|
||||
animation.value_track_set_update_mode(i, Animation.UPDATE_DISCRETE)
|
||||
animation.track_set_path(i, "%s:frame" % sprite_node_names[i])
|
||||
|
||||
# add a the frames to the track
|
||||
for j in range(anim_part.start_index, anim_part.end_index + 1):
|
||||
animation.track_insert_key(i, float(j - anim_part.start_index) / anim_part.fps, j)
|
||||
|
||||
lib.add_animation(anim_part.animation_name, animation)
|
||||
|
||||
%ChangeNotAppliedLabel.visible = false
|
||||
refresh_all()
|
||||
|
||||
func _on_refresh_button_pressed():
|
||||
refresh_all()
|
|
@ -1,209 +0,0 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://dh4eckdue2vu"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/modular_sprite_animation_factory/dock/msaf_dock.gd" id="1_0o686"]
|
||||
|
||||
[node name="MSAF" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_0o686")
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 10
|
||||
|
||||
[node name="LibraryTitle" type="Label" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Animation Library"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="LibraryItemList" type="ItemList" parent="ScrollContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
allow_reselect = true
|
||||
allow_search = false
|
||||
auto_height = true
|
||||
|
||||
[node name="Separator0" type="ColorRect" parent="ScrollContainer/VBoxContainer"]
|
||||
custom_minimum_size = Vector2(0, 2)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SpriteNodeTitle" type="Label" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Sprite2D nodes"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="SpriteNodeItemList" type="ItemList" parent="ScrollContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
allow_reselect = true
|
||||
allow_search = false
|
||||
auto_height = true
|
||||
icon_scale = 0.05
|
||||
|
||||
[node name="HBoxContainer5" type="HBoxContainer" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 10
|
||||
|
||||
[node name="SelectAllButton" type="Button" parent="ScrollContainer/VBoxContainer/HBoxContainer5"]
|
||||
layout_mode = 2
|
||||
text = "Select all"
|
||||
|
||||
[node name="SelectNoneButton" type="Button" parent="ScrollContainer/VBoxContainer/HBoxContainer5"]
|
||||
layout_mode = 2
|
||||
text = "Select none"
|
||||
|
||||
[node name="Separator1" type="ColorRect" parent="ScrollContainer/VBoxContainer"]
|
||||
custom_minimum_size = Vector2(0, 2)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="AnimationTitle" type="Label" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Animations"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="AnimationItemList" type="ItemList" parent="ScrollContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
allow_search = false
|
||||
auto_height = true
|
||||
|
||||
[node name="DeleteAnimButton" type="Button" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Delete selected animation"
|
||||
|
||||
[node name="NewAnimTitle" type="Label" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "New animation"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="ScrollContainer/VBoxContainer/HBoxContainer"]
|
||||
custom_minimum_size = Vector2(140, 0)
|
||||
layout_mode = 2
|
||||
text = "Animation name: "
|
||||
|
||||
[node name="AnimNameLineEdit" type="LineEdit" parent="ScrollContainer/VBoxContainer/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
placeholder_text = "i.e. Idle, Walk, Run, Jump, etc"
|
||||
|
||||
[node name="HBoxContainer3" type="HBoxContainer" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label2" type="Label" parent="ScrollContainer/VBoxContainer/HBoxContainer3"]
|
||||
custom_minimum_size = Vector2(140, 0)
|
||||
layout_mode = 2
|
||||
text = "Loop:"
|
||||
|
||||
[node name="LoopCheckButton" type="CheckButton" parent="ScrollContainer/VBoxContainer/HBoxContainer3"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HBoxContainer2" type="HBoxContainer" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="ScrollContainer/VBoxContainer/HBoxContainer2"]
|
||||
custom_minimum_size = Vector2(140, 0)
|
||||
layout_mode = 2
|
||||
text = "Start frame:"
|
||||
|
||||
[node name="StartFrameLineEdit" type="LineEdit" parent="ScrollContainer/VBoxContainer/HBoxContainer2"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
placeholder_text = "int"
|
||||
|
||||
[node name="HBoxContainer4" type="HBoxContainer" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label2" type="Label" parent="ScrollContainer/VBoxContainer/HBoxContainer4"]
|
||||
custom_minimum_size = Vector2(140, 0)
|
||||
layout_mode = 2
|
||||
text = "End frame:"
|
||||
|
||||
[node name="EndFrameLineEdit" type="LineEdit" parent="ScrollContainer/VBoxContainer/HBoxContainer4"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
placeholder_text = "int"
|
||||
|
||||
[node name="HBoxContainer6" type="HBoxContainer" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label2" type="Label" parent="ScrollContainer/VBoxContainer/HBoxContainer6"]
|
||||
custom_minimum_size = Vector2(140, 0)
|
||||
layout_mode = 2
|
||||
text = "FPS:"
|
||||
|
||||
[node name="FPSLineEdit" type="LineEdit" parent="ScrollContainer/VBoxContainer/HBoxContainer6"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
placeholder_text = "float"
|
||||
|
||||
[node name="AddAnimButton" type="Button" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Add new animation"
|
||||
|
||||
[node name="Separator2" type="ColorRect" parent="ScrollContainer/VBoxContainer"]
|
||||
custom_minimum_size = Vector2(0, 2)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ChangeNotAppliedLabel" type="Label" parent="ScrollContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
custom_minimum_size = Vector2(100, 0)
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(1, 0.25, 0.25, 1)
|
||||
text = "*Changes not applied until you click on Generate"
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="HBoxContainer7" type="HBoxContainer" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="ScrollContainer/VBoxContainer/HBoxContainer7"]
|
||||
custom_minimum_size = Vector2(140, 0)
|
||||
layout_mode = 2
|
||||
text = "Overwrite existing?"
|
||||
|
||||
[node name="OverwriteCheckBox" type="CheckBox" parent="ScrollContainer/VBoxContainer/HBoxContainer7"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="GenerateButton" type="Button" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Generate"
|
||||
|
||||
[node name="RefreshButton" type="Button" parent="ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Refresh"
|
||||
|
||||
[node name="AcceptDialog" type="AcceptDialog" parent="."]
|
||||
unique_name_in_owner = true
|
||||
title = "Error"
|
||||
|
||||
[connection signal="item_selected" from="ScrollContainer/VBoxContainer/LibraryItemList" to="." method="_on_library_item_list_item_selected"]
|
||||
[connection signal="item_selected" from="ScrollContainer/VBoxContainer/SpriteNodeItemList" to="." method="_on_sprite_node_item_list_item_selected"]
|
||||
[connection signal="pressed" from="ScrollContainer/VBoxContainer/HBoxContainer5/SelectAllButton" to="." method="_on_select_all_button_pressed"]
|
||||
[connection signal="pressed" from="ScrollContainer/VBoxContainer/HBoxContainer5/SelectNoneButton" to="." method="_on_select_none_button_pressed"]
|
||||
[connection signal="pressed" from="ScrollContainer/VBoxContainer/DeleteAnimButton" to="." method="_on_delete_anim_button_pressed"]
|
||||
[connection signal="pressed" from="ScrollContainer/VBoxContainer/AddAnimButton" to="." method="_on_add_anim_button_pressed"]
|
||||
[connection signal="pressed" from="ScrollContainer/VBoxContainer/GenerateButton" to="." method="_on_generate_button_pressed"]
|
||||
[connection signal="pressed" from="ScrollContainer/VBoxContainer/RefreshButton" to="." method="_on_refresh_button_pressed"]
|
BIN
addons/modular_sprite_animation_factory/msaf_logo.png
(Stored with Git LFS)
BIN
addons/modular_sprite_animation_factory/msaf_logo.png
(Stored with Git LFS)
Binary file not shown.
|
@ -1,34 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://byxf0djhsanrb"
|
||||
path="res://.godot/imported/msaf_logo.png-60acddc1a9644cdd9dd997f1d7e8732c.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/modular_sprite_animation_factory/msaf_logo.png"
|
||||
dest_files=["res://.godot/imported/msaf_logo.png-60acddc1a9644cdd9dd997f1d7e8732c.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
|
@ -1,9 +0,0 @@
|
|||
extends Object
|
||||
|
||||
class_name MSAFPart
|
||||
|
||||
@export var animation_name: String
|
||||
@export var start_index: int
|
||||
@export var end_index: int
|
||||
@export var fps: float
|
||||
@export var loop: bool
|
|
@ -1,7 +0,0 @@
|
|||
[plugin]
|
||||
|
||||
name="Modular Sprite Animation Factory"
|
||||
description="A plugin to generate animations for modular 2d sprites. Generated animations will have multiple tracks, one for each Sprite2D node."
|
||||
author="kyboon"
|
||||
version="1.0.1"
|
||||
script="plugin.gd"
|
|
@ -1,57 +0,0 @@
|
|||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
const AUTOLOAD_NAME = "ModularSpriteAnimationFactory"
|
||||
|
||||
var dock
|
||||
|
||||
func _enter_tree():
|
||||
dock = preload("res://addons/modular_sprite_animation_factory/dock/msaf_dock.tscn").instantiate()
|
||||
|
||||
func _exit_tree():
|
||||
dock.queue_free()
|
||||
|
||||
func _handles(object):
|
||||
return object_is_valid_candidate(object)
|
||||
|
||||
func _edit(object):
|
||||
if object:
|
||||
if !dock.get_parent():
|
||||
add_control_to_dock(EditorPlugin.DOCK_SLOT_RIGHT_UL, dock)
|
||||
|
||||
var sprite_children = get_sprite_2d_children(object)
|
||||
var anim_children = get_anim_player_children(object)
|
||||
dock.setup_dock(sprite_children.map(get_node_name), anim_children[0])
|
||||
else:
|
||||
remove_control_from_docks(dock)
|
||||
|
||||
func object_is_valid_candidate(object):
|
||||
# The heirachy should be as below
|
||||
# - Node2D
|
||||
# - AnimationPlayer
|
||||
# - Sprite2D 1
|
||||
# - Sprite2D 2
|
||||
# - ...
|
||||
|
||||
# When selected the parent Node2D, handles it
|
||||
if object and object is Node2D:
|
||||
var children = object.get_children()
|
||||
return children.any(is_anim_player) and children.any(is_sprite_2d)
|
||||
return false
|
||||
|
||||
func is_sprite_2d(object):
|
||||
return object is Sprite2D
|
||||
|
||||
func is_anim_player(object):
|
||||
return object is AnimationPlayer
|
||||
|
||||
func get_node_name(object):
|
||||
return object.name
|
||||
|
||||
func get_sprite_2d_children(object: Node2D):
|
||||
var children = object.get_children()
|
||||
return children.filter(is_sprite_2d)
|
||||
|
||||
func get_anim_player_children(object: Node2D):
|
||||
var children = object.get_children()
|
||||
return children.filter(is_anim_player)
|
Loading…
Reference in a new issue