Unity开发记录_4_安卓项目 手指操作物体旋转避免万向节死锁 手指控制物体缩放和旋转方案

Unity开发记录_4_安卓项目 手指操作物体旋转避免万向节死锁 手指控制物体缩放和旋转方案

问题描述

网上搜索了几篇手指控制物体旋转的代码 但是效果都不佳只好自己写了

但是在写的过程中发现,如果用手指在屏幕上下 和 左右 操作来控制物体 单轴 的旋转,总会有万向节死锁的问题,就想了个取巧的方案去实现-----每次旋转之前都新建一个父物体 完成旋转后父物体还原

先看结果

在这里插入图片描述

使用方式—支持PC和安卓

将代码挂在在要旋转的物体身上,在PC编辑器想查看效果 可以勾选 bool TurnOnRotationOnPC
我的代码中旋转的是X Y轴,如果实际感觉旋转的不对,需要你调整相机位置为正方向 或者 去修改代码是否你想要的旋转是Y Z轴。
在这里插入图片描述


完整代码:

@Override
using UnityEngine;

public class FingerController : MonoBehaviour
{
    public bool TurnOnRotationOnPC = true;
    public float RotationSpeed = 10f;
    private GameObject m_parentObject;
    private Transform m_target;
    private bool m_isRotating = false;
    private Transform m_initParent;

#if UNITY_ANDROID
    public Vector2 BoundScale = new Vector2(0.1f, 10);
    private float m_newdis;
    private float m_olddis;
    private float m_scalingSpeed = 2;
    //缩放计时器---避免当缩放取消的时候 手指离开屏幕瞬间 导致物体旋转被触发
    private bool m_isScaling;
    private float m_ScalingTimeCount;//更改这个值可以控制间隔时间--初始0.2f
#endif

    private void Start()
    {
        m_target = transform;
    }

    private void Update()
    {
        HandleRotationInput();
        HandleScalingInput();
    }

    /// <summary>
    /// 旋转控制
    /// </summary>
    private void HandleRotationInput()
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        if (m_isScaling)
        {
            m_ScalingTimeCount -= Time.deltaTime;
            if (m_ScalingTimeCount < 0)
            {
                m_ScalingTimeCount = 0;
                m_isScaling = false;
            }
            return;
        }
        if (Input.touchCount == 1)
        {
            if (!m_isRotating) 
            {
                StartRotation();
            }
            HandleRotation();
        }
        else if (m_isRotating) 
        {
            StopRotation();
        }
#endif
        if (TurnOnRotationOnPC)
        {
            if (Input.GetMouseButtonDown(0))
            {
                StartRotation();
            }
            if (Input.GetMouseButton(0))
            {
                HandleRotation();
            }
            if (Input.GetMouseButtonUp(0))
            {
                StopRotation();
            }
        }
    }

    /// <summary>
    /// 缩放控制
    /// </summary>
    private void HandleScalingInput()
    {
        StartScaling();
    }

    /// <summary>
    /// 开始旋转
    /// </summary>
    private void StartRotation()
    {
        if (!m_isRotating)
        {
            m_initParent = transform.parent;

            if (m_parentObject == null)
            {
                m_parentObject = new GameObject("RotationParent")
                {
                    transform = { position = m_target.position }
                };
                m_target.SetParent(m_parentObject.transform);
            }

            m_isRotating = true;
        }
    }

    /// <summary>
    /// 旋转中
    /// </summary>
    private void HandleRotation()
    {
        if (!m_isRotating) return;

        Vector2 deltaPos = Vector2.zero;
#if UNITY_ANDROID && !UNITY_EDITOR
        if (Input.touchCount > 0)
        {
            deltaPos = Input.GetTouch(0).deltaPosition;
        }
#endif

        if (Input.GetMouseButton(0) && TurnOnRotationOnPC)
        {
            deltaPos = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
        }

        float rotationAmountY = -deltaPos.x * RotationSpeed;
        float rotationAmountX = deltaPos.y * RotationSpeed;

        m_parentObject.transform.Rotate(Vector3.up * rotationAmountY, Space.World);
        m_parentObject.transform.Rotate(Vector3.right * rotationAmountX, Space.Self);
    }

    /// <summary>
    /// 停止旋转
    /// </summary>
    private void StopRotation()
    {
        if (m_parentObject != null)
        {
            m_target.SetParent(m_initParent);
            Destroy(m_parentObject);
            m_parentObject = null;
        }

        m_isRotating = false;
    }

    /// <summary>
    /// 开始缩放---安卓平台
    /// </summary>
    private void StartScaling()
    {
#if UNITY_ANDROID
        if (Input.touchCount > 1)
        {
            if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
            {
                m_newdis = Vector2.Distance(Input.GetTouch(0).position, Input.GetTouch(1).position);
                float scaleDelta = Mathf.Clamp01(m_newdis) * Time.deltaTime * m_scalingSpeed;
                scaleDelta = m_newdis > m_olddis ? scaleDelta : -scaleDelta;
                transform.localScale += new Vector3(scaleDelta, scaleDelta, scaleDelta);
                float valScale = Mathf.Clamp(transform.localScale.x, BoundScale.x, BoundScale.y);
                transform.localScale = new Vector3(valScale, valScale, valScale);
                m_olddis = m_newdis;
                m_isScaling = true;
                m_ScalingTimeCount = 0.2f;
            }
        }
#endif
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值