Как можно реализовать движение кубов свайпом?

Всем привет, решил переделать игру с урока и переделать под Android. Уже кучу методов перепробовал, не один не сработал. Нужно чтобы розовый и синий куб двигался по оси x (на скриншоте показано стрелками), а зеленый куб (плохо видно что он зеленый, но материал на нем зеленый :/ ), двигался вверх или вниз по оси Y. То есть свайпнул по экрану вправо или влево и розовый и синий куб двигался по направлению свайпа, а если свайпаешь вверх или вниз зеленый куб двигался по направлению свайпа. Если обьясните с кодом буду очень благодарен !

введите сюда описание изображения


Ответы (2 шт):

Автор решения: Максим Фисман

Все комментарии в самом коде.

    public enum Dir // Перечисление возможных направлений
    {
        X, Y, Z
    }
    [SerializeField] private Dir moveDir; // Нынешнее направление данного куба
    private float screenPosZ; // Позиция кубика по Z (но не в мировых коорд., а в экранных)
    private Vector3 curPos; // Нынешняя позиция

    void OnMouseDown()
    {
        screenPosZ = cam.WorldToScreenPoint(transform.position).z; // Настраиваем экранную позицию по Z
    }

    void OnMouseDrag()
    {
        curPos = transform.position;
        Vector3 screenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPosZ); // Позиция клика на экране
        Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); // Позиция клика в мире
        // Сдвигаем
        if (moveDir == Dir.X) curPos = new Vector3(worldPos.x, curPos.y, curPos.z);
        else if (moveDir == Dir.Y) curPos = new Vector3(curPos.x, worldPos.y, curPos.z);
        else if (moveDir == Dir.Z) curPos = new Vector3(curPos.x, curPos.y, worldPos.z);
        
        transform.position = curPos; // Собственно изменяем позицию
    }

Если остались вопросы, задавайте:)

→ Ссылка
Автор решения: Psyxoz0x13

Для этой реализации необходимо создать прозрачную панель на весь экран, которая будет отлавливать свайпы

canvas

На эту панель вешаем вот этот скрипт:

public class DragControl : MonoBehaviour, IDragHandler, IEndDragHandler
{
   public delegate void OnDragDelegate(Vector2 dragVector);
   public static event OnDragDelegate OnScreenDrag;
   public static event OnDragDelegate OnScreenDragEnd;

   private Vector2 _dragVector;

   public void OnDrag(PointerEventData eventData)
   {
       _dragVector = new SnapVector(eventData.delta.normalized, 90f);
       OnScreenDrag?.Invoke(_dragVector);
   }

   public void OnEndDrag(PointerEventData eventData)
   {
       OnScreenDragEnd?.Invoke(_dragVector);
   }
}   
public class SnapVector
{
   public Vector2 SourceVector { get; private set; }
   public float SnapAngle { get; private set; }

   public static implicit operator Vector2(SnapVector vector)
   {
       return GetSnapVector(vector);
   }

   public SnapVector(Vector2 vector, float snapAngle)
   {
       SourceVector = vector;
       SnapAngle = snapAngle;
   }

   private static Vector2 GetSnapVector(SnapVector snapVector)
   {
       var angle = Vector2.Angle(snapVector.SourceVector, Vector2.up);
       if (angle < snapVector.SnapAngle / 2.0f)
       {
           return Vector2.up * snapVector.SourceVector.magnitude;
       }    
       if (angle > 180.0f - snapVector.SnapAngle / 2.0f)
       {
           return Vector2.down * snapVector.SourceVector.magnitude;
       }

       var roundAngle = Mathf.Round(angle / snapVector.SnapAngle);
       var deltaAngle = (roundAngle * snapVector.SnapAngle) - angle;

       var axis = Vector3.Cross(Vector2.up, snapVector.SourceVector);
       var quaternion = Quaternion.AngleAxis(deltaAngle, axis);

       return quaternion * snapVector.SourceVector;
   }
}

Далее необходимо на каждый куб повесить данный скрипт предварительно отредактировав под свои нужды:

    [RequireComponent(typeof(Rigidbody))]
public class CubeMove : MonoBehaviour
{
    [SerializeField] private float _moveForce = 200f;

    private Rigidbody _cubeRigidbody;

    void Start()
    {
        _cubeRigidbody = GetComponent<Rigidbody>();

        DragControl.OnScreenDragEnd += ForceCube; //
        //DragControl.OnScreenDrag += ForceCube;
    }

    private void ForceCube(Vector2 dragVector)
    {
        var moveVector = transform.TransformDirection(new Vector3(dragVector.x, 0f, 0f)); //only x move
        //var moveVector = transform.TransformDirection(new Vector3(0f, 0f, dragVector.y)); only y move
        _cubeRigidbody.AddForce(moveVector * _moveForce, ForceMode.Force);
    }
}
→ Ссылка