2
\$\begingroup\$

I'm developing a using the Entity-Component model, and so far have components for position, input, graphics and a camera, and systems for rendering graphics and handling input.

All seems to be working well, and I can use my model to create a multi-player, multi-camera setup relatively easily.

Anyway, my problem is that my input system checks keypresses against each player's controls, but I'm not sure how to react to these keypresses without introducing a lot of coupling.

For example, if 'W' is pressed, I want to tell player 1 to move upwards, but that first involves some collision detection -- something I'm not sure my input system should handle.

Advice greatly appreciated!

Thanks in advance, Rich.

\$\endgroup\$
5
\$\begingroup\$

Input is usually more abstracted from character behaviour than that. Usually by some kind of "character controller" that translates requested state into movement/actions.

Ideally you don't want to couple that too closely to actual player input. What if in the future you want an AI behaviour tree to drive that entity? Or what if you implement networked multiplayer and you're simulating entities that are being controlled remotely?

The data a character controller is usually operating on is more closely tied to the actions that particular type of entity can perform (desired movement direction and speed, booleans to indicate whether or not particular actions are being requested, etc).

Personally for things like input, AI controllers, cameras etc, my preference is not to hang those directly off the entity itself, as you potentially might to make it more flexible to leave your options open. E.g what happens if you want to be able to dynamically switch the camera/control to another entity without destroying the old one, and have the old entity be taken over by AI? (Like in some team sports games, for example). What if you want to have a cutscene where the camera gets temporarily switched to a cinematic camera?

Collision detection and the like really don't belong on the input level. The best way to think about it in my opinion is that input is what the player/AI is asking to do. Whether or not it can do those things is irrelevant to the input system.

\$\endgroup\$
  • \$\begingroup\$ This is essentially what I came here to say. +1 \$\endgroup\$ – darkside May 3 '17 at 10:31
  • \$\begingroup\$ To add to Bryan's answer, you'd still accept the movement request with W and apply a linear movement force. The physics system will attempt to move the character based on this movement force and if possible will do so. If it cannot, a collision will be detected and the character won't be moved. It is here that you can raise an event or some other notification means allowing your ECS environment to deal with other collision responses dynamically, like play a sound because they're hitting a wall, etc. \$\endgroup\$ – Naros May 3 '17 at 12:59
  • \$\begingroup\$ This all sounds great - thanks for the advice. So the input system would detect a key press and add the desired movement to a 'physics' component, and then a physics system would try to resolve the movement. Does that sound right? \$\endgroup\$ – Rich. T. May 3 '17 at 16:30
  • \$\begingroup\$ Yeah except ideally you want a layer in between that, in my view. You don't want to going directly from input to a physics component like that. It's more like input -> (translation layer that translates input data into "player intentions") -> (character controller layer that acts on "player intentions", and doesn't care whether or not they came from an input device) -> 'physics component' \$\endgroup\$ – Bryan Robertson May 3 '17 at 16:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.