@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 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 attack_detection(pos:Vector3,target_pos:Vector3,target_radius:float,target_height:float,attack_dir:Vector2,attack_height:float,attack_size:Vector2,attack_radius:float) -> bool: # 检查Y var attack_y_min = pos.y var attack_y_max = pos.y + attack_height var target_y_min = target_pos.y var target_y_max = target_pos.y + target_height if attack_y_min > target_y_max || attack_y_max < target_y_min: return false # 保底距离 if pos.distance_to(target_pos) < 0.01: return true # 2d距离 var dist_2d = Vector2(pos.x,pos.z).distance_to(Vector2(target_pos.x,target_pos.z)) # 如果是圆形 if attack_radius: return dist_2d <= attack_radius + target_radius # 旋转target var angle = attack_dir.angle_to(Vector2.RIGHT) target_pos = target_pos - pos target_pos = target_pos.rotated(Vector3.UP,angle) var dist_x = abs(target_pos.x) - attack_size.x var dist_y = abs(target_pos.z) - attack_size.y if dist_x <= target_radius && dist_y <= target_radius: if (dist_x <= 0 || dist_y <= 0): return true var dist_squared = pow(dist_x, 2) + pow(dist_y, 2) return dist_squared <= pow(target_radius, 2) return false 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(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 get_all_player_skill(): var ret = [] var dir_path = "res://config/player_skill" var dir = DirAccess.open(dir_path) for file in dir.get_files(): var path = dir_path + "/" + file var res = load(path) if res is PlayerSkillCfg: ret.append(res) return ret