Jump to content
  • Advertisement
Sign in to follow this  
rpiller

User Interaction System Ideas

This topic is 730 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm looking for ideas/pointers on how to approach user interaction with the world. The game I'm working on allows a lot of interactions (generally interactions with a 3D world are done from picking from the mouse position and/or a a button press). Interactions also generally come with a lot of checks (if statements). Are you in distance, do you have x in your hand, etc.

 

Currently I have these in the update statement as one would maybe expect. However, because there are so many I'm finding the code can get fairly complicated and large to follow. I'm wondering if there is some system that I can create that moves this to more of a configuration at the start of the game vs a bunch of if statements for each interaction in the the Update() method.

 

An example of what I have currently in the Update() function would be: 

if click_tree then
	if in_distance then
		if have_axe_in_hand then
			cut tree
		end
	else
		move_to_tree
	end
end
	

By itself this doesn't seem bad, but when you add hundreds of possible interactions and possibilities the code just gets large and cluttered with tons of if statements. I feel like there should be a way to abstract these interactions to conditions and actions that can be configured at the start of the game. I'm also using Lua so the configuration of these may even be able to be put into a database/file as string names of functions and translated to actual functions at run-time.

 

Any thoughts/comments?

 

Thanks!

Edited by rpiller

Share this post


Link to post
Share on other sites
Advertisement

So you are checking every single object in turn rather than say responding to an event? I don't have a specific method in mind but you could do this as an even rather than a per update. User clicks (nothing in particular) then you do a quick search for items in range, items in front of user, check if user can interact with the item. That should give you a very small list (if any) objects. Then you can raycast to check if the user is pointing at the object and finally do the action.

 

The only difficult part that might get convoluted would be the part that checks if the user can interact (the part, do they have an axe) depending on how varied your system is. I would definitely go for this approach rather than the dig the player click tree1, did the player click tree2, did the player click tree3 etc. You could have each object having a method that takes a player object: bool CanInteract(Player). The object itself can then check for any required tools and you could also use scripting here for anything more complicated.

Share this post


Link to post
Share on other sites

Hi rpiller!

Nanoha == :ph34r:,
:lol:, but I've written a simple system which could encapsulate the interactions between the player and other entities and required conditions to be fulfilled, so still I'll post it in here.
It's extremely pseudo and a bit too C#-esq :) + I haven't actually tried it out :unsure:, so take it with a grain of salt, but with some clean-up and tailoring to the language of your choice, it could be used easily.
I made a hybrid object-oriented with a tiny bit lambda here and there, but a full- object oriented / event driven / functional approach is just as much possible and convenient.

Here it goes:

// The base building block to make interactive game-objects/entities.
interface IInteractive
{
	bool TryInteract(Player p);
}

// A standard implementation for interactive objects,
// which also acts as a "switch",
// to choose between different interaction methods based on the fulfillment of a condition...
class Interactive : IInteractive
{
	public virtual bool TryInteract(Player p)
	{
		if (this.Condition == null || this.Condition(p))
		{
			if (this.OnTryInteract != null)
			{
				return this.OnTryInteract(p);
			}
		}
		else if (this.Otherwise != null)
		{
			return this.Otherwise(p);
		}
		return false;
	}
	
	public Func<Player, bool> Condition;
	
	public Func<Player, bool> OnTryInteract;
	
	public Func<Player, bool> Otherwise;
}

// And here comes your specific sample implemented with the system:
class Tree : Interactive
{
	private Interactive OnInDistance;
	
	public Tree()
	{
		// This way the objects with which the player tries to interact with,
		// will specify when and how interaction can be done
		// and what to do in specific situations.
		
		// Base interaction, checking distance,
		// delegating to "OnInDistance" if close enough, 
		// otherwise start moving the player towards the tree.
		base.Condition = (Player p) => { return p.IsInDistance(this); };
		base.OnTryInteract = (Player p) =>
		{
			return this.OnInDistance.TryInteract(p);
		};
		base.Otherwise = (Player p) =>
		{
			p.MoveTo(this);
			return true;
		};
		
		// Interaction handler when player is close.
		this.OnInDistance = new Interactive()
		{
			Condition = (Player p) => { return p.HasInHand(Items.Axe); },
			OnTryInteract = (Player p) =>
			{
				p.Cut(this);
				return true;
			}
		};
	}
}

// In your update method:
var interactive = GetClickedGameObject() as IInteractive;
if (interactive != null)
{
	interactive.TryInteract(player);
}

// Of course this can be used in a composition based system easily, in your update method:
var clicked = GetClickedGameObject()
if (clicked.HasComponent<IInteractive>())
{
	clicked.GetComponent<IInteractive>().TryInteract(player);
}



// Another simple extension that comes to my mind
// is a simple construct to "Chain" possible interactions/conditions
// for a complex object or for a really complex interaction logic,
// with huge number of different conditions or interaction types.
// May come in handy:
class InteractionChain : IInteractive, List<IInteractive>
{
	bool TryInteract(Player p)
	{
		bool handled = false;
		foreach (var interactive in base)
		{
			if (interactive.TryInteract(p))
			{
				handled = true;
				if (this.StopOnFirstInteraction)
				{
					break;
				}
			}
		}
		return handled;
	}
	
	bool StopOnFirstInteraction { get; set; }
}

Hope it helps ^_^!

Edited by Spidi

Share this post


Link to post
Share on other sites

On a very abstract level, this could be:

1) Find out what was clicked on (the target)
2) Determine any properties of the click (eg. "in distance")
3) Find out what object the player has selected (the tool)
4) Find the best match in a table of actions, where 'best match' is probably the one with the most conditions

eg.

click_actions = {
    {obj:"tree", properties:["in_distance"], tool:"axe", action:"cut_tree"},
    {obj:"tree", action:"move_to_tree"}
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!