Getting components by their base class name in Lens Studio
Yet another small thing, this time to solve something that annoyed the heck out of me since day one. I really dislike this construction that you have to use when you have to get a reference to a component from a SceneObject
someSceneObject.getComponent(MyComponentClass.getTypeName()) as MyComponentClass;
And what is even worse, it does not work at all when when you need to find the reference but you only have the component’s base class. Suppose I have this trivial base controller component:
@component
export class MyBaseClass extends BaseScriptComponent {
public hello(): void {
print("Hello from MyBaseClass");
}
}
However, I have multiple prefabs types with a slightly different child class suited for their particular purpose, for instance:
import { MyBaseClass } from "./MyBaseClass";
@component
export class MyChildClass extends MyBaseClass {
public hello(): void {
print("Hello from MyChildClass");
}
}
If I add this child class to my prefab, then try to find a reference to its controlling component using the MyBaseClass class
myPrefab.getComponent(MyBaseClass.getTypeName()) as MyBaseClass;
I wil get a null value result! This is highly confusing for someone coming from Unity, and rather limiting as well.
However, there is a solution. I have extended my SceneUtils with this little method:
export function getComponent<T>(
sceneObject: SceneObject,
myClassType: new (...args: any[]) => T): T | null {
for (const component of sceneObject.getComponents("Component") as Component[]) {
if (component instanceof myClassType) {
return component as T
}
}
return null;
}
I made a little test script in the demo project to show how it works:
import { MyBaseClass } from "./MyBaseClass";
import { getComponent } from "LocalJoost/Utilities/SceneUtils";
@component
export class TestScript extends BaseScriptComponent {
@input prefab : ObjectPrefab;
onAwake() {
var instance = this.prefab.instantiate(this.getSceneObject());
var getComponentResult = instance.getComponent(MyBaseClass.getTypeName()) as MyBaseClass;
print("getComponentByClass: " + (getComponentResult != null));
var findScriptComponentResult = getComponent<MyBaseClass>(instance, MyBaseClass);
print("findScriptComponentByClass: " + (findScriptComponentResult != null));
findScriptComponentResult.hello();
}
}
Here’s the logger output that actually proves it works

Although I search using the base class, I get a reference to a child class object. Which is exactly what you would expect. Or at least what I would expect. It’s only five lines of code, so I wonder why Snap didn’t implement it this way in their own getComponent. Maybe they wanted to leave in some challenges for grumpy old skool software engineers to solve 😁. However, this works and it easy to use.
MVP Profile
Try my app HoloATC!
HoloLens 2
Magic Leap 2
Meta Quest
Android phones
Snap Spectacles
Buy me a drink ;)
BlueSky
Mastodon
Discord: LocalJoost#3562