Проблема с Camera.main.ScreenToWorldPoint(touch.position) в Unty

159
24 января 2019, 11:30

Как сделать в моей 2д игре, так, чтобы игра не отслеживала моё палец (тач), когда я нажимаю на кнопки ходьбы. В моей игре, оружие персонажа следит за касанием экрана, целится туда, где находится палец. Но когда нажимаю кнопки ходьбы, то смотрит туда же. Можно ли сделать так, чтобы отслеживалось нажатие на элемент Canvas -> Panel, Вот код:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ShootPoint : MonoBehaviour
{
    void Update()
    {
        LookAt();
    }
    void LookAt()
    {
        if (Input.touchCount > 0)
        {
            Touch touch = Input.GetTouch(0);
            Vector3 touchPosition = Camera.main.ScreenToWorldPoint(touch.position);
            Vector2 direction = new Vector2(touchPosition.x - transform.position.x, touchPosition.y - transform.position.y);
            transform.right = direction;
        }
    }
}
Answer 1

у Unity есть система интерфейсных событий EventSystem. Суть её в том, что она позволяет отслеживать различные действия ввода прилагательно к конкретным игровым объектам.

В вашем случае помогут два интерфейса этой системы IPointerDownHandler и IDragHandler. Метод первого вызывается, когда "поинтер" (тач/курсор) опускается на объект, на котором висит данный скрипт, метод второго вызывается каждый кадр, в течении которого палец двигается по этому объекту.

И так, у нас есть два инструмента. Как их использовать? Добавить на сцену EventSystem (она так же добавится сама при добавлении первого Canvas), написать класс, который реализует оба этих интерфейса и который будет отслеживать нажатие игрока на поле и сообщать о нём всем заинтересованным, добавить этот класс на ваше игровое поле.

Выглядеть это будет примерно так:

public class ShootPoint : MonoBehaviour
{
    [SerializeField]
    LookAtHandler _handler;
    private void Start()
    {
        _handler.OnTouchEvent += LookAt;
    }
    void LookAt(Vector3 touchPosition)
    {
        Vector2 direction = new Vector2(touchPosition.x - transform.position.x, touchPosition.y - transform.position.y);
        transform.right = direction;
    }
}

class LookAtHandler : MonoBehaviour, IPointerDownHandler, IDragHandler
{
    public event Action<Vector3> OnTouchEvent = delegate { };
    public void OnDrag(PointerEventData eventData)
    {
        OnTouchCalculate();
    }
    public void OnPointerDown(PointerEventData eventData)
    {
        OnTouchCalculate();
    }
    void OnTouchCalculate()
    {
        if (Input.touchCount > 0)
        {
            Touch touch = Input.GetTouch(0);
            var touchPosition = Camera.main.ScreenToWorldPoint(touch.position);
            OnTouchEvent(touchPosition);
        }
    }
}

Т.е. у нас есть класс LookAtHandler - он реализует ранее описанные интерфейсы и реагирует на события нажатия(он должен висеть на вашей панели). При каждом нажатии он вызывает у себя событие, в которое передаёт рассчитанную точку нажатия.

Так же у нас есть ваш класс ShootPoint - он подписывается на событие handler-а на старте и отвечает за то, чтобы повернуть юнит в нужную нам точку, когда срабатывает событие нажатия.

READ ALSO
Не работает шаблон TreeViewItem

Не работает шаблон TreeViewItem

Я пытаюсь кастомизировать элемент TreeView с помощью шаблоновВ дереве будет 2 уровня узлов (родитель и дочерний)

189
SQLite error (5): database is locked C# Dapper

SQLite error (5): database is locked C# Dapper

Использую в проекте SQLite (устанавливал через NuGet) и DapperВ проекте используется пул потоков для чтения из БД, запись в БД производится из отдельного...

221
Что такое принцип подстановки Liskov

Что такое принцип подстановки Liskov

Изучаю подходы к SOLID принципам

155
Наследование TreeNode

Наследование TreeNode

Хочу создать свою TreeNode - TreeINodeНаследую TreeNode в TreeINode

180