feat: performs basic validation for ESCAnimationResource in-editor and in-game
This commit is contained in:
@@ -40,6 +40,9 @@ func validate(arguments: Array):
|
|||||||
% [get_command_name(), arguments[1]]
|
% [get_command_name(), arguments[1]]
|
||||||
)
|
)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
(escoria.object_manager.get_object(arguments[0]).node as ESCPlayer).validate_animations(load(arguments[1]))
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ export(NodePath) var camera_node
|
|||||||
|
|
||||||
|
|
||||||
# ESCAnimationsResource (for walking, idling...)
|
# ESCAnimationsResource (for walking, idling...)
|
||||||
var animations: ESCAnimationResource
|
var animations: ESCAnimationResource setget set_animations
|
||||||
|
|
||||||
# Reference to the animation node (null if none was found)
|
# Reference to the animation node (null if none was found)
|
||||||
var animation_sprite = null
|
var animation_sprite = null
|
||||||
@@ -171,6 +171,9 @@ var _animation_player: ESCAnimationPlayer = null
|
|||||||
# Whether to force regsitration with the object manager. Defaults to false.
|
# Whether to force regsitration with the object manager. Defaults to false.
|
||||||
var _force_registration: bool = false
|
var _force_registration: bool = false
|
||||||
|
|
||||||
|
# Warnings for scene.
|
||||||
|
var _scene_warnings: PoolStringArray = []
|
||||||
|
|
||||||
|
|
||||||
# Add the movable node, connect signals, detect child nodes
|
# Add the movable node, connect signals, detect child nodes
|
||||||
# and register this item
|
# and register this item
|
||||||
@@ -183,6 +186,8 @@ func _ready():
|
|||||||
# items in a scene tree.
|
# items in a scene tree.
|
||||||
add_to_group(GROUP_ITEM_CAN_COLLIDE)
|
add_to_group(GROUP_ITEM_CAN_COLLIDE)
|
||||||
|
|
||||||
|
validate_animations(animations)
|
||||||
|
|
||||||
if not self.is_connected("mouse_entered", self, "_on_mouse_entered"):
|
if not self.is_connected("mouse_entered", self, "_on_mouse_entered"):
|
||||||
connect("mouse_entered", self, "_on_mouse_entered")
|
connect("mouse_entered", self, "_on_mouse_entered")
|
||||||
if not self.is_connected("mouse_exited", self, "_on_mouse_exited"):
|
if not self.is_connected("mouse_exited", self, "_on_mouse_exited"):
|
||||||
@@ -341,6 +346,12 @@ func _unhandled_input(input_event: InputEvent) -> void:
|
|||||||
get_tree().set_input_as_handled()
|
get_tree().set_input_as_handled()
|
||||||
|
|
||||||
|
|
||||||
|
# To display warnings in the scene tree should there be any.
|
||||||
|
func _get_configuration_warning():
|
||||||
|
validate_animations(animations)
|
||||||
|
return _scene_warnings.join("\n")
|
||||||
|
|
||||||
|
|
||||||
func _is_in_shape(position: Vector2) -> bool:
|
func _is_in_shape(position: Vector2) -> bool:
|
||||||
var colliders = get_world_2d().direct_space_state.intersect_point(
|
var colliders = get_world_2d().direct_space_state.intersect_point(
|
||||||
position,
|
position,
|
||||||
@@ -358,6 +369,61 @@ func _is_in_shape(position: Vector2) -> bool:
|
|||||||
return false
|
return false
|
||||||
|
|
||||||
|
|
||||||
|
# Validates the ESCAnimationResource if it exists. Note that we pass in the
|
||||||
|
# ESCAnimationResource as an argument so that it can also be used to validate
|
||||||
|
# an ESCAnimationResource prior to being set.
|
||||||
|
#
|
||||||
|
# #### Parameters
|
||||||
|
#
|
||||||
|
# - animation_resource: the ESCAnimationResource to validate.
|
||||||
|
func validate_animations(animations_resource: ESCAnimationResource) -> void:
|
||||||
|
if not is_instance_valid(animations_resource):
|
||||||
|
return
|
||||||
|
|
||||||
|
# This initialization must always be here since this is a tool script.
|
||||||
|
_scene_warnings = []
|
||||||
|
|
||||||
|
if is_instance_valid(animations_resource):
|
||||||
|
_validate_animations_property_all_not_null(animations_resource.dir_angles, "dir_angles")
|
||||||
|
|
||||||
|
var num_dir_angles = animations_resource.dir_angles.size()
|
||||||
|
|
||||||
|
if animations_resource.directions.size() != num_dir_angles:
|
||||||
|
_scene_warnings.append("%s animation angles specified but %s 'directions' animation(s) given." \
|
||||||
|
% [num_dir_angles, animations_resource.directions.size()])
|
||||||
|
else:
|
||||||
|
_validate_animations_property_all_not_null(animations_resource.directions, "directions")
|
||||||
|
|
||||||
|
if animations_resource.idles.size() != num_dir_angles:
|
||||||
|
_scene_warnings.append("%s animation angles specified but %s 'idles' animation(s) given." \
|
||||||
|
% [num_dir_angles, animations_resource.idles.size()])
|
||||||
|
else:
|
||||||
|
_validate_animations_property_all_not_null(animations_resource.idles, "idles")
|
||||||
|
|
||||||
|
if animations_resource.speaks.size() != num_dir_angles:
|
||||||
|
_scene_warnings.append("%s animation angles specified but %s 'speaks' animation(s) given." \
|
||||||
|
% [num_dir_angles, animations_resource.speaks.size()])
|
||||||
|
else:
|
||||||
|
_validate_animations_property_all_not_null(animations_resource.speaks, "speaks")
|
||||||
|
|
||||||
|
if Engine.is_editor_hint():
|
||||||
|
update_configuration_warning()
|
||||||
|
elif _scene_warnings.size() > 0:
|
||||||
|
escoria.logger.error(
|
||||||
|
self,
|
||||||
|
_scene_warnings.join(", ")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Setter for the animations property.
|
||||||
|
func set_animations(p_animations: ESCAnimationResource) -> void:
|
||||||
|
if p_animations == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
animations = p_animations
|
||||||
|
|
||||||
|
if not animations.is_connected("changed", self, "_validate_animations"):
|
||||||
|
animations.connect("changed", self, "_validate_animations")
|
||||||
|
|
||||||
|
|
||||||
# Return the animation player node
|
# Return the animation player node
|
||||||
@@ -653,3 +719,23 @@ func _get_inventory_texture() -> Texture:
|
|||||||
return null
|
return null
|
||||||
else:
|
else:
|
||||||
return inventory_texture
|
return inventory_texture
|
||||||
|
|
||||||
|
|
||||||
|
# Checks whether the given ESCAnimationResource property array has all non-null entries, and adds
|
||||||
|
# to the scene's warnings if not.
|
||||||
|
#
|
||||||
|
# #### Parameters
|
||||||
|
#
|
||||||
|
# - property: ESCAnimationResource property. Must be an array.
|
||||||
|
# - property_name: the name of the property being passed in.
|
||||||
|
func _validate_animations_property_all_not_null(property: Array, property_name: String) -> void:
|
||||||
|
var has_empty_entry: bool = false
|
||||||
|
|
||||||
|
for item in property:
|
||||||
|
if item == null:
|
||||||
|
has_empty_entry = true
|
||||||
|
break
|
||||||
|
|
||||||
|
if has_empty_entry:
|
||||||
|
_scene_warnings.append("At least one entry in '%s' is empty." % property_name)
|
||||||
|
|
||||||
|
|||||||
@@ -10,21 +10,59 @@ class_name ESCAnimationResource
|
|||||||
# start_angle must be between 0 and 360.
|
# start_angle must be between 0 and 360.
|
||||||
# Angles 0 and 360 are the same and correspond to UP/NORTH,
|
# Angles 0 and 360 are the same and correspond to UP/NORTH,
|
||||||
# 90 is RIGHT/EAST, 180 is DOWN/SOUTH, 270 is LEFT/WEST etc.
|
# 90 is RIGHT/EAST, 180 is DOWN/SOUTH, 270 is LEFT/WEST etc.
|
||||||
export(Array, Resource) var dir_angles: Array = []
|
export(Array, Resource) var dir_angles: Array = [] setget set_dir_angles
|
||||||
|
|
||||||
# Array of animations for each direction, from UP to RIGHT_UP clockwise
|
# Array of animations for each direction, from UP to RIGHT_UP clockwise
|
||||||
# [animation_name, scale]: scale parameter can be set to -1 to mirror
|
# [animation_name, scale]: scale parameter can be set to -1 to mirror
|
||||||
# the animation
|
# the animation
|
||||||
export(Array, Resource) var directions: Array = []
|
export(Array, Resource) var directions: Array = [] setget set_directions
|
||||||
|
|
||||||
|
|
||||||
# Array containing the idle animations for each direction (in the
|
# Array containing the idle animations for each direction (in the
|
||||||
# order defined by dir_angles): scale parameter can be set to -1 to mirror
|
# order defined by dir_angles): scale parameter can be set to -1 to mirror
|
||||||
# the animation
|
# the animation
|
||||||
export(Array, Resource) var idles: Array = []
|
export(Array, Resource) var idles: Array = [] setget set_idles
|
||||||
|
|
||||||
# Array containing the speak animations for each direction (in the
|
# Array containing the speak animations for each direction (in the
|
||||||
# order defined by dir_angles): scale parameter can be set to -1 to mirror
|
# order defined by dir_angles): scale parameter can be set to -1 to mirror
|
||||||
# the animation
|
# the animation
|
||||||
export(Array, Resource) var speaks: Array = []
|
export(Array, Resource) var speaks: Array = [] setget set_speaks
|
||||||
|
|
||||||
|
|
||||||
|
# Sets the dir_angles property.
|
||||||
|
#
|
||||||
|
# #### Parameters
|
||||||
|
#
|
||||||
|
# - p_dir_angles: array of direction angle resources to set.
|
||||||
|
func set_dir_angles(p_dir_angles: Array) -> void:
|
||||||
|
dir_angles = p_dir_angles
|
||||||
|
emit_changed()
|
||||||
|
|
||||||
|
|
||||||
|
# Sets the directions property.
|
||||||
|
#
|
||||||
|
# #### Parameters
|
||||||
|
#
|
||||||
|
# - p_directions: array of direction resources to set.
|
||||||
|
func set_directions(p_set_directions: Array) -> void:
|
||||||
|
directions = p_set_directions
|
||||||
|
emit_changed()
|
||||||
|
|
||||||
|
|
||||||
|
# Sets the idles property.
|
||||||
|
#
|
||||||
|
# #### Parameters
|
||||||
|
#
|
||||||
|
# - p_set_idles: array of idle resources to set.
|
||||||
|
func set_idles(p_set_idles: Array) -> void:
|
||||||
|
idles = p_set_idles
|
||||||
|
emit_changed()
|
||||||
|
|
||||||
|
|
||||||
|
# Sets the speaks property.
|
||||||
|
#
|
||||||
|
# #### Parameters
|
||||||
|
#
|
||||||
|
# - p_set_idles: array of speak resources to set.
|
||||||
|
func set_speaks(p_set_speaks: Array) -> void:
|
||||||
|
speaks = p_set_speaks
|
||||||
|
emit_changed()
|
||||||
|
|||||||
Reference in New Issue
Block a user