[Godot]1.在Godot中创建你的第一个角色(动图教程)

这个例子所使用的素材来自Sprout Lands Basic pack,来自:Sprout Lands - 制作人:Cup Nooble

演示环境

Godot版本:4.3 stable

操作系统:Windows 11 x86-64

本章节目标效果:

如果在自行操作的过程中遇到难以解决的困难,也可以直接到文末获取该godot项目完整的代码。

如果你还未下载和安装Godot,可以参考0.下载安装和使用godot

创建你的Godot项目

启动godot程序,点击创建

输入项目名称,选择项目路径。为了便于后续找到你的项目,请保持好良好的文件存放习惯。

建议将你的Godot项目全部存放在电脑C盘以外的某个磁盘(如果你的系统是win),并按照一定逻辑命名项目路径。

为了避免潜在的不兼容风险,请确保项目路径中不要有中文。

由于本项目完全不涉及3D场景,后续可能有发布到Web平台的需求,因此渲染器选择”兼容”。

版本控制元数据:选择”无”。

点击”创建并编辑”,正式创建项目。

素材获取与导入

素材获取

素材包Sprout Lands Basic pack 由创作者Cup Nooble发布于itch.io

itch.io是一个海外知名独立游戏平台,在其上有着大量免费或收费的游戏素材。Godot开发者也可以把自己的游戏作品发布到该平台。

素材获取地址:

Sprout Lands - Asset Pack by Cup Nooble

 

下载后解压如下图:

素材重命名

godot官方文档建议将项目内所有文件(C#脚本除外)命名为snake_case格式,原因详见官方文档,因此请先把所有目录内所有文件按snake_case风格进行重命名。

snake_case命名风格,即全部单词小写,单词之间用下划线_分割。

下面提供一段Python程序,帮助你快速完成重命名工作。

import os
import re
# 将字符串转换为snake_case(不修改后缀名的点)
def to_snake_case(name):
    # 分离文件名和扩展名
    name, ext = os.path.splitext(name)
    # 使用正则表达式将大写字母转为小写并前面加下划线(只对文件名部分)
    name = re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', name)
    # 将所有空格或其他非字母数字字符转换为下划线(只对文件名部分)
    name = re.sub(r'[^a-z0-9\u4e00-\u9fa5]+', '_', name.lower())  # 允许中文字符
    # 移除开头和结尾的下划线
    name = name.strip('_')
    # 保持扩展名的小写(只修改扩展名的字母部分)
    return name + ext.lower()
# 重命名目录和文件
def rename_files_and_dirs(root_dir):
    for root, dirs, files in os.walk(root_dir, topdown=False):
        # 重命名文件
        for filename in files:
            old_file = os.path.join(root, filename)
            new_file = os.path.join(root, to_snake_case(filename))
            if old_file != new_file:
                print(f'Renaming file: {old_file} -> {new_file}')
                os.rename(old_file, new_file)
        # 重命名目录
        for dirname in dirs:
            old_dir = os.path.join(root, dirname)
            new_dir = os.path.join(root, to_snake_case(dirname))
            if old_dir != new_dir:
                print(f'Renaming directory: {old_dir} -> {new_dir}')
                os.rename(old_dir, new_dir)
if __name__ == "__main__":
    # 输入你想要重命名的目录路径
    print("该程序会将路径内(不包括路径根目录)所有的的文件夹和文件的名字按以下规则修改: ")
    print("1.所有大写字母将会被修改为小写(包括后缀名中的大写字母)")
    print("2.所有空格会被替换为下划线")
    print("3.中文字符不受影响")
    print()
    root_dir = input("请输入要重命名的目录路径: ")
    rename_files_and_dirs(root_dir)

导入素材到项目

在godot的左下角可见如下”文件系统”。右键res://,创建文件夹resource。并将素材文件夹内的全部内容拖拽到resource中。

导入过程及完成后的效果如下:

创建角色场景

在Godot中,玩家所看到角色、场景等”物体”都由节点来构成。

对于一个角色,它可能有精灵节点(显示样貌),音频流节点(播放音效),角色身体节点(处理物理交互),碰撞形状节点(表示其能够碰撞的范围)。

用一颗树来表示,可能是这样子的

CharacterBody2D(角色身体节点,处理物理交互)

├── CollisionShape2D(碰撞形状节点,表示碰撞范围)

├── Sprite2D(精灵节点,显示角色样貌)

├── AudioStreamPlayer(音频流节点,播放音效)

当然,这种做法并不唯一。在本章节中,暂时不会使用AudioStreamPlayer。

想要一次性把这些节点打包,可以创建一个场景。在这个场景中创建好上述节点。将这个场景称为角色场景。

在其他的场景中,可以将这个场景作为子场景实例化,一次性把里面的节点放到另一个场景中。

创建角色场景

在文件系统中创建文件夹player。

在其中创建一个CharacterBody2D场景,命名为player。

给角色添加精灵

在左侧”场景树”中,给角色添加一个AnimatedSprite2D节点。

在右侧”检查器”,给AnimatedSprite2D创建一个新的Sprite Frame,并添加动画"go_down"

按下鼠标滑轮,可以移动在中央的场景中移动。滑动鼠标滑轮,可以放大或缩小。按下▶,观察动画效果。发现其播放速度过慢,可调节FPS来更改。

可以看到,在放大后,图像变得模糊不清。需要在左上角点击 项目-项目设置-渲染-纹理-画布纹理-默认纹理过滤 中,改为Nearest。

一般在像素风游戏中,都要进行此更改。

请依照前几步的方法,陆续添加go_left,go_right,go_down等动画。

给角色添加碰撞形状

在场景树中,添加一个CollisionShape2D节点。

在右侧”检查器”中,给碰撞体添加形状,并调整到一个合适的大小。以能够覆盖角色的大部分为宜,但不必完全覆盖。

创建背景场景

创建场景

在文件系统中,创建文件夹ground,用于存放角色活动的背景的godot场景。

创建场景ground,类型为Node2D(只需要在根节点类型处选择”2D场景”即可)。

实现场景边界

为了避免角色移动到ground场景之外,我们使用边界碰撞形状。

在检查器中,将Shape设成WorldBoundaryShape2D。

这个操作将会创建一个无限长的碰撞箱。角色场景有碰撞形状,两者之间的交互会使得角色无法离开碰撞形状划分开的区域。

可以对节点进行复制粘贴,创建另外三个边界。注意三个边界的朝向。

效果如下:

可以留意到,每个节点旁边都有警告⚠。这是因为,CollisionShape2D必须作为Area2D(或者Area2D的继承类,如角色场景中的CharacterBody2D)的子节点存在。

由于我们需要让角色的CharacterBody2D无法通过边界,因此使用Area2D的另一个继承类StaticBody2D。

创建一个Area2D场景,将四个CollisionShape2D作为子节点放入其中。

实例化角色子场景

将角色场景Player.tscn作为子场景实例化,并移动到合适的位置

调整角色的大小

先确保此时选中的是角色

在右侧检查器中的Transform的Scale属性中,调整角色缩放。

也可以直接用鼠标在数字上左右移动来调整它的值。

可以将x和y的值都设为5。

测试场景

按F5。或者点击下图所示按钮。

在弹出的窗口中,询问选择项目主场景。

所谓主场景,就是游戏启动时打开的场景。

点击”选择当前”。

可以在弹出的游戏窗口中看到角色。

给角色创建脚本

添加输入映射

在正式创建脚本前,先添加用于控制角色的输入映射。

在 项目-项目设置-输入映射 中添加输入映射。请仿照下面的动图,添加控制角色向四个方向走动的输入映射:go_up,go_left,go_right,go_down。

创建脚本

选中角色根节点,点击右上角的图标创建一个脚本。在弹出的窗口中直接点击创建。

在弹出的窗口中编写脚本。

声明速率变量

Godot使用的脚本语言叫GDscript,缩写gds,语法类似python。

gds使用的是动态变量,变量的类型并不固定。

在gds中,使用关键字var来创建变量。可以在变量名后使用:变量类型的方式指定类型。但是,这个也类型并非是固定的,在后续也可以给变量更改类型。

var speed:float=100

单位为:像素/秒。

重写_physics_process函数

_physics_process函数是Node类的方法。而CharacterBody2D作为Node的继承节点,也有这个方法。

_physics_process函数,在游戏的每一个物理处理帧中都会被调用。

它的参数delta是每个物理帧之间的时间间隔。

目前想实现的操作是:当我使用按键映射输入"go_up"时,角色向上移动,速度为变量speed。其他三个方向同理。

在此之前,需要了解一些前置知识。

函数重写

在godot中,如果一个类拥有某个函数fun(),而它的继承类也会拥有这个函数。

在继承类的代码中,如果重新定义函数fun(),就可以把函数fun()给覆盖,这种操作称为函数的重写。

坐标系

在计算机图像中,通常x,y坐标是这样的,Godot中也不例外:

图像最左上角的像素为坐标原点。x坐标向右为正方向,y坐标向下为正方向。单位长度为1px,即一个像素的边长。与通常的数学中的坐标系不同。

Vector2二维向量

在Godot中,有一个数据类型叫Vector2 。即2维向量。可以使用这样的代码初始化一个Vector2

var a=Vector2(100,200)

用这样的方式,创建了一个Vector2二维向量,它的x值为100,y值为200,再将它的值赋给变量a。

在godot中,Vector2可以与另外一个Vector2进行加减乘除,可以与一个float或int进行乘除,或者进行更加复杂的数学运算,详见官方文档

代码:向上移动

在脚本中,写入以下内容:

if Input.is_action_pressed("go_up"):
	velocity=Vector2(0,-speed)
else:
	velocity=Vector2(0,0) #Vector2(0,0)也可以替换为Vector2.ZERO
move_and_slide()

Input是godot中处理键盘按钮,鼠标等输入的一个单例

is_action_pressed是该单例的成员方法,检测传入字符串对应的操作事件是否被按下

例如:前文中设定了w键对应"go_up",那么当w键按下时,该方法返回逻辑真true,反之返回逻辑假false。

velocity(中文:速率)是CharacterBody2D类的成员属性,它的类型是二维变向量Vector2.但是仅设置velocity并不会使角色移动。

move_and_slide()是CharacterBody2D类的成员属性,当它被执行时,会按照velocity的速度进行移动。

为了使”go_up”按下时,角色速度应该被设定为向上(即y轴负方向)移动,在其他情况下,再将速度设为0.使得按钮松开时角色停止移动。

按F5启动游戏,测试一下效果。

为了让角色向上移动时,能够播放相应的动画,还应该进行以下操作:

使用@export修饰变量sprite,指定它的类型为AnimatableBody2D。

@export var sprite:AnimatedSprite2D

保存代码后,在角色检查器中可以看到新的属性sprite。

使用@export可以将属性暴露在检查器。

将AnimatedSprite2D拖到这个属性中。

后续在代码中,就可以通过变量sprite来操作这个AnimatedSprite2D节点。

在代码中,使用sprite.play("go_up")来播放向上走的动画,使用stop()停止动画。

@export var sprite:AnimatedSprite2D

func _physics_process(delta: float) -> void:
	if Input.is_action_pressed("go_up"):
		velocity=Vector2(0,-speed)
		sprite.play("go_up")
	else:
		velocity=Vector2(0,0)
		sprite.stop()
	move_and_slide()

代码:向四个方向移动

仿照上面的代码,继续实现向四个方向移动的操作。

下面直接给出player.gd完整的代码

extends CharacterBody2D

@export var sprite:AnimatedSprite2D
var speed:float=100

func _physics_process(delta: float) -> void:
	if Input.is_action_pressed("go_up"):
		velocity=Vector2(0,-speed)
		sprite.play("go_up")
	elif Input.is_action_pressed("go_down"):
		velocity=Vector2(0,speed)
		sprite.play("go_down")
	elif Input.is_action_pressed("go_right"):
		velocity=Vector2(speed,0)
		sprite.play("go_right")
	elif Input.is_action_pressed("go_left"):
		velocity=Vector2(-speed,0)
		sprite.play("go_left")
	else:
		velocity=Vector2(0,0)
		sprite.stop()
	move_and_slide()

效果如下:

写在文末

至此,本章内容结束。如果本文反响(点赞、评论)较好在后续章节,将会继续完善该项目,使之更加”接近”一个完整的游戏。

如果想要获取godot工程文件,可以到笔者的Gitee仓库中获取。

HuLunTunTao/GodotForBeginners - Gitee.com

如有纰漏/代码问题/错别字,欢迎批评与指正。

如果觉得有帮助,记得给本文或上面的仓库点个赞(star,like)。

<think>好的,现在用户问的是如果想做3D模型并且能,应该用哪些开发工具。之前用户问过QML能否做3D,我回答过QML结合Qt Quick 3D可以实现,但这次用户的问题更广泛,不限于QML,可能需要推荐更全面的工具链。 首先,用户可能对3D开发不太熟悉,需要区分建模工具和开发引擎。他们可能需要先创建3D模型,然后添加画,最后集成到应用中。所以,我应该分两部分回答:建模工具和画引擎。 建模工具方面,Blender是免费且功能强大的,适合初学者和专业人士。Maya和3ds Max是行业标准,但价格高,可能适合企业用户。ZBrush用于高模雕刻,可能需要补充说明适用场景。 画部分,如果用户想自己制作画,可以用Blender的画工具,或者使用引擎内置的画系统。然后需要考虑开发引擎,比如Unity和Unreal Engine适合复杂的交互和游戏开发,Godot和Three.js适合轻量级或Web项目,而Qt Quick 3D适合桌面或嵌入式应用,尤其是已有Qt背景的开发者。 用户可能还需要知道如何将模型导出到引擎,比如导出glTF或FBX格式。另外,针对不同需求,比如是否需要编程、目标平台是什么,可能需要不同的工具组合。 需要注意用户的技术背景,如果他们是开发者,可能更倾向于编程工具;如果是设计师,可能更需要易用的建模软件。此外,是否需要实时渲染、物理模拟等高级功能也会影响工具选择。 可能遗漏的点:移端开发工具,比如ARKit或ARCore,但用户的问题比较广泛,可能不需要深入AR。还有在线工具如Spline,适合快速原型制作,但可能不够专业。需要平衡全面性和简洁性,避免信息过载。 最后,总结工具链,给出步骤建议,帮助用户根据自己的需求选择合适的工具组合。确保推荐的工具之间有良好的兼容性,比如Blender导出到Unity的工作流程。同时提醒学习资源和社区支持,帮助用户入门。</think>--- ### 一、工具链选择思路 根据需求复杂度和技术目标,推荐以下组合方案: | **需求类型** | **推荐工具组合** | **适用场景** | |--------------------|--------------------------------------|----------------------------| | 简单3D展示 | Blender建模 + Three.js网页渲染 | 网页端轻量级展示 | | 交互式3D应用 | Maya/Blender + Unity/Unreal Engine | 游戏、AR/VR、工业仿真 | | 嵌入式或跨平台应用 | Qt Quick 3D + C++ | 工业控制界面、汽车HMI | | 艺术创意画 | Cinema 4D + After Effects | 影视特效、广告画 | --- ### 二、核心工具详解 #### 1. **建模工具** - **Blender**(免费开源) - ✅ 优势:完整3D创作套件(建模、雕刻、画、渲染) - 🌰 画能力:支持关键帧、骨骼、形状键、物理模拟 - 输出格式:`.glb`/`.glTF`(推荐)、`.fbx`、`.obj` - **Autodesk Maya**(商业软件) - ✅ 优势:电影级角色画管线 - 🌰 典型应用:人物表情控制、复杂机械联 - **ZBrush**(数字雕刻) - ✅ 优势:高精度有机生物模型雕刻 - 🌰 适用:游戏角色、影视怪兽模型 #### 2. **开发引擎** - **Unity** - ✅ 核心能力: - 可视化画编辑器(Timeline) - C#脚本控制逻辑 - 支持ShaderGraph编写材质画 - 示例流程: ```csharp // 控制模型旋转 void Update() { transform.Rotate(0, 30 * Time.deltaTime, 0); } ``` - **Unreal Engine** - ✅ 突出特性: - 蓝系统(无需编码实现画逻辑) - Nanite虚拟几何体技术 - 实时物理模拟(Chaos物理引擎) - **Three.js**(WebGL库) - ✅ 轻量级方案: ```javascript // 创建旋转画 function animate() { requestAnimationFrame(animate); mesh.rotation.x += 0.01; renderer.render(scene, camera); } ``` #### 3. **专业效工具** - **Cinema 4D + After Effects** - ✅ 优势:MoGraph模块可实现抽象数学效 - 工作流:C4D建模 → AE合成 → Lottie输出 - **Houdini** - ✅ 独特价值:程序化生成态拓扑结构 - 典型应用:破碎效果、流体模拟 --- ### 三、开发流程示例(以Blender+Unity为例) 1. **建模与绑定** - 在Blender中完成模型创建 - 添加骨骼系统(Armature) - 权重绘制(Weight Painting) 2. **画制作** - 录制关键帧画 - 导出为`.fbx`格式(包含画数据) 3. **引擎集成** ```csharp // Unity中控制画状态 Animator anim = GetComponent<Animator>(); anim.Play("Run"); // 播放名为"Run"的画片段 ``` 4. **交互逻辑** - 通过Collider组件检测点击事件 - 使用AnimationCurve编辑非线性画 --- ### 四、技术选型建议 1. **优先考虑数据流兼容性** - 确保建模工具与引擎支持相同格式(推荐`.glTF 2.0`) - 检查法线/UV等属性的正确传递 2. **性能优化重点** - 模型:控制三角面数(移端建议<5万面) - 贴:使用压缩格式(ASTC/ETC2) - 批处理:合并相同材质的物体 3. **学习资源推荐** - Blender官方教程:[Blender Fundamentals](https://www.blender.org/support/tutorials/) - Unity Learn平台:[角色画课程](https://learn.unity.com/course/working-with-3d-animation) - glTF标准文档:[Khronos Group](https://www.khronos.org/gltf/) --- ### 五、新兴趋势 - **AI辅助工具**: - 使用NVIDIA Omniverse实现跨软件实时协作 - Runway ML生成基础画关键帧 - **WebGPU技术**: - 新一代网页形接口,替代WebGL - 示例框架:Babylon.js 6.0+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值