代码之家  ›  专栏  ›  技术社区  ›  Jay

Godot玩家之间的平稳过渡

  •  0
  • Jay  · 技术社区  · 3 年前

    我有一个“父”玩家场景,我为每个玩家继承场景。父玩家场景有一个摄影机。当游戏在玩家之间切换时,一名玩家关闭相机,另一名玩家打开相机:

    if state != State.ACTIVE:
        # If this player is becoming active, also
        # set camera current    
        state = State.ACTIVE
        camera.current = true
    else:
        # If player is not becoming active,
        # disable this players camera
        camera.current = false
    

    但玩家可能处于不同的位置,因此摄像机会从一个位置“跳”到另一个位置。我们能做一些更复杂的事情吗,比如把新相机设置到当前位置,这样平滑的设置就可以用来处理过渡了?

    一个想法是 get_viewport().get_camera() 以找到相机的当前位置,尝试将当前相机的位置与即将打开但似乎不适用于2D场景的新相机同步。CF: https://github.com/godotengine/godot/pull/38317

    0 回复  |  直到 3 年前
        1
  •  1
  •   Theraot    3 年前

    遗憾的是,正如你所发现的,没有办法获得电流 Camera2D 在Godot3.x中。 您找到了将该功能添加到Godot 4.0的pull请求。

    我的建议是有一个鞋底 Camera2D ,所以一个总是当前的。你可以定义 Position2D 在您的场景中,可以作为插值目标来移动 Camera2D


    我有一个剧本,我认为对你有用(我把它做成了 RemoteTransform2D 但向后,它确实推动了一个变换,它拉动了它),我称之为 anchor_transform_2d.gd :

    tool
    class_name AnchorTransform2D
    extends Node2D
    
    export var anchor_path:NodePath setget set_anchor_path
    export var reference_path:NodePath setget set_reference_path
    export var set_local_transform:bool
    export(int, FLAGS, "x", "y") var translation_mode:int
    export(int, FLAGS, "x", "y") var scale_mode:int
    export var rotation_mode:bool
    
    
    var _anchor:Node2D
    var _reference:Node2D
    
    
    func _physics_process(_delta: float) -> void:
        if not is_instance_valid(_anchor) or Engine.editor_hint:
            set_physics_process(false)
            return
    
        #INPUT
        var input := _anchor.global_transform
        if is_instance_valid(_reference):
            input = _reference.global_transform.affine_inverse() * input
    
        #TRANSLATION
        var origin := Vector2 (
                input.origin.x if translation_mode & 1 else 0.0,
                input.origin.y if translation_mode & 2 else 0.0
            )
    
        #ROTATION
        var angle := 0.0
        if rotation_mode:
            angle = input.get_rotation()
    
        #SCALE
        var source_scale = input.get_scale()
        var scaling := Vector2 (
            source_scale.x if scale_mode & 16 else 1.0,
            source_scale.y if scale_mode & 32 else 1.0
        )
    
        #RESULT
        _set_target_transform(
            Transform2D(angle, origin) * Transform2D.IDENTITY.scaled(scaling)
        )
    
    
    func set_anchor_path(new_value:NodePath) -> void:
        anchor_path = new_value
        if not is_inside_tree():
            yield(self, "tree_entered")
    
        _anchor = get_node_or_null(anchor_path) as Node2D
        set_physics_process(is_instance_valid(_anchor) and not Engine.editor_hint)
        if Engine.editor_hint:
            update_configuration_warning()
    
    
    func set_reference_path(new_value:NodePath) -> void:
        reference_path = new_value
        if not is_inside_tree():
            yield(self, "tree_entered")
    
        _reference = get_node_or_null(reference_path) as Node2D
    
    
    func _set_target_transform(new_value:Transform2D) -> void:
        if set_local_transform:
            transform = new_value
            return
    
        global_transform = new_value
    
    
    func _get_configuration_warning() -> String:
        if _anchor == null:
            return "Anchor not found"
    
        return ""
    

    将此附件添加到 Node2D 在里面 anchor_path 设置要从中提取变换的目标( anchor_path NodePath ,你可以设置为 $Position2D.get_path() )。并设置要复制的内容(可以选择位置x、位置y、缩放x、缩放y和旋转的任意组合)。然后把 Camera2D 作为 AnchorTransform2D ,并设置 smoothing_enabled true

    属性的递减:

    • anchor_path :A NodePath 指向 Node2D 您要从中提取变换。
    • reference_path :A NodePath 指向 Node2D 用于使变换是相对的(您将对输入的内容进行变换 anchor_path 相对于你投入的 引用路径 )。
    • set_local_transform :设置为 真的 如果要将变换作为局部(相对于的父对象 AnchorTransform2D ),留给 false 以设置全局变换。
    • translation_mode :指定是要复制x位置、y位置,还是两者都不复制。
    • scale_mode :指定是要复制x比例、y比例,还是两者都不复制。
    • rotation_mode :指定是否要复制旋转。

    脚本是工具脚本的唯一原因是,如果您忘记设置 anchor_path