#Changing how pivot works with player root

1 messages · Page 1 of 1 (latest)

tall quail
#

My game got area3Ds which changes player gravity on entering and they re work pretty well, when player comes inside such area its root rotates (so any surcface from camera perspective would looks like a floor)
But heres comes a problem: Mouse movment only rotates Pivot around X, and Root rotates around Z
If player sight (pivot angle) looks towards Z axis everything is ok, but if it looks toward X axis then camera do a backflip wich is i assume gonna be extremley confusing to a player
I cant figure a proper way to force this all works to integrate pivot rotation into player root rotation so instead of backflip player sight will simply flip
Code are in comments

desert gorgeBOT
tall quail
#

This one are code that makes player flip and synchronizes up direction

func _align(delta) -> void:
    up_direction = -gravityDir
    var look_dir := -transform.basis.z
    var dot := look_dir.dot(up_direction)
    if abs(dot) < 0.99:
        var target_basis := Basis.looking_at(look_dir, up_direction)
        transform.basis = transform.basis.slerp(target_basis, delta * 5)
    else:
        var right := transform.basis.x
        var target_basis := Basis.looking_at(right, up_direction)
        transform.basis = transform.basis.slerp(target_basis, delta * 5)

This one are camera code, may be helpfull

var ctx : CameraContext = CameraContext.new()
var inx: float = 0.0
var iny: float = 1.5
var roll: float = 0.0
var effects: Array [CameraEffect] = []
@export var mouseSense : float = 0.2
@export var maxRotationSpeed : float = 1.0
var piv_basis := Basis(Vector3.UP, inx)
var cam_piv_basis := Basis(Vector3.RIGHT, iny)

func _update_camera(delta: float) -> void:
    ctx.direction = direction
    ctx.velocity = velocity
    ctx.on_wall = is_on_wall_only()
    ctx.armature_basis = armature.global_basis

    inx -= input.x * 0.002
    iny -= input.y * 0.002
    
    iny = clamp(iny, deg_to_rad(0), deg_to_rad(180))

    piv_basis = Basis(Vector3.UP, inx)
    cam_piv_basis = Basis(Vector3.RIGHT, iny)
    
    #pivot.basis = transform.basis.inverse() * piv_basis (игнорирование гравитации)


    pivot.basis = piv_basis
    cam_piv.basis = cam_piv_basis

    var roll_basis := Basis.IDENTITY
    for e in effects:
        roll_basis = e.apply(roll_basis, delta, ctx)
    roll_node.basis = roll_basis

    input = Vector2.ZERO
#

And names of nodes of course (i hope i doesnt forget anything impotant)

@onready var cam_piv: Node3D = $Pivot/Arm/CamPiv
@onready var roll_node: Node3D = $Pivot/Arm/CamPiv/Roll
@onready var cam: Camera3D = $Pivot/Arm/CamPiv/Roll/Camera3D
@onready var armature : Node3D = $Pivot/Armature
@onready var springarm: SpringArm3D = $Pivot/Arm

On board this sounds simple but i cant figure it out honestly i feel myself so stupid
Most likely there are just have to be some pretty simple operation of multiplying two matrixes but i cant figure out what kind of
Or maybe i just have to use one rotation instead of dividing it into pivot that track most of rotation inside and root that works only with aligning to grabvity direction rotation