playMaker

Author Topic: Cinemachine ConfinerSetProperties missing confiner.InvalidatePathCache()[SOLVED]  (Read 1012 times)

szomaza

  • Sr. Member
  • ****
  • Posts: 253
    • View Profile
I am changing the confiner shape size during runtime and noticed that it often does not work, meaning: the confiner shape is in fact larger, still the vcam is restricted to the previous smaller area of movement.

I searched and found the solution here:
https://forum.unity.com/threads/cinemachine-confiner-2d-update-area.515133/
"2D confiner caches the path shape, for performance. When you change the path, call confiner.InvalidatePathCache() to rebuild the cache."

https://docs.unity3d.com/Packages/com.unity.cinemachine@2.1/api/Cinemachine.CinemachineConfiner.html#Cinemachine_CinemachineConfiner_InvalidatePathCache

ConfinerSetProperties action does not have this:
Code: [Select]
// (c) Copyright HutongGames, LLC 2010-2018. All rights reserved.
// Author jean@hutonggames.com
// This code is licensed under the MIT Open source License

using Cinemachine;
using UnityEngine;

namespace HutongGames.PlayMaker.Actions.ecosystem.cinemachine
{
    [ActionCategory("Cinemachine")]
[Tooltip("Sets the properties of a Confiner Virtual Camera extension")]
    public class ConfinerSetProperties : CinemachineActionBase<CinemachineConfiner>
    {
        [RequiredField]
[Tooltip("The Cinemachine Confiner Extension")]
        [CheckForComponent(typeof(CinemachineConfiner))]
        public FsmOwnerDefault gameObject;

        [Tooltip("The confiner can operate using a 2D bounding shape or a 3D bounding volume.\n" +
                 "Leave to none for no effect")]
        [ObjectType(typeof(CinemachineConfiner.Mode))]
        public FsmEnum confineMode;

        [Tooltip("The 3d volume within which the camera is to be contained if ConfineMode is set to Confine3D.\n" +
                 "Leave to none for no effect")]
        [CheckForComponent(typeof(Collider))]
        [HideIf("UsesConfine2d")]
        public FsmOwnerDefault boundingVolume3d;

        [Tooltip("The 2D shape within which the camera is to be contained.\n" +
                 "Leave to none for no effect")]
        [CheckForComponent(typeof(Collider2D))]
        [HideIf("UsesConfine3d")]
        public FsmOwnerDefault boundingVolume2d;

        [Tooltip("If camera is orthographic, screen edges will be confined to the volume.  If not checked, then only the camera center will be confined.\n" +
                "Leave to none for no effect")]
        public FsmBool confineScreenEdges;


        [Tooltip("Upper limit on how many obstacle hits to process.  Higher numbers may impact performance.  In most environments, 4 is enough.\n" +
                 "Leave to none for no effect")]
        [HasFloatSlider(0f,10f)]
        public FsmFloat damping;

        [Tooltip("repeat every frame, useful for animation")]
        public bool everyFrame;


        GameObject _goCol3d;
        GameObject _goCol2d;

        public override void Reset()
        {
            gameObject = null;
            confineMode = new FsmEnum() { UseVariable = true };

            boundingVolume3d = new FsmOwnerDefault() {OwnerOption= OwnerDefaultOption.SpecifyGameObject};
            boundingVolume3d.GameObject = new FsmGameObject() { UseVariable = true };

            boundingVolume2d = new FsmOwnerDefault() { OwnerOption = OwnerDefaultOption.SpecifyGameObject };
            boundingVolume2d.GameObject = new FsmGameObject() { UseVariable = true };

            confineScreenEdges = new FsmBool() {UseVariable = true };
            damping = new FsmFloat() { UseVariable = true };

            everyFrame = false;
        }

        public bool UsesConfine2d()
        {
            return (CinemachineConfiner.Mode)confineMode.Value == CinemachineConfiner.Mode.Confine2D;
        }

        public bool UsesConfine3d()
        {
            return (CinemachineConfiner.Mode)confineMode.Value == CinemachineConfiner.Mode.Confine3D;
        }

        public override void OnEnter()
        {
            Execute();

            if (!everyFrame)
            {
                Finish();
            }
        }

        public override void OnUpdate()
        {
            Execute();
        }

        void Execute()
        {
            if (!UpdateCache(Fsm.GetOwnerDefaultTarget(gameObject)))
            {
                return;
            }

            if (!confineMode.IsNone)
            {
                this.cachedComponent.m_ConfineMode = (CinemachineConfiner.Mode)confineMode.Value;
            }

            if (boundingVolume3d.OwnerOption == OwnerDefaultOption.UseOwner ||
                !boundingVolume3d.GameObject.IsNone
               )
            {
                _goCol3d = Fsm.GetOwnerDefaultTarget(boundingVolume3d);

                this.cachedComponent.m_BoundingVolume = _goCol3d?_goCol3d.GetComponent<Collider>():null ;
            }

            if (boundingVolume2d.OwnerOption == OwnerDefaultOption.UseOwner ||
                !boundingVolume2d.GameObject.IsNone
               )
            {
                _goCol2d = Fsm.GetOwnerDefaultTarget(boundingVolume2d);
                this.cachedComponent.m_BoundingShape2D = _goCol2d?_goCol2d.GetComponent<Collider2D>() : null;
            }

            if (!confineScreenEdges.IsNone)
            {
                this.cachedComponent.m_ConfineScreenEdges = confineScreenEdges.Value;
            }

            if (!damping.IsNone)
            {
                this.cachedComponent.m_Damping = damping.Value;
            }


        }
    }
}

Where should I add it and how?
Or should this be a separate action?

edit: It actually should be both: in this action where you can change the confiner by setting it and also a separate action is needed too because you can change the confiner shape/size already in use, with many different actions, so need to be able to call this confiner.InvalidatePathCache() any time, separately.

Please help and also update in the ecosystem with this improvement.

Br,
szomaza

« Last Edit: January 29, 2019, 01:26:22 AM by jeanfabre »

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 14703
  • Official Playmaker Support
    • View Profile
Re: Cinemachine ConfinerSetProperties missing confiner.InvalidatePathCache()
« Reply #1 on: January 08, 2019, 01:43:07 AM »
Hi,

 ok, I'll see how I can integrate this, thanks for mentioning it.

Bye,

 Jean

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 14703
  • Official Playmaker Support
    • View Profile
Re: Cinemachine ConfinerSetProperties missing confiner.InvalidatePathCache()
« Reply #2 on: January 08, 2019, 02:21:00 AM »
Hi,

 ok, it's done, please redownload the package. Let me know if all is working for you. I am not sure if the 3d collider confiner needs an update too, so I left it without, and I have asked on the forum, if I need to add it for the 3d collider, then I'll do it as well.

Let me know how it works on your end, and if all is ok, I'll announce that new version.

 Bye,

 Jean

szomaza

  • Sr. Member
  • ****
  • Posts: 253
    • View Profile
Re: Cinemachine ConfinerSetProperties missing confiner.InvalidatePathCache()
« Reply #3 on: January 19, 2019, 03:09:02 AM »
After updating the cinemachine package some errors appeared:

Code: [Select]
This one on a bunch of ArrayTable... actions.:

Assets/PlayMaker ArrayMaker/Addons/Custom/Table/Actions/ArrayTableAddRow.cs(59,62): error CS0117: `PlayMakerUtils' does not contain a definition for `LogFullPathToAction'

and

Assets/PlayMaker Cinemachine/Components/CinemachineBrainProxy.cs(30,43): error CS0123: A method or delegate `CinemachineBrainProxy.HandleCameraActivatedAction(Cinemachine.ICinemachineCamera)' parameters do not match delegate `UnityEngine.Events.UnityAction<Cinemachine.ICinemachineCamera,Cinemachine.ICinemachineCamera>(Cinemachine.ICinemachineCamera, Cinemachine.ICinemachineCamera)' parameters

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 14703
  • Official Playmaker Support
    • View Profile
Re: Cinemachine ConfinerSetProperties missing confiner.InvalidatePathCache()
« Reply #4 on: January 20, 2019, 11:19:50 PM »
Hi,

Odd. what are the other addons from the ecosystem you have on your project?

I have republished ArrayMaker to use the latest PlayMaker utils, can you download it from the Ecosystem. Let me know if you still get that error.

bye,

 Jean

szomaza

  • Sr. Member
  • ****
  • Posts: 253
    • View Profile
Re: Cinemachine ConfinerSetProperties missing confiner.InvalidatePathCache()
« Reply #5 on: January 28, 2019, 06:21:25 AM »
Thank you very much.
After updating Arraymaker and getting the Cinemachine package there are no errors now and the resizing of the confiner area seems to function nicely now.