[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6HSFM6MXBKBKM3K4CP53XYK":3,"skill-same:01M6HSFM6MXBKBKM3K4CP53XYK":107},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":40,"linkOnly":41,"markdownContent":42,"markdownBody":43,"frontMatter":44,"refName":87,"commitSha":88,"skillDirectory":89,"forksCount":90,"repositoryHtmlUrl":91,"repositoryHomepageUrl":6,"ownerHtmlUrl":92,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":93,"install":94,"resources":106},"01M6HSFM6MXBKBKM3K4CP53XYK","player-system",null,"玩家控制系统技能。生成完整的玩家控制器，包括移动、跳跃、攻击、状态机等功能。 支持 2D 和 3D 多种控制模式。","welflau\u002Fai-dev-system","welflau","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F7010385?v=4","01M6HPTDGF18RFY07M229P8CTM","01M6HPTDMRMZCJPYBFEA9XVVYT",3,"MIT","https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system\u002Fblob\u002Fmain\u002Fbackend\u002Fskills\u002Fmarketplace\u002Fcodebuddy-plugins-official\u002Fplugins\u002Fgodot-mcp\u002Fskills\u002Fgodot-dev\u002Flevel-2-modules\u002Fplayer-system\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39],"player system","system","player","scripts","entities","dash","2d","person","true","generator","script","states","directory","false","type","scenes","生成","3D","first","file","code","core","2026-11-10 10:12:30",false,"---\nname: player-system\ndescription: >\n  玩家控制系统技能。生成完整的玩家控制器，包括移动、跳跃、攻击、状态机等功能。\n  支持 2D 和 3D 多种控制模式。\nversion: 1.0.0\ndependencies:\n  - godot-core\n  - code-generator\n  - input-system\ntriggers:\n  - pattern: \"玩家控制|角色控制|移动系统|Player|玩家移动\"\ninputs:\n  - name: player_type\n    type: string\n    enum: [\"platformer_2d\", \"topdown_2d\", \"third_person_3d\", \"first_person_3d\"]\n    required: true\n  - name: features\n    type: array\n    items:\n      enum: [\"movement\", \"jump\", \"double_jump\", \"dash\", \"attack\", \"interact\", \"crouch\", \"climb\", \"swim\"]\n    required: false\noutputs:\n  - name: player_scene\n    type: file\n    path_pattern: \"res:\u002F\u002Fscenes\u002Fprefabs\u002Fplayer\u002Fplayer.tscn\"\n  - name: player_script\n    type: file\n    path_pattern: \"res:\u002F\u002Fscripts\u002Fentities\u002Fplayer\u002Fplayer.gd\"\n  - name: player_states\n    type: directory\n    path_pattern: \"res:\u002F\u002Fscripts\u002Fentities\u002Fplayer\u002Fstates\u002F\"\n---\n\n# 玩家控制系统技能\n\n生成完整的玩家控制系统，包含移动、状态机、输入处理等功能。\n\n## 支持的控制器类型\n\n### Platformer 2D（平台跳跃）\n\n**适用游戏**：横版动作、银河恶魔城、平台跳跃\n\n**特点**：\n- 基于 CharacterBody2D\n- 重力物理系统\n- 可配置浮空时间（Coyote Time）\n- 跳跃缓冲（Jump Buffer）\n- 可变跳跃高度\n\n**生成文件**：\n```\nres:\u002F\u002Fscenes\u002Fprefabs\u002Fplayer\u002Fplayer_2d.tscn\nres:\u002F\u002Fscripts\u002Fentities\u002Fplayer\u002Fplayer_2d.gd\nres:\u002F\u002Fscripts\u002Fentities\u002Fplayer\u002Fplayer_2d_controller.gd\nres:\u002F\u002Fscripts\u002Fentities\u002Fplayer\u002Fstates\u002F\n    ├── player_state.gd\n    ├── idle_state.gd\n    ├── run_state.gd\n    ├── jump_state.gd\n    ├── fall_state.gd\n    └── ...\n```\n\n### Top-down 2D（俯视角）\n\n**适用游戏**：RPG、动作冒险、射击游戏\n\n**特点**：\n- 8 方向移动\n- 可选瞄准系统\n- 平滑旋转\n\n### Third Person 3D（第三人称）\n\n**适用游戏**：动作 RPG、冒险游戏\n\n**特点**：\n- 与摄像机联动的移动方向\n- 斜坡处理\n- 阶梯检测\n\n### First Person 3D（第一人称）\n\n**适用游戏**：FPS、探索游戏、恐怖游戏\n\n**特点**：\n- 鼠标视角控制\n- 头部摇摆\n- 可选武器系统\n\n---\n\n## Platformer 2D 完整实现\n\n### 玩家场景结构\n\n```\nPlayer (CharacterBody2D)\n├── CollisionShape2D\n├── Sprite2D \u002F AnimatedSprite2D\n├── AnimationPlayer\n├── StateMachine\n│   ├── IdleState\n│   ├── RunState\n│   ├── JumpState\n│   ├── FallState\n│   ├── DashState (可选)\n│   └── AttackState (可选)\n├── Hitbox (Area2D) - 攻击判定\n├── Hurtbox (Area2D) - 受伤判定\n├── CoyoteTimer (Timer)\n├── JumpBufferTimer (Timer)\n└── Camera2D (可选)\n```\n\n### 玩家主脚本 (player_2d.gd)\n\n```gdscript\n## 2D 平台跳跃玩家控制器\n##\n## 包含移动、跳跃、攻击等核心功能\n## @author AI Generated\n## @version 1.0.0\nclass_name Player2D\nextends CharacterBody2D\n\n# region 信号\nsignal died\nsignal health_changed(old_value: int, new_value: int)\nsignal state_changed(old_state: String, new_state: String)\nsignal jumped\nsignal landed\nsignal attacked\n# endregion\n\n# region 常量\nconst GRAVITY: float = 980.0\n# endregion\n\n# region 导出变量 - 移动\n@export_group(\"Movement\")\n@export var move_speed: float = 200.0\n@export var acceleration: float = 1500.0\n@export var friction: float = 1200.0\n@export var air_friction: float = 600.0\n# endregion\n\n# region 导出变量 - 跳跃\n@export_group(\"Jump\")\n@export var jump_velocity: float = -350.0\n@export var max_jumps: int = 1\n@export var coyote_time: float = 0.1\n@export var jump_buffer_time: float = 0.1\n@export var variable_jump_multiplier: float = 0.5\n# endregion\n\n# region 导出变量 - 冲刺\n@export_group(\"Dash\")\n@export var dash_enabled: bool = true\n@export var dash_speed: float = 400.0\n@export var dash_duration: float = 0.2\n@export var dash_cooldown: float = 1.0\n# endregion\n\n# region 导出变量 - 属性\n@export_group(\"Stats\")\n@export var max_health: int = 100\n# endregion\n\n# region 状态变量\nvar current_health: int:\n    set(value):\n        var old = current_health\n        current_health = clampi(value, 0, max_health)\n        health_changed.emit(old, current_health)\n        if current_health \u003C= 0:\n            _die()\n\nvar is_alive: bool:\n    get: return current_health > 0\n\nvar facing_direction: int = 1  # 1 = 右, -1 = 左\nvar jumps_remaining: int = 0\nvar can_coyote_jump: bool = false\nvar jump_buffered: bool = false\nvar can_dash: bool = true\nvar is_dashing: bool = false\n# endregion\n\n# region 节点引用\n@onready var sprite: Sprite2D = $Sprite2D\n@onready var animation_player: AnimationPlayer = $AnimationPlayer\n@onready var state_machine: Node = $StateMachine\n@onready var coyote_timer: Timer = $CoyoteTimer\n@onready var jump_buffer_timer: Timer = $JumpBufferTimer\n# endregion\n\n# region 生命周期\nfunc _ready() -> void:\n    current_health = max_health\n    jumps_remaining = max_jumps\n    _setup_timers()\n\nfunc _physics_process(delta: float) -> void:\n    if not is_alive:\n        return\n    \n    # 重力\n    if not is_on_floor() and not is_dashing:\n        velocity.y += GRAVITY * delta\n    \n    # 更新朝向\n    var input_dir = Input.get_axis(\"move_left\", \"move_right\")\n    if input_dir != 0:\n        facing_direction = signi(input_dir)\n        sprite.flip_h = facing_direction \u003C 0\n    \n    move_and_slide()\n    \n    # 检测落地\n    if is_on_floor():\n        jumps_remaining = max_jumps\n        if jump_buffered:\n            jump()\n\nfunc _unhandled_input(event: InputEvent) -> void:\n    if not is_alive:\n        return\n    \n    if event.is_action_pressed(\"jump\"):\n        _handle_jump_input()\n    \n    if event.is_action_released(\"jump\"):\n        _handle_jump_release()\n    \n    if event.is_action_pressed(\"dash\") and dash_enabled:\n        _handle_dash_input()\n    \n    if event.is_action_pressed(\"attack\"):\n        attacked.emit()\n# endregion\n\n# region 移动\nfunc apply_movement(delta: float, direction: float) -> void:\n    if direction != 0:\n        velocity.x = move_toward(velocity.x, direction * move_speed, acceleration * delta)\n    else:\n        var current_friction = friction if is_on_floor() else air_friction\n        velocity.x = move_toward(velocity.x, 0, current_friction * delta)\n\nfunc apply_gravity(delta: float, multiplier: float = 1.0) -> void:\n    if not is_on_floor():\n        velocity.y += GRAVITY * multiplier * delta\n# endregion\n\n# region 跳跃\nfunc _handle_jump_input() -> void:\n    if is_on_floor() or can_coyote_jump:\n        jump()\n    elif jumps_remaining > 0:\n        jump()\n    else:\n        # 缓冲跳跃\n        jump_buffered = true\n        jump_buffer_timer.start(jump_buffer_time)\n\nfunc _handle_jump_release() -> void:\n    # 可变跳跃高度\n    if velocity.y \u003C 0:\n        velocity.y *= variable_jump_multiplier\n\nfunc jump() -> void:\n    velocity.y = jump_velocity\n    jumps_remaining -= 1\n    jump_buffered = false\n    can_coyote_jump = false\n    jumped.emit()\n\nfunc start_coyote_time() -> void:\n    can_coyote_jump = true\n    coyote_timer.start(coyote_time)\n# endregion\n\n# region 冲刺\nfunc _handle_dash_input() -> void:\n    if can_dash and not is_dashing:\n        dash()\n\nfunc dash() -> void:\n    is_dashing = true\n    can_dash = false\n    velocity = Vector2(facing_direction * dash_speed, 0)\n    \n    await get_tree().create_timer(dash_duration).timeout\n    is_dashing = false\n    \n    await get_tree().create_timer(dash_cooldown).timeout\n    can_dash = true\n# endregion\n\n# region 伤害与死亡\nfunc take_damage(amount: int, knockback: Vector2 = Vector2.ZERO) -> void:\n    if not is_alive:\n        return\n    \n    current_health -= amount\n    \n    if knockback != Vector2.ZERO:\n        velocity = knockback\n\nfunc heal(amount: int) -> void:\n    current_health += amount\n\nfunc _die() -> void:\n    died.emit()\n    # 播放死亡动画或处理\n# endregion\n\n# region 工具方法\nfunc _setup_timers() -> void:\n    coyote_timer.one_shot = true\n    coyote_timer.timeout.connect(func(): can_coyote_jump = false)\n    \n    jump_buffer_timer.one_shot = true\n    jump_buffer_timer.timeout.connect(func(): jump_buffered = false)\n\nfunc get_input_direction() -> float:\n    return Input.get_axis(\"move_left\", \"move_right\")\n# endregion\n```\n\n### 状态机基类 (state_machine.gd)\n\n```gdscript\n## 通用状态机\nclass_name StateMachine\nextends Node\n\nsignal state_changed(old_state: State, new_state: State)\n\n@export var initial_state: State\n\nvar current_state: State\nvar states: Dictionary = {}\n\nfunc _ready() -> void:\n    # 收集所有子状态\n    for child in get_children():\n        if child is State:\n            states[child.name.to_lower()] = child\n            child.state_machine = self\n            child.player = get_parent()\n    \n    # 设置初始状态\n    if initial_state:\n        current_state = initial_state\n        current_state.enter()\n\nfunc _process(delta: float) -> void:\n    if current_state:\n        current_state.update(delta)\n\nfunc _physics_process(delta: float) -> void:\n    if current_state:\n        current_state.physics_update(delta)\n        \n        # 检查状态转换\n        var next_state_name = current_state.get_transition()\n        if next_state_name != &\"\":\n            transition_to(next_state_name)\n\nfunc _unhandled_input(event: InputEvent) -> void:\n    if current_state:\n        current_state.handle_input(event)\n\nfunc transition_to(state_name: StringName) -> void:\n    var new_state = states.get(str(state_name).to_lower())\n    if new_state == null:\n        push_error(\"State not found: \" + str(state_name))\n        return\n    \n    if new_state == current_state:\n        return\n    \n    var old_state = current_state\n    current_state.exit()\n    current_state = new_state\n    current_state.enter()\n    \n    state_changed.emit(old_state, new_state)\n```\n\n### 状态基类 (state.gd)\n\n```gdscript\n## 状态基类\nclass_name State\nextends Node\n\nvar state_machine: StateMachine\nvar player: CharacterBody2D\n\nfunc enter() -> void:\n    pass\n\nfunc exit() -> void:\n    pass\n\nfunc update(_delta: float) -> void:\n    pass\n\nfunc physics_update(_delta: float) -> void:\n    pass\n\nfunc handle_input(_event: InputEvent) -> void:\n    pass\n\nfunc get_transition() -> StringName:\n    return &\"\"\n```\n\n### Idle 状态 (idle_state.gd)\n\n```gdscript\n## 待机状态\nclass_name IdleState\nextends State\n\nfunc enter() -> void:\n    player.animation_player.play(\"idle\")\n\nfunc physics_update(delta: float) -> void:\n    player.apply_movement(delta, 0)\n\nfunc get_transition() -> StringName:\n    if not player.is_on_floor():\n        return &\"fall\"\n    \n    if player.get_input_direction() != 0:\n        return &\"run\"\n    \n    return &\"\"\n```\n\n### Run 状态 (run_state.gd)\n\n```gdscript\n## 奔跑状态\nclass_name RunState\nextends State\n\nfunc enter() -> void:\n    player.animation_player.play(\"run\")\n\nfunc physics_update(delta: float) -> void:\n    var direction = player.get_input_direction()\n    player.apply_movement(delta, direction)\n\nfunc get_transition() -> StringName:\n    if not player.is_on_floor():\n        player.start_coyote_time()\n        return &\"fall\"\n    \n    if player.get_input_direction() == 0:\n        return &\"idle\"\n    \n    return &\"\"\n```\n\n### Jump 状态 (jump_state.gd)\n\n```gdscript\n## 跳跃状态\nclass_name JumpState\nextends State\n\nfunc enter() -> void:\n    player.animation_player.play(\"jump\")\n\nfunc physics_update(delta: float) -> void:\n    var direction = player.get_input_direction()\n    player.apply_movement(delta, direction)\n    player.apply_gravity(delta)\n\nfunc get_transition() -> StringName:\n    if player.velocity.y >= 0:\n        return &\"fall\"\n    \n    return &\"\"\n```\n\n### Fall 状态 (fall_state.gd)\n\n```gdscript\n## 下落状态\nclass_name FallState\nextends State\n\nfunc enter() -> void:\n    player.animation_player.play(\"fall\")\n\nfunc physics_update(delta: float) -> void:\n    var direction = player.get_input_direction()\n    player.apply_movement(delta, direction)\n    player.apply_gravity(delta)\n\nfunc get_transition() -> StringName:\n    if player.is_on_floor():\n        player.landed.emit()\n        if player.get_input_direction() != 0:\n            return &\"run\"\n        else:\n            return &\"idle\"\n    \n    return &\"\"\n```\n\n---\n\n## Top-down 2D 实现\n\n### 玩家脚本 (player_topdown.gd)\n\n```gdscript\n## 俯视角 2D 玩家控制器\nclass_name PlayerTopdown\nextends CharacterBody2D\n\n# region 信号\nsignal died\nsignal health_changed(old_value: int, new_value: int)\n# endregion\n\n# region 导出变量\n@export_group(\"Movement\")\n@export var move_speed: float = 200.0\n@export var acceleration: float = 2000.0\n@export var friction: float = 1800.0\n\n@export_group(\"Stats\")\n@export var max_health: int = 100\n# endregion\n\n# region 状态\nvar current_health: int:\n    set(value):\n        var old = current_health\n        current_health = clampi(value, 0, max_health)\n        health_changed.emit(old, current_health)\n        if current_health \u003C= 0:\n            _die()\n\nvar look_direction: Vector2 = Vector2.RIGHT\n# endregion\n\n# region 节点引用\n@onready var sprite: Sprite2D = $Sprite2D\n@onready var animation_player: AnimationPlayer = $AnimationPlayer\n# endregion\n\nfunc _ready() -> void:\n    current_health = max_health\n\nfunc _physics_process(delta: float) -> void:\n    var input_dir = Input.get_vector(\"move_left\", \"move_right\", \"move_up\", \"move_down\")\n    \n    if input_dir != Vector2.ZERO:\n        look_direction = input_dir.normalized()\n        velocity = velocity.move_toward(input_dir * move_speed, acceleration * delta)\n        _update_animation(\"walk\")\n    else:\n        velocity = velocity.move_toward(Vector2.ZERO, friction * delta)\n        _update_animation(\"idle\")\n    \n    # 更新朝向\n    _update_sprite_direction()\n    \n    move_and_slide()\n\nfunc _update_animation(anim_base: String) -> void:\n    var direction_suffix = _get_direction_suffix()\n    var anim_name = anim_base + \"_\" + direction_suffix\n    if animation_player.has_animation(anim_name):\n        animation_player.play(anim_name)\n\nfunc _get_direction_suffix() -> String:\n    # 8方向动画\n    var angle = look_direction.angle()\n    if angle \u003C -2.75 or angle > 2.75:\n        return \"left\"\n    elif angle \u003C -1.96:\n        return \"up_left\"\n    elif angle \u003C -1.18:\n        return \"up\"\n    elif angle \u003C -0.39:\n        return \"up_right\"\n    elif angle \u003C 0.39:\n        return \"right\"\n    elif angle \u003C 1.18:\n        return \"down_right\"\n    elif angle \u003C 1.96:\n        return \"down\"\n    else:\n        return \"down_left\"\n\nfunc _update_sprite_direction() -> void:\n    sprite.flip_h = look_direction.x \u003C 0\n\nfunc take_damage(amount: int) -> void:\n    current_health -= amount\n\nfunc _die() -> void:\n    died.emit()\n```\n\n---\n\n## Third Person 3D 实现\n\n### 玩家脚本 (player_3d.gd)\n\n```gdscript\n## 第三人称 3D 玩家控制器\nclass_name Player3D\nextends CharacterBody3D\n\n# region 信号\nsignal died\nsignal health_changed(old_value: int, new_value: int)\n# endregion\n\n# region 导出变量\n@export_group(\"Movement\")\n@export var move_speed: float = 5.0\n@export var sprint_speed: float = 8.0\n@export var acceleration: float = 10.0\n@export var rotation_speed: float = 10.0\n\n@export_group(\"Jump\")\n@export var jump_velocity: float = 4.5\n@export var gravity_multiplier: float = 1.0\n\n@export_group(\"Stats\")\n@export var max_health: int = 100\n\n@export_group(\"References\")\n@export var camera_pivot: Node3D\n# endregion\n\n# region 状态\nvar current_health: int\nvar is_sprinting: bool = false\nvar gravity: float = ProjectSettings.get_setting(\"physics\u002F3d\u002Fdefault_gravity\")\n# endregion\n\n# region 节点引用\n@onready var mesh: MeshInstance3D = $MeshInstance3D\n@onready var animation_tree: AnimationTree = $AnimationTree\n# endregion\n\nfunc _ready() -> void:\n    current_health = max_health\n    Input.mouse_mode = Input.MOUSE_MODE_CAPTURED\n\nfunc _physics_process(delta: float) -> void:\n    # 重力\n    if not is_on_floor():\n        velocity.y -= gravity * gravity_multiplier * delta\n    \n    # 跳跃\n    if Input.is_action_just_pressed(\"jump\") and is_on_floor():\n        velocity.y = jump_velocity\n    \n    # 冲刺\n    is_sprinting = Input.is_action_pressed(\"sprint\") and is_on_floor()\n    \n    # 移动输入\n    var input_dir = Input.get_vector(\"move_left\", \"move_right\", \"move_up\", \"move_down\")\n    \n    # 相对于摄像机的移动方向\n    var camera_basis = camera_pivot.global_transform.basis\n    var direction = (camera_basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()\n    direction.y = 0\n    \n    if direction:\n        var target_speed = sprint_speed if is_sprinting else move_speed\n        velocity.x = move_toward(velocity.x, direction.x * target_speed, acceleration * delta)\n        velocity.z = move_toward(velocity.z, direction.z * target_speed, acceleration * delta)\n        \n        # 旋转角色朝向移动方向\n        var target_rotation = atan2(-direction.x, -direction.z)\n        rotation.y = lerp_angle(rotation.y, target_rotation, rotation_speed * delta)\n    else:\n        velocity.x = move_toward(velocity.x, 0, acceleration * delta)\n        velocity.z = move_toward(velocity.z, 0, acceleration * delta)\n    \n    move_and_slide()\n    \n    # 更新动画\n    _update_animations()\n\nfunc _update_animations() -> void:\n    if animation_tree:\n        var speed = Vector2(velocity.x, velocity.z).length() \u002F sprint_speed\n        animation_tree.set(\"parameters\u002Fblend_position\", speed)\n\nfunc _unhandled_input(event: InputEvent) -> void:\n    if event.is_action_pressed(\"ui_cancel\"):\n        Input.mouse_mode = Input.MOUSE_MODE_VISIBLE\n\nfunc take_damage(amount: int) -> void:\n    var old = current_health\n    current_health = clampi(current_health - amount, 0, max_health)\n    health_changed.emit(old, current_health)\n    if current_health \u003C= 0:\n        died.emit()\n```\n\n---\n\n## 输入映射配置\n\n生成玩家系统时，自动在 project.godot 中添加输入映射：\n\n```ini\n[input]\n\nmove_left={\n\"deadzone\": 0.2,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"window_id\":0,\"alt_pressed\":false,\"shift_pressed\":false,\"ctrl_pressed\":false,\"meta_pressed\":false,\"pressed\":false,\"keycode\":65,\"physical_keycode\":0,\"key_label\":0,\"unicode\":0,\"echo\":false,\"script\":null)\n, Object(InputEventJoypadMotion,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"axis\":0,\"axis_value\":-1.0,\"script\":null)\n]\n}\nmove_right={\n\"deadzone\": 0.2,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"window_id\":0,\"keycode\":68,\"script\":null)\n, Object(InputEventJoypadMotion,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"axis\":0,\"axis_value\":1.0,\"script\":null)\n]\n}\nmove_up={\n\"deadzone\": 0.2,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"keycode\":87,\"script\":null)\n, Object(InputEventJoypadMotion,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"axis\":1,\"axis_value\":-1.0,\"script\":null)\n]\n}\nmove_down={\n\"deadzone\": 0.2,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"keycode\":83,\"script\":null)\n, Object(InputEventJoypadMotion,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"axis\":1,\"axis_value\":1.0,\"script\":null)\n]\n}\njump={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"keycode\":32,\"script\":null)\n, Object(InputEventJoypadButton,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"button_index\":0,\"pressure\":0.0,\"pressed\":false,\"script\":null)\n]\n}\ndash={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"keycode\":4194325,\"script\":null)\n, Object(InputEventJoypadButton,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"button_index\":4,\"script\":null)\n]\n}\nattack={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventMouseButton,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"window_id\":0,\"button_index\":1,\"pressed\":false,\"script\":null)\n, Object(InputEventJoypadButton,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"button_index\":5,\"script\":null)\n]\n}\ninteract={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"keycode\":69,\"script\":null)\n, Object(InputEventJoypadButton,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"button_index\":3,\"script\":null)\n]\n}\nsprint={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"keycode\":4194325,\"script\":null)\n]\n}\n```\n\n---\n\n## 使用示例\n\n### 生成 Platformer 2D 玩家\n\n```\n创建一个 2D 平台跳跃玩家控制器：\n- 支持移动、跳跃、二段跳\n- 支持冲刺\n- 支持攻击\n- 包含完整状态机\n```\n\n### 生成 Third Person 3D 玩家\n\n```\n创建一个第三人称 3D 玩家：\n- WASD 移动，空格跳跃\n- 与摄像机方向联动\n- 支持冲刺\n- 简单的攻击动作\n```\n","# 玩家控制系统技能\n\n生成完整的玩家控制系统，包含移动、状态机、输入处理等功能。\n\n## 支持的控制器类型\n\n### Platformer 2D（平台跳跃）\n\n**适用游戏**：横版动作、银河恶魔城、平台跳跃\n\n**特点**：\n- 基于 CharacterBody2D\n- 重力物理系统\n- 可配置浮空时间（Coyote Time）\n- 跳跃缓冲（Jump Buffer）\n- 可变跳跃高度\n\n**生成文件**：\n```\nres:\u002F\u002Fscenes\u002Fprefabs\u002Fplayer\u002Fplayer_2d.tscn\nres:\u002F\u002Fscripts\u002Fentities\u002Fplayer\u002Fplayer_2d.gd\nres:\u002F\u002Fscripts\u002Fentities\u002Fplayer\u002Fplayer_2d_controller.gd\nres:\u002F\u002Fscripts\u002Fentities\u002Fplayer\u002Fstates\u002F\n    ├── player_state.gd\n    ├── idle_state.gd\n    ├── run_state.gd\n    ├── jump_state.gd\n    ├── fall_state.gd\n    └── ...\n```\n\n### Top-down 2D（俯视角）\n\n**适用游戏**：RPG、动作冒险、射击游戏\n\n**特点**：\n- 8 方向移动\n- 可选瞄准系统\n- 平滑旋转\n\n### Third Person 3D（第三人称）\n\n**适用游戏**：动作 RPG、冒险游戏\n\n**特点**：\n- 与摄像机联动的移动方向\n- 斜坡处理\n- 阶梯检测\n\n### First Person 3D（第一人称）\n\n**适用游戏**：FPS、探索游戏、恐怖游戏\n\n**特点**：\n- 鼠标视角控制\n- 头部摇摆\n- 可选武器系统\n\n---\n\n## Platformer 2D 完整实现\n\n### 玩家场景结构\n\n```\nPlayer (CharacterBody2D)\n├── CollisionShape2D\n├── Sprite2D \u002F AnimatedSprite2D\n├── AnimationPlayer\n├── StateMachine\n│   ├── IdleState\n│   ├── RunState\n│   ├── JumpState\n│   ├── FallState\n│   ├── DashState (可选)\n│   └── AttackState (可选)\n├── Hitbox (Area2D) - 攻击判定\n├── Hurtbox (Area2D) - 受伤判定\n├── CoyoteTimer (Timer)\n├── JumpBufferTimer (Timer)\n└── Camera2D (可选)\n```\n\n### 玩家主脚本 (player_2d.gd)\n\n```gdscript\n## 2D 平台跳跃玩家控制器\n##\n## 包含移动、跳跃、攻击等核心功能\n## @author AI Generated\n## @version 1.0.0\nclass_name Player2D\nextends CharacterBody2D\n\n# region 信号\nsignal died\nsignal health_changed(old_value: int, new_value: int)\nsignal state_changed(old_state: String, new_state: String)\nsignal jumped\nsignal landed\nsignal attacked\n# endregion\n\n# region 常量\nconst GRAVITY: float = 980.0\n# endregion\n\n# region 导出变量 - 移动\n@export_group(\"Movement\")\n@export var move_speed: float = 200.0\n@export var acceleration: float = 1500.0\n@export var friction: float = 1200.0\n@export var air_friction: float = 600.0\n# endregion\n\n# region 导出变量 - 跳跃\n@export_group(\"Jump\")\n@export var jump_velocity: float = -350.0\n@export var max_jumps: int = 1\n@export var coyote_time: float = 0.1\n@export var jump_buffer_time: float = 0.1\n@export var variable_jump_multiplier: float = 0.5\n# endregion\n\n# region 导出变量 - 冲刺\n@export_group(\"Dash\")\n@export var dash_enabled: bool = true\n@export var dash_speed: float = 400.0\n@export var dash_duration: float = 0.2\n@export var dash_cooldown: float = 1.0\n# endregion\n\n# region 导出变量 - 属性\n@export_group(\"Stats\")\n@export var max_health: int = 100\n# endregion\n\n# region 状态变量\nvar current_health: int:\n    set(value):\n        var old = current_health\n        current_health = clampi(value, 0, max_health)\n        health_changed.emit(old, current_health)\n        if current_health \u003C= 0:\n            _die()\n\nvar is_alive: bool:\n    get: return current_health > 0\n\nvar facing_direction: int = 1  # 1 = 右, -1 = 左\nvar jumps_remaining: int = 0\nvar can_coyote_jump: bool = false\nvar jump_buffered: bool = false\nvar can_dash: bool = true\nvar is_dashing: bool = false\n# endregion\n\n# region 节点引用\n@onready var sprite: Sprite2D = $Sprite2D\n@onready var animation_player: AnimationPlayer = $AnimationPlayer\n@onready var state_machine: Node = $StateMachine\n@onready var coyote_timer: Timer = $CoyoteTimer\n@onready var jump_buffer_timer: Timer = $JumpBufferTimer\n# endregion\n\n# region 生命周期\nfunc _ready() -> void:\n    current_health = max_health\n    jumps_remaining = max_jumps\n    _setup_timers()\n\nfunc _physics_process(delta: float) -> void:\n    if not is_alive:\n        return\n    \n    # 重力\n    if not is_on_floor() and not is_dashing:\n        velocity.y += GRAVITY * delta\n    \n    # 更新朝向\n    var input_dir = Input.get_axis(\"move_left\", \"move_right\")\n    if input_dir != 0:\n        facing_direction = signi(input_dir)\n        sprite.flip_h = facing_direction \u003C 0\n    \n    move_and_slide()\n    \n    # 检测落地\n    if is_on_floor():\n        jumps_remaining = max_jumps\n        if jump_buffered:\n            jump()\n\nfunc _unhandled_input(event: InputEvent) -> void:\n    if not is_alive:\n        return\n    \n    if event.is_action_pressed(\"jump\"):\n        _handle_jump_input()\n    \n    if event.is_action_released(\"jump\"):\n        _handle_jump_release()\n    \n    if event.is_action_pressed(\"dash\") and dash_enabled:\n        _handle_dash_input()\n    \n    if event.is_action_pressed(\"attack\"):\n        attacked.emit()\n# endregion\n\n# region 移动\nfunc apply_movement(delta: float, direction: float) -> void:\n    if direction != 0:\n        velocity.x = move_toward(velocity.x, direction * move_speed, acceleration * delta)\n    else:\n        var current_friction = friction if is_on_floor() else air_friction\n        velocity.x = move_toward(velocity.x, 0, current_friction * delta)\n\nfunc apply_gravity(delta: float, multiplier: float = 1.0) -> void:\n    if not is_on_floor():\n        velocity.y += GRAVITY * multiplier * delta\n# endregion\n\n# region 跳跃\nfunc _handle_jump_input() -> void:\n    if is_on_floor() or can_coyote_jump:\n        jump()\n    elif jumps_remaining > 0:\n        jump()\n    else:\n        # 缓冲跳跃\n        jump_buffered = true\n        jump_buffer_timer.start(jump_buffer_time)\n\nfunc _handle_jump_release() -> void:\n    # 可变跳跃高度\n    if velocity.y \u003C 0:\n        velocity.y *= variable_jump_multiplier\n\nfunc jump() -> void:\n    velocity.y = jump_velocity\n    jumps_remaining -= 1\n    jump_buffered = false\n    can_coyote_jump = false\n    jumped.emit()\n\nfunc start_coyote_time() -> void:\n    can_coyote_jump = true\n    coyote_timer.start(coyote_time)\n# endregion\n\n# region 冲刺\nfunc _handle_dash_input() -> void:\n    if can_dash and not is_dashing:\n        dash()\n\nfunc dash() -> void:\n    is_dashing = true\n    can_dash = false\n    velocity = Vector2(facing_direction * dash_speed, 0)\n    \n    await get_tree().create_timer(dash_duration).timeout\n    is_dashing = false\n    \n    await get_tree().create_timer(dash_cooldown).timeout\n    can_dash = true\n# endregion\n\n# region 伤害与死亡\nfunc take_damage(amount: int, knockback: Vector2 = Vector2.ZERO) -> void:\n    if not is_alive:\n        return\n    \n    current_health -= amount\n    \n    if knockback != Vector2.ZERO:\n        velocity = knockback\n\nfunc heal(amount: int) -> void:\n    current_health += amount\n\nfunc _die() -> void:\n    died.emit()\n    # 播放死亡动画或处理\n# endregion\n\n# region 工具方法\nfunc _setup_timers() -> void:\n    coyote_timer.one_shot = true\n    coyote_timer.timeout.connect(func(): can_coyote_jump = false)\n    \n    jump_buffer_timer.one_shot = true\n    jump_buffer_timer.timeout.connect(func(): jump_buffered = false)\n\nfunc get_input_direction() -> float:\n    return Input.get_axis(\"move_left\", \"move_right\")\n# endregion\n```\n\n### 状态机基类 (state_machine.gd)\n\n```gdscript\n## 通用状态机\nclass_name StateMachine\nextends Node\n\nsignal state_changed(old_state: State, new_state: State)\n\n@export var initial_state: State\n\nvar current_state: State\nvar states: Dictionary = {}\n\nfunc _ready() -> void:\n    # 收集所有子状态\n    for child in get_children():\n        if child is State:\n            states[child.name.to_lower()] = child\n            child.state_machine = self\n            child.player = get_parent()\n    \n    # 设置初始状态\n    if initial_state:\n        current_state = initial_state\n        current_state.enter()\n\nfunc _process(delta: float) -> void:\n    if current_state:\n        current_state.update(delta)\n\nfunc _physics_process(delta: float) -> void:\n    if current_state:\n        current_state.physics_update(delta)\n        \n        # 检查状态转换\n        var next_state_name = current_state.get_transition()\n        if next_state_name != &\"\":\n            transition_to(next_state_name)\n\nfunc _unhandled_input(event: InputEvent) -> void:\n    if current_state:\n        current_state.handle_input(event)\n\nfunc transition_to(state_name: StringName) -> void:\n    var new_state = states.get(str(state_name).to_lower())\n    if new_state == null:\n        push_error(\"State not found: \" + str(state_name))\n        return\n    \n    if new_state == current_state:\n        return\n    \n    var old_state = current_state\n    current_state.exit()\n    current_state = new_state\n    current_state.enter()\n    \n    state_changed.emit(old_state, new_state)\n```\n\n### 状态基类 (state.gd)\n\n```gdscript\n## 状态基类\nclass_name State\nextends Node\n\nvar state_machine: StateMachine\nvar player: CharacterBody2D\n\nfunc enter() -> void:\n    pass\n\nfunc exit() -> void:\n    pass\n\nfunc update(_delta: float) -> void:\n    pass\n\nfunc physics_update(_delta: float) -> void:\n    pass\n\nfunc handle_input(_event: InputEvent) -> void:\n    pass\n\nfunc get_transition() -> StringName:\n    return &\"\"\n```\n\n### Idle 状态 (idle_state.gd)\n\n```gdscript\n## 待机状态\nclass_name IdleState\nextends State\n\nfunc enter() -> void:\n    player.animation_player.play(\"idle\")\n\nfunc physics_update(delta: float) -> void:\n    player.apply_movement(delta, 0)\n\nfunc get_transition() -> StringName:\n    if not player.is_on_floor():\n        return &\"fall\"\n    \n    if player.get_input_direction() != 0:\n        return &\"run\"\n    \n    return &\"\"\n```\n\n### Run 状态 (run_state.gd)\n\n```gdscript\n## 奔跑状态\nclass_name RunState\nextends State\n\nfunc enter() -> void:\n    player.animation_player.play(\"run\")\n\nfunc physics_update(delta: float) -> void:\n    var direction = player.get_input_direction()\n    player.apply_movement(delta, direction)\n\nfunc get_transition() -> StringName:\n    if not player.is_on_floor():\n        player.start_coyote_time()\n        return &\"fall\"\n    \n    if player.get_input_direction() == 0:\n        return &\"idle\"\n    \n    return &\"\"\n```\n\n### Jump 状态 (jump_state.gd)\n\n```gdscript\n## 跳跃状态\nclass_name JumpState\nextends State\n\nfunc enter() -> void:\n    player.animation_player.play(\"jump\")\n\nfunc physics_update(delta: float) -> void:\n    var direction = player.get_input_direction()\n    player.apply_movement(delta, direction)\n    player.apply_gravity(delta)\n\nfunc get_transition() -> StringName:\n    if player.velocity.y >= 0:\n        return &\"fall\"\n    \n    return &\"\"\n```\n\n### Fall 状态 (fall_state.gd)\n\n```gdscript\n## 下落状态\nclass_name FallState\nextends State\n\nfunc enter() -> void:\n    player.animation_player.play(\"fall\")\n\nfunc physics_update(delta: float) -> void:\n    var direction = player.get_input_direction()\n    player.apply_movement(delta, direction)\n    player.apply_gravity(delta)\n\nfunc get_transition() -> StringName:\n    if player.is_on_floor():\n        player.landed.emit()\n        if player.get_input_direction() != 0:\n            return &\"run\"\n        else:\n            return &\"idle\"\n    \n    return &\"\"\n```\n\n---\n\n## Top-down 2D 实现\n\n### 玩家脚本 (player_topdown.gd)\n\n```gdscript\n## 俯视角 2D 玩家控制器\nclass_name PlayerTopdown\nextends CharacterBody2D\n\n# region 信号\nsignal died\nsignal health_changed(old_value: int, new_value: int)\n# endregion\n\n# region 导出变量\n@export_group(\"Movement\")\n@export var move_speed: float = 200.0\n@export var acceleration: float = 2000.0\n@export var friction: float = 1800.0\n\n@export_group(\"Stats\")\n@export var max_health: int = 100\n# endregion\n\n# region 状态\nvar current_health: int:\n    set(value):\n        var old = current_health\n        current_health = clampi(value, 0, max_health)\n        health_changed.emit(old, current_health)\n        if current_health \u003C= 0:\n            _die()\n\nvar look_direction: Vector2 = Vector2.RIGHT\n# endregion\n\n# region 节点引用\n@onready var sprite: Sprite2D = $Sprite2D\n@onready var animation_player: AnimationPlayer = $AnimationPlayer\n# endregion\n\nfunc _ready() -> void:\n    current_health = max_health\n\nfunc _physics_process(delta: float) -> void:\n    var input_dir = Input.get_vector(\"move_left\", \"move_right\", \"move_up\", \"move_down\")\n    \n    if input_dir != Vector2.ZERO:\n        look_direction = input_dir.normalized()\n        velocity = velocity.move_toward(input_dir * move_speed, acceleration * delta)\n        _update_animation(\"walk\")\n    else:\n        velocity = velocity.move_toward(Vector2.ZERO, friction * delta)\n        _update_animation(\"idle\")\n    \n    # 更新朝向\n    _update_sprite_direction()\n    \n    move_and_slide()\n\nfunc _update_animation(anim_base: String) -> void:\n    var direction_suffix = _get_direction_suffix()\n    var anim_name = anim_base + \"_\" + direction_suffix\n    if animation_player.has_animation(anim_name):\n        animation_player.play(anim_name)\n\nfunc _get_direction_suffix() -> String:\n    # 8方向动画\n    var angle = look_direction.angle()\n    if angle \u003C -2.75 or angle > 2.75:\n        return \"left\"\n    elif angle \u003C -1.96:\n        return \"up_left\"\n    elif angle \u003C -1.18:\n        return \"up\"\n    elif angle \u003C -0.39:\n        return \"up_right\"\n    elif angle \u003C 0.39:\n        return \"right\"\n    elif angle \u003C 1.18:\n        return \"down_right\"\n    elif angle \u003C 1.96:\n        return \"down\"\n    else:\n        return \"down_left\"\n\nfunc _update_sprite_direction() -> void:\n    sprite.flip_h = look_direction.x \u003C 0\n\nfunc take_damage(amount: int) -> void:\n    current_health -= amount\n\nfunc _die() -> void:\n    died.emit()\n```\n\n---\n\n## Third Person 3D 实现\n\n### 玩家脚本 (player_3d.gd)\n\n```gdscript\n## 第三人称 3D 玩家控制器\nclass_name Player3D\nextends CharacterBody3D\n\n# region 信号\nsignal died\nsignal health_changed(old_value: int, new_value: int)\n# endregion\n\n# region 导出变量\n@export_group(\"Movement\")\n@export var move_speed: float = 5.0\n@export var sprint_speed: float = 8.0\n@export var acceleration: float = 10.0\n@export var rotation_speed: float = 10.0\n\n@export_group(\"Jump\")\n@export var jump_velocity: float = 4.5\n@export var gravity_multiplier: float = 1.0\n\n@export_group(\"Stats\")\n@export var max_health: int = 100\n\n@export_group(\"References\")\n@export var camera_pivot: Node3D\n# endregion\n\n# region 状态\nvar current_health: int\nvar is_sprinting: bool = false\nvar gravity: float = ProjectSettings.get_setting(\"physics\u002F3d\u002Fdefault_gravity\")\n# endregion\n\n# region 节点引用\n@onready var mesh: MeshInstance3D = $MeshInstance3D\n@onready var animation_tree: AnimationTree = $AnimationTree\n# endregion\n\nfunc _ready() -> void:\n    current_health = max_health\n    Input.mouse_mode = Input.MOUSE_MODE_CAPTURED\n\nfunc _physics_process(delta: float) -> void:\n    # 重力\n    if not is_on_floor():\n        velocity.y -= gravity * gravity_multiplier * delta\n    \n    # 跳跃\n    if Input.is_action_just_pressed(\"jump\") and is_on_floor():\n        velocity.y = jump_velocity\n    \n    # 冲刺\n    is_sprinting = Input.is_action_pressed(\"sprint\") and is_on_floor()\n    \n    # 移动输入\n    var input_dir = Input.get_vector(\"move_left\", \"move_right\", \"move_up\", \"move_down\")\n    \n    # 相对于摄像机的移动方向\n    var camera_basis = camera_pivot.global_transform.basis\n    var direction = (camera_basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()\n    direction.y = 0\n    \n    if direction:\n        var target_speed = sprint_speed if is_sprinting else move_speed\n        velocity.x = move_toward(velocity.x, direction.x * target_speed, acceleration * delta)\n        velocity.z = move_toward(velocity.z, direction.z * target_speed, acceleration * delta)\n        \n        # 旋转角色朝向移动方向\n        var target_rotation = atan2(-direction.x, -direction.z)\n        rotation.y = lerp_angle(rotation.y, target_rotation, rotation_speed * delta)\n    else:\n        velocity.x = move_toward(velocity.x, 0, acceleration * delta)\n        velocity.z = move_toward(velocity.z, 0, acceleration * delta)\n    \n    move_and_slide()\n    \n    # 更新动画\n    _update_animations()\n\nfunc _update_animations() -> void:\n    if animation_tree:\n        var speed = Vector2(velocity.x, velocity.z).length() \u002F sprint_speed\n        animation_tree.set(\"parameters\u002Fblend_position\", speed)\n\nfunc _unhandled_input(event: InputEvent) -> void:\n    if event.is_action_pressed(\"ui_cancel\"):\n        Input.mouse_mode = Input.MOUSE_MODE_VISIBLE\n\nfunc take_damage(amount: int) -> void:\n    var old = current_health\n    current_health = clampi(current_health - amount, 0, max_health)\n    health_changed.emit(old, current_health)\n    if current_health \u003C= 0:\n        died.emit()\n```\n\n---\n\n## 输入映射配置\n\n生成玩家系统时，自动在 project.godot 中添加输入映射：\n\n```ini\n[input]\n\nmove_left={\n\"deadzone\": 0.2,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"window_id\":0,\"alt_pressed\":false,\"shift_pressed\":false,\"ctrl_pressed\":false,\"meta_pressed\":false,\"pressed\":false,\"keycode\":65,\"physical_keycode\":0,\"key_label\":0,\"unicode\":0,\"echo\":false,\"script\":null)\n, Object(InputEventJoypadMotion,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"axis\":0,\"axis_value\":-1.0,\"script\":null)\n]\n}\nmove_right={\n\"deadzone\": 0.2,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"window_id\":0,\"keycode\":68,\"script\":null)\n, Object(InputEventJoypadMotion,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"axis\":0,\"axis_value\":1.0,\"script\":null)\n]\n}\nmove_up={\n\"deadzone\": 0.2,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"keycode\":87,\"script\":null)\n, Object(InputEventJoypadMotion,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"axis\":1,\"axis_value\":-1.0,\"script\":null)\n]\n}\nmove_down={\n\"deadzone\": 0.2,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"keycode\":83,\"script\":null)\n, Object(InputEventJoypadMotion,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"axis\":1,\"axis_value\":1.0,\"script\":null)\n]\n}\njump={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"keycode\":32,\"script\":null)\n, Object(InputEventJoypadButton,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"button_index\":0,\"pressure\":0.0,\"pressed\":false,\"script\":null)\n]\n}\ndash={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"keycode\":4194325,\"script\":null)\n, Object(InputEventJoypadButton,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"button_index\":4,\"script\":null)\n]\n}\nattack={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventMouseButton,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"window_id\":0,\"button_index\":1,\"pressed\":false,\"script\":null)\n, Object(InputEventJoypadButton,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"button_index\":5,\"script\":null)\n]\n}\ninteract={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"keycode\":69,\"script\":null)\n, Object(InputEventJoypadButton,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":-1,\"button_index\":3,\"script\":null)\n]\n}\nsprint={\n\"deadzone\": 0.5,\n\"events\": [Object(InputEventKey,\"resource_local_to_scene\":false,\"resource_name\":\"\",\"device\":0,\"keycode\":4194325,\"script\":null)\n]\n}\n```\n\n---\n\n## 使用示例\n\n### 生成 Platformer 2D 玩家\n\n```\n创建一个 2D 平台跳跃玩家控制器：\n- 支持移动、跳跃、二段跳\n- 支持冲刺\n- 支持攻击\n- 包含完整状态机\n```\n\n### 生成 Third Person 3D 玩家\n\n```\n创建一个第三人称 3D 玩家：\n- WASD 移动，空格跳跃\n- 与摄像机方向联动\n- 支持冲刺\n- 简单的攻击动作\n```\n",{"name":5,"inputs":45,"outputs":68,"version":78,"triggers":79,"description":82,"dependencies":83},[46,55],{"enum":47,"name":52,"type":53,"required":54},[48,49,50,51],"platformer_2d","topdown_2d","third_person_3d","first_person_3d","player_type","string",true,{"name":56,"type":57,"items":58,"required":41},"features","array",{"enum":59},[60,61,62,23,63,64,65,66,67],"movement","jump","double_jump","attack","interact","crouch","climb","swim",[69,72,75],{"name":70,"type":37,"path_pattern":71},"player_scene","res:\u002F\u002Fscenes\u002Fprefabs\u002Fplayer\u002Fplayer.tscn",{"name":73,"type":37,"path_pattern":74},"player_script","res:\u002F\u002Fscripts\u002Fentities\u002Fplayer\u002Fplayer.gd",{"name":76,"type":30,"path_pattern":77},"player_states","res:\u002F\u002Fscripts\u002Fentities\u002Fplayer\u002Fstates\u002F","1.0.0",[80],{"pattern":81},"玩家控制|角色控制|移动系统|Player|玩家移动","玩家控制系统技能。生成完整的玩家控制器，包括移动、跳跃、攻击、状态机等功能。 支持 2D 和 3D 多种控制模式。\n",[84,85,86],"godot-core","code-generator","input-system","main","18d0e63d1313ca87098f614aa7c1e2dcf6de79c7","backend\u002Fskills\u002Fmarketplace\u002Fcodebuddy-plugins-official\u002Fplugins\u002Fgodot-mcp\u002Fskills\u002Fgodot-dev\u002Flevel-2-modules\u002Fplayer-system",1,"https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system","https:\u002F\u002Fgithub.com\u002Fwelflau","2026-11-12 14:55:20",{"source":8,"skillName":5,"commands":95,"prompt":105,"zipAvailable":54},[96,99,102],{"tool":97,"command":98},"npx","npx skills add welflau\u002Fai-dev-system --skill player-system",{"tool":100,"command":101},"bunx","bunx skills add welflau\u002Fai-dev-system --skill player-system",{"tool":103,"command":104},"pnpm","pnpm dlx skills add welflau\u002Fai-dev-system --skill player-system","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system\u002Fblob\u002Fmain\u002Fbackend\u002Fskills\u002Fmarketplace\u002Fcodebuddy-plugins-official\u002Fplugins\u002Fgodot-mcp\u002Fskills\u002Fgodot-dev\u002Flevel-2-modules\u002Fplayer-system\u002FSKILL.md",[],[108,142,173,198,224,248],{"skillNo":109,"name":110,"nameZh":6,"description":111,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":112,"licenseFileUrl":113,"sourceHtmlUrl":114,"categories":115,"keywords":121,"publishedAt":40},"01M6HSTDP4M3JFXEBK91VFB4PA","web-artifacts-builder","Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn\u002Fui). Use for complex artifacts requiring state management, routing, or shadcn\u002Fui components - not for simple single-file HTML\u002FJSX artifacts.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system\u002Fblob\u002Fmain\u002Fbackend\u002Fskills\u002Fmarketplace\u002Fcodebuddy-plugins-official\u002Fplugins\u002Fweb-artifacts-builder\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system\u002Fblob\u002Fmain\u002Fbackend\u002Fskills\u002Fmarketplace\u002Fcodebuddy-plugins-official\u002Fplugins\u002Fweb-artifacts-builder\u002FSKILL.md",[116],{"categoryNo":117,"categoryName":118,"taxonomyType":119,"taxonomyTypeDesc":120},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",[122,123,124,125,126,127,128,129,130,131,132,133,37,134,135,136,137,138,139,140,141],"web artifacts builder","web","artifacts","artifacts builder","builder","frontend","css","components","react","routing","state management","state","Tailwind","use","single-file","simple","ui components","multi","for","single",{"skillNo":143,"name":144,"nameZh":6,"description":145,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":112,"licenseFileUrl":146,"sourceHtmlUrl":147,"categories":148,"keywords":158,"publishedAt":40},"01M6HSDXH0JSP8R3QTNY9XZ8HN","frontend-design","Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML\u002FCSS layouts, or when styling\u002Fbeautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.","https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system\u002Fblob\u002Fmain\u002Fbackend\u002Fskills\u002Fmarketplace\u002Fcodebuddy-plugins-official\u002Fplugins\u002Ffrontend-design\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system\u002Fblob\u002Fmain\u002Fbackend\u002Fskills\u002Fmarketplace\u002Fcodebuddy-plugins-official\u002Fplugins\u002Ffrontend-design\u002FSKILL.md",[149,150,153],{"categoryNo":117,"categoryName":118,"taxonomyType":119,"taxonomyTypeDesc":120},{"categoryNo":151,"categoryName":152,"taxonomyType":119,"taxonomyTypeDesc":120},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":154,"categoryName":155,"taxonomyType":156,"taxonomyTypeDesc":157},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[127,159,160,128,123,129,130,161,162,38,124,163,164,165,135,166,167,168,169,170,171,172],"design","frontend design","react components","create","examples","applications","landing","ui design","pages","aesthetics","web ui","with","generic","when",{"skillNo":174,"name":175,"nameZh":6,"description":176,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":112,"licenseFileUrl":177,"sourceHtmlUrl":178,"categories":179,"keywords":181,"publishedAt":40},"01M6HSA77QYVP7A72HREGTDN2C","algorithmic-art","Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.","https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system\u002Fblob\u002Fmain\u002Fbackend\u002Fskills\u002Fmarketplace\u002Fcodebuddy-plugins-official\u002Fplugins\u002Falgorithmic-art\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system\u002Fblob\u002Fmain\u002Fbackend\u002Fskills\u002Fmarketplace\u002Fcodebuddy-plugins-official\u002Fplugins\u002Falgorithmic-art\u002FSKILL.md",[180],{"categoryNo":151,"categoryName":152,"taxonomyType":119,"taxonomyTypeDesc":120},[182,183,184,162,38,185,186,187,188,135,189,190,191,192,170,193,194,195,196,197,172],"algorithmic art","Art","algorithmic","flow","js","work","interactive","generative art","exploration","systems","users","Existing","request","generative","copyright","fields",{"skillNo":199,"name":200,"nameZh":6,"description":201,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":112,"licenseFileUrl":202,"sourceHtmlUrl":203,"categories":204,"keywords":206,"publishedAt":40},"01M6HS9HE0X390Y6RQKTY1YNGJ","theme-factory","Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors\u002Ffonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.","https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system\u002Fblob\u002Fmain\u002Fbackend\u002Fskills\u002Fmarketplace\u002Fcodebuddy-plugins-official\u002Fexternal_plugins\u002Ftheme-factory\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system\u002Fblob\u002Fmain\u002Fbackend\u002Fskills\u002Fmarketplace\u002Fcodebuddy-plugins-official\u002Fexternal_plugins\u002Ftheme-factory\u002FSKILL.md",[205],{"categoryNo":151,"categoryName":152,"taxonomyType":119,"taxonomyTypeDesc":120},[207,208,209,210,211,212,124,213,214,215,165,216,217,167,218,170,219,220,221,140,222,223],"theme factory","factory","theme","docs","toolkit","generate","SET","fly","slides","styling","artifact","themes","you","fonts","can","apply","new",{"skillNo":225,"name":226,"nameZh":6,"description":227,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":228,"categories":229,"keywords":233,"publishedAt":40},"01M6HS74GASM6FJ77F83EY679E","browsing","Use when you need direct browser control - teaches Chrome DevTools Protocol for controlling existing browser sessions, multi-tab management, form automation, and content extraction via use_browser MCP tool","https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system\u002Fblob\u002Fmain\u002Fbackend\u002Fskills\u002Fmarketplace\u002Fcodebuddy-plugins-official\u002Fexternal_plugins\u002Fsuperpowers-chrome\u002Fskills\u002Fbrowsing\u002FSKILL.md",[230],{"categoryNo":231,"categoryName":232,"taxonomyType":119,"taxonomyTypeDesc":120},"01JBSEEDCAT000000000000023","Skill与智能体开发",[226,234,235,236,237,238,239,240,241,242,243,135,244,245,246,247,139,219,140,193],"MCP","automation","chrome","sessions","protocol","browser","devtools","chrome devtools","tool","direct","browser control","control","via","form",{"skillNo":249,"name":250,"nameZh":6,"description":251,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":112,"licenseFileUrl":252,"sourceHtmlUrl":253,"categories":254,"keywords":261,"publishedAt":40},"01M6HS6BZT2CKDNQ6YF20DXN4T","slack-gif-creator","Knowledge and utilities for creating animated GIFs optimized for Slack. Provides constraints, validation tools, and animation concepts. Use when users request animated GIFs for Slack like \"make me a GIF of X doing Y for Slack.\"","https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system\u002Fblob\u002Fmain\u002Fbackend\u002Fskills\u002Fmarketplace\u002Fcodebuddy-plugins-official\u002Fexternal_plugins\u002Fslack-gif-creator\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system\u002Fblob\u002Fmain\u002Fbackend\u002Fskills\u002Fmarketplace\u002Fcodebuddy-plugins-official\u002Fexternal_plugins\u002Fslack-gif-creator\u002FSKILL.md",[255,258],{"categoryNo":256,"categoryName":257,"taxonomyType":119,"taxonomyTypeDesc":120},"01JBSEEDCAT000000000000005","邮件与沟通",{"categoryNo":259,"categoryName":260,"taxonomyType":119,"taxonomyTypeDesc":120},"01JBSEEDCAT000000000000016","图像与多媒体",[262,263,264,265,266,267,268,269,270,135,271,192,272,273,274,140,194,172],"slack gif creator","slack","gif","creator","validation","Tools","constraints","Animation","knowledge","me","make","Utilities","concepts"]