Get World Coordinates by Mouse
by Kiyaku · in Torque Game Engine · 07/25/2008 (5:15 am) · 6 replies
Hi,
i just have a small question.
When you use the World Editor, you can ask world position with your mouse to select objects, paint on Terrains, etc.
Is it possible to get the same mouse while playing? (not in the world editor).
I just want to be able to show the mouse cursor, click on a terrain and let an AIPlayer move to this position.
I saw the several "mouse movement", "object selection" etc articles but they are sometimes too old and i can't get them working.
Though i also can't understand why i have to change so much sourcecode, if there is already a mouse function like this in the world editor.
So does someone know if i can use this for my games too?
Thanks in advance!
i just have a small question.
When you use the World Editor, you can ask world position with your mouse to select objects, paint on Terrains, etc.
Is it possible to get the same mouse while playing? (not in the world editor).
I just want to be able to show the mouse cursor, click on a terrain and let an AIPlayer move to this position.
I saw the several "mouse movement", "object selection" etc articles but they are sometimes too old and i can't get them working.
Though i also can't understand why i have to change so much sourcecode, if there is already a mouse function like this in the world editor.
So does someone know if i can use this for my games too?
Thanks in advance!
#2
07/25/2008 (8:39 am)
If you want to do the AIPlayer moving to the point you clicked, then you are going to have to make C++ changes, but it's not too difficult. I can provide you with some code to get you started if you like...
#3
07/25/2008 (8:44 am)
That would be great!
#4
07/25/2008 (9:08 am)
OK, easiest thing is to extend the EditTSCtrl, so you'll need to add a class:class MyTSControl : public EditTSCtrl
{
private:
typedef EditTSCtrl Parent;
public:
struct CollisionInfo
{
SceneObject *obj;
Point3F pos;
VectorF normal;
Point3F start;
};
SceneObject * getControlObject();
bool collide(const Gui3DMouseEvent & event, CollisionInfo & info);
MyTSControl ();
~MyTSControl ();
// SimObject
bool onWake();
void onSleep();
// EditTSCtrl
void on3DMouseMove(const Gui3DMouseEvent & event);
void on3DMouseDown(const Gui3DMouseEvent & event);
void on3DMouseUp(const Gui3DMouseEvent & event);
void on3DMouseDragged(const Gui3DMouseEvent & event);
void on3DMouseEnter(const Gui3DMouseEvent & event);
void on3DMouseLeave(const Gui3DMouseEvent & event);
void on3DRightMouseDown(const Gui3DMouseEvent & event);
void on3DRightMouseUp(const Gui3DMouseEvent & event);
void updateGuiInfo();
//
void onRender(Point2I offset, const RectI &updateRect);
void renderScene(const RectI & updateRect);
static void initPersistFields();
DECLARE_CONOBJECT(MyTSControl );
};
#endif
#5
Ok, final thing is to update the PlayGUI... Change the first control in the playGui.gui file to be this new class:
That should be it... Once other thing you may need to account for, is objects in the PlayGui that will take your mouse input away from you. FirstResponders and such...
This is pretty bear bones I know, so just let me know if you have any troubles and I'll keep you pointed in the right direction.
07/25/2008 (9:32 am)
Ok, relevent implementation. Obvious this is not a cut and paste implementation, but should give you all the important parts:SceneObject * MyTSControl::getControlObject()
{
GameConnection * connection = GameConnection::getLocalClientConnection();
if(connection)
return(dynamic_cast<SceneObject*>(connection->getControlObject()));
return(0);
}Note: This code is TGEA, so some calls may need to be changed to work in TGE, especially in regards to the above method. With a quick search, you should be able to find similar code and update to work in TGE.bool MyTSControl::collide(const Gui3DMouseEvent & event, CollisionInfo & info)
{
SceneObject * controlObj = getControlObject();
if(controlObj)
controlObj->disableCollision();
Point3F startPnt = event.pos;
Point3F endPnt = event.pos + event.vec * 500.f;
RayInfo ri;
bool hit;
hit = gServerContainer.castRay(startPnt, endPnt, TerrainObjectType | PlayerObjectType | StaticShapeObjectType, &ri);
if(controlObj)
controlObj->enableCollision();
if(hit)
{
info.pos = ri.point;
info.obj = ri.object;
info.normal = ri.normal;
AssertFatal(info.obj, "FF_GUI_BattleControl::collide - client container returned non SceneObject");
AssertFatal(info.obj->isServerObject(), "Non server object!");
}
else
{
hit = false;
}
return(hit);
}
void MyTSControl ::on3DMouseDown(const Gui3DMouseEvent & event)
{
CollisionInfo info;
if(collide(event, info))
{
if(info.obj)
{
AIPlayer *unit = dynamic_cast<AIPlayer*>(info.obj);;
if(unit)
{
//we are over a unit, so make it selected, if you are expecting the user
//to click on the unit before moving it
}
else
{
//We are over terrain, so move the unit you want moved
//For example:
//selected_unit->setMoveDestination(info.pos, true);
//selected_unit->setMoveSpeed(1);
}//end else over terrain
}//end if obj
}//end if collide
}Ok, final thing is to update the PlayGUI... Change the first control in the playGui.gui file to be this new class:
%guiContent = new MyTSControl (PlayGui) {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "1";
Profile = "GuiContentProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "0 0";
Extent = "1024 768";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
...That should be it... Once other thing you may need to account for, is objects in the PlayGui that will take your mouse input away from you. FirstResponders and such...
This is pretty bear bones I know, so just let me know if you have any troubles and I'll keep you pointed in the right direction.
#6
07/27/2008 (9:07 am)
This is very kind of you. My knowledge about the C++ part isn't that great yet but i will give it a try and see how far i come with your informations. Thanks a lot!
Associate James Ford
Sickhead Games