You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
8.7 KiB
GDScript

@tool
extends Node3D
func get_resource_name(resource: Resource) -> String: return resource.resource_path.get_file().trim_suffix('.tres') #todo 性能
func snap_vector3(value: Vector3) -> Vector3: return Vector3(snap_float(value.x), snap_float(value.y), snap_float(value.z))
func snap_float(value: float) -> float: return floor(value/Setting.pixel_size) * Setting.pixel_size
func dir_angle(dir: Vector2) -> float:
dir.x = abs(dir.x)
return dir.angle_to(Vector2.RIGHT)
func vector_reduce(vector: Vector2, reduce: float) -> Vector2:
var length: float = vector.length()
if length == 0:
return vector
var new_len = max(length - reduce, 0)
var scale_rate = new_len / length
return vector * scale_rate
func raycast_wall(from: Vector3, to: Vector3) -> bool:
var space_state: PhysicsDirectSpaceState3D = get_world_3d().direct_space_state
var query: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.create(from, to, 1)
var result: Dictionary = space_state.intersect_ray(query)
return result.size()>0
func raycast_character(shape: Shape3D, origin: Vector3, dir: Vector2) -> Array[Character]:
var space_state: PhysicsDirectSpaceState3D = get_world_3d().direct_space_state
var query: PhysicsShapeQueryParameters3D = PhysicsShapeQueryParameters3D.new()
var angle: float = dir_angle(dir)
query.shape = shape
query.transform.origin = origin
query.transform.basis = query.transform.basis.rotated(Vector3.UP, angle)
var result: Array[Dictionary] = space_state.intersect_shape(query)
var result2: Array = result.map(func(v): return v["collider"]).filter(func(v): return v is Character)
var result3: Array[Character]
for node in result2:
result3.append(node as Character)
return result3
func refresh_animation_lib():
var animation_library_path: String = "res://resource/skill_animation_library/animation_library.tres"
var animation_library = load(animation_library_path)
var dir_path: String = "res://resource/skill_animation"
var dir: DirAccess = DirAccess.open(dir_path)
for file in dir.get_files():
var path: String = dir_path + "/" + file
var res = load(path)
if res is Animation:
var animation: Animation = res as Animation
var animation_name: String = Util.get_resource_name(animation)
print("refresh_animation_lib: ", animation_name)
animation_library.add_animation(animation_name, animation)
animation_library.animation_added.emit(animation_name)
ResourceSaver.save(animation_library, animation_library_path)
func refresh_mesh_library(path_list: Array):
print("refresh_mesh_library")
var default_shape_full: Array[Variant] = [load("res://resource/mesh_library/default_shape_full.tres") as Shape3D, Transform3D.IDENTITY]
var default_shape_half: Array[Variant] = [load("res://resource/mesh_library/default_shape_half.tres") as Shape3D, Transform3D.IDENTITY]
var mesh_library: MeshLibrary = load("res://resource/mesh_library/mesh_library.tres") as MeshLibrary
for file_name_full in path_list:
var mesh_name = file_name_full.get_file().split('-')[0].trim_suffix('.vox')
print(mesh_name)
var mesh: Mesh = load(file_name_full) as Mesh
var mesh_id: int = mesh_library.find_item_by_name(mesh_name)
if mesh_id == -1:
mesh_id = mesh_library.get_last_unused_item_id()
mesh_library.create_item(mesh_id)
mesh_library.set_item_name(mesh_id, mesh_name)
mesh_library.set_item_mesh(mesh_id, mesh)
if mesh_name.begins_with("f_"):
mesh_library.set_item_shapes(mesh_id, default_shape_full)
elif mesh_name.begins_with("h_"):
mesh_library.set_item_shapes(mesh_id, default_shape_half)
elif mesh_name.begins_with("s_"):
var new_shape: Array[Variant] = [mesh.create_convex_shape(), Transform3D.IDENTITY]
mesh_library.set_item_shapes(mesh_id, new_shape)
var ids: PackedInt32Array = mesh_library.get_item_list()
var meshes: Array[Variant] = []
for id in ids:
meshes.append(mesh_library.get_item_mesh(id))
var previews: Array[Texture2D] = EditorInterface.make_mesh_previews(meshes, 64)
for i in range(len(ids)):
mesh_library.set_item_preview(ids[i], previews[i])
ResourceSaver.save(mesh_library)
func refresh_all_animation_by_sprite_frames(sprite_frames: SpriteFrames):
var dir_path: String = "res://resource/skill_animation"
var dir: DirAccess = DirAccess.open(dir_path)
var sprite_frames_name: String = sprite_frames.resource_path.get_file().split('-')[0]
for file in dir.get_files():
var path: String = dir_path + "/" + file
var res = load(path)
if not res is Animation:
continue
var animation: Animation = res as Animation
var sprite_frames_track: int = animation.find_track(NodePath("View:sprite_frames"), Animation.TYPE_VALUE)
if sprite_frames_track < 0:
continue
var sprite_frames_track_key_count: int = animation.track_get_key_count(sprite_frames_track)
if sprite_frames_track_key_count == 0:
continue
var sprite_frames_value: SpriteFrames = animation.track_get_key_value(sprite_frames_track, 0) as SpriteFrames
var target_sprite_frames_name: String = sprite_frames_value.resource_path.get_file().split('-')[0]
if sprite_frames_name != target_sprite_frames_name:
continue
var animation_track: int = animation.find_track(NodePath("View:animation"), Animation.TYPE_VALUE)
if animation_track < 0:
continue
var animation_track_key_count: int = animation.track_get_key_count(animation_track)
if animation_track_key_count == 0:
continue
var animation_value: String = animation.track_get_key_value(animation_track, 0) as String
refresh_animation_by_sprite_frames(path, sprite_frames, animation_value, animation)
Util.refresh_animation_lib()
func refresh_animation_by_sprite_frames(animation_path: String, sprite_frames: SpriteFrames, animation_name: String, animation: Animation) -> void:
if not sprite_frames.has_animation(animation_name):
print("动画不存在: ", animation_name)
return
var track_sprite_frames: int = animation.find_track(NodePath("View:sprite_frames"), Animation.TYPE_VALUE)
if track_sprite_frames < 0:
track_sprite_frames = animation.add_track(Animation.TYPE_VALUE)
animation.track_set_path(track_sprite_frames, "View:sprite_frames")
animation.track_insert_key(track_sprite_frames, 0, sprite_frames)
var track_animation: int = animation.find_track(NodePath("View:animation"), Animation.TYPE_VALUE)
if track_animation < 0:
track_animation = animation.add_track(Animation.TYPE_VALUE)
animation.track_set_path(track_animation, "View:animation")
animation.track_insert_key(track_animation, 0, animation_name)
var track_frame: int = animation.find_track(NodePath("View:frame"), Animation.TYPE_VALUE)
if track_frame >= 0:
animation.remove_track(track_frame)
track_frame = animation.add_track(Animation.TYPE_VALUE)
animation.track_set_path(track_frame, "View:frame")
var animation_speed: float = Setting.animation_frame_rate
var animation_frame_count: int = sprite_frames.get_frame_count(animation_name)
animation.length = animation_speed*animation_frame_count
for i in range(0, animation_frame_count):
var time = i * animation_speed
animation.track_insert_key(track_frame, time, i)
animation.value_track_set_update_mode(track_sprite_frames, Animation.UPDATE_DISCRETE)
animation.value_track_set_update_mode(track_animation, Animation.UPDATE_DISCRETE)
animation.value_track_set_update_mode(track_frame, Animation.UPDATE_DISCRETE)
print("refresh_animation: ", animation_name, "(", animation_frame_count, " frames)")
ResourceSaver.save(animation, animation_path)
func get_all_skill_player_weapon() -> Array[SkillPlayerCfg]:
var ret: Array[SkillPlayerCfg] = []
var dir_path: String = "res://config/skill_player_weapon"
var dir: DirAccess = DirAccess.open(dir_path)
for file in dir.get_files():
var path: String = dir_path + "/" + file
var res = load(path)
if res is SkillPlayerCfg:
ret.append(res)
return ret
func get_all_skill_player_basic() -> Array[SkillPlayerCfg]:
var ret: Array[SkillPlayerCfg] = []
var dir_path: String = "res://config/skill_player_basic"
var dir: DirAccess = DirAccess.open(dir_path)
for file in dir.get_files():
var path: String = dir_path + "/" + file
var res = load(path)
if res is SkillPlayerCfg:
ret.append(res)
return ret
func get_skill_player_weapon_by_weapon(weapon: WeaponCfg) -> Array[SkillPlayerCfg]:
var ret: Array[SkillPlayerCfg] = []
var dir_path: String = "res://config/skill_player_weapon"
var dir: DirAccess = DirAccess.open(dir_path)
for file in dir.get_files():
var path: String = dir_path + "/" + file
var res = load(path)
if res is SkillPlayerCfg:
if res.weapon == weapon:
ret.append(res)
return ret