Does anyone know how to get a mouse to click and drag a box. Then select all the game entity inside the box? I was trying to do this with a raycast but not sure if I’m on the right path here.
Raycasting only works if the entities have colliders.
In your particular instance, I would approach the problem like this:
- Get the starting mouse coordinate (when the user presses down)
- Get the ending coordinates
- Turn the 2D mouse coordinates into 3D world coordinates
(Might help: http://doc.xenko.com/latest/en/manual/physics/raycasting.html ) - Loop over all the entities and check if they are inside the rectangle (This is going to involve a bit of maths)
Thank you for answering. Yea we got that part down as in what to do its how to do number four that is the issues at the moment.
Yeah, number 4 is a lot of fun.
So, now that you have some 3D world coordinates that define a box, you have to check if a point (entity) is inside that non-axis-aligned box:
https://math.stackexchange.com/questions/1472049/check-if-a-point-is-inside-a-rectangular-shaped-area-3d
Ok I take that back we dont have number 3 yet working. I thought we did but still working on getting the “box” in 3d cords. This is what we have so far
public class EnvironmentControl : BaseSyncScript
{
public static readonly EventKey _EventKeyEndUserMouseStruct = new EventKey();
public CameraComponent _Camera;
public Prefab _LeftMouseClickedPrefabParticleEffect;
private Simulation _Simulation;
private InputMouse _InputMouse = new InputMouse();
private Vector2 _OrginalMouseBeginPosition;
private Vector2 _OrgingalMouseEndPosition;
public override void Start()
{
base.Start();
_Simulation = this.GetSimulation();
}
public override void Update()
{
if (Input.Mouse.IsButtonDown(MouseButton.Left))
{
foreach (var pointerEvent in Input.PointerEvents.Where(x => x.EventType == PointerEventType.Pressed))
{
if (_OrginalMouseBeginPosition == Vector2.Zero)
{
_OrginalMouseBeginPosition = pointerEvent.Position;
}
_OrgingalMouseEndPosition = pointerEvent.Position;
// if Detect Click Drag
// Create Box
// Select All Entities in box
// else Detect entity clicked
}
}
else if(Input.Mouse.IsButtonDown(MouseButton.Right))
{
_OrginalMouseBeginPosition = Vector2.Zero;
_OrgingalMouseEndPosition = Vector2.Zero;
}
}
}
// if Detect Click Drag
So, you have 2 mouse coordinates. You have to project those coordinates into world space.
You can probably use this code: http://answers.xenko.com/questions/2761/mouse-world-coordinates.html
After that, you have 2 world space coordinates which lie on a plane.
Now you have 2 options:
-
Take one of the 2 points and move it further away from the camera. Then, you would have the corners of a rectangular prism. After that you have to check if a point (entity) is inside that rectangular prism.
-
Check if the rectangle (the 2 points in world coordinates) is in front of the points (entities). Something like this might work.
(Here is a very mathematical explanation of it: https://math.stackexchange.com/a/2157973 )
I’m sorry for being so vague about number 4. It does involve a fair bit of Maths and I’m not a Maths genius. I’m just a person who is trying to be helpful.
Thank you stefnotch I will see what I can figure out and then post the code maybe it will help someone else
My suggestion would be to use the Xenko Toolkit’s CameraComponent.ScreenToWorldPoint
function coupled with the code above. Then, you can use those coordinates to define a box.