As it is a mobile game the user will interact with the game by touch. That being said, the player can interact with the camera by using pan, zoom and rotate which are functioning perfectly. One of the other possible interactions, is clicking these blue rectangles on the map that will perform an action.
The problem is, that when panning the camera, the rectangles will be selected if you start the panning movement on top of one of them.
I did some research and found that changing the Drag Threshold can usually fix the problem. So I did something like this but it didn’t fix the issue. I want to make clear that I am aware that in order to correctly test that, building the project is required.
void Start () {
int defaultValue = EventSystem.current.pixelDragThreshold;
EventSystem.current.pixelDragThreshold =
Mathf.Max(
defaultValue ,
(int) (defaultValue * Screen.dpi / 160f));
}
}```
Code from: http://ilkinulas.github.io/programming/unity/2016/03/18/unity_ui_drag_threshold.html
The last thing that I believe is relevant to mention is that both of those functions (camera controlling and rectangle selections) are in different scripts.
What makes sense to me is doing something like "When the camera is panning, do not cast the ray that checks if the click was on a rectangle", but I'm unsure of how to that given that they are different scripts and also not sure if It will work, because I have doubts if it selects the rectangle before or after it enters the panning loop.
Anyways, I am opened to suggestions and If further information is required, please do not hesitate to ask, I will provide it swiftly.
Your panning script and the blue boxes (which I assume is using the eventsystem) are doing their work in parallel from each other. Since the behavior of the one script needs to directly affect the control flow of the others you need to set up some interaction between them
You can have your camera control script access the PointerInputModule (the one which is propagating the click events to the blue squares) and call the method GetPointerData(touch or touchId, out pointerEventData,false) when it begins its panning behaviour. Then set pointerEventData.pointerClick to null if GetPointerData() returned true (true meaning one existed). Basically what this does is it tells the input module that there is no object to send an OnClick event to. Thus when the pointer is released the input module will not raise a click event down to the blue boxes.
You can also do other things to the recovered pointereventdata as well, such as change the dragstate or access what object the player pressed on.
Hey Joshua, I’m sorry for the delay in my response, but I have been using my time to solve other issues of the project.
I really liked how your logic would fit into my existing code and I understood the general idea, thought I need to figure some things out, like how can I use the GetPointerData method if it is protected?
Its protected, you can write a custom class that inherits from the Inputmodule, its not a sealed class. And you can have that class clear the click state internally on function call.
The code isn’t too difficult. The answer you are referring to was for Unity 4.6 which was years ago. The Eventsystem has since then been moved to a package and the API documentation likewise also moved to the Packages API site
using UnityEngine.EventSystems;
public class MyInputModule : StandaloneInputModule
{
public void ClearAllPressedPointers()
{
PointerEventData data;
for(int index = 0, count = Input.touchCount; index < count; index++)
{
if(GetPointerData(index,out data,false))
{
data.pointerPress = null;
}
}
}
}
This simply loops through all the current pointers being tracked and clears the tagged gameobject that was pressed in them. When you release your pointer Unity will then process the Pointer event data and will find that theres no Pointer Press object to process, and thus no object to send OnPointerUp and OnPointerClick messages to. The pointereventdata may still be tracking that object in its rawPointerPress field, so you may need to null that field as well if it still causes problems, but iirc Unity only uses that field on pointer press, not on pointer release.
I came across a very strange bug related to this.
I have an iPhone 11 Pro and I have been building the project onto it from the beginning and it worked perfectly. Once I released my game to the public, I got some reports that this functionality was being an issue (When trying to select something, it does not work as it’s supposed to, probably because the code thinks the person is dragging).
So, I tested it out on three different iPhoneX’s (Xs and X) and one iPhone 7 and it really has the issue the users were claiming.
What is weird is that it works perfectly on Android phone’s and in mine iPhone 11 Pro.
I am posting this because I have no clue of what this might be. I already have the “Drag Threshold Fix Script” added to my EventSystem.