Half of the effort is knowing the right questions to ask, so I’ll give this another go.
Suppose there is a scenario where you want to dynamically spawn different prefabs on a detected face (on the main face transform, as well as the left and right eyes) via a UI. How is this done?
None of the examples on the AR Foundation Samples repository demonstrate this, as they all have a fixed prefab sitting in the face manager’s prefab slot. I figured that, in order to make this dynamic, the code would be as simple as reassigning what goes in the “Face Prefab” slot of the face manager. I was incorrect, and I don’t know what to do, so I’ve been investigating for the past couple of months.
The AR Face Manager has a “facesChanged” event. Supposedly, when this is invoked, whatever happens to be in the “face prefab” slot gets instantiated. Supposedly, I would handle this on my end via some kind of OnFacesChanged method which takes an ARFacesChangedEventArgs instance. How would this be efficiently done?
I tried subscribing this to the event:
private void OnFacesChanged(ARFacesChangedEventArgs obj)
{
_faceManager.facePrefab = _myPrefab;
}
but this only works the first time a face is detected. I do not know when these events are invoked, because the documentation does not explain what occurs during invocation:
Is this true? I have my doubts. Perhaps some dynamic examples would highlight exactly what’s being described here. When a face prefab is spawned by the face manager, does that happen immediately after the event is invoked, or before? When is the face manager deciding to look at its “Face Prefab” slot to decide when to spawn? If the above method is indeed invoked as described in the documentation, why wouldn’t a prefab reassignment like the one above work to change the prefab on the face? Am I supposed to be managing another list altogether?
There are three lists which, I assume, are completely managed by the face manager. Or, is that incorrect and, in fact, I have to do my own Object.Destroy() methods to detach them from detected faces?
Or, am I not supposed to be using the facesChanged event at all? Should I, instead, be using the ARFace.updated method and keep track of them that way?
I’ve also seen recommendations such as:
foreach(ARFace face in _faceManager.trackables)
{
Object.Instantiate(_facePrefab, face.transform);
}
but this only works for spawning objects on the base transform of the ARFace. Some ARFaces in _faceManager.trackables have the .leftEye and .rightEye components missing completely (null ref exceptions), even if the subsystem supports eye tracking the entire time.
Hopefully this better highlights the ways in which I am misunderstanding how this stuff is working.