2017-08-10 21:34:57 KiTok 阅读数 8510
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。


玩过手游崩坏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。打包到手机上面,测试测试吧。

效果展示:

这里写图片描述

这里写图片描述

这里写图片描述



这里写图片描述

Hello ,I am 李本心明


首先谢谢大家的支持,其次如果你碰到什么其他问题的话,欢迎来 我自己的一个 讨论群559666429来(扫扫下面二维码或者点击群链接 Unity3D[ 交流&副业]CLUB ),大家一起找答案,共同进步 同时欢迎各大需求商入住,发布自己的需求,给群内伙伴提供副职,赚取外快。对了,资源的话,要在群公告里面找。

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

在这里插入图片描述


2018-09-17 14:57:19 RandomValue 阅读数 423
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

// ***********************************************************
// Written by Heyworks Unity Studio http://unity.heyworks.com/
// ***********************************************************
using UnityEngine;
/// <summary>
/// Gyroscope controller that works with any device orientation.
/// </summary>
public class GyroController : MonoBehaviour
{
	#region [Private fields]

		private bool gyroEnabled = true;
		private const float lowPassFilterFactor = 0.2f;

		private readonly Quaternion baseIdentity = Quaternion.Euler (90, 0, 0);
		private readonly Quaternion landscapeRight = Quaternion.Euler (0, 0, 90);
		private readonly Quaternion landscapeLeft = Quaternion.Euler (0, 0, -90);
		private readonly Quaternion upsideDown = Quaternion.Euler (0, 0, 180);
	
		private Quaternion cameraBase = Quaternion.identity;
		private Quaternion calibration = Quaternion.identity;
		private Quaternion baseOrientation = Quaternion.Euler (90, 0, 0);
		private Quaternion baseOrientationRotationFix = Quaternion.identity;
		private Quaternion referanceRotation = Quaternion.identity;
		private bool debug = true;
		private GameObject RotateObjectGame;

	#endregion

	#region [Unity events]

		protected void Start ()
		{
			//	RotateObjectGame = gameObject;
				Input.gyro.enabled = true;
				AttachGyro ();
		}

		protected void Update ()
		{
				if (!gyroEnabled)
						return;
				transform.localRotation = Quaternion.Slerp (transform.localRotation,
		                                       cameraBase * (ConvertRotation (referanceRotation * Input.gyro.attitude) * GetRotFix ()), lowPassFilterFactor);

				//RotateObjectGame.transform.localEulerAngles = new Vector3 (0, 0, transform.localEulerAngles.y);
		}



	#endregion

	#region [Public methods]

		/// <summary>
		/// Attaches gyro controller to the transform.
		/// </summary>
		private void AttachGyro ()
		{
				gyroEnabled = true;
				ResetBaseOrientation ();
				UpdateCalibration (true);
				UpdateCameraBaseRotation (true);
				RecalculateReferenceRotation ();
		}

		/// <summary>
		/// Detaches gyro controller from the transform
		/// </summary>
		private void DetachGyro ()
		{
				gyroEnabled = false;
		}

	#endregion

	#region [Private methods]

		/// <summary>
		/// Update the gyro calibration.
		/// </summary>
		private void UpdateCalibration (bool onlyHorizontal)
		{
				if (onlyHorizontal) {
						var fw = (Input.gyro.attitude) * (-Vector3.forward);
						fw.z = 0;
						if (fw == Vector3.zero) {
								calibration = Quaternion.identity;
						} else {
								calibration = (Quaternion.FromToRotation (baseOrientationRotationFix * Vector3.up, fw));
						}
				} else {
						calibration = Input.gyro.attitude;
				}
		}
	
		/// <summary>
		/// Update the camera base localRotation.
		/// </summary>
		/// <param name='onlyHorizontal'>
		/// Only y localRotation.
		/// </param>
		private void UpdateCameraBaseRotation (bool onlyHorizontal)
		{
				if (onlyHorizontal) {
						var fw = transform.forward;
						fw.y = 0;
						if (fw == Vector3.zero) {
								cameraBase = Quaternion.identity;
						} else {
								cameraBase = Quaternion.FromToRotation (Vector3.forward, fw);
						}
				} else {
						cameraBase = transform.localRotation;
				}
		}
	
		/// <summary>
		/// Converts the localRotation from right handed to left handed.
		/// </summary>
		/// <returns>
		/// The result localRotation.
		/// </returns>
		/// <param name='q'>
		/// The localRotation to convert.
		/// </param>
		private static Quaternion ConvertRotation (Quaternion q)
		{
				return new Quaternion (q.x, q.y, -q.z, -q.w);	
		}
	
		/// <summary>
		/// Gets the rot fix for different orientations.
		/// </summary>
		/// <returns>
		/// The rot fix.
		/// </returns>
		private Quaternion GetRotFix ()
		{
#if UNITY_3_5
		if (Screen.orientation == ScreenOrientation.Portrait)
			return Quaternion.identity;
		
		if (Screen.orientation == ScreenOrientation.LandscapeLeft || Screen.orientation == ScreenOrientation.Landscape)
			return landscapeLeft;
				
		if (Screen.orientation == ScreenOrientation.LandscapeRight)
			return landscapeRight;
				
		if (Screen.orientation == ScreenOrientation.PortraitUpsideDown)
			return upsideDown;
		return Quaternion.identity;
#else
				return Quaternion.identity;
#endif
		}
	
		/// <summary>
		/// Recalculates reference system.
		/// </summary>
		private void ResetBaseOrientation ()
		{
				baseOrientationRotationFix = GetRotFix ();
				baseOrientation = baseOrientationRotationFix * baseIdentity;
		}

		/// <summary>
		/// Recalculates reference localRotation.
		/// </summary>
		private void RecalculateReferenceRotation ()
		{
				referanceRotation = Quaternion.Inverse (baseOrientation) * Quaternion.Inverse (calibration);
		}

	#endregion
}

 

2017-01-06 17:08:50 ax1274669874 阅读数 598
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

在做手游的时候,80%时间是在PC调试的,例如业务逻辑、AI算法、核心玩法等。

拿到魔镜提供的demo,晕了,必须得安装到Android机器上,才能调试,究其原因,有三:

  1. 需要用到手机陀螺仪
  1. 需要用到蓝牙手柄
  1. 需要用到魔镜的凸透镜
 
1 模拟手机陀螺仪输入
  • 快捷键F: ok键
  • 快捷键Alt:按住,鼠标模拟GazePostion位移
  • 快捷键Ctrl:按住,鼠标模拟GazePostion旋转
2 模拟蓝牙输入
  • 快捷键WASD:模拟蓝牙
  • 快捷键Q:模拟蓝牙OK
3 模拟非VR Mode切换
  • 快捷键R:模拟切换VR Mode
  • 快捷键B:模拟回到主菜单

这些都是客观原因,但是每次打包后,安装Android,再戴到头上,Debug、log啥的都看不清,呵呵。

故就着手改造一下输入快捷键,从而可以方便的模拟手机陀螺仪输入、模拟蓝牙输入、模拟非VR Mode切换。

这个在mojing.cs有现成隐藏代码,在UpdateState()函数中。

在学习了MojingInputManager.OnButtonDown\OnButtonUp后,知道只要传递过去string即可,其中用/分隔,第一位暂时不用,第二位用MojingKeyCode预定定义的数字。

VR Mode切换,是通过设置Mojing.SDK.VRModeEnabled实现的,原理是对Left、Right Camera和Center Camera可见性进行隐藏或者显示实现切换,找到了Demo.cs脚本中,已经封装好了切换和返回主菜单函数,调用即可:GameObject.FindObjectOfType<Demo>().ToggleVRMode();

 

借用网络一句话:VR开发,比App开发,多一个Camera。 搭建好调试环境,就会好很多。

 

源码下载:MojingInputManagerEditor.cs

使用:在MojingInputManager.prefab添加MojingInputManagerEditor脚本,然后点击Apply即可。


没有更多推荐了,返回首页