Unity 陀螺仪使用案例 - 仿崩坏3的UI 动效


玩过手游崩坏3的应该会发现游戏里面的UI 界面还有一些场景 会根据 玩家手机的平衡状态对UI或者相机进行位移或者旋转。
今天我们要使用移动端的重力感应,做类似的效果,来增加UI界面的流动感。
其实就是通过移动端的重力感应获得一个 三维向量,然后根据这个向量,对目标 UI 进行 旋转,位移 等等操作。


1. 首先我们先了解移动端手机陀螺仪的向量方向。首先,水平拿着手机,有Home键的一端右手拿。然后,由于图可知,绿线X轴就是垂直向上的线,Y轴就是水平向左的线。而Y轴就是伸向手机屏幕里面的线。在你左右前后摇动手机的时候。Unity 可以通过 Input.acceleration获取一个Vector3,用来记录这三个值的变化。记住,这三个值的取值都在 -11.

这里写图片描述

2. 既然,知道了怎么获取手机的陀螺仪的变化。那么,通过这个值我们用来控制UI或者其他任何对象。
3. 但是,要让Unity 的UI 进行位移,旋转变化的话。还得先设置点东西。
首先找到 UI画布的Canvas组件。修改Render ModeScreen Space-Camera.并且指定相应的的Camera。进行这一步操作,你的UI 才可以进行正确的位移和旋转。

这里写图片描述

4. 其次呢。就是逻辑了。我们在这里是运用手机的X轴的变化来改变tager对象的Y轴旋转,X轴移动; Y轴的变化来改变tager对象的X轴旋转,Y轴移动;Z轴的变化只去改变tager对象的Z轴位置。
5. 剩下的就比较简单了,就是代码了,所以老规矩上脚本吧。代码没有优化,比较智障,请平复一下心情再看。
using System;
using UnityEngine;

[Serializable]
public class SetUp
{
    [Tooltip("敏感度")]
    public float sensitivity = 15f;   //敏感度
    
    [Tooltip("最大水平移动速度")]
    public float maxturnSpeed = 35f;    // 最大移动速度

    [Tooltip("最大垂直傾斜角移动速度")]
    public float maxTilt = 35f;    // 最大倾斜角

    [Tooltip("位移加成速率")]
    public float posRate = 1.5f;    
}

public class MobileScreenOrientation : MonoBehaviour
{

    public enum MotionAxial
    {
        All = 1,  //全部轴
        None = 2,   
        x = 3,   
        y = 4,
        z = 5
    }

    public enum MotionMode
    {
        Postion = 1,   //只是位置辩护
        Rotation = 2,   
        All = 3    //全部变化
    }

    //就是这里比较笨了。本来使用UnityEditor类库的多选功能。但是这个类库不支持移动平台。
    public MotionAxial motionAxial1 = MotionAxial.y;     
    public MotionAxial motionAxial2 = MotionAxial.None;

    public MotionMode motionMode = MotionMode.Rotation;   //运动模式

    public SetUp setUp;

    public GameObject tager;     //被移动的对象

    Vector3 m_MobileOrientation;   //手机陀螺仪变化的值

    Vector3 m_tagerTransform;
    Vector3 m_tagerPos;
    public Vector3 ReversePosition = Vector3.one; //基于陀螺仪方向的取反

    void Awake()
    {
        Screen.orientation = ScreenOrientation.Landscape;
        m_tagerTransform = Vector3.zero;
        m_tagerPos = Vector3.zero;
        
    }

    void LateUpdate()
    {
        if (tager == null)
            return;

        m_MobileOrientation = Input.acceleration;



        if (motionAxial1 == MotionAxial.None && motionAxial2 == MotionAxial.None)   //不操作任何轴
            return;
        else if (motionAxial1 == MotionAxial.x && motionAxial2 == MotionAxial.None)   // X轴
        {
            m_tagerTransform.x = Mathf.Lerp(m_tagerTransform.x, m_MobileOrientation.y * setUp.maxTilt * ReversePosition.x, 0.2f);
        }
        else if (motionAxial1 == MotionAxial.y && motionAxial2 == MotionAxial.None)   //Y 轴
        {
            m_tagerTransform.y = Mathf.Lerp(m_tagerTransform.y, -m_MobileOrientation.x * setUp.maxturnSpeed * ReversePosition.y, 0.2f);
        }
        else if (motionAxial1 == MotionAxial.z && motionAxial2 == MotionAxial.None)   // z轴
        {
            m_tagerTransform.z = Mathf.Lerp(m_tagerTransform.z, -m_MobileOrientation.z * setUp.maxTilt * ReversePosition.z, 0.2f);
        }
        else if (motionAxial1 == MotionAxial.x && motionAxial2 == MotionAxial.y)   // X和Y轴
        {
            m_tagerTransform.y = Mathf.Lerp(m_tagerTransform.y, -m_MobileOrientation.x * setUp.maxturnSpeed * ReversePosition.y, 0.2f);
            m_tagerTransform.x = Mathf.Lerp(m_tagerTransform.x, m_MobileOrientation.y * setUp.maxTilt * ReversePosition.x, 0.2f);
        }
        else if (motionAxial1 == MotionAxial.y && motionAxial2 == MotionAxial.x) // Y和X轴
        {
            m_tagerTransform.y = Mathf.Lerp(m_tagerTransform.y, -m_MobileOrientation.x * setUp.maxturnSpeed * ReversePosition.y, 0.2f);
            m_tagerTransform.x = Mathf.Lerp(m_tagerTransform.x, m_MobileOrientation.y * setUp.maxTilt * ReversePosition.x, 0.2f);
        }
        else if (motionAxial1 == MotionAxial.x && motionAxial2 == MotionAxial.z)  // x 和 Z 轴
        {
            m_tagerTransform.x = Mathf.Lerp(m_tagerTransform.x, m_MobileOrientation.y * setUp.maxTilt * ReversePosition.x, 0.2f);
            m_tagerTransform.z = Mathf.Lerp(m_tagerTransform.z, -m_MobileOrientation.z * setUp.maxTilt * ReversePosition.z, 0.2f);
        }
        else if (motionAxial1 == MotionAxial.z && motionAxial2 == MotionAxial.x)  // Z 和 X 轴
        {
            m_tagerTransform.x = Mathf.Lerp(m_tagerTransform.x, m_MobileOrientation.y * setUp.maxTilt * ReversePosition.x, 0.2f);
            m_tagerTransform.z = Mathf.Lerp(m_tagerTransform.z, -m_MobileOrientation.z * setUp.maxTilt * ReversePosition.z, 0.2f);
        }
        else if (motionAxial1 == MotionAxial.y && motionAxial2 == MotionAxial.z)   // Y和Z 轴
        {
            m_tagerTransform.y = Mathf.Lerp(m_tagerTransform.y, -m_MobileOrientation.x * setUp.maxturnSpeed * ReversePosition.y, 0.2f);
            m_tagerTransform.z = Mathf.Lerp(m_tagerTransform.z, -m_MobileOrientation.z * setUp.maxTilt * ReversePosition.z, 0.2f);
        }
        else if (motionAxial1 == MotionAxial.z && motionAxial2 == MotionAxial.y)   // Z和 Y轴
        {
            m_tagerTransform.y = Mathf.Lerp(m_tagerTransform.y, -m_MobileOrientation.x * setUp.maxturnSpeed * ReversePosition.y, 0.2f);
            m_tagerTransform.z = Mathf.Lerp(m_tagerTransform.z, -m_MobileOrientation.z * setUp.maxTilt * ReversePosition.z, 0.2f);
        }
        else if (motionAxial1 == MotionAxial.All && motionAxial2 == MotionAxial.All)   // 所有轴向都运动
        {
            m_tagerTransform.y = Mathf.Lerp(m_tagerTransform.y, -m_MobileOrientation.x * setUp.maxturnSpeed * ReversePosition.y, 0.2f);
            m_tagerTransform.x = Mathf.Lerp(m_tagerTransform.x, m_MobileOrientation.y * setUp.maxTilt * ReversePosition.x, 0.2f);
            m_tagerTransform.z = Mathf.Lerp(m_tagerTransform.z, m_MobileOrientation.z * setUp.maxTilt * ReversePosition.z, 0.2f);
        }

        m_tagerPos.x = m_tagerTransform.y;
        m_tagerPos.y = -m_tagerTransform.x;
        m_tagerPos.z = m_tagerTransform.z;

        if (motionMode == MotionMode.Postion)
        {
            tager.transform.localPosition = Vector3.Lerp(tager.transform.localPosition, m_tagerPos * setUp.posRate, Time.deltaTime * setUp.sensitivity);
        }
        else if (motionMode == MotionMode.Rotation)
        {
            tager.transform.localRotation = Quaternion.Lerp(tager.transform.localRotation, Quaternion.Euler(m_tagerTransform), Time.deltaTime * setUp.sensitivity);
        }
        else
        {
            tager.transform.localPosition = Vector3.Lerp(tager.transform.localPosition, m_tagerPos * setUp.posRate, Time.deltaTime * setUp.sensitivity);
            tager.transform.localRotation = Quaternion.Lerp(tager.transform.localRotation, Quaternion.Euler(m_tagerTransform), Time.deltaTime * setUp.sensitivity);
        }
    }
    
}
6. 赶紧把脚本挂在Canvas对象上面,然后指定tager。打包到手机上面,测试测试吧。

效果展示:

这里写图片描述

这里写图片描述

这里写图片描述



这里写图片描述

我是李本心明


首先谢谢大家的支持,其次如果你碰到什么其他问题的话,欢迎来 我自己的一个 讨论群559666429来(扫扫下面二维码或者点击群链接 Unity3D[ 交流] ),大家一起找答案,共同进步

由于工作生活太忙了,对于大家的帮助时间已经没有之前那么充裕了。如果有志同道合的朋友,可以接受无偿的帮助别人,可以加我QQ单独联系我,一块经营一下。

在这里插入图片描述


  • 7
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
Unity UnityWebSocket插件是一款用于在Unity项目中实现WebSocket通信的插件。WebSocket是一种新的网络通信协议,它建立在HTTP协议之上,可以提供全双工通信,使得客户端和服务器可以通过一次HTTP握手建立持久的连接,实现实时的双向通信。 Unity UnityWebSocket插件可以方便地在Unity使用WebSocket协议进行网络通信。它提供了简洁易用的API接口,开发者可以轻松地实现连接、发送和接收消息等操作。通过该插件,我们可以构建实时的游戏功能,例如聊天系统、多人游戏和实时更新等。 使用Unity UnityWebSocket插件,开发者可以通过几行代码实现WebSocket的连接和消息处理。首先需要创建WebSocket连接,通过指定服务器地址和端口号等参数进行连接。连接建立后,可以通过发送消息来与服务器进行通信,并通过接收消息事件来处理服务器返回的数据。 Unity UnityWebSocket插件还提供了一些高级功能,例如心跳机制和断线重连。心跳机制可以保持连接的稳定性,防止连接断开。断线重连功能可以在网络连接断开后自重新连接服务器,确保通信的连续性。 总之,Unity UnityWebSocket插件是一款强大的工具,可以帮助开发者在Unity中实现WebSocket通信。它提供了简单易用的接口,并支持一些高级功能,使得开发者可以轻松地构建实时的游戏功能。该插件的使用可以提高开发率,为游戏开发带来更多可能性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值