Godot 4 中的多检查点系统(3D)

问题描述 投票:0回答:1

我对 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)

[enter image description here](https://i.stack.imgur.com/an3cO.png)

3d game-engine gdscript godot4
1个回答
0
投票

基本检查点系统需要两部分。

  • 存储最后到达的检查点的地方。哪个 - 按照你的方法 - 我将使用自动加载。
  • 您在世界中放置的检查点,当玩家角色触发时,该检查点将存储位置。这将是一个
    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
© www.soinside.com 2019 - 2024. All rights reserved.