@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 len = vector.length() if len == 0: return vector var new_len = max(len - reduce,0) var scale_rate = new_len / len return vector * scale_rate func raycast_wall(from:Vector3 ,to:Vector3) -> bool: var space_state = get_world_3d().direct_space_state var query = PhysicsRayQueryParameters3D.create(from,to,1) var result = space_state.intersect_ray(query) return result.size()>0 func raycast_character(shape:Shape3D ,origin:Vector3 ,dir:Vector2): var space_state = get_world_3d().direct_space_state var query = PhysicsShapeQueryParameters3D.new() var angle = dir_angle(dir) query.shape = shape query.transform.origin = origin query.transform.basis = query.transform.basis.rotated(Vector3.UP, angle) var result = space_state.intersect_shape(query) result = result.map(func(v): return v["collider"]) result = result.filter(func(v): return v is Character) return result func refresh_animation_lib(): var animation_library_path = "res://resource/skill_animation_library/animation_library.tres" var animation_library = load(animation_library_path) var dir_path = "res://resource/skill_animation" var dir = DirAccess.open(dir_path) for file in dir.get_files(): var path = dir_path + "/" + file var res = load(path) if res is Animation: var animation = res as Animation var animation_name = 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): var default_shape_full = [load("res://resource/mesh_library/default_shape_full.tres") as Shape3D,Transform3D.IDENTITY] var default_shape_half = [load("res://resource/mesh_library/default_shape_half.tres") as Shape3D,Transform3D.IDENTITY] var mesh_library = 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 = load(file_name_full) as Mesh var mesh_id = 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 = [mesh.create_convex_shape(),Transform3D.IDENTITY] mesh_library.set_item_shapes(mesh_id,new_shape) var ids = mesh_library.get_item_list() var meshes = [] for id in ids: meshes.append(mesh_library.get_item_mesh(id)) var previews = 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 = "res://resource/skill_animation" var dir = DirAccess.open(dir_path) var sprite_frames_name = sprite_frames.resource_path.get_file().split('-')[0] for file in dir.get_files(): var path = dir_path + "/" + file var res = load(path) if not res is Animation: continue var animation = res as Animation var sprite_frames_track = animation.find_track(NodePath("View:sprite_frames"),Animation.TYPE_VALUE) if sprite_frames_track < 0: continue var sprite_frames_track_key_count = animation.track_get_key_count(sprite_frames_track) if sprite_frames_track_key_count == 0: continue var sprite_frames_value = animation.track_get_key_value(sprite_frames_track,0) as SpriteFrames var target_sprite_frames_name = sprite_frames_value.resource_path.get_file().split('-')[0] if sprite_frames_name != target_sprite_frames_name: continue var animation_track = animation.find_track(NodePath("View:animation"),Animation.TYPE_VALUE) if animation_track < 0: continue var animation_track_key_count = animation.track_get_key_count(animation_track) if animation_track_key_count == 0: continue var animation_value = 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): if not sprite_frames.has_animation(animation_name): print("动画不存在: ",animation_name) return var track_sprite_frames = 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 = 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 = 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 = Setting.animation_frame_rate var animation_frame_count = 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(): var ret = [] var dir_path = "res://config/skill_player_weapon" var dir = DirAccess.open(dir_path) for file in dir.get_files(): var path = 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): var ret = [] var dir_path = "res://config/skill_player_weapon" var dir = DirAccess.open(dir_path) for file in dir.get_files(): var path = dir_path + "/" + file var res = load(path) if res is SkillPlayerCfg: if res.weapon == weapon: ret.append(res) return ret