phantom-camera
phantom-camera copied to clipboard
Initial setup for `_follow_spring_arm_node` is delayed for first time assignment of `Properties.follow_target_node`
Issue description
When in ThirdPersonFollow mode and follow_target
is assigned to something non-null for the first time, the initial setup for _follow_spring_arm_node
is triggered, but not until the next _process
tick of the PhantomCamera3D. # The default behavior is for the spring arm orientation to be initialized to the orientation of the PhantomCamera3D, however, I would like for it to initialize to the orientation of the follow_target
that was just assigned. If I try to set it immediately after I assign follow_target
(pcam._follow_spring_arm_node.basis = pcam.get_follow_target_node().global_basis
), the initialization code inside PhantomCamera3D._process will overwrite it on the next process tick.
This is only a problem for the first assignment of follow_target
. Subsequent assignments will not trigger the initialization code and so I can immediately set the orientation of the spring arm. Currently, a simple workaround for my use case is to add a small delay so that _process can tick once before I assign the orientation:
if not pcam.get_parent() == pcam._follow_spring_arm_node:
get_tree().create_timer(0.01).timeout.connect(func(): pcam._follow_spring_arm_node.basis = pcam.get_follow_target_node().global_basis )
else:
pcam._follow_spring_arm_node.basis = pcam.get_follow_target_node().global_basis
IMO, the best solution would be to take any initialization code out of _process
and instead trigger it from its own function when conditions for initialization have been met.
Steps to reproduce
- Create a scene with a PhantomCamera3D in Follow Mode: Third Person without assigning a follow target.
- Assign a follow target and immediately try to
pcam.set_third_person_rotation
. This assignment will apply, but will be immediately overwritten.
i ran into the same issue of needing to initialize some properties of the third person spring_arm on ready and it not working. instead of a using a timer i added a signal to the phantom camera that emits after it reparents the spring_arm. that seemed to work for my use case and it might work for yours. i don't know if its a good solution over all or not though
Is this still an issue in 0.7?
Yes. I didn't realized it when I made this change, but there's still initialization code inside PhantomCamera3D._process
Moving the rest of the initialization code into _ready()
allows for me to change the workaround code from
if not pcam.get_parent() == pcam._follow_spring_arm:
get_tree().create_timer(0.01).timeout.connect(func(): pcam._follow_spring_arm.basis = pcam.follow_target.global_basis )
else:
pcam._follow_spring_arm.basis = pcam.follow_target.global_basis
into
pcam._follow_spring_arm.set.call_deferred("basis", pcam.follow_target.global_basis)
Can see you're assigning a basis value to the springarm node, would adding a setter function to the addon script make that easier?