First-PErson-Player interacting with GameObjects

Hi everyone :grinning:

My friend and I are currently working on a Low-Poly 3D-Survival Game. So far we are able to randomly generate a island with a 3D-Person Player being able to walk around with items in his hands (like in Minecraft :smile:).

We are now trying to implement an interaction system which should handle the interaction between the item the player currently has in his hands and the target object the player aims at (e.g. hitting a tree with an axe, etc.).
We already have some code handling this case, but I think is´s not very clean so I decided to refactor it. As for now, we have a Control called AttackControl attached to the player which listens for mouse input and then casts a ray, in order to get the object the player is aiming at. The code looks similar to that:

    /* This code gets called when the left mouse button is pressed */
    Spatial entity = findTargetByCastingRay();
    attackAnimationControl.playAnimation();
    
    if(entity != null){

        //Check if the item in the players hands can interact with the collided
        Item item = (Item)inventory.getCurrentItem();

        //If the item is not null
        if(item != null){
            //Check if the item is in range, in order to be used against an entity
            if(item.isInRange(distance)){
                
                InteractionControl interactionControl = entity.getControl(InteractionControl.class);
                
                //Use the item against the entity - returns true if it could interact with the entity
                if(item.onInteract(player, entity)){
                    
                    if(interactionControl != null){
                        if(interactionControl.isNotifyOnInteraction() || interactionControl.isNotifyAlways()){
                            interactionControl.onInteraction(world, player, item);
                        }
                    }
                    
                    //Check if the item got destroyed by using it
                    if(item.isDestroyed()){
                        //Call the items onDestruction (maybe trigger some effect when the item gets destroed)
                        if(item.onDestruction()){
                            //If the item could be succesfully destroyed - remove it from the inventory
                            inventory.removeCurrentItem();
                        }
                    }
                } else {
                    //Throw item if it can be thrown
                    if(item.isThrowable()){
                    }
                    
                    if(interactionControl != null){
                       if(interactionControl.isNotifyOnInteractionNotSuccessful() ||
                          interactionControl.isNotifyAlways()){
                           interactionControl.onInteraction(world, player, item);
                       }
                    }
                }
            }
        }

All this code is handled by the AttackControl at the moment. But thinking about it, casting the ray as well as checking if the interaction was succesful etc. isn´t part of the player. So I had the idea that the player sends an Event when he presses the left mouse button which contains all the information which is needed for the responsible Listener (being the InteractionSystem) in order to do a ray-cast and check for an interaction.

So my question is: Would this approach be clean or are there simpler solutions?

Thanks in advance :grinning:

Again, I’d use an app state for global stuff and not a control. You could attach/detach the ‘axe handling’ app state as needed or just enable/disable it.

The axe swinging animation, etc. is just a visual side effect of the game objects doing their thing.

Ahh ok so using AppStates is really the way to go, it just takes some time to get used to it and all the possible usages :sweat_smile:

So playing the animation would be a responsability of the control of the item or target, seems logically with me.
But an event like interaction is no continous event, it just occurs when the player presses the left mouse button, but an AppState should be something continous (cause it gets updated continously). So is this kind of application also okay for an AppState? Even it doesn´t need to update anything in it´s update method?

Sorry if I am asking that much, but I want to learn the right way to do things in order to prevent our game from getting unmaintainable.

Thanks a lot :grinning:

In AppState you also use InputManager, ActionListener… No need to do everything in update method.

See “Use Case Examples” in http://wiki.jmonkeyengine.org/doku.php/jme3:advanced:application_states/. It said:

a subset of input handlers and mappings,

Thanks a lot :grinning:
So AppStates can also be there for encapsulating different game systems, or turning different systems on/off?

Yes. As paul said, what you need is just enable/disable it.

Ok thanks a lot guys :grinning:
My question is answered with that :sweat_smile: