Attach GhostControl to Animation

Below is my code contribution of how to attach a ghost control to an animation.

This is useful when you shoot a bullet against a target. When both ghost controls collide it means you hit the target. The target would be static, you should code that part. Below explains the bullet ghost control only.

A saw a similar post but it doesn’t provide detail.

    public void simpleInitApp() {                          
        
        Node animationNode = (Node) assetManager.loadModel("Models/bullet animation 01/model.j3o");
        Node animationChildNode = (Node) animationNode.getChild("bullet");
        
        Node attachmentNode = (Node) animationNode.getChild("Bone_attachnode");
        
        GhostControl ghost = new GhostControl(
        new BoxCollisionShape(new Vector3f(1,1,1)));  // a box-shaped ghost
        attachmentNode.addControl(ghost); // Make the ghost follow the attachment node
        
        /** Set up Physics */
        BulletAppState bulletAppState = new BulletAppState();
        stateManager.attach(bulletAppState);
        
        bulletAppState.getPhysicsSpace().add(ghost);
        bulletAppState.setDebugEnabled(true);
                
        AnimChannel channel;
        AnimControl control; 
        
        control = animationChildNode.getControl(AnimControl.class);
        control.addListener(new AnimEventListener(){
            @Override
            public void onAnimCycleDone(AnimControl ac, AnimChannel ac1, String string) {

            }

            @Override
            public void onAnimChange(AnimControl ac, AnimChannel ac1, String string) {

            }
        });
        channel = control.createChannel();
        channel.setAnim("bullet_fired");
        channel.setLoopMode(LoopMode.Loop);
        channel.setSpeed(1f);
        
        // Attach entire animation node which contains the lights.
        rootNode.attachChild(animationNode);     
    }

The most important part:

// Load an animation

// Get the attachment node from the scene (.j3o) file
Node attachmentNode = (Node) animationNode.getChild("Bone_attachnode");
...
// Make the ghost follow the attachment node
attachmentNode.addControl(ghost);

Requirement:
Go to Scene Composer:
Select a bone from animation > Right click > Get attachment Node
Name this bone “Bone_attachmentnode”.


The image shows MOVING bullet travelings in the Z+ axis. And a ghost control box attached to the origin of the bullet animation.

More over you could attach a ghost control to a node without animation then move the node in the Update loop. The problem with that approach is that the movement patterns doesn’t allow for custom movement outside of math functions. Second, attaching the ghost control directly to the animation keeps you from needing a class attribute, so you can keep things as local variable. This helps keep your code clean and modular.

1 Like

Thank you for sharing your code and know-how.

At 60 frames per second, fast-moving bullet might pass through a thin target without the GhostControl ever detecting any overlap. You could mitigate that issue by stretching the bullet’s collision shape in the direction of motion.

A sweep test is more precise and would likely be more efficient. See Managing collisions :: The Minie project

3 Likes