The ChaseCamera has the .registerWithInput(InputManager inputManager)
method. However, I can’t find a way to do the opposite and clean up the mappings properly. Because I use the ChaseCamera only in one of my app states which gets attached/detached several times it would be great if there is a way to do this properly. I currently disable the cam, but I would like to remove it and make a new one after the AppState is attached again.
I mean I can always just clean it up manually but I think that’s not how it should be.
For the FlyCam I unregister the mappings manually. Of course, that breaks the computer scientist’s rule of “information hiding” and needs knowledge about the source (the String names of the input mappings).
Another way I sometimes use: Do not let the SimpleApplication add the FlyCamState in the first place and simply use my own FlyCam2AppState. So it uses my own FlyCam2 which is almost the same code but contains anything missing. Of course this breaks the rule of “don’t write it twice because you will have to check for updates in the original code again and again if you want to copy all the features of the original into your copy” (aka “code duplication”).
From my point of view there are too many private fields in other people’s code anyways. I often find it much more convenient to make things protected or even public.
I know that gurus like Bloch don’t agree to this, but I often find myself in a situation where restrictions are bad for me and I need to ask others to remove those restrictions (or write my own branch - with a lot of “code duplication”).
My view for these things is: The programmer must know how to properly use a library anyways - so simply using random methods without knowing what I’m supposed to do brings havok to my software - and this leads to the conclusion that you can remove restrictions and tell the other programmers “look how you are supposed to do it” and “do not use random methods just because you can”.
I’d write my own ChaseCamera2 if I were you. And that one would have all the methods you need either protected or public - so you can do what you want and are not restricted or encounter “missing counterparts” (like a missing “unregisterInput”). It’s a different philosophy (my philosophy) which other people might not like so much.
These unnecessary restrictions I found in JDK code too: For example I use a BetterRandom
class which gives you access to the currently used seed - which strangely needs me to replace large sections of the Random
class and mimic the behavior of the original (breaks information hiding, introduces code duplication).
Yeah I feel you, I already have my own ChaseCamera class, because the default was missing a method for setting distance. I’ll try.
Feel free to submit a pull request for these kinds of changes.
I personally don’t use any of these built in cameras except for demos and examples (they tend to treat spatials like game-objects which is an antipattern) so this particular annoyance never bubbled into my priorities. I think it’s a good idea, though.
I’m a big fan that things should be able to clean themselves up, though.
Ok, I’ll see what I can come up with in my subclass and then just copy the method into the ChaseCamera.
Ended up adding this to my subclass and manually calling it when I detach my appstate:
public void cleanupWithInput(InputManager mgr){
mgr.deleteMapping(CameraInput.CHASECAM_TOGGLEROTATE);
mgr.deleteMapping(CameraInput.CHASECAM_DOWN);
mgr.deleteMapping(CameraInput.CHASECAM_UP);
mgr.deleteMapping(CameraInput.CHASECAM_MOVELEFT);
mgr.deleteMapping(CameraInput.CHASECAM_MOVERIGHT);
mgr.deleteMapping(CameraInput.CHASECAM_ZOOMIN);
mgr.deleteMapping(CameraInput.CHASECAM_ZOOMOUT);
mgr.removeListener(this);
}
Feel free to copy paste it into jME itself. Maybe I can do it when I have some time.
So say we all.
So you run your own chase camera without that setTarget where the target is the game object to follow? I simply used an emty node in that case. It did the trick together with Zay-ES. But anyway I would like to learn the right way. Do you have samples for this? Some kind of best practice sampley? I would be interested.
Basically, I do it with an app state that simply watches the player position like any of a half-dozen other app states… this one just happens to position the camera behind the player (or at their head).
Mine will even clip to the terrain/buildings and slowly tween back out again. So if you stand with your back to the wall it reverts temporarily to first person.
Aha that way. I do it with my link system I link the camera to the entity, it follows then automatically that entity. That way I can easily swich my actors or follow some AI controled entities But yeah it seems you do it very similar.