Unity工作随记_空间中不同角度的屏幕滑动操作适配相应的旋转移动

根据需求,在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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值