Godot学习-3D基本环境设置以及3D角色移动

文章目录


一、新建项目和导入资产

这里演示的是如何让角色移动起来。为此我们新建测试工程,并且导入对应的3D模型文件。并且新建一个3D场景,命名为Main。

然后我选择一个角色模型,如下图,我选择的是:Astronaut_FinnTheFrog.gltf。鼠标双击打开,如下图所示:

左侧分为两部分,分别是模型和动画。选择AnimationPlayer下面的idle、run、walk节点,然后点击播放,查看动画状态,然后我们选择重新导入。

然后我们把模型拖到Main节点下面。

值得注意的是:有些模型可能会出现褪色的情况,此时我们选择模型对应的图片,然后点击导入,勾选上高质量即可。最后重新导入。

操作步骤如下图:

二、创建玩家场景

1.修改模型节点类型为CharacterBody3D

然后我们选择Astronaut_FinnTheFrog节点旁边的图标, 单机鼠标,在编辑器中打开:

我们选择仍然打开。

如下图所示的模型场景:

修改根节点类型和名称分别为:CharacterBody3D和Player。

2.添加碰撞对象并且设置碰撞区域

此时黄色警号告诉我们没有为角色设置碰撞,那么我们按照提示新建一个碰撞体。为Player创建子节点:CollisionShape3D,形状选择CapsuleShape3D。这是一个3D胶囊碰撞形状。然后我们设置好碰撞。

此时我们应该调整角色和胶囊的位置,让胶囊很好的包裹角色。勉强就这样吧:

为CollisionShape3D节点修改名称,为Player_Collider。这样更加直观

3.根据动画的运动状态调整碰撞区域

关于动画的一些基本介绍,可以参考我的文章:Godot学习-创建简单动画

因为我刚才设置的碰撞器,就是那个胶囊碰撞器针对的是空闲状态的角色,但是当跳起来、或者跑起来,或者走起来的时候,碰撞器和角色就不是很好匹配了,因此要重新设置碰撞器。

当我选择Jump的时候,如下图:胶囊没有包裹住头顶。

操作如下:

1、选择碰撞器节点

2、选择idle(空闲状态)

3、选择position属性右侧的小钥匙。

我们直接选择创建即可。

此时在轨道最下面就有我们的position属性轨道,并且在1那里添加关键帧:

然后点击编辑,选择复制轨道,弹出下面的弹框,我们选择我们的碰撞器:

选择Run动画状态,点击编辑,然后复制轨道。此时将最后的关键帧调整位置:

Walk动画状态也是同样的操作。

选择Jump动画状态,此时我们不用复制轨道,我们需要手动添加关键帧,并且调整胶囊的位置。

1、创建position轨道。

2、调整胶囊的位置,添加关键帧。

我点击循环播放,可以看出胶囊赶着角色上下跳动。

对Jump_Idle和Jump_Land都做同样的操作即可。

此时我们把场景另存为player.tscn。

此时我们回到主场景,删除模型节点。

然后实例化我们刚才保存的子场景:

三、使用CSGMesh3D创建地面

给Main节点创建子节点:CSGMesh3D

然后选择Mesh。原来是有PlaneMesh的,现在新版本没有这个了,我们选择BoxMesh。

1.设置网格尺寸

并且设置对应的尺寸:

在CSGShape3D里面,勾选上:Use Collision。这个是为了自动创建碰撞。(为我们的 CSG 形状向物理引擎添加碰撞形状。这样行为就始终与静态物体类似。请注意,即使 CSG 形状本身被隐藏,碰撞形状仍处于活动状态。)

2.设置网格材质

我们选择第一个材质。

然后点击这个材质,在Albedo属性里面设置对应的颜色。

四、添加3D相机和光照

1、为Main节点添加一个子节点,Camera3D

2、点击视图,选择多个窗口,可以预览。,我选择2个。

3、然后选择相机节点,通过调整坐标,观察角色位置,记得勾选预览。如下图,右边是我的预览。

此时我们运行游戏,选择当前节点,如下图所示:

整个场景是暗黑的,我们需要加上太阳光和环境光。

再次运行,如下图所示:

五、为角色移动编写代码

1.基本移动和旋转

1、切换到Player场景,为其创建脚本,命名为play.gdscript

2、关于输入动作我们使用内置的,也可以绑定其他的。我这里使用内置的绑定。

python 复制代码
extends CharacterBody3D
@export var speed : = 4.0

var movement
var direction

func _physics_process(delta: float) -> void:
	
	# 基本移动输入操作
	var movement := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	var direction := (transform.basis * Vector3(movement.x, 0, movement.y)).normalized()
	if direction:
		velocity.x = direction.x * speed
		velocity.z = direction.z * speed
	else:
		velocity.x = move_toward(velocity.x, 0, speed)
		velocity.z = move_toward(velocity.z, 0, speed)

	move_and_slide()

此时发现角色不能旋转,而CharacterArmature节点控制旋转,因此我们要修改下代码:

python 复制代码
extends CharacterBody3D


@export var speed : = 4.0
@onready var player_body=$CharacterArmature
var angular_speed=10
var movement
var direction


func _physics_process(delta: float) -> void:
	
	# 基本移动输入操作
	var movement := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	var direction := (transform.basis * Vector3(movement.x, 0, movement.y)).normalized()
	if direction:
		velocity.x = direction.x * speed
		velocity.z = direction.z * speed
		player_body.rotation.y=lerp(player_body.rotation.y,atan2(velocity.x,velocity.z),delta * angular_speed)
	else:
		velocity.x = move_toward(velocity.x, 0, speed)
		velocity.z = move_toward(velocity.z, 0, speed)

	move_and_slide()

此时可以旋转了,但是我们还需要调用动画。

2.调用角色动画

修改后的代码:

python 复制代码
extends CharacterBody3D


@export var speed : = 4.0
@onready var player_body=$CharacterArmature
@onready var player_anim=$AnimationPlayer
var angular_speed=10
var movement
var direction


func _physics_process(delta: float) -> void:
	
	# 基本移动输入操作
	var movement := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	var direction := (transform.basis * Vector3(movement.x, 0, movement.y)).normalized()
	if direction:
		player_anim.play("Walk")
		velocity.x = direction.x * speed
		velocity.z = direction.z * speed
		player_body.rotation.y=lerp(player_body.rotation.y,atan2(velocity.x,velocity.z),delta * angular_speed)
	else:
		player_anim.play("Idle")
		velocity.x = move_toward(velocity.x, 0, speed)
		velocity.z = move_toward(velocity.z, 0, speed)

	move_and_slide()

总结

以上就是今天要讲的内容,本文仅仅简单介绍了模型导入、动画设置、地面创建、光照创建和角色基本移动。但是相机跟着角色旋转和移动这块还是有点问题,下次再看。

相关推荐
gjf05_053 小时前
人该怎样活着呢?版本75.8
学习
li星野5 小时前
【学习记录】PCB与PCBA核心知识全解析:从设计到制造的关键细节
学习·制造
卿卿的产品经理日记5 小时前
【AI产品经理实战】Day 35|从“沉迷工具“到回归 AI 底层:Skill 收官、系统复盘与下一个 13 天
人工智能·学习·产品经理
一条泥憨鱼6 小时前
【从0开始学习计算机网络】| ARP 协议:地址解析,ARP 欺骗,链路层寻址
网络·后端·学习·计算机网络
HY小宝F6 小时前
树莓派智能摄像头系统 30 天重学计划之 Day 04 · HTTP / API:控制链入口 —— 学习总结
网络协议·学习·http
总要学点什么8 小时前
第51篇:数据分析-热力图——笔刷画的是圆,落到地上却成了椭圆
3d·数据挖掘·数据分析·前端框架·gis·webgl·cesium
悟乙己8 小时前
AFAC2026 赛题四金融长文本 Agent竞赛学习笔记:赛题解析(一)
笔记·学习·金融
霍霍的袁8 小时前
【C++】哈希表实现指南:从原理到开放定址法、链地址法的实现
c++·学习·哈希算法·散列表·visual studio
PC2005-cloud8 小时前
MySQL学习笔记:GTID 主从复制,从原理到实践,告别传统 Binlog+Position 的痛点
笔记·学习·mysql
Martina_03219 小时前
AI生成的海岸城市一移动镜头,水面反射就跳?用6步统一反射探针、SSR与平面反射
图像处理·人工智能·平面·3d·ai·自然语言处理·游戏策划