Horreurs de OnPointerDown contre OnBeginDrag dans Unity3D

Je suis préoccupé par la différence entre OnPointerDown contre OnBeginDrag dans un seul mouvement de doigt de code.

(Dans la dernière Unité paradigme de l'aide d'un physique raycaster: donc, finalement, l'Unité sera correctement ignorer le contact sur la couche d'INTERFACE utilisateur.

Donc à partir de 2015 ce que vous devez faire est ceci:

  1. Oublier la merde traditionnel Input ou Touches système qui sont de la merde et même Unité admettre sont tout à fait inutile de la merde depuis qu'ils ne fonctionnent pas
  2. Ajouter un vide objet de jeu avec une BoxCollider2D, probablement plus grande que l'écran. Faire la couche de "Dessiner" (paramètres physiques, il interagit avec rien)
  3. Simplement ajouter à l'appareil photo, 2D ou en 3D, la physique raycaster. masque d'événement de votre "Tirage" de la couche.

Horreurs de OnPointerDown contre OnBeginDrag dans Unity3D

Faire un script comme ci-dessous et de le mettre sur "dessiner".

(Pointe - n'oubliez pas d'ajouter simplement un EventSystem à la scène. Bizarrement, l'Unité ne pas faire cela automatiquement pour vous dans certaines situations, mais l'Unité ne le faire automatiquement pour vous dans d'autres situations, il est donc ennuyeux si vous oubliez!)

Mais voici le problème.

Il y a obtenu d'être certains subtile différence entre l'utilisation de OnPointerDown contre OnBeginDrag (et correspondant à la fin des appels). (Vous pouvez juste changer l'action dans l'exemple de code suivant.)

Naturellement l'Unité n'offre pas de conseils sur ce; le code suivant magnifiquement rejette errants attrape et aussi parfaitement ignore votre couche d'INTERFACE utilisateur (grâce à l'Unité! lors de la dernière!) mais je suis complètement perplexe à propos de la différence entre les deux approches (commencer à glisser V commencer à toucher) et je ne peut pas de toute façon de trouver la logique de la différence entre les deux dans les tests unitaires.

Quelle est la réponse?

/*

general movement of something by a finger.

*/

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;

public class FingerMove:MonoBehaviour,
      IPointerDownHandler,
      IBeginDragHandler,
      IDragHandler,
      IPointerUpHandler,
      IEndDragHandler
  {
  public Transform moveThis;

  private Camera theCam;
  private FourLimits thingLimits;

  private Vector3 prevPointWorldSpace;
  private Vector3 thisPointWorldSpace;
  private Vector3 realWorldTravel;

  public void Awake()
    {
    theCam = Camera.main or whatever;
    }

  public void OnMarkersReady() //(would be EVENT DRIVEN for liveness)
    {
    thingLimits = Grid.liveMarkers. your motion limits
    }

  private int drawFinger;
  private bool drawFingerAlreadyDown;

  public void OnPointerDown (PointerEventData data)
    {
    Debug.Log("    P DOWN "  +data.pointerId.ToString() );
    }

  public void OnBeginDrag (PointerEventData data)
    {
    Debug.Log("    BEGIN DRAG "  +data.pointerId.ToString() );

    if (drawFingerAlreadyDown == true)
      {
      Debug.Log("    IGNORE THAT DOWN! "  +data.pointerId.ToString() );
      return;
      }
    drawFinger = data.pointerId;
    drawFingerAlreadyDown=true;

    prevPointWorldSpace = theCam.ScreenToWorldPoint( data.position );
    }

  public void OnDrag (PointerEventData data)
    {
    Debug.Log("    ON DRAG "  +data.pointerId.ToString() );

    if (drawFingerAlreadyDown == false)
      {
      Debug.Log("    IGNORE THAT PHANTOM! "  +data.pointerId.ToString() );
      }

    if ( drawFinger != data.pointerId )
      {
      Debug.Log("    IGNORE THAT DRAG! "  +data.pointerId.ToString() );
      return;
      }

    thisPointWorldSpace = theCam.ScreenToWorldPoint( data.position );
    realWorldTravel = thisPointWorldSpace - prevPointWorldSpace;
    _processRealWorldtravel();
    prevPointWorldSpace = thisPointWorldSpace;
    }

  public void OnEndDrag (PointerEventData data)
    {
    Debug.Log("    END DRAG "  +data.pointerId.ToString() );

    if ( drawFinger != data.pointerId )
      {
      Debug.Log("    IGNORE THAT UP! "  +data.pointerId.ToString() );
      return;
      }

    drawFingerAlreadyDown = false;
    }
  public void OnPointerUp (PointerEventData data)
    {
    Debug.Log("    P UP "  +data.pointerId.ToString() );
    }

  private void _processRealWorldtravel()
    {
    if ( Grid. your pause concept .Paused ) return;

   //potential new position...
    Vector3 pot = moveThis.position + realWorldTravel;

    //almost always, squeeze to a limits box...
    //(whether the live screen size, or some other box)

    if (pot.x < thingLimits.left) pot.x = thingLimits.left;
    if (pot.y > thingLimits.top) pot.y = thingLimits.top;
    if (pot.x > thingLimits.right) pot.x = thingLimits.right;
    if (pot.y < thingLimits.bottom) pot.y = thingLimits.bottom;

    //kinematic ... moveThis.position = pot;
    //or
    //if pushing around physics bodies ...  rigidbody.MovePosition(pot);
    }
  }

Et voici une chose à portée de main. Enregistrer en tapant avec la même chose pour les scènes en 3D, en utilisant le peu connu mais exquis

pointerCurrentRaycast

voici comment... notez l'excellente

data.pointerCurrentRaycast.worldPosition

appel de courtoisie à l'Unité.

public class FingerDrag .. for 3D scenes:MonoBehaviour,
      IPointerDownHandler,
      IDragHandler,
      IPointerUpHandler
  {
  public Transform moveMe;

  private Vector3 prevPointWorldSpace;
  private Vector3 thisPointWorldSpace;
  private Vector3 realWorldTravel;

  private int drawFinger;
  private bool drawFingerAlreadyDown;

  public void OnPointerDown (PointerEventData data)
    {
    if (drawFingerAlreadyDown == true)
      return;
    drawFinger = data.pointerId;
    drawFingerAlreadyDown=true;

    prevPointWorldSpace = data.pointerCurrentRaycast.worldPosition;
    //in this example we'll put it under finger control...
    moveMe.GetComponent<Rigidbody>().isKinematic = false;
    }

  public void OnDrag (PointerEventData data)
    {
    if (drawFingerAlreadyDown == false)
      return;
    if ( drawFinger != data.pointerId )
      return;

    thisPointWorldSpace = data.pointerCurrentRaycast.worldPosition;

    realWorldTravel = thisPointWorldSpace - prevPointWorldSpace;
    _processRealWorldtravel();

    prevPointWorldSpace = thisPointWorldSpace;
    }

  public void OnPointerUp (PointerEventData data)
    {
    if ( drawFinger != data.pointerId )
      return;

    drawFingerAlreadyDown = false;
    moveMe.GetComponent<Rigidbody>().isKinematic = false;
    moveMe = null;
    }

  private void _processRealWorldtravel()
    {
    Vector3 pot = moveMe.position;

    pot.x += realWorldTravel.x;
    pot.y += realWorldTravel.y;
    moveMe.position = pot;
    }
  }
Pour être juste, je n'ai pas utilisé OnPointerDown et OnBeginDrag avant parce qu'il était buggé quand il est sorti au sujet de un ou deux ans. J'utilise raycast sur les appareils mobiles pour détecter le toucher sur l'objet. Vous voulez savoir la différence entre OnPointerDown et OnBeginDrag et quand ils devraient être utilisés?
J'ai copié le script dans un projet de test, l'Unité 5.2.1. quand j'ai cliqué sur le Box2D il a enregistré l'OnPointerDown trucs, quand j'ai commencé à glisser connecté OnBeginDrag choses. Donc, si vous cliquez et maintenez-mais ne pas bouger, que OnPointerDown est appelé, OnBeginDrag ne le fait pas.
Salut Prog & Nikster. Oui, je comprends la différence en tant que telle, que Nika explique ... je suppose que je veux savoir à utiliser ... en fait, dans le monde réel qui est le chemin à parcourir?
je l'ai mis dans un exemple de la super-pratique pointerCurrentRaycast pour la scène 3D utiliser. Enregistrer en tapant

OriginalL'auteur Fattie | 2016-03-16