Entity Picking    (v0.261 or higher)


Picking is a term used to refer to clicking on objects within a game. The QuickStart Engine allows you to get information about any Entity you click on, so long as that entity has physics. Physics is required because it's really the physics you're clicking on. Generally most entities that are visible also have physics (with the exception of things like lights, or skies).

The Sample Demo has an example of picking. To use it make sure you enable the mouse cursor, then hold 'back quote' ( ` ) and click on the entity you want to test against. (Back quote is usually the key above Tab on US keyboards). If you'd like to see how the Demo does this, go to SampleScene.cs within the QuickStartSampleGame_Windows project, and go to the function called RayCastForEntityReport().

Here's how the sample demo does picking:

// First we determine the line segment between the camera's position and the cursor
// as if it were at the far plane.
MsgGetLineSegmentToCursor msgGetSegment = ObjectPool.Aquire<MsgGetLineSegmentToCursor>();
this.game.SendInterfaceMessage(msgGetSegment, InterfaceType.Camera);
            
// Now we use that line segment to check for physics collisions
PhysicsInterface physics = this.game.SceneManager.GetInterface(InterfaceType.Physics) as PhysicsInterface;
if (null == physics)
{
    throw new Exception("Cannot perform a physics ray cast without a registered PhysicsInterface");
}

// Use a collision filter that will collide with all physics bodies            
CollisionSkinPredicate1 predicate = CollisionPredicateUtils.GetPredicateByType(CollisionPredicateType.CollideWithAll);

// Now we pass the line segment container and our collision predicate to the physics system, which will
// pass back info about what we've clicked on (if anything)
SegmentIntersectInfo info; physics.PerformSegmentIntersectQuery(msgGetSegment.lineSegment, predicate, out info);
// All skins in the QSEngine are, or derive from QSCollisionSkin, so this cast is safe
// and QSCollisionSkin is what stores the EntityID of what you picked, so that you may
// use that ID to send messages to.
QSCollisionSkin skin = info.skin as QSCollisionSkin; if (null == skin || skin.EntityID == QSGame.UniqueIDEmpty) return;

// You've received valid info from the picking system, do what you want with it here

 

After picking has completed you'll either have a collision skin returned from the physics system, or it will be null. If you have a collision skin then that means it found something under the cursor that was allowed to be picked based on the collision predicate you used. Collision predicates are basically collision filters, each predicate allows you to define what can be collided with and what cannot be collided with. For example, the TerrainPredicate allows only for collision with heightfield physics shapes. Using the EntityID that is returned in the collision skin you can do pretty much anything you want with that Entity through the message system.

Last edited Feb 8, 2012 at 6:41 AM by LordIkon, version 2

Comments

Dnagreen Sep 28, 2012 at 7:26 PM 
I am trying to build an RTS with the QS Engine. Is there a simple way to draw a selection rectangle and do group based picking, similar to this example, but over an area?