根据需求,在Ar场景中需要实现屏幕在不同角度看向物体的某个组件时,根据屏幕上的手势进行相应的操作。
可以理解为当正向看向物体时,若是在屏幕横向滑动对应物体在y轴对应旋转的话,那么当物体Z轴旋转90度后,若还要使物体的Y轴转动,那么在屏幕的滑动手势为纵向。`//=============================================================================
//
//屏幕滑动与物体对应的旋转位移
//Author:Fuliang
//Data:2018/9/19
//
//=============================================================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MyTool
{
///
/// 操作轴向
///
public enum UseTypeAxis { Null, X_Axis, Y_Axis, Z_Axis }
///
/// 操作做方式类型
///
public enum UseTypeMethod { Null, Move, Rotate }
public class MT_OperatedComponents : MonoBehaviour
{
///
/// 轴向
///
[SerializeField] private UseTypeAxis TypeAxis;
///
/// 操作方式
///
[SerializeField] private UseTypeMethod TypeMethod;
///
/// 操作目标
///
[SerializeField] private Transform transOperationTagit;
[SerializeField] private float speedRotate = 10f;
[SerializeField] private float speedMove = 0.3f;
/// <summary>
/// 轴向映射到屏幕位置的向量化
/// </summary>
private Vector2 ScrNormalized;
/// <summary>
/// 是否可以进行操作
/// </summary>
private bool isOperation;
/// <summary>
/// 相对轴向偏移
/// </summary>
private Vector3 magnitude;
/*Vector3偏移量*/
private Vector3 VecStart;
private Vector3 VecEnd;
private Vector3 VecOffset;
/*Vector2偏移量*/
private Vector2 ScrStart;
private Vector2 ScrEnd;
private Vector2 ScrOffset;
private RaycastHit hit;
private Vector3 vecMapped;
private Vector3 vecAxial;
// Use this for initialization
private void Start() { }
private void Update() { }
#region 对物体的操作
public void Mt_ReceiveDataBegin(Camera cam, Vector3 ScreenPos)
{
VecStart = ScreenPos;
CamMapped(cam);
Debug.Log("ReceiveDataBegin");
}
public void Mt_ReceiveDataDrug(Vector3 ScreenPos)
{
if (TypeMethod == UseTypeMethod.Null && TypeAxis == UseTypeAxis.Null && isOperation) return;
VecEnd = ScreenPos;
VecOffset = VecEnd - VecStart;
switch (TypeMethod)
{
case UseTypeMethod.Move: OperationMove(); break;
case UseTypeMethod.Rotate: OperationRotate(); break;
default: break;
}
VecStart = ScreenPos;
Debug.Log("ReceiveDataDrug");
}
public void Mt_ReceiveDataEnd()
{
VecStart = Vector3.zero;
VecOffset = Vector3.zero;
isOperation = false;
Debug.Log("ReceiveDataEnd");
}
/// <summary>
/// 物体移动计算
/// </summary>
private void OperationMove()
{
float offset = ((VecOffset.x * ScrNormalized.x) + (VecOffset.y * ScrNormalized.y)) * Time.deltaTime * speedMove;
transOperationTagit.Translate(vecAxial * offset, Space.Self);
}
/// <summary>
/// 物体旋转计算
/// </summary>
private void OperationRotate()
{
float offset = ((VecOffset.x * ScrNormalized.y) + (VecOffset.y * ScrNormalized.x)) * Time.deltaTime * speedRotate;
transOperationTagit.Rotate(vecAxial, offset);
}
#endregion
#region 计算屏幕向量
/// <summary>
/// 屏幕向量
/// </summary>
/// <param name="cam">屏幕</param>
/// <returns></returns>
private Vector2 CamMapped(Camera cam)
{
VecMapped();
magnitude = transOperationTagit.position + vecMapped;
ScrStart = cam.WorldToScreenPoint(transOperationTagit.position);
ScrEnd = cam.WorldToScreenPoint(magnitude);
ScrOffset = ScrEnd - ScrStart;
return ScrOffset;
}
private void ExaminingOperation(Vector2 normalized)
{
isOperation = false;
ScrNormalized = normalized;
float normalizedX = normalized.x;
float normalizedY = normalized.y;
if (ExaminingSection(normalizedX, 0.05f, 0.95f) && ExaminingSection(normalizedY, 0.05f, 0.95f))
isOperation = true;
else
isOperation = false;
}
private bool ExaminingSection(float data, float minSection, float maxSection)
{
if (Mathf.Abs(data) > minSection && Mathf.Abs(data) < minSection)
return false;
else
return true;
}
#endregion
}
}
demo地址:https://download.csdn.net/download/qq_24099007/10676249