I want to get mouse input from behavior Update method so I can use it as user input. The only way I’ve found is to use TCastleView, Motion, Press and Release methods to retrieve the input and “send” it somehow to the behavior object (I didn’t test this actually, I’ll try it just after I post this).
Is there a better way to get mouse input?
Also how to hide the mouse cursor and prevent the cursor to exit the window?
In every TCastleView you have a Container.MousePosition - this is the raw mouse position on Screen. However, looking at implementation of SetMousePousition setter it doesn’t actually set the mouse position. If you want to set mouse position to something specific (e.g. to implement your own version of mouse look behavior) you can try Castle Game Engine: CastleWindow: Class TCastleWindow — I was doing it through this, but maybe currently there is something more generic exposed.
Note that “prevent cursor from exiting window” is not very straightforward. As soon as cursor leaves the window we lose track of it. I know there is a way to track mouse cursor absolute coordinates - however I don’t remember if the specific call is available in Castle Engine.
Setting cursor invisible (or to specific image) can be done through TCastleUiControl.CursorCastle Game Engine: CastleUIControls: Class TCastleUserInterface - you can set it to mcNone or, if some control tries to override the cursor look - mcForceNone to make sure it is always invisible. Note that TCastleView inherits from TCastleUiControl and as such has Cursor property.
So there’s no simple way. I was trying to build an FPS controller as a Behavior instead of as a Navigator but I’m thinking it is not possible. (Tempted to write a rant about why Behavior is better than Navigator IMO I’ll not yet but…) I think input (keyboard, mouse, gamepad, joystick…) should be more exposed, maybe as Components. Or an approach similar to Allegro (al_get_keyboard_stateal_get_mouse_stateal_get_joystick_state) or Unity (Input). Maybe it can’t be done because it might need deep changes in the engine core. A bunch of calls or properties to hide the cursor and capture the mouse easily are quite useful too.
I’ll try to build a Navigator that moves a Transform instead of the Camera. But I still think that a Behavior is a better approach.
Actually this is very possible. Just instead of checking “if the mouse is outside of the window” one needs to check if the mouse is not in the center and unless it isn’t adjust camera rotation accordingly and move the mouse back to center (this is how Navigator’s MouseLook is implemented). The only drawback here is that if player moves the mouse VERY quickly it can jump outside of the window and hence loose input, but it’s almost impossible even while actually trying to do so
What is something I’m not aware of (it doesn’t mean it’s not implemented) - is how to keep mouse cursor within the window borders, not just window center (where there is a big margin to the borders). Just yesterday checked and Unity seems simply give some “safety margin” for this cause - if the cursor is like 100 pixels away from border - teleport it to the opposite border : this is absolutely doable with CGE
I want to extend the TCastleAxis to have various alternative bindings (so assign e.g. multiple alternative keys). The idea is to achieve something similar to Godot or Unity inputs.
And let me know. We are looking for feedback to the whole https://github.com/castle-engine/castle-engine/pull/533/ work, it’s a big PR, it will take some time to review, test, and maybe finalize some API. So all feedback is welcome
We have an API to essentially lock the mouse to the window, allowing user to not care about the mouse position, and perform infinite mouse movement. It the practical usage, this means that mouse is hidden.
these behaviors move TCastleTransform, in theory any transform. It can be a visible player (like in 2D platformer games or 3D avatar) or a transform with camera (for FPS games)
and yes, it is somewhat analogous to Unity input system usage.
We’ve been designing this with Andrzej Kilijański for quite some time, and we reached the same conclusions as you above
I see I have to download the complete PR, not just the CastleInputAxis unit. I suppose I have to merge it with trunk and compile the engine and editors, haven’t I? Never did it. I suppose I just use make in the root directory.
Also have I to use gh to get the PR? As I said I’m not a GIT user (despite I have a GitHub user :p).
Moreover, the error is a bit weird – the AllLayers identifier is in CastleTransform unit and, from what I see, that PR didn’t change it actually, it was and is in the same unit in the same file, before and after this PR.
Are you sure the Lazarus compilation doesn’t pick some old Castle Game Engine sources on your disk?
Can you post the full compilation log – it should contain the file paths, and should allow to see whether it uses correct locations for all .pas units. You can get the log e.g. easily by doing it from command-line :
Post the log from the build that you want to do, but that fails. So, from the one from PR.
I see you have 2 engines on disk. It is simplest (to resolve the problems) to just “move one aside” to make sure it is not picked up. E.g. just rename the directory of the engine (that temporarily should not be used) to something like castle-game-engine-not-to-be-used-for-now.
Once you have built and tested the engine from PR, you can always go back to the “original” engine by just renaming it back.