Трехмерная подводная лодка, движимая «движителями» без физики ... Местная ориентация на глобальное движение? - PullRequest
0 голосов
/ 30 апреля 2019

Представьте себе куб с 4 движителями на каждом лице, похожий на маленькую космическую капсулу. Все вместе они генерируют тягу в 12 направлениях (вперед, назад, влево, вправо, вверх, вниз, + рыскание, -гау, + тангаж,-тангаж, + крен, -руль)

Тяга для каждого направления рассчитывается и (должна быть) реализована в каждом игровом цикле.

Мои вращения (Yaw, Pitch and Roll) работают как шарм ... но я слишком глуп, чтобы интегрировать линейную тягу (генерируемую локально для ориентации объекта) в единый глобальный перевод для моего объекта, сохраняя (но немного уменьшается) накопленная скорость в любом другом направлении.

Проблема в последней паре строк кода. Пожалуйста, помогите!

extends KinematicBody

var Decay:float = 2.0;
var CurrDecay:float = 0.0;

var ThrustX:float = 0.0;
var ThrustY:float = 0.0;
var ThrustZ:float = 0.0;
var ThrustMax:float = 50.0;#Meters/Second

var RotateY:float = 0.0;
var RotateX:float = 0.0;
var RotateZ:float = 0.0;
var RotateMax:float = 10.0;#Degrees/Second

onready var Velocity:Vector3 = transform.origin;

func _process(delta):

    if Input.is_action_pressed("Shift"):

        if Input.is_action_pressed("Pitch+"):
            RotateX -= (RotateMax-abs(RotateX)) * delta;
        if Input.is_action_pressed("Pitch-"):
            RotateX += (RotateMax-RotateX) * delta;

        if Input.is_action_pressed("ThrustLeft"):
            ThrustX -= (ThrustMax-abs(ThrustX)) * delta;
        if Input.is_action_pressed("ThrustRight"):
            ThrustX += (ThrustMax-ThrustX) * delta;

        if Input.is_action_pressed("ThrustUp"):
            ThrustY += (ThrustMax-ThrustY) * delta;
        if Input.is_action_pressed("ThrustDown"):
            ThrustY -= (ThrustMax-abs(ThrustY)) * delta;

    else:

        if Input.is_action_pressed("ThrustFront"):
            ThrustZ -= (ThrustMax-abs(ThrustZ)) * delta;
        if Input.is_action_pressed("ThrustBack"):
            ThrustZ += (ThrustMax-ThrustZ) * delta;

        if Input.is_action_pressed("Yaw+"):
            RotateY += (RotateMax-RotateY) * delta;
        if Input.is_action_pressed("Yaw-"):
            RotateY -= (RotateMax-abs(RotateY)) * delta;

        if Input.is_action_pressed("Roll+"):
            RotateZ -= (RotateMax-abs(RotateZ)) * delta;
        if Input.is_action_pressed("Roll-"):
            RotateZ += (RotateMax-RotateZ) * delta;

    #DAMPEN
    CurrDecay = delta*Decay;
    RotateX = lerp(RotateX,0.0,CurrDecay);
    RotateY = lerp(RotateY,0.0,CurrDecay);
    RotateZ = lerp(RotateZ,0.0,CurrDecay);
    ThrustX = lerp(ThrustX,0.0,CurrDecay);
    ThrustY = lerp(ThrustY,0.0,CurrDecay);
    ThrustZ = lerp(ThrustZ,0.0,CurrDecay);

    #EXECUTE    
    rotate_object_local(Vector3.FORWARD,deg2rad(RotateZ));
    rotate_object_local(Vector3.RIGHT,deg2rad(RotateX));
    rotate_object_local(Vector3.UP,deg2rad(RotateY));

    #MY MISGUIDED LOW-IQ ATTEMP TO DO ACTUAL MOVEMENT
    var ThrustVector = Vector3(ThrustX,ThrustY,ThrustZ)/100;
    global_translate(ThrustVector);# ???
    #move_and_collide(ThrustVector);# ???
    #translate(ThrustVector);# ???

Цените любую помощь здесь:)

1 Ответ

0 голосов
/ 03 мая 2019

После некоторых копаний и расспросов я нашел рабочее решение:

extends KinematicBody

var Drag:float = 1.0;

var ThrustX:float = 0.0;
var ThrustY:float = 0.0;
var ThrustZ:float = 0.0;
var ThrustMax:float = 5.0;#Meters/Second?
var ThrustDecay:float = 2.0;

var ThrustVector:Vector3 = Vector3(0,0,0);
var MoveVector:Vector3 = Vector3(0,0,0);
var Velocity:Vector3 = Vector3(1,1,1);

var RotateY:float = 0.0;
var RotateX:float = 0.0;
var RotateZ:float = 0.0;
var RotateMax:float = 8.0;#Degrees/Second?

func _physics_process(delta:float) -> void:

    if Input.is_action_pressed("Shift"):

        if Input.is_action_pressed("Pitch+"):
            RotateX -= (RotateMax-abs(RotateX)) * delta;
        if Input.is_action_pressed("Pitch-"):
            RotateX += (RotateMax-RotateX) * delta;

        if Input.is_action_pressed("ThrustLeft"):
            ThrustX -= (ThrustMax-abs(ThrustX)) * delta;
        if Input.is_action_pressed("ThrustRight"):
            ThrustX += (ThrustMax-ThrustX) * delta;

        if Input.is_action_pressed("ThrustUp"):
            ThrustY += (ThrustMax-ThrustY) * delta;
        if Input.is_action_pressed("ThrustDown"):
            ThrustY -= (ThrustMax-abs(ThrustY)) * delta;

    else:

        if Input.is_action_pressed("ThrustFront"):
            ThrustZ -= (ThrustMax-abs(ThrustZ)) * delta;
        if Input.is_action_pressed("ThrustBack"):
            ThrustZ += (ThrustMax-ThrustZ) * delta;

        if Input.is_action_pressed("Yaw+"):
            RotateY += (RotateMax-RotateY) * delta;
        if Input.is_action_pressed("Yaw-"):
            RotateY -= (RotateMax-abs(RotateY)) * delta;

        if Input.is_action_pressed("Roll+"):
            RotateZ += (RotateMax-RotateZ) * delta;
        if Input.is_action_pressed("Roll-"):
            RotateZ -= (RotateMax-abs(RotateZ)) * delta;

    #DAMPEN THRUST
    var CurrDecay:float = delta*ThrustDecay;
    RotateX = lerp(RotateX,0.0,CurrDecay);
    RotateY = lerp(RotateY,0.0,CurrDecay);
    RotateZ = lerp(RotateZ,0.0,CurrDecay);
    ThrustX = lerp(ThrustX,0.0,CurrDecay);
    ThrustY = lerp(ThrustY,0.0,CurrDecay);
    ThrustZ = lerp(ThrustZ,0.0,CurrDecay);

    #INTEGRATE FORCES
    ThrustVector = (global_transform.basis.x*ThrustX) + (global_transform.basis.y*ThrustY) + (global_transform.basis.z*ThrustZ)
    MoveVector = Velocity+ThrustVector;
    MoveVector = lerp(MoveVector,Vector3(0,0,0),Drag*delta);#Water-drag

    #EXECUTE
    rotate_object_local(Vector3.RIGHT,deg2rad(RotateX));
    rotate_object_local(Vector3.UP,deg2rad(RotateY));
    rotate_object_local(Vector3.BACK,deg2rad(RotateZ));
    Velocity = move_and_slide(MoveVector);

Надеюсь, это может помочь кому-то еще:)

...