? Поддерживает ли реализация OnPointerHandler? или, может быть, я должен использовать другой метод?

я хочу добиться: зубная щетка должна появляться там, где пользователь нажимает внутриBoxCollider A, включая пространство внутриBoxCollider B, Но, видимо, щелкнув внутриB не будет показывать зубную щетку (OnPointerDown не запускается).

Что я пробовал: Изменение порядка слоев.

Зубная щетка показана после того, как пользователь щелкнул внутри коллайдераA, но если пользователь щелкает внутри поля коллайдераB- зубная щетка не появится, а это значит,OnPointerDown не срабатывает.

Я думаю, что это из-за совпадения одногоBoxCollider2D внутри другогоBoxCollider2D, В моем случаеB внутриAЯ предполагаю, что это виновник, но я понятия не имею, как ее решить или, может быть, есть другой метод для реализацииOnPointerDown?

Я используюPerspective камера. но в этой сцене все элементы в одномz position который равен 0. Можно ли вызвать событие IPointerHander в каждом соответствующемBoxCollider2D ?

DragableObject.cs

Этот скрипт прикреплен к зубной щетке.BoxCollider2D А также принадлежит зубной щетке.

public void OnPointerDown(PointerEventData eventData)
{
    Debug.Log("pointer down");

    if (GetComponent<DragableObject>() == null)
        return;

    currentObject = GetComponent<DragableObject>();

    MeshRenderer renderer = GetComponent<MeshRenderer>();

    if (ShowOnTouch)
        ShowObject();

    // Store original state
    originalPosition = transform.position;
    originalOrderLayer = renderer.sortingOrder;
    // Snap to mouse
    Vector3 newPos = cam.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 30));
    newPos.z = 30;
    transform.position = newPos;

    if (BringToFront)
    {
        if (renderer != null)
        {
            renderer.sortingOrder = 90;
        }
    }

    ObjectActive.Invoke();
}
TargetListener.cs

Этот скрипт прикреплен кBoxCollider2D B.

public void OnPointerDown(PointerEventData eventData)
{
    for (int i = 0; i < Affectors.Count; i++) 
    {
        if (Affectors [i] == DragableObject.currentObject)
        {
            DragableObject.currentObject.OnEnterTarget(transform);

            ITriggerEffect[] iTrigger = GetComponents<ITriggerEffect>();

            for (int j = 0; j < iTrigger.Length; j++) 
            {
                Debug.Log("iTrigger enter");
                Debug.Log(iTrigger [j]);
                iTrigger [j].Execute(eventData, PointerState.Down);
            }
        }
        else
            continue;
    }
}

Если я нажму наA зубная щетка появится, кроме тех случаев, когда я нажимаю внутриB, Здесь журнал отладки.

ЭтоBoxCollider2D А прикреплен к, который является*Toothbrush сам вместе сdragable.cs скрипт.

ОБНОВЛЕНИЕ: Благодаря другим, кто отвечает, проблема стала более ясной для меня. НижеBoxCollider2D А иBoxCollider2D Б. У обоих из них есть сценарий, который имеет большинствоOnPointerHander, Как мне убедиться, что всеOnPointerHandler срабатывает на соответствующемBoxCollider2D ?.

Проблемы, которые у меня возникают:

OnPointerExit наA срабатывает при входе моего указателяB.если нажать внутриB ,OnPointerDown только срабатывает наB но нетA
 Programmer13 сент. 2017 г., 10:08
@IgnacioAlorre EventSystem / OnPointerDown следует использовать, если это возможно. Это новая функция, которая позволяет писать один код, который работает на настольных и мобильных устройствах, вместо того, чтобы писать несколько кодов для каждого. Кроме того, вы не должны использовать GetMouseButtonDown на мобильных устройствах. См. Мой первый ответ о том, как я использовал препроцессор для разделения ввода с мобильного и настольного компьютера, а затем мой второй ответ о том, как один код с EventSystem будет работать на любой платформе. Да, это сложно с EventSystem, но это потому, что она не предназначена специально для выполнения задач, которые запрашивает OP, но это возможно.
 Ignacio Alorr,e13 сент. 2017 г., 06:48
Добавьте код, который вы имеете в OnTriggerEnter для обоих случаев
 Ignacio Alorre13 сент. 2017 г., 10:10
@ Программист, я понимаю. Спасибо за информацию
 Programmer13 сент. 2017 г., 08:48
Хорошо. Это то, о чем я думал. Твой английский хороший. Просто ваша проблема сложная. Возвращайтесь через минуту. Просто проверяю это перед публикацией.
 Programmer13 сент. 2017 г., 07:36
СтавитьDebug.Log в коде OnPointerDown, который прикреплен кBoxCollider2D B и дает нам знать, если это называется. Если возможно, отключите другие коллайдеры, кромеBoxCollider2D B и посмотреть, если проблема все еще там. Это способ устранения неполадок и помощи людям в решении вашей проблемы, в противном случае вы будете получать случайные ответы.

Ответы на вопрос(2)

что вы хотите, чтобы зубная щетка отображалась каждый раз, когда пользователь щелкает в области рта?

Если это так, то одним из забавных способов исправить это было бы изменение порядка расположения объектов «B» над объектом «A» в Иерархии так, чтобы они перекрывали область столкновения A. Это, в свою очередь, позволит их взаимодействию заблокировать взаимодействие области, определенной под областью столкновения, определенной каждым коллайдером "B".

Что мы делаем с этой методологией, так это заставляем событие OnPointerDown происходить с коллайдером «B», прежде чем оно сможет столкнуться с коллайдером «A».

Дайте мне знать, если это имеет смысл, и не стесняйтесь задавать дополнительные вопросы о методе.

Все еще не уверен, что ваш случай таков, как я думаю, но вот видео о методе, о котором я говорил:Демо Видео

 Tengku Fathullah13 сент. 2017 г., 05:57
Зубная щетка должна отображаться везде, где пользователь нажимает внутри BoxColliderA в том числе BoxColliderB, но зубная щетка не появляется (OnPointerDown не срабатывает), если пользователь щелкает внутри BoxColliderB, В конце концов я тоже попробовал описанный выше трюк, изменив порядок слоя, но он все еще не работает. Благодарю.
 Tengku Fathullah13 сент. 2017 г., 07:41
Спасибо за видео, но что мне делать, если я хочу щелкнуть поле B, чтобы вызвать обаOnPointerDown которыйB а также за этим, в этом случаеA ? Поддерживает ли реализация OnPointerHandler? или, может быть, я должен использовать другой метод?
 Eissa13 сент. 2017 г., 07:17
Понял. Если вы наложили кнопки правильно (вы используете холст пользовательского интерфейса с кнопками правильно?), То щелчки должны быть зарегистрированы, если сценарий был добавлен кA а такжеB объекты. Это точно не работает?
 Eissa13 сент. 2017 г., 07:32
Я добавил видео к своему ответу в качестве демонстрации того, что я имею в виду. В конце концов, это проблема с наслоением, которое вызывает коллайдер объектаA быть raycast первым вместо коллайдера объектаB.
 Tengku Fathullah13 сент. 2017 г., 07:24
Боюсь, что нет, зубная щетка показать / скрыть (OnPointerDown / OnPointerUp) включенаdragable.cs скрипт для управления им. это покажетif user click insideBoxCollider2D` A, работает, кроме случаев, когда пользователь нажимает внутриBoxCollider2D Б. Потому что обаBoxCollider2D A и B имеют OnPointerHandler. Так что я полагаю, в этом проблема?
Решение Вопроса

что события не проходят через GameObjects. Первое попадание возвращается. Хотя, похоже, ты этого не хочешь. Сложно заставить EventSystem возвращать несколько GameObjects,

Есть два решения для вас:

1. Получить поездкуEventSystem (OnPointerDown а такжеIPointerDownHandler) и использовать старую систему raycast.

Physics2D.RaycastAll а такжеPhysics2D.RaycastNonAlloc могу сделать это. Этот пример будет использоватьRaycastNonAlloc по причинам производительности. Это очень просто.

Присоединить только к одному GameObject (пустой GameObject):

public class HitAll : MonoBehaviour
{
    //Detect up to 100 Objects
    const int raycastAmount = 100;
    RaycastHit2D[] result = new RaycastHit2D[raycastAmount];

    void Update()
    {
        #if UNITY_IOS || UNITY_ANDROID
        if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
        {
            checkRaycast(Input.GetTouch(0).position);
        }
        #else
        if (Input.GetMouseButtonDown(0))
        {
            checkRaycast(Input.mousePosition);
        }
        #endif
    }

    void checkRaycast(Vector2 mousePos)
    {
        Vector3 origin = Camera.main.ScreenToWorldPoint(mousePos);

        int hitCount = Physics2D.RaycastNonAlloc(origin, Vector2.zero, result, 200);
        Debug.Log(hitCount);

        for (int i = 0; i < hitCount; i++)
        {
            Debug.Log("Hit: " + result[i].collider.gameObject.name);
        }
    }
}

2. Продолжайте использоватьEventSystem но отбросить событие.

Во-первых, вы бросаете Raycast сEventSystem.current.RaycastAll затем вы вручную вызываете событие сExecuteEvents.Execute.

Присоедините ко всему GameObject с 2D-коллайдером и убедитесь, чтоPhysics2DRaycaster прикреплен к камере:

public class ThroughEventScript : MonoBehaviour, IPointerDownHandler
{

    public void OnPointerDown(PointerEventData eventData)
    {
        rethrowRaycast(eventData, eventData.pointerCurrentRaycast.gameObject);

        //DO STUFF WITH THE OBJECT HIT BELOW
        Debug.Log("Hit: " + eventData.pointerCurrentRaycast.gameObject.name);
    }

    void rethrowRaycast(PointerEventData eventData, GameObject excludeGameObject)
    {
        PointerEventData pointerEventData = new PointerEventData(EventSystem.current);

        pointerEventData.position = eventData.pressPosition;
        //pointerEventData.position = eventData.position;}

        //Where to store Raycast Result
        List<RaycastResult> raycastResult = new List<RaycastResult>();

        //Rethrow the raycast to include everything regardless of their Z position
        EventSystem.current.RaycastAll(pointerEventData, raycastResult);

        //Debug.Log("Other GameObject hit");
        for (int i = 0; i < raycastResult.Count; i++)
        {
            //Debug.Log(raycastResult[i].gameObject.name);

            //Don't Rethrow Raycayst for the first GameObject that is hit
            if (excludeGameObject != null && raycastResult[i].gameObject != excludeGameObject)
            {
                //Re-simulate OnPointerDown on every Object hit
                simulateCallbackFunction(raycastResult[i].gameObject);
            }
        }
    }

    //This causes functions such as OnPointerDown to be called again
    void simulateCallbackFunction(GameObject target)
    {
        PointerEventData pointerEventData = new PointerEventData(EventSystem.current);
        //pointerEventData.ra
        RaycastResult res = new RaycastResult();
        res.gameObject = target;
        pointerEventData.pointerCurrentRaycast = res;
        ExecuteEvents.Execute(target, pointerEventData, ExecuteEvents.pointerDownHandler);
    }
}

Ваш ответ на вопрос