protected virtual void Update()
    {
        Vector3 oldPos      = transform.position;
        float   oldRotation = transform.eulerAngles.z;

        SideScrollNodeInfo info = GetCurrentScrollInfo();

        AdvancePath(info.pathSpeed, Time.deltaTime);
        MoveSkybox(transform.position.x - oldPos.x);

        // Values will have changed after advancing the path, so update FOV, rotation, etc.
        info = GetCurrentScrollInfo();
        UpdateFOV(info.cameraFov);

        if (rotationFollowCurve)
        {
            UpdateRotation(GetPathAngle());
        }
        else
        {
            UpdateRotation(info.camAngle);
        }

        AutoSideScrollFollower.MoveAll(Camera.main.transform.position - oldPos, Camera.main.transform.eulerAngles.z - oldRotation);

        UpdateEdgeCollision();
    }
    // Create node values interpolated between p1 and p2.
    //
    // p1: The previous node.
    // p2: The next node.
    // pct: The percentage [0.0,1.0] along the path between the two.
    //
    public static SideScrollNodeInfo GetInterpolatedInfo(SideScrollNodeInfo p1, SideScrollNodeInfo p2, float pct)
    {
        pct = Mathf.Clamp01(pct);
        SideScrollNodeInfo info = new SideScrollNodeInfo();

        info.cameraFov = Mathf.Lerp(p1.cameraFov, p2.cameraFov, pct);
        info.pathSpeed = Mathf.Lerp(p1.pathSpeed, p2.pathSpeed, pct);
        info.camAngle  = Mathf.Lerp(p1.camAngle, p2.camAngle, pct);

        return(info);
    }
    // Get the scrolling info at the current point along the curve.
    //
    protected override SideScrollNodeInfo GetCurrentScrollInfo()
    {
        int pointIndex = Mathf.FloorToInt(t);

        SideScrollNodeInfo p1 = GetInfoAtPoint(pointIndex);

        if (pointIndex >= curve.pointCount - 1)
        {
            return(p1);
        }

        SideScrollNodeInfo p2 = GetInfoAtPoint(pointIndex + 1);
        float pct             = t - ((float)pointIndex);

        return(SideScrollNodeInfo.GetInterpolatedInfo(p1, p2, pct));
    }