在Godot中为您的游戏添加并控制游戏角色的完整技术指南

这是一个在Godot中为您的游戏添加并控制玩家角色的完整技术指南。这个过程分为三大步:​准备资源、构建场景、编写控制脚本。

道可道,非常道,名可名,非常名!


第一步:准备资源(建模与动画)

在将角色放入Godot之前,您需要准备好模型本身和它的动画。

  1. 获取模型​:

    • 自己制作:使用Blender、Maya等3D软件创建您的3D游戏人物角色模型。确保骨骼(Armature)设置正确,这是做动画的基础。
    • 使用市场资源:可以从TurboSquid、CGTrader或Godot/Unity的Asset Store购买符合设定风格的3D游戏人物角色模型。
    • 重要格式 :将模型导出为 **.gltf​ 或 ​ .glb** 格式。这是Godot官方推荐的最佳格式,能完美保留模型、材质和骨骼信息。
  2. 准备动画​:

    • 您的角色需要一系列动画片段(Animation Clip)。最起码需要:
      • Idle(待机呼吸动画)
      • Run(跑步)
      • Attack_01, Attack_02(攻击动画,舞剑、施法等)
      • (可选)Jump(跳跃)
    • 这些动画可以是模型自带的,也可以在Blender中制作,或者从动画库中购买并重定向(Retarget)到您的模型上。
  3. 导入Godot​:

    • 将下载或制作好的 .gltf/.glb 文件直接拖放到Godot的 ​"文件系统"​ dock中。
    • 选中导入的模型资源,在 ​"导入"​ dock中,确保 ​"存储"​ 模式被选中(推荐),然后点击 ​"重新导入"​ 。这会将模型转换为Godot内部的场景格式(.tscn)。

第二步:在Godot中构建角色场景

Godot采用场景树(Scene Tree)的层次结构,一个复杂的角色通常不是一个简单的节点,而是一个由多个节点组成的场景。

  1. 创建根节点 :新建一个场景,选择 **CharacterBody3D** 作为根节点,并将其命名为 Game Character。这是专门用于受物理控制的三维角色的节点类型。
  2. 添加子节点
    • CharacterBody3D 下添加一个 **MeshInstance3D​ 节点。将导入的3D游戏角色人物模型拖拽到其 ​Mesh** 属性中。
    • CharacterBody3D 下添加一个 **CollisionShape3D​ 节点。为其 ​ Shape​ 属性选择一个简单的碰撞体,如 CapsuleShape3D(胶囊体)。调整胶囊体的大小,使其包裹住模型。​这是为了物理引擎能处理角色的移动和碰撞。**
    • CharacterBody3D 下添加一个 **AnimationPlayer​ 节点。将您准备好的动画片段(如Idle, Run, Attack)导入或赋值给该节点。​这是控制角色动画的核心。**
    • (可选但推荐)在 CharacterBody3D 下添加一个 **Camera3D​ 节点,并将其设置为当前视角。再添加一个 ​ SpringArm3D​ (弹簧臂)节点,并将 Camera3D 作为其子节点。​这样可以轻松实现一个跟随角色并避免穿墙的第三人称相机。**

完成后,您的场景结构应大致如下:

复制代码
FemaleCultivator (CharacterBody3D)
├── MeshInstance3D (你的游戏角色模型)
├── CollisionShape3D (CapsuleShape3D)
├── AnimationPlayer
└── SpringArm3D
    └── Camera3D

保存这个场景 ​(例如 game_character.tscn)。


第三步:编写控制脚本(GDScript)

CharacterBody3D 根节点附加一个新的脚本(例如 game_character.gd),这是实现键盘鼠标控制的核心。

复制代码
extends CharacterBody3D

# 角色移动属性
@export var speed = 5.0
@export var jump_velocity = 4.5
@export var rotation_speed = 10.0 # 鼠标控制旋转的速度

# 获取子节点引用
@onready var animation_player = $AnimationPlayer
@onready var spring_arm = $SpringArm3D

func _ready():
    # 初始播放待机动画
    animation_player.play("Idle")

func _input(event):
    # 鼠标点击事件处理攻击
    if event is InputEventMouseButton and event.pressed:
        if event.button_index == MOUSE_BUTTON_LEFT: # 左键攻击
            animation_player.play("Attack_01")
        # 可以扩展右键或其他按键

func _physics_process(delta):
    # 获取输入方向
    var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
    var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()

    # 应用重力
    if not is_on_floor():
        velocity.y -= 9.8 * delta
    else:
        # 跳跃
        if Input.is_action_just_pressed("ui_accept"): # 空格键
            velocity.y = jump_velocity

    # 地面移动
    if direction:
        velocity.x = direction.x * speed
        velocity.z = direction.z * speed
        
        # 让角色面向移动方向(平滑旋转)
        var target_angle = atan2(direction.x, direction.z)
        rotation.y = lerp_angle(rotation.y, target_angle, delta * rotation_speed)
        
        # 播放跑步动画(如果当前没在攻击)
        if animation_player.current_animation != "Attack_01":
            animation_player.play("Run")
    else:
        velocity.x = move_toward(velocity.x, 0, speed)
        velocity.z = move_toward(velocity.z, 0, speed)
        # 播放待机动画(如果当前没在攻击且在地面)
        if is_on_floor() and animation_player.current_animation != "Attack_01":
            animation_player.play("Idle")

    # 使用CharacterBody3D的内置方法移动角色
    move_and_slide()

    # --- 鼠标控制相机旋转(可选,增强体验)---
    if Input.is_action_pressed("rotate_camera"): # 例如,按住右键旋转相机
        var mouse_motion = Input.get_last_mouse_velocity()
        spring_arm.rotation_degrees.y -= mouse_motion.x * delta * 0.1
        spring_arm.rotation_degrees.x = clamp(spring_arm.rotation_degrees.x - mouse_motion.y * delta * 0.1, -90, 30)
关键代码解释:​
  1. **_physics_process(delta)**:每帧被调用的物理处理函数,处理移动、重力、跳跃等。
  2. **Input.get_vector(...)**:获取WASD键盘输入,并转换为一个方向向量。
  3. **move_and_slide()**:CharacterBody3D的核心方法,根据计算好的 velocity 移动角色并处理碰撞。
  4. **AnimationPlayer.play()**:播放指定的动画片段。
  5. **_input(event)**:处理输入事件,这里用于捕获鼠标点击来触发攻击动画。
第四步:配置输入映射

在Godot顶部菜单栏进入:​项目 -> 项目设置 -> 输入映射

添加以下操作(Action),并绑定对应的按键:

  • move_left -> A键
  • move_right -> D键
  • move_forward -> W键
  • move_back -> S键
  • ui_accept -> Space键 (跳跃)
  • rotate_camera -> Mouse Right Button (鼠标右键)

总结与测试

  1. 将你保存好的 game_character.tscn 角色场景拖放到你的主世界场景中。
  2. 运行游戏。
  3. 你现在应该可以使用 WASD 控制游戏角色移动,空格键 跳跃,鼠标左键触发攻击动画。一个基础的第三人称控制器就完成了。

后续优化方向​:

  • 动画状态机 :使用 AnimationTree 节点的 State Machine 来管理动画切换,比用代码 play() 更强大、更清晰。
  • 连招系统 :在 _input 函数中记录按键序列,根据不同的序列播放不同的攻击动画组合。
  • 技能特效:在攻击动画的关键帧上插入函数调用,实例化(Instantiate)刀光、剑气等粒子特效(Particles)场景。

从零开始,进行游戏项目开发,是一个循序渐进 的过程!稳步前行,稳中求胜

相关推荐
eqwaak02 小时前
科技信息差(8.26)
大数据·开发语言·人工智能·编辑器
腾讯云云开发2 小时前
AI编程能做什么?9个优秀案例,手把手图文教程,部分实战作品已开源
ai编程·游戏开发·小程序·云开发
yaoxin5211234 小时前
168. Java Lambda 表达式 - 专用比较器
java·开发语言
shylyly_4 小时前
Linux->多线程3
java·linux·开发语言·阻塞队列·生产者消费者模型
yw00yw5 小时前
常见的设计模式
开发语言·javascript·设计模式
我不是星海6 小时前
RabbitMQ基础入门实战
java·开发语言
jingfeng5146 小时前
C++多态
开发语言·c++
kyle~6 小时前
C/C++---浮点数与整形的转换,为什么使用sqrt函数时,要给参数加上一个极小的小数(如1e-6)
c语言·开发语言·c++
暖苏7 小时前
python-多线程(笔记)(持续更新)
大数据·开发语言·python