Floating Origin with Cinemachine

Hi All,

I’m having trouble with my Cinemachine camera that pops (non smooth transition) back to target when I reset my player to origin.

Did some digging and found that others have had this problem and was given a solution ( Reposition target and camera runtime - how to avoid the "popping"? ).

I’ve tried to implement the script in my own project however I am still getting the popping effect, I’ll post what I’ve tried and the solution below.

Solution:

            // Inform any vcams that might be tracking this target
            int numVcams = CinemachineCore.Instance.VirtualCameraCount;
            for (int i = 0; i < numVcams; ++i)
                CinemachineCore.Instance.GetVirtualCamera(i).OnTargetObjectWarped(
                    transform, posDelta);

My Code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;


public class FloatingOrigin : MonoBehaviour
{
    public Transform Universe;
    public Transform Player;
 
    [Range(10, 5000)]
    public float unitsPerReset;

    private void FixedUpdate()
    {             
        Vector3 offset = Player.position - Vector3.zero;     

        float sqrLen = offset.sqrMagnitude;

            if(sqrLen >= unitsPerReset * unitsPerReset)
            {
                updateCam(offset);
                Universe.transform.position -= (Player.transform.position);         
                Player.transform.position = Vector3.zero;                             
                Debug.Log("Reset Ticked", gameObject);
            }                
    }

    private void updateCam(Vector3 posDelta)
    {
        int numVcams = CinemachineCore.Instance.VirtualCameraCount;
        for (int i = 0; i < numVcams; ++i)
        {
            CinemachineCore.Instance.GetVirtualCamera(i).OnTargetObjectWarped(Player, posDelta);
        }         
    }
}

Looking at the official documentation, it does appear I am using it correctly (Class CinemachineComponentBase | Package Manager UI website)

Ahh managed to solve it myself with a couple tweaks. The main issue was the posDelta needed to be inverted to a negative value. Although this was just a poorly implemented FloatingOrigin Solution, it was the backbones of what I needed to get moving forward.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;


public class FloatingOrigin : MonoBehaviour
{
    public Transform Universe;
    public Transform Player;
    public bool Debugging;
    private Rigidbody rb;
  
    [Range(10, 5000)]
    public float unitsPerReset;

    private void Start()
    {
        rb = Player.GetComponent<Rigidbody>();
    }

    private void FixedUpdate()
    {
        Vector3 offset = Player.position;
        float sqrLen = offset.sqrMagnitude;

            if(sqrLen >= unitsPerReset * unitsPerReset)
            {              
                Universe.transform.position -= (Player.transform.position);          
                rb.MovePosition(Vector3.zero);
                updateCam(offset);

                if (Debugging) { Debug.Log("Floating Origin Ticked", gameObject); }
            }                 
    }

    private void updateCam(Vector3 posDelta)
    {
        int numVcams = CinemachineCore.Instance.VirtualCameraCount;
        for (int i = 0; i < numVcams; ++i)
        {         
            CinemachineCore.Instance.GetVirtualCamera(i).OnTargetObjectWarped(Player, -posDelta);
        }          
    }
}
7 Likes