I want to start by saying that Input
and Touches
are not crappy.They are still usefull and were the best way to check for touch
on mobile devices before OnPointerDown
and OnBeginDrag
came along. OnMouseDown()
you can call crappy because it was not optimized for mobile. For a beginner who just started to learn Unity, Input
and Touches
are their options.
As for your question, OnPointerDown
and OnBeginDrag
are NOT the-same. Although they almost do the-same thing but they were implemented to perform in different ways. Below I will describe most of these:
OnPointerDown
:
Called when there is press/touch on the screen (when there is a click or finger is pressed down on touch screen)
OnPointerUp
:
Called when press/touch is released (when click is released or finger is removed from the touch screen)
OnBeginDrag
:
Called once before a drag is started(when the finger/mouse is moved for the first time while down)
OnDrag
:
Repeatedly called when user is dragging on the screen (when the finger/mouse is moving on the touch screen)
OnEndDrag
:
Called when drag stops (when the finger/mouse is no longer moving on the touch screen).
OnPointerDown
versus OnBeginDrag
and OnEndDrag
OnPointerUp
will NOT be called if OnPointerDown
has not been called. OnEndDrag
will NOT be called if OnBeginDrag
has not been called. Its like the curly braces in C++,C#, you open it '{' and you close it '}'.
THE DIFFERENCE:
OnPointerDown will be called once and immediately when finger/mouse is on the touch screen. Nothing else will happen until there is a mouse movement or the finger moves on the screen then OnBeginDrag
will be called once followed by OnDrag.
These are made for doing advanced usage such such as custom UI with controls that is not included in Unity.
WHEN TO USE EACH ONE:
1. When you have to implement a simple click button, for example, Up,Down, Shoot Button on the screen, you only need OnPointerDown
to detect the touch. This should work for Sprite Images.
2. When you have to implement a custom toggle switch and you want it to be realistic so that the player can drag to left/right or up/down to toggle it then you need OnPointerDown
, OnBeginDrag
, OnDrag
, OnEndDrag
, OnPointerUp
. You need to write your code in this order to have a smooth Sprite/Texture transition on the screen. Some toggle switches are made to be to clicked and it will toggle. Some people prefer to make it look realistic by making it so that you have to drag it in order to toggle it.
3. Also when you want to implement a Generic re-usable pop-up window that is draggable, you also need to use those 5 functions (OnPointerDown
, OnBeginDrag
, OnDrag
, OnEndDrag
, OnPointerUp
).
First detect when there is a click(OnPointerDown
), check to make sure that the Sprite clicked is the right one you want to move. Wait for player to move(OnBeginDrag
) their finger/mouse. Once they start dragging, maybe you can call a coroutine function with while
loop that will start moving the Sprite and inside that coroutine, you can smooth the movement of the Sprite with Time.deltaTime
or any other preferred method.
Since OnBeginDrag
is called once, it is a good place to start the coroutine.
As the player continue to drag the Sprite, OnDrag
will be called repeatedly. Use the OnDrag
function to get the current location of the finder and update that to a Vector3
that the coroutine that is already running will use to update the position of the Sprite. When the player stops moving their finger/mouse on the screen, OnEndDrag
is called and you can boolean
variable and tell the coroutine to stop updating the position of the Sprite. Then, when the player releases their finger(OnPointerUp
) you can then stop the coroutine with the StopCoroutine function.
Because of OnBeginDrag
we we are able to start coroutine once drag started while waiting for drag to end. It wouldn't make sense to start that coroutine in OnPointerDown
because that means that each time player touches the screen, a coroutine would be started.
Without OnBeginDrag
, we have to use boolean
variable to make the coroutine start only once in the OnDrag
function which is called every time or else there would be coroutine running everywhere and unexpected movement of the Sprite will occur.
4. When you want to determine how long player moved their finger. Example of this is that famous game called Fruit Ninja. Lets just say you want to determine far the player swiped on the screen.
First, wait until OnPointerDown
is called, wait again until OnBeginDrag
is called, then you can get the current position of the finger inside OnBeginDrag
function because OnBeginDrag
is called before the finger starts moving. After the finger is released, OnEndDrag
is called. Then you can get the current position of finger again. You can use these two positions to check how far the finger moved by subtracting them.
If you instead decide to use OnPointerDown
as the place to get the first position of the finger, you will get a wrong result because if the player swipes right, then waits and swipes left then waits again and swipe up without releasing their finger after each swipe, the only good result you have is the first swipe(right swipe). The left and the up swipe will have invalid values because that first value you got when OnPointerDown
was called is the value you are still using. This is because the player never removed their finger from the screen so therefore, OnPointerDown
is never called again and the first old old value is still there.
But when you use OnBeginDrag
instead of OnPointerDown
, this problem will be gone because when the finger stops moving, OnEndDrag
is called and when it starts moving again OnBeginDrag
is called once again causing the first position to be overwritten with the new one.