由 'thrusters' 推动的 3D 潜艇没有物理......局部导向推力到全球运动?
3D submarine propelled by 'thrusters' without physics ... Local oriented thrust to global movement?
想象一个每个面上都有 4 个推进器的立方体,就像一个小的 space 胶囊。
这些共同产生 12 个方向的推力(向前、向后、向左、向右、向上、向下、+Yaw、-Yaw、+Pitch、-Pitch、+Roll、-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);# ???
在此感谢任何帮助:)
经过一番挖掘和四处询问,我找到了一个可行的解决方案:
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);
希望这可以帮助其他人:)
想象一个每个面上都有 4 个推进器的立方体,就像一个小的 space 胶囊。 这些共同产生 12 个方向的推力(向前、向后、向左、向右、向上、向下、+Yaw、-Yaw、+Pitch、-Pitch、+Roll、-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);# ???
在此感谢任何帮助:)
经过一番挖掘和四处询问,我找到了一个可行的解决方案:
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);
希望这可以帮助其他人:)