Spatial stays on ground at all times

I am wanting a spatial that is moving set to a specific direction to stay on the ground. Here is what I mean:

image

Right now, this spider is in mid-air. It moves toward the player’s position as I update it in simpleUpdate() as shown below:

spider.spider.lookAt(character.getPhysicsLocation(), Vector3f.UNIT_Y);
            Quaternion currentDirection = spider.spider.getLocalRotation();
            spider.spider.move(currentDirection.getRotationColumn(2).mult(tpf).mult(16.5f));

However, I want it to stay on the ground always. How can I do this?

1 Like

why not just use Physics?

Try casting a ray downward from the spatial and snapping the spatial to the collision point.

// collidables node
Node collidables = new Node("stuff the spider can collide with");
collidables.attachChild(/*attach collidable stuff here*/);

// spatial initialization
Spatial spider = assetManager.loadModel("Models/spider_thing.j3o");
spider.setLocalTranslation(/*spider coordinates*/);

// fields
Vector3f movementDirection = new Vector3f(0, 0, -1);
float downwardMargin = 2.5f;

// cast and react to ray
CollisionResults results = new CollisionResults();
Ray ray = new Ray(spider.getLocalTranslation(), Vector3f.UNIT_Y.negate());
collidables.collideWith(ray, results);
if (results.size() > 0) {
    Vector3f closest = results.getClosestCollision().getContactPoint();
    Vector3f sp = spider.getLocalTranslation();
    spider.setLocalTranslation(sp.getX(), closest.getY()+downwardMargin, sp.getZ());
}

This will automatically snap spider to the ground directly below it. It doesn’t allow for falling by gravity specifically. You can tweak the collisions to allow for falling by only snapping if the distance to the closest collision is less than a specific amount (in this case downwardMargin).

// cast and react to ray
CollisionResults results = new CollisionResults();
Ray ray = new Ray(spider.getLocalTranslation(), Vector3f.UNIT_Y.negate());
collidables.collideWith(ray, results);
if (results.size() > 0) {
    Vector3f closest = results.getClosestCollision().getContactPoint();
    Vector3f sp = spider.getLocalTranslation();
    if (sp.distance(closest) < downwardMargin) {
        spider.setLocalTranslation(sp.getX(), closest.getY()+downwardMargin, sp.getZ());
    }
}

Edit: Sorry, accidentally provided the wrong directional vector for the ray direction. It should be pointing down (Vector3f.UNIT_Y.negate()). Fixed now.

1 Like

I think I will use this for a different part of my game where I need spatials to roll down a ramp and stay on the ground without any physics. But my spiders need physics as they need to be able to have gravity and detect collisions and so I think it would be best to use PhysicsControl.

Can I use multiple physics controls (so like both RigidBodyControl AND GhostControl)

1 Like