You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Godot中生成车辆时出现异常高速移动问题求助

车辆生成后高速飞过关卡问题排查与解决

问题描述

实现车辆生成系统时,车辆通过对象池生成后会以极高速度飞过关卡,但手动将车辆添加到场景中时运行正常。相关脚本如下:

生成器脚本

private void Spawn()
{
    //Get object and check for errors
    var obj = _objectPool.GetObject();
    if(obj == null)
        return;
    //Change location and enable object 
    GD.Randomize(); //Randomize seed
    var index = (int)GD.RandRange(0, 4);
    obj.Position = new Vector2(_pos[index], _posY.GlobalPosition.y);
    obj.SetProcess(true);
    GD.Print("Spawn" + obj.GlobalPosition);
}// I also have a timer that repeats this function 

对象池脚本

private void Instantiate(){
    _objects = new Node2D[_count];
    for(int i=0; i<_count; i++){
        //Instanciate object
        Node2D node =(Node2D)_scene.Instance();
        //Disable it
        node.SetProcess(false);
        //Add to scene
        AddChild(node);
        //Add to object list
        _objects[i] = node;
    }
}

public Node2D GetObject(){
    //Return a diactivated object
    foreach (var obj in _objects){
        if(!obj.IsProcessing())
            return obj;
    }
    return null;
}

车辆脚本

public override void _Ready()
{
    GD.Randomize();
    goingUp = false;
    _speed = 10;//(int)GD.RandRange(_minSpeed, _maxSpeed);   
}

// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(float delta)
{
    Move(delta);
}   

private void Move(float delta)
{
    var motion = Vector2.Zero;
    motion = goingUp ? Vector2.Up : Vector2.Down;
    //Apply movement
    MoveAndSlide(motion);
}

解决方案

1. 修复移动逻辑:应用速度与delta时间

车辆的Move方法未将运动向量乘以速度值和delta时间,导致每帧移动固定像素距离,高帧率下移动速度会异常飙升。手动添加时可能因测试场景帧率较低未暴露问题,修改后的Move方法如下:

private void Move(float delta)
{
    var motion = Vector2.Zero;
    motion = goingUp ? Vector2.Up : Vector2.Down;
    // 乘以速度与delta时间,保证移动速度不受帧率影响
    motion *= _speed * delta;
    MoveAndSlide(motion);
}

2. 对象池复用:重置车辆状态

对象池中的车辆被回收后未重置状态,再次取出时可能保留之前的运动参数(例如goingUp被修改过),导致异常移动。需要添加回收逻辑并重置车辆状态:

在对象池脚本中添加回收方法

public void ReturnObject(Node2D obj)
{
    obj.SetProcess(false);
    // 调用车辆的状态重置方法
    if (obj is Vehicle vehicle)
    {
        vehicle.ResetState();
    }
}

在车辆脚本中添加状态重置方法

public void ResetState()
{
    // 重置运动方向与速度
    goingUp = false;
    _speed = 10;
    // 可选:重置位置(生成时会重新设置,可根据需求添加)
    // Position = Vector2.Zero;
}

3. 可选:检查坐标设置

生成车辆时如果使用obj.Position,若车辆是容器子节点,可能需要改用obj.GlobalPosition确保坐标正确,避免父节点坐标偏移导致的初始位置异常:

obj.GlobalPosition = new Vector2(_pos[index], _posY.GlobalPosition.y);

内容的提问来源于stack exchange,提问作者Δημήτρης Δημητριαδης

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 03:47:38