Hi, I tried to create a playground, but it doesn’t support import statements, so I’m not sure how to make one.
Anyways, my code uses imports, the behavior works if I force the type, but the type error makes me think there is a hidden problem.
I have a plane mesh that I’m adding a PointerDragBehavior, and a custom behavior called PointerInputBehavior.
import { PointerDragBehavior } from '@babylonjs/core'
import { PointerInputBehavior } from './PointerInputBehavior'
...
// Add Grip and scroll behavior
const scrollDragBehavior = new PointerDragBehavior({ dragPlaneNormal: this.root.up })
...
this.mesh.addBehavior(scrollDragBehavior)
const pointerInputBehavior = new PointerInputBehavior()
// TODO FIXME as unknown?
this.mesh.addBehavior(pointerInputBehavior as unknown as PointerDragBehavior)
The type error is I have to cast my custom behavior to PointerDragBehavior to get it to work (as unknown as …).
If I don’t cast as unknown, I get this type error:
Argument of type 'PointerInputBehavior' is not assignable to parameter of type 'Behavior<Node>'.
Types of property 'attach' are incompatible.
Type '(target: AbstractMesh) => void' is not assignable to type '(target: Node) => void'.
Types of parameters 'target' and 'target' are incompatible.
Type 'Node' is missing the following properties from type 'AbstractMesh': _internalAbstractMeshDataInfo, cullingStrategy, facetNb, partitioningSubdivisions, and 254 more.
I don’t understand why it see’s the ‘Node’ type.
Here’s my custom behavior’s file (stripped down version of the PointerDragBehavior):
import type { Behavior, Nullable, Observer, PointerInfo } from 'babylonjs'
import { AbstractMesh, Scene, Observable } from 'babylonjs'
export type PointerInputBehaviorOptions = { hello?: string }
const DEFAULTS = {}
/**
* A behavior that when attached to a mesh will allow the mesh to be dragged around the screen based on pointer events
*/
export class PointerInputBehavior implements Behavior<AbstractMesh> {
/**
* Abstract mesh the behavior is set on
*/
public attachedNode?: AbstractMesh
private _scene?: Scene
private _pointerObserver?: Nullable<Observer<PointerInfo>>
/**
* Fires each time behavior enabled state changes
*/
public onEnabledObservable = new Observable<boolean>()
/**
* If the behavior will emit pointer input events (Default: true)
*/
public set enabled(value: boolean) {
if (value != this._enabled) {
this.onEnabledObservable.notifyObservers(value)
}
this._enabled = value
}
public get enabled() {
return this._enabled
}
private _enabled = true
private _options: PointerInputBehaviorOptions
/**
* Gets the options used by the behavior
*/
public get options(): PointerInputBehaviorOptions {
return this._options
}
/**
* Sets the options used by the behavior
*/
public set options(options: PointerInputBehaviorOptions) {
this._options = options
}
/**
* Creates a pointer drag behavior that can be attached to a mesh
*/
constructor(options?: PointerInputBehaviorOptions) {
this._options = options || DEFAULTS
}
/**
* The name of the behavior
*/
public get name(): string {
return 'PointerInput'
}
/**
* Initializes the behavior
*/
public init() {
console.log('init')
}
/**
* Attaches the drag behavior the passed in mesh
* @param target The mesh that will emit inputs when under the pointer
*/
public attach(target: AbstractMesh): void {
this._scene = target.getScene()
this.attachedNode = target
this._pointerObserver = this._scene.onPointerObservable.add((pointerInfo) => {
if (!this.enabled) return
switch (pointerInfo.type) {
case BABYLON.PointerEventTypes.POINTERDOWN:
console.log('POINTER DOWN')
break
case BABYLON.PointerEventTypes.POINTERUP:
console.log('POINTER UP')
break
case BABYLON.PointerEventTypes.POINTERMOVE:
console.log('POINTER MOVE')
break
case BABYLON.PointerEventTypes.POINTERWHEEL:
console.log('POINTER WHEEL')
break
case BABYLON.PointerEventTypes.POINTERPICK:
console.log('POINTER PICK')
break
case BABYLON.PointerEventTypes.POINTERTAP:
console.log('POINTER TAP')
break
case BABYLON.PointerEventTypes.POINTERDOUBLETAP:
console.log('POINTER DOUBLE-TAP')
break
}
})
}
/**
* Detaches the behavior from the mesh
*/
public detach(): void {
if (this._pointerObserver) {
this._scene?.onPointerObservable.remove(this._pointerObserver)
}
}
}
Any suggestions? Thank you!