我对 Godot 很陌生,但有一些 Python 编程经验。我正在制作一个 3D 简单运动游戏来了解引擎,并且我想在整个关卡中添加检查点。我按照本教程(https://youtu.be/AEdEUeK_g4A)获取了检查点的大部分代码,但它不起作用。我又花了几个小时研究和更改代码,现在我已经快到了,我只是不知道如何让检查点知道它的位置在哪里。
我已经从原始教程中移动了一些内容,现在检查点脚本(扩展 Area3D)是自动加载的,因此我可以从其他脚本访问它。我已经测试过(使用打印功能),它知道何时进入该区域,但是当我按下加载检查点时,它会将我带回到 0,0,0。我已将初始 check_point_pos vector3 设置为 10,10,10,它把我带到了那里。 所以看来问题是 vector3 没有更新。我需要添加什么才能使 vector3 更新为每个检查点的正确位置?我已经尝试了一些方法,但到目前为止没有任何效果。
extends Area3D
var check_point_pos = Vector3.ZERO
func save_check_point(pos_x, pos_y, pos_z):
check_point_pos.x = pos_x
check_point_pos.y = pos_y
check_point_pos.z = pos_z
func _on_area_entered(_body):
print("checkpoint")
save_check_point(self.position.x, self.position.y, self.position.z)
if Input.is_action_pressed("load_checkpoint"):
set_position(checkpt.check_point_pos)
基本检查点系统需要两部分。
Area3D
。这是代码的一部分,用于存储最后到达的检查点(以及自动加载中的内容):
extends Area3D
var check_point_pos = Vector3.ZERO
func save_check_point(pos_x, pos_y, pos_z):
check_point_pos.x = pos_x
check_point_pos.y = pos_y
check_point_pos.z = pos_z
这些是我要做的修改:
Area3D
,事实上它不需要在世界上占有一席之地。所以我会改变它Node
。save_check_point
。Variant
。这就是结果(这也是您将制作成自动加载的结果):
extends Node
var check_point_pos:Vector3
在将其设置为自动加载时,请确保为其指定名称。我相信您使用的是
checkpt
这个名字,所以我将用它来回答这个问题。
您放置在世界中的
Area3D
,有这部分代码:
extends Area3D
func _on_area_entered(_body):
print("checkpoint")
save_check_point(self.position.x, self.position.y, self.position.z)
这些是我要做的修改:
save_check_point
,我们将直接设置变量。position
,因为它是相对于父级 Node3D
的。相反,我们将使用相对于游戏世界原点的global_position
。这是结果:
class_name CheckPoint
extends Area3D
func _ready() -> void:
if not area_entered.is_connected(_on_area_entered):
area_entered.connect(_on_area_entered)
func _on_area_entered(_area:Area3D) -> void:
print("checkpoint")
checkpt.check_point_pos = global_position
我希望您会使用
body_entered
而不是 area_entered
。仔细检查 area_entered
是否是您想要的。如果你真的想要body_entered
,代码将是这样的:
class_name CheckPoint
extends Area3D
func _ready() -> void:
if not body_entered.is_connected(_on_body_entered):
body_entered.connect(_on_body_entered)
func _on_body_entered(_body:Node3D) -> void:
print("checkpoint")
checkpt.check_point_pos = global_position
我建议更改碰撞遮罩,以便只有玩家角色才会触发它,而不会触发其他任何东西。
当然,调用检查点看起来像这样(在你的玩家角色中):
global_position = checkpt.check_point_pos
我还想指出,使用
static var
是一个可行的替代方案,这样您就不需要 Autoload
并且所有内容都将在一个脚本中:
class_name CheckPoint
extends Area3D
static var check_point_pos:Vector3
func _ready() -> void:
if not area_entered.is_connected(_on_area_entered):
area_entered.connect(_on_area_entered)
func _on_area_entered(_area:Area3D) -> void:
print("checkpoint")
CheckPoint.check_point_pos = global_position
这次调用检查点看起来像这样(在你的玩家角色中):
global_position = CheckPoint.check_point_pos