Как можно реализовать движение кубов свайпом?
Всем привет, решил переделать игру с урока и переделать под 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; // Собственно изменяем позицию
}
Если остались вопросы, задавайте:)
Для этой реализации необходимо создать прозрачную панель на весь экран, которая будет отлавливать свайпы
На эту панель вешаем вот этот скрипт:
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);
}
}

