Godot Version
4.8.dev2.mono
Question
I am attempting to implement an Aircraft HUD with angle-to-ground indicators that scroll based on the player’s rotation.x value (pitch). Akin to the first person view in any Ace Combat game. The markers fine… if I don’t roll. The rotation of them works great, but upon receiving a roll input, my player.rotation.x value alters downward (i.e. player.rotation.x = 120 → 60) and the HUD element no longer works for the remainder of the scene. Specifically, the HUD begins to cap between 70-80 degrees in the positive pitch axis and around 60 degrees in the negative. I suspect this is due to some error with initial values, but trying various combinatorics of them returned no notable improvements.
Controls for the player use rather standard roll/pitch/yaw inputs
The scrolling hud element uses nested control nodes, notably a clipping mask whose child is HUDRotation, which is the element that rotates, and HUDScrolling, a VSplitContainer which holds individual children nodes that make up the sprites and labels that form the full scrolling apparatus from -95 degrees to 95 degrees.
The following is the relevant code used for the HUDController in the main scene, including my troubleshooting aid comments:
func _ready():
#Obtain child node references for scrolling, rotating, and the +90 pitch degree marker
HudScrolling = FirstPersonHudNode.get_node("FirstPersonOnlyHud/ClippingMask/HUDRotation/HUDScrolling")
HudRotation = FirstPersonHudNode.get_node("FirstPersonOnlyHud/ClippingMask/HUDRotation")
hud90Degree = FirstPersonHudNode.get_node("FirstPersonOnlyHud/ClippingMask/HUDRotation/HUDScrolling/+90")
#Establish baseline hudPosition.
hudPositionInitial = HudScrolling.position.y
#Find location of the 90 degree marker, create position factor based on said location
hudHeight = hud90Degree.global_position.y
hudPositionFactor = hudHeight / 90
func _physics_process(_delta):
#obtain player pitch value
var convertedRotation : float
if player.rotation_degrees.x >= 180:
convertedRotation = player.rotation_degrees.x - 360
#convertedRotation = absf(fmod(player.rotation_degrees.x, 180)) - 360 no difference noticed
else:
convertedRotation = player.rotation_degrees.x
#change hud position based on player pitch value, change angle based on roll value
HudScrolling.position.y = (convertedRotation * hudPositionFactor *-1) + hudPositionInitial
HudRotation.rotation = angle_difference(0, player.rotation.z)
#print(str("HudScrolling y pos: " + str(convertedRotation*hudPositionFactor)))
#print("player.rotation.x: " + str(rad_to_deg(player.rotation.x)) + ", hudPosInit: " + str(hudPositionInitial) + ", hudScrolling.y: " + str(HudScrolling.position.y) + \
#", convertedRotation: " + str(convertedRotation) + ", HudScrollingFactor: " + str(convertedRotation*hudPositionFactor*-1))
In the process of writing this out and copying this over, I have a suspicion that my tree hierarchy of:
-First Person Only Hud
- Clipping Mask
- HUDRotation
- HUD Scrolling
- 21 HUD textures
- 2 Labels inside each HUD element
- 21 HUD textures
- HUD Scrolling
- HUDRotation
is then resulting in HUDRotation correctly rotating upon a roll input, but somehow this is changing the Y values required by my HUDScrolling to work. That makes me think
hudHeight = hud90Degree.global_position.y is part of what’s causing it to fail, but just using plain ol’ position.y is giving results 5000 pixels off and resulting in zero functionality. It’s strange how it tends to mostly work when pitch is the only input and then consistently fail the moment I roll, most noticeably when rolling during a straight vert ascent, resulting in a max displayed pitch (in both the inspector reading rad_to_deg(player.rotation.x) and with the on-screen tool) of around 70-80 degrees.