The problem with spatial objects and interaction with them (original) (raw)

December 13, 2025, 1:08pm 1

My problem is that when I try to change the spatial’s position or rotation, nothing happens, and I can’t figure out what’s going on. I’m new to Java, so forgive me if the code is a bit hacky or silly.

Game:

package main;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Spatial;

public class Game extends SimpleApplication {

    private BulletAppState bulletAppState = new BulletAppState();

    private Player player;

    public static void main(String[] args) {
        Game app = new Game();
        app.setShowSettings(false);
        app.start();
    }

    @Override
    public void simpleInitApp() {

        flyCam.setEnabled(false);
        stateManager.attach(bulletAppState);

        initLight();
        initTerrain();
        initPlayer();
    }

    private void initPlayer() {

        player = new Player(new Vector3f(0, 100, 0), inputManager, assetManager.loadModel("Models/Oto/Oto.mesh.xml"), cam);
        player.getChaseCam().setLookAtOffset(new Vector3f(0, 5, 0));
        player.getChaseCam().setMaxDistance(50);
        player.getSpatial().move(0, 3, 0);

        bulletAppState.getPhysicsSpace().add(player.getControl());
        rootNode.attachChild(player.getNode());

      }
    
    private void initTerrain() {
        
          Spatial land = assetManager.loadModel("Scenes/town/main.scene").scale(3f);
        
        RigidBodyControl landControl = new RigidBodyControl(CollisionShapeFactory.createMeshShape(land), 0);
        land.addControl(landControl);

        bulletAppState.getPhysicsSpace().add(landControl);

        rootNode.attachChild(land);

    }

    private void initLight() {

        DirectionalLight dl = new DirectionalLight();
        dl.setColor(ColorRGBA.White);
        dl.setDirection(new Vector3f(-5f, -5f, -5f));
        rootNode.addLight(dl);

        AmbientLight al = new AmbientLight();
        al.setColor(ColorRGBA.White.mult(3f));
        rootNode.addLight(al);

    }

    @Override
    public void simpleUpdate(float tpf) {
        player.update();
    }

    @Override
    public void simpleRender(RenderManager rm) {}
}

Player

package main;

import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.input.ChaseCamera;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;


public class Player implements ActionListener {


    private CharacterControl control = new CharacterControl(new CapsuleCollisionShape(1.5f, 2f), 0.1f);

    private Vector3f walkDir, camDir;

    private boolean forward, backward;

    private float camHorizontalRotation;

    private ChaseCamera chaseCam;

    private Spatial character;

    private Node node = new Node();


    Player(Vector3f PhysicsLocation, InputManager inputManager, Spatial character, Camera cam) {

        this.character = character;

        control.setGravity(50);
        control.setJumpSpeed(30);
        control.setFallSpeed(20);

        node.setLocalTranslation(PhysicsLocation);

        character.addControl(control);
        character.setName("Character model");
        node.attachChild(character);

        chaseCam = new ChaseCamera(cam, this.character, inputManager);
        chaseCam.setMaxDistance(10);
        chaseCam.setMinDistance(0);
        control.setPhysicsLocation(PhysicsLocation);

        inputManager.addMapping("W", new KeyTrigger(KeyInput.KEY_W));
        inputManager.addMapping("S", new KeyTrigger(KeyInput.KEY_S));
        inputManager.addMapping("SPACE", new KeyTrigger(KeyInput.KEY_SPACE));

        inputManager.addListener(this, "W", "S", "SPACE");

    }

    
    @Override
    public void onAction(String name, boolean isPressed, float tpf) {

        if (name.equals("S")) backward = isPressed;
        else if (name.equals("W")) forward = isPressed;
        else if (name.equals("SPACE") && isPressed) control.jump();

    }


    public ChaseCamera getChaseCam() {
        return chaseCam;
    }

    
    public CharacterControl getControl() {
        return control;
    }


    public Spatial getSpatial() {
        return character;
    }


    public Spatial getNode() {
        return node;
    }


    public void update() {

        walkDir = new Vector3f(0, 0, 0);

        camHorizontalRotation = chaseCam.getHorizontalRotation();
        camDir = new Vector3f((float) Math.cos(camHorizontalRotation), 0, (float) Math.sin(camHorizontalRotation));

        if (forward) walkDir.addLocal(camDir.negate());
        else if (backward) walkDir.addLocal(camDir);

        control.setWalkDirection(walkDir);

    }
}

codex December 13, 2025, 1:41pm 2

Welcome @fedot135,

CharacterControl is actively setting the transform of the spatial to the control’s physical transform. Any attempts to transform the spatial via setLocalTranslation, setLocalRotation, move, etc. won’t work because their effects are immediately overwritten by the CharacterControl. Instead use warp (to translate immediately to a physical position) and setViewDirection (to rotate the spatial to face a particular direction) on the control itself.

fedot135 December 13, 2025, 1:42pm 3

Okay, thank you very much!

fedot135 December 13, 2025, 2:05pm 4

@codex Another small question: can I somehow change the position of the model, not the physical hitbox?

(after adding control)

fedot135 December 13, 2025, 2:16pm 5

Okay, so I found a solution. Control can be transferred to Node, and manipulation of the model itself will then be successful. Thanks for your help!