Making a computer-controlled character move?

How can I make a computer-controlled character move? Should I use the spatial.move method? I tried putting it in the update loop to make a goblin move in its direction but it doesn’t move:

[java] public void simpleUpdate(float tpf) {



Vector3f modelDirection = goblin.getLocalRotation().toRotationMatrix().getColumn(2);

modelDirection.multLocal(tpf * 5);

goblin.move(modelDirection);

}

[/java]

…where goblin is a Spatial. Can you tell me how it should be done? It plays the walk animation correctly.

goblin.setLocalTranslation() is the easiest way to move any spatial.



Alternatively you can for example use a control and make use of a MotionPath/MotionEvent

using path finding to generate the path the npc is supposed to move along.

1 Like

First of all, don’t call multLocal on a reference to a vec3 which belongs to a spatial. Either clone the vec3 first or use mult (). To move it in the direction it is facing multiply the rotation by Vector3f.Unit_z. Normalize it and then multiple it by tpf and your movement factor. There’s examples of this in my video tutorial series and math for dummies.

1 Like
@wezrule said:
First of all, don't call multLocal on a reference to a vec3 which belongs to a spatial. Either clone the vec3 first or use mult (). To move it in the direction it is facing multiple the rotation by Vector3f.Unit_z. Normalize it and then multiple it by tpf and your movement factor. There's examples of this in my video tutorial series and math for dummies.

Can you please elaborate a bit on this since I'm a newbie and I didn't find other code examples in the math for dummies other than .move. I want to know how to use this technique you're mentioning but I've got no experience in doing it. Could you show some code based in my effort?
@perfecticus said:
goblin.setLocalTranslation() is the easiest way to move any spatial.

Alternatively you can for example use a control and make use of a MotionPath/MotionEvent
using path finding to generate the path the npc is supposed to move along.

I tried it but it didn't seem to do anything:
[java] public void simpleUpdate(float tpf) {

Vector3f modelDirection = goblin.getLocalRotation().toRotationMatrix().getColumn(2);
goblin.setLocalTranslation(modelDirection.add(new Vector3f(1, 0, -0)));
}[/java]
I must be doing it wrong. Can you please tell me more how to do it? Thanks

The hello tutorials show how to move stuff around…

2 Likes

@niklasro , try these tests:



http://code.google.com/p/jme-simple-examples/source/browse/JMESimpleExamples/src/Basics/SpatialMotionsLinear.java

http://code.google.com/p/jme-simple-examples/source/browse/JMESimpleExamples/src/Basics/SpatialMotionsSmooth1.java

http://code.google.com/p/jme-simple-examples/source/browse/JMESimpleExamples/src/Basics/SpatialMotionsNonLinear.java

But for physics you will need setWalkDirection() instead of setLocalTranslation().

1 Like
@mifth said:
But for physics you will need setWalkDirection() instead of setLocalTranslation().

I think I did just that but the goblin wasn't moving. I created an animated goblin and now I want it to move:
[java] goblin = assetManager.loadModel("objects/goblin.j3o");
goblin.scale(4f, 4f, 4f);
goblincharacter = new CharacterControl(capsule, 2);
goblin.addControl(goblincharacter);
goblincharacter.setPhysicsLocation(new Vector3f(60, 3.5f, -60));
//goblincharacter.setViewDirection(new Vector3f(1, 0, 0));
//character.setWalkDirection(new Vector3f(1, 0, 0));
control = goblin.getControl(AnimControl.class);
control.addListener(this);
channel = control.createChannel();
channel.setAnim("walk");
rootNode.attachChild(goblin);[/java]

Please… Everything you want to do is explained from A to Z in the tutorial series… And btw the tutorials @mifth linked are not supported by us and don’t necessarily show best practices.

1 Like

try this in the simpleUpdate() method:

[java]goblincharacter.setWalkDirection(goblincharacter.getLocalRotation().mult(Vector3f.UNIT_Z).multLocal(0.4f));

[/java]



And as Normen said you will need to have a look at walkingCharacter test.

1 Like
@mifth said:
try this in the simpleUpdate() method:
[java]goblincharacter.setWalkDirection(goblincharacter.getLocalRotation().mult(Vector3f.UNIT_Z).multLocal(0.4f));
[/java]

And as Normen said you will need to have a look at walkingCharacter test.

This worked for me! Many thanks!

Now I want the goblin to be able to move in many directions. I’m trying this code which is working for the forward direction but not for the other directions:

[java] goblinWalkDirection.set(0, 0, 0);



if (goblinleft) {

System.out.println(“goblin left”);

goblinWalkDirection.addLocal(goblin.getLocalRotation()

.mult(Vector3f.UNIT_X).multLocal(0.09f));

}

if (goblinright) {

System.out.println(“goblin right”);

goblinWalkDirection.addLocal(goblin.getLocalRotation()

.mult(Vector3f.UNIT_X).multLocal(0.09f));

}

if (goblinup) {

System.out.println(“goblin forward”);

// move goblin forward

goblinWalkDirection.addLocal(goblin.getLocalRotation()

.mult(Vector3f.UNIT_Z).multLocal(0.09f));

}

if (goblindown) {

System.out.println(“goblin backwards”);

goblinWalkDirection.addLocal(goblin.getLocalRotation()

.mult(Vector3f.UNIT_Z).multLocal(0.09f).negate());

}

if (goblinWalkDirection.length() == 0) {

if (!“idleA”.equals(animationChannel.getAnimationName())) {

goblinChannel.setAnim(“idleA”, 1f);

}

} else {

goblincharacter.setViewDirection(goblinWalkDirection);

if (!“walk”.equals(goblinChannel.getAnimationName())) {

goblinChannel.setAnim(“walk”, 1f);

}

}

goblincharacter.setWalkDirection(goblinWalkDirection);[/java]

For the forward direction, it works perfectly. Now I think I only need to know how to make the directions for the other Vectors. Perhaps you can tell me?



Thanks!

Please give me a hint if you have any more idea how I can implement my NPC AI for moving around the goblin. I’m stuck at trying to make the gobline move. I could not get the vectors right when trying to move the goblin in trivial directions, Can you help me with some hints?

Thanks

Your code for goblin left and right is identical, that’s probably not what you intended.



For backwards you probably want to use negateLocal as well (faster/more efficient - same result)