hey guys, I’m new to JME3 and tried a few days now getting into it!
This forum helped me alot, but now I’m stuck at the topic above.
If I add like 100 NPCs (quite common for strategy games) my fps drop down to 9. I add them like this:
[java] for (int i = 100; i >= 1; i–) {
Spatial npc = assetManager.loadModel(“Models/Sinbad/Sinbad.mesh.xml”);
CharacterControl npcControl = new CharacterControl(new BoxCollisionShape(new Vector3f(2f, 4f, 0.5f)), 100f);
npc.addControl(npcControl);
npcControl.setPhysicsLocation(new Vector3f((float)(Math.random()*400),-100f,(float)(Math.random()*400)));
bulletAppState.getPhysicsSpace().add(npc);
physicsNode.attachChild(npc);
}
[/java]
is there another way to make NPCs stand (and walk) on a solid terrain? Or is JME3 simply not made for strategygames? or am I doing something terribly wrong?
It’s not that my graphicscard can’t handle all the models. it is even when I don’t attach them to a Node… so I guess it’s a physic problem!
please help me… after days of trying, I am about to punch a hole in my monitor!
It’s not a physics problem, it’s that you load 100 models. Wastes up your RAM. Try using a same model or something like that for all. Not sure
EDIT: Or maybe it is physics
EDIT2: Try using Profiler, to see which method wastes the most time, and stuff like that, next to the thing where you build and clean your game should be debug, and after that Profiling I think
Do you have to have 100 ‘different’ units? When they move, do they move together? 100 Character Controls are a lot. If they are a batch of soldiers, use just one Character Control.
Alternatively, if you have 100 different units, you might want to attach the Character Controls only when needed.
A full physics sim is probably overkill for 100 models in a strategy game. After all all they need to do is follow the terrain and not walk through things…
Try removing the physics and see what that does for your performance
I don’t think you will be able to use the same CharacterControl. You can use the same collision shape however for multiple character controls
I am not sure how to use one model for all Spatials. i tried this:
[java]
Spatial npc_model = assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");
for (int i = 100; i >= 1; i–) {
Spatial npc = npc_model.clone();
CharacterControl npcControl = new CharacterControl(new BoxCollisionShape(new Vector3f(2f, 4f, 0.5f)), 100f);
npc.addControl(npcControl);
npcControl.setPhysicsLocation(new Vector3f((float)(Math.random()*400),-100f,(float)(Math.random()*400)));
bulletAppState.getPhysicsSpace().add(npc);
physicsNode.attachChild(npc);
}
[/java]
but same result. CPU load is 30%, RAM used is 700mb (but used RAM only 45%… so still space)!
And yes, i want to have 100 different units… like in Empire Earth, in Age of Empires, in Supreme Commander… like in nearly every strategygame! and isnt the charactercontrol always needed? normaly u have workers walking around, collecting stuff, and other units attacking and stuff… so thats no solution… I will try the profiler later… but if I comment out the for(…) all works fine with 400+ fps… other ideas of implementing more than 100 moving units?
@zarch said:
A full physics sim is probably overkill for 100 models in a strategy game. After all all they need to do is follow the terrain and not walk through things...
Try removing the physics and see what that does for your performance :)
what do you mean by "removing the physics"? writing my own charactercontrol class without physicsimplementation? so checking for collisions manually and stuff?
and i thought the CharacterControl is espacially for “non-physic” things… isnt that the reason why you can’t apply forces to the charactercontrol?
I see the difficulty… However, in Empire Earth (if I judged well from screenshots), you wouldn’t need to use physics. I don’t think that games like Age of Mythology and Age of Empires use physics. At most, just give them Character Controls when a battle starts, although I still think that’s unnecessary. If zarch and wezrule couldn’t come up with a solution, I don’t think it’s possible.
EDIT: Character Control is still physics. You add it to the bulletAppState and can collide.
sure those games dont use (complex) physic… but in JME it’s the easiest (and as I get from the tutorials, the only way) to move things over solid ground!? so there is no “moveSimpleNPCoverSolidTerrain” control? so the only choice i have is writing my own control class?
I don’t know whether or not I’m understanding you. But you can move a spatial. Just use:
[java]spatial.setLocalTranslation(spatial.getLocalTranslation().add(new Vector3f(0, 0, 1));[/java]
I didn’t test that code, but it should work.
sure I can move them… but then I have to calculate the Vector for every step with a predicting colision detection, dont I? like if I have this NPC… then i have to set the position i want to move it, and test the height with a topdown ray on that position… closest collision with terrain is my real position, that i want to move to!?
The issue here is that you don’t need precise collisions When you move a Physics Body, you’d still be calculating new Vectors - but moving a spatial is more efficient.
Let’s say there are two villagers walking down a street. There are two options:
- Let them pass through each other.
OR
- Create a path and make sure they don’t intersect - then if they do, respond accordingly.
I think you’d opt for the second one. And yet, it doesn’t include any physics. Sure, there might be other cases where physics are needed, but if you can do without them, then do so!
Regarding terrain height, I’m afraid someone else would have to help. But I would try to avoid using so many Physics Bodies.
that sounds like a plan! quite happy with it! thanks alot! i will try it tomorrow!
The easiest solution would be to have a flat terrain (like most strategy games use), even Starcraft 2 uses mostly flat terrain. For collision detection, you can try either: kinematic rigidbodies with physics raytests and sweeptests or ghostcontrols and detect collisions in the PhysicsTick event listener. In any event, your gonna struggle with 100 different animated bodies fighting on the screen at once, without at least some trickery to make it more efficient.
I found the fastest for a lot of characters is bullet rays and heightmap collision shapes.
Glad I could help. Also, regarding terrain height, you might want to look at this tutorial instead of using rays:
https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:collision_and_intersection
Also, to add to what wezrule said, if you want to have different terrain heights you might want to split the terrain into different parts with varying heights. Then position each unit accordingly.
I think the simplest thing would be to just work out the new x,z location for the character keeping y the same. Then cast a line down intercepting it with the terrain only. You know the height you should be above the terrain so something simple like:
[java]height-expected < MAX_CLIMB - too steep, can’t move
else
height -expected < MAX_WALK - play climb animation, move center up
else
height -expected > MAX_DESCENT - too steep, can’t move
else
height -expected > MAX WALK - play climb down animation, move center down
else
play walk animation, move center to correct height off terrain[/java]
Remember to allow for tpf with MAX_CLIMB/MAX_WALK etc (could be as simple as multiplying the thresholds by tpf).
@memonick said:
If zarch and wezrule couldn't come up with a solution, I don't think it's possible.
Well keep in mind that I've never actually used JME's physics (don't need it for my current game) so I'm just theorycrafting :)
and most of the time, I just google search the topic and c & p whatever normen says