What's the best way to achieve Steam VR Input behavior separation in Unity?

Sorry if this has been asked before. I have my own solution to this problem that is working okayishly, but I don’t want to “lead the witness”, so I thought I would ask first:

What’s the best way to achieve Steam VR Input behavior separation in Unity?

Some background: I’m an old hand at software engineering, but I’m new to Unity and C#. My primary language is Ruby. When I first got into SteamVR Unity programming, I watched this video by Sean Lee, which does a great job giving people a starting point to start programming/hacking:

The problem with Sean’s approach is that it doesn’t scale well. The trigger/grab/movement logic lives in the TouchController behavior. In writing Mesh Maker VR, I decided I needed that logic to live in the objects being touched/selected/moved etc. This is especially important when an object must receive input from both controllers at the same time, such as in pinch scaling operations.

So, given that many of you are much more experienced in C# and Unity than I am, what’s the best way to achieve that separation of concerns?

Thanks!

No responses. Interesting.

So, what I’ve been doing is creating behaviors that act as “Interfaces”. For example, if I have an object that requires Drag input, I apply a GrabbableController. The GrabbableController doesn’t do anything itself. It just acts as an interface so the TouchController behavior can automatically tell if the object should be able to accept grab/drag input. It also provides a way to assign via the Editor where that input should go. It functions as a sort of router. Here’s an example:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;

[System.Serializable]
public class MyGrabEvent : UnityEvent<Transform, int> {
}

public class GrabbableController : MonoBehaviour {
    public MyGrabEvent onGrabStart;
    public MyGrabEvent onGrabUpdate;
    public MyGrabEvent onGrabEnd;

    // Use this for initialization
    void Start () {
       
    }
   
    // Update is called once per frame
    void Update () {
       
    }
}

I then define an onGrabStart method on my object’s real controller behavior that does the real work. It becomes a little tedious always having to remember to route this input in the Editor, but it’s better than having all of those routes in code, IMO.