Get (raw?) mouse input

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.Cursor Castle 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 :roll_eyes: 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_state al_get_mouse_state al_get_joystick_state) or Unity (Input). Maybe it can’t be done because it might need deep changes in the engine core. :slightly_frowning_face: 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 :slight_smile:

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 :slight_smile:

EDIT: E.g. I was doing my own mouselook years ago src/input/decomouse.pas · master · EugeneLoza / Decoherence · GitLab

1 Like

It seems what you want is something like TCastleAxis which we already worked on with Andrzej Kilijański in https://github.com/castle-engine/castle-engine/pull/533 . The idea is to define an axis that you can easily query in e.g. any Update (like from a behavior). I think this exactly addresses your use-case :slight_smile:

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.

So… go ahead and test the work in PR New physics based first/third person 3d and platformer like modular navigation + input axis and others by and3md · Pull Request #533 · castle-engine/castle-engine · GitHub :slight_smile: If you don’t want to wait, you should be able to get the src/behaviors/input/castleinputaxis.pas unit from that PR and just use it in your projects – before we merge this PR.

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 :slight_smile:

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.

See the example examples/user_interface/dragging_test on castle-engine/examples/user_interface/dragging_test at master · castle-engine/castle-engine · GitHub – see there the README and code. It is also automatically used by current TCastleWalkNavigation.MouseLook .

These 2 answers “connect” of course, you can see in PR https://github.com/castle-engine/castle-engine/pull/533 how to have mouse look + TCastleAxis.

No need to write a rant, as it seems we actually think the same :slight_smile: and the PR https://github.com/castle-engine/castle-engine/pull/533/ should make you happy – this is actually exactly addressing this thing. I.e.

  • it uses behaviors to perform navigation
  • 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 :slight_smile:

I’ll test it and tell you.

I’m not a GIT user but I’ll do my best.

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).

Sorry for the questions.

You do not need to merge with master. You only have to download the code from given PR:

Remember afterwards to build the new engine – see Compiling from source | Manual | Castle Game Engine .

Seems that gh makes things quite easy. Maybe I should learn more about it and then stop procrastinating the GitHub’s Allegro.pas mirror updates.

Anyway, after getting the PR and following Compiling from source instructions I found an error when building the castle_editor_components package:

castleeditorpropedits_physics_layer.inc(239,15) Error: Identifier not found “AllLayers”

Before that I build castle-engine and installed the castle_components package.

I tested compiling castle_editor_components from the branch in PR https://github.com/castle-engine/castle-engine/pull/533/ and it goes OK for me.

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 :

lazbuild packages/castle_base.lpk > log.txt
lazbuild packages/castle_components.lpk >> log.txt
lazbuild packages/castle_editor_components.lpk >> log.txt

(assuming your lazbuild executable is on PATH).

No, I’m not sure. I have two CGE installed: the one I downloaded from Download | Castle Game Engine and the PR I got from GitHub.

From which directory, the one I downloaded or the PR?

Note: As you see I have no much free time so I can do this only once per week, twice if lucky.

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.