#Click and Drag Mechanic
1 messages · Page 1 of 1 (latest)
Heres a video, This is me clicking once to select... and then clicking and holding (which is turning on the green ring and walkie-talkie icon..
This happens currently even when i drag away from the selected unit, (which is when the Next mechanic) should be triggered
I need a way to know whether or not we are dragging the mouse (away from the selected unit)
Compare the position of the object to the mouse point relative to the plane/floor.
ya, so when i click on the selected object and the raycast confirms its selectable.. i can set a bool?
thats what i currently do now isDraggin = true..
and yea, then i should do additional checks while that bool is true
i gotta tweak teh current setup too, because its not perfect...
you can click on the unit and while holding it'll enable the walkie-talkie menu.. this happens regardless if u move off of the selected unit afterwards..
When the object is selected (via raycast hit a valid target), you could then start evaluating the distance to the mouse position by maybe firing a coroutine or subscribing an event to continually occur etc
but thats why i was gonna tie in the extra logic.. b/c we can just click and hold.. or we can click and hold and drag
that extra function would confirm which of those is happening
Haven't cehcked out your gist code yet.
public void Update()
{
if(Input.GetMouseButtonDown(0))
{
RequestSelection(Input.mousePosition);
}
void RequestSelection(Vector3 pos)
{
Ray ray = Camera.main.ScreenPointToRay(pos);
RaycastHit hit;
if(Physics.Raycast(ray,out hit,distanceOfRay))
{
focusedTransform = hit.transform;
if(hit.collider.TryGetComponent(out ISelect selectable))
{
scrollLock = true; // the map shouldn't move until we release
holdingAction = true; // we're (possibly holding down the mouse button)
lastSelectable = selectable;
// Store the initial mouse position when the drag starts
initialMousePosition = Input.mousePosition;
isDraggin = true;
}
else
{
Debug.Log("We clicked something unselectable");
lastSelectable = null;
}
}```
Yeah
if(holdingAction)
{
actionTimer -= Time.deltaTime;
if(actionTimer <= 0)
{
if(IsSelected(lastSelectable))
{
GiveOrders();
}
else
{
//maybe select
}
actionTimer = actionTime;
holdingAction = false;
}
if(Input.GetMouseButtonUp(0))
{
// releasing mouse after clicking and holding on a ISelect
if(IsSelected(lastSelectable))
{
RemoveSelectable(lastSelectable);
}
else
{
AddSelectable(lastSelectable);
}
actionTimer = actionTime;
holdingAction = false;
}
}```
and this is currently whats looping in the update
the GiveOrders() is the walkie that pops up
but ya, i havent filled out the isDraggin part
if(isDraggin)
{
//check if we're still hovering the thing
//if we're not over the thing we must be dragging
if(Input.GetMouseButtonUp(0))
{
isDraggin = false;
}
}```
im sooo close
So you've got a lastSelectable. That would be the object currently selected?
thats what the mouse was hovering (the interface) when the mousebutton down() gets triggered yea
i also have another raycast that monitors what ur hovering all the time.. but it doesnt set the lastSelectable
only the mousedown one does
You'd just compare your mouse position to it if you're trying to determine going-to/comming-from the target
and IsSelected() is just a bool i return to make sure that u didnt hover over a different selectable
alrighty.. that sounds promising..
this is the last mechanic of the mouse click stuff i need to do.. before i can go back and clean some stuff up
You can probably determine if you're needing to compare distance by checking if selectable is null in update or something
single click, click and hold (w/o draggin) and click and hold (with draggin)
You'd also set the reference to null on release or whatever
ya, i currently do that only when i click again
soo ur right.. during the drag id need to monitor that as well
Not sure how it'll all fall together but I think you've got this 
lol..this is the make or break moment
does my system work.. can it work with the drag
or do i need to revise 🤞 lol
we shall see, if it works thats fantastic.. if not i'll probably jump over to the new input system
since it has things like click and hold built in
With your current system, if you're just wanting to know the mouse distance from the target, I'd do something like... cs if(lastSelectable)//not null { float distance = Vector3.Distance(lastSelectable, mousePosition); }where you'd assign the mouse position in the raycast-trygetcomponent if-statement.
this is originally what i was thinking, but since i have a raycast running in the update that uses the interface check.. i could probably make it return the thing, and call it while im dragging to see if i moved away from it
that makes sense.. idk why i didnt think of just using the lastSelectable as the position
Just make sure to free the selectable reference on release if you're no longer selecting something - assuming you're not needing the variable elsewhere in code.
ya, makes sense, the last selected is only really there so the WalkieTalkie thing can pop up..
b/c theoretically click on 1 unit and while holding hover over another selected unit and that would trigger the original one
Does the request selection return true if you hit the floor?
so i added that part to make sure ur hovering over the thing u originally clicked
and not just another one
Maybe you might need another raycast
no, only things with interfaces
or the ISelect interface more specifically
void RequestSelection(Vector3 pos)
{
Ray ray = Camera.main.ScreenPointToRay(pos);
RaycastHit hit;
if(Physics.Raycast(ray,out hit,distanceOfRay))
{
focusedTransform = hit.transform;
if(hit.collider.TryGetComponent(out ISelect selectable))
{
scrollLock = true; // the map shouldn't move until we release
holdingAction = true; // we're (possibly holding down the mouse button)
lastSelectable = selectable;
// Store the initial mouse position when the drag starts
initialMousePosition = Input.mousePosition;
isDraggin = true;
}
else
{
Debug.Log("We clicked something unselectable");
lastSelectable = null;
}
}
}```
heres the request selection snip
void RequestMouseTarget(Vector3 pos)
{
Ray ray = Camera.main.ScreenPointToRay(pos);
RaycastHit hit;
if(Physics.Raycast(ray,out hit,distanceOfRay))
{
focusedTransform = hit.transform;
}
else
{
focusedTransform = null;
Debug.Log("Where you lookin, champ?");
}
}
``` and the request mouse target (this is the raycast that runs all the time in update)
it just returns whatever
well sets focusedTransform
but i currently dont use that for anything
thanks for looking, btw.. i know its a big script
public bool MousePositionOnFloor(out Vector3 position)
{
Ray ray = Camera.main.ScreenPointToRay(pos);
bool valid = Physics.Raycast(ray, out RaycastHit hit, distanceOfRay, floorLayerMask);
position = valid ? hit.point : Vector3.zero;
return valid;
}```
The above example would return the mouse position on the ground etc
You'd only evaluate position if the return value was true.
alrighty, i think i understand enough to try something
thanky for taking a look.. i'll ping ya if i get stuck or when i get it working 🙂