ramokz / phantom-camera

👻🎥 Control the movement and dynamically tween 2D & 3D cameras. Built for Godot 4. Inspired by Cinemachine.
https://phantom-camera.dev/
MIT License
2.26k stars 77 forks source link

Unable to animate CameraAttributesPractical inside a PhantomCamera3D node in game #388

Open SubhadeepJasu opened 1 month ago

SubhadeepJasu commented 1 month ago

Issue description

I have an AnimationPlayer controlling a PhantomCamera3D node, which has CameraAttributesPractical. I have exposure, and dof animations in the player which play nicely when in the editor. But these attribute animations don't work when running the game.

Steps to reproduce

Add an Camera3D with a PCamHost, a PhantomCamera3D node and an AnimationPlayer (with MeshInstance3Ds to view something). Animate the PhantomCamera3D position, rotation and attributes. The animation plays properly in editor, but in game only the position and rotation animations play and not the attributes.

(Optional) Minimal reproduction project

No response

ramokz commented 1 month ago

This is a known limitation with the current system.

At the minute, the system cannot update the Attribute resource via the PCam3D during runtime, but it can via the Camera3D directly. If you modify the attribute resource of a PCam3D during runtime, it should only be affected when it gets tweened to from another PCam3D.

I haven't been able to find a performant way of doing this during runtime, as I can't quite see a way to only update the Camera3D's attribute whenever the PCam3D's changes, like with, e.g., a signal. The only alternative that I can think of is to update the resource every tick, but that is a fairly expensive approach, so have refrained from doing it for performance reasons. It works in the editor because I'm assigning the attribute every tick, mainly so one can see what changes a change has, but disable that logic during runtime.

SubhadeepJasu commented 1 month ago

I am currently getting around it by setting the process mode of the host to DISABLED and then controlling the camera directly using Animation player.

TranquilMarmot commented 1 month ago

Funny that a few of us are running into this all at the same time 😄 🎥

I haven't been able to find a performant way of doing this during runtime, as I can't quite see a way to only update the Camera3D's attribute whenever the PCam3D's changes, like with, e.g., a signal.

I'd be okay with a function that we could call on PhantomCamera3D that would force an update of the parent camera's attributes (update_owner_attributes?). It can be called whenever we know that a value has changed. Not great and would have to be documented as a "quirk" 🤷

At the minute, the system cannot update the Attribute resource via the PCam3D during runtime, but it can via the Camera3D directly.

This does work. Here's what I ended up with:

var host_camera_attributes := (
    phantom_camera.pcam_host_owner.camera_3d.attributes as CameraAttributesPractical
)

if phantom_camera.is_active():
    host_camera_attributes.dof_blur_near_enabled = true

    var target_blur = 2.0 if aiming else 0.0
    host_camera_attributes.dof_blur_near_distance = lerpf(
        host_camera_attributes.dof_blur_near_distance, target_blur, delta * 10
    )
else:
    host_camera_attributes.dof_blur_near_enabled = false
    host_camera_attributes.dof_blur_near_distance = 0.0

I currently only have one camera that I need the blur on, but I could see this getting a bit complicated if you want to have different values that are animated in code for different cameras.