Unity制作360全景图(移动端陀螺仪交互)

版权声明:转发,使用请留言告知 https://blog.csdn.net/qq_37310110/article/details/86082494

工程源码:https://download.csdn.net/download/qq_37310110/10904464

一.全景图的制作

有很多种方法制作全景图。但是在unity里面实现的话最常用的有两种方法

1.新建sphere直接附上全景贴图(Unity默认的sphere仅仅有770个三角面 全景图变形夸张,建议用模型软件制作10k左右面的球形模型)下图对比

2.用全景图制作天空盒子

第一种方法稍微为复杂一点,第二种就很简单了。这里主要记录一下第一种。

制作全景图:测试用的就没有用专业设备制作了,直接用手机拍摄全景图即可

二.制作全景图载体

在unity新建一个sphere位置归零,设置scale为10,相机位置也归零,把之前的全景图赋给sphere。这个时候相机渲染的game视图并没有任何变化,因为新建sphere的材质为unity默认材质,是单面的,相机从内部看就是直接透出了。这里就需要编写简单shader使法线翻转一下。新建材质选择编写的shader并chon重新赋给sphere。这个时候相机的额渲染界面就能看到全景图的内容。

shader代码如下

Shader "Unlit / Pano360Shader"
{
	Properties
	{
			_MainTex("Base(RGB)", 2D) = "white"{}
			_Color("Main Color", Color) = (1,1,1,0.5)
	}
		SubShader
			{
					Tags{ "RenderType" = "Opaque" }
					//This is used to print the texture inside of the sphere
					Cull Front
					CGPROGRAM
			#pragma surface surf SimpleLambert
					half4 LightingSimpleLambert(SurfaceOutput s, half3 lightDir, half atten)
			{
					half4 c;
					c.rgb = s.Albedo;
					return c;
			}

			sampler2D _MainTex;
			struct Input
			{
					float2 uv_MainTex;
					float4 myColor : COLOR;
			};

			fixed3 _Color;
			void surf(Input IN, inout SurfaceOutput o)
			{
				//This is used to mirror the image correctly when printing it inside of the sphere
				IN.uv_MainTex.x = 1 - IN.uv_MainTex.x;
				fixed3 result = tex2D(_MainTex, IN.uv_MainTex)*_Color;
				o.Albedo = result.rgb;
				o.Alpha = 1;
		}
		ENDCG
			}
				Fallback "Diffuse"
}

三.编写控制脚本

全景图的控制模式也有两种:一种就是手指触屏移动控制,第二种是调用陀螺仪自动旋转

功能简介:

1.没有交互的时候全景图场景自转,有交互后,场景停止自传,自转速率可控

2.交互分三种模式:a.水平竖直同步;b.只能水平;c.只能竖直

3.设置最大仰角和zui最大俯角

#region 模块信息
// **********************************************************************
// Copyright (C) 2019 The company name
//
// 文件名(File Name):             NewBehaviourScript.cs
// 作者(Author):                  #AuthorName#
// 创建时间(CreateTime):           #CreateTime#
// 团队成员(TeamMembers):
// 脚本描述(Module description):
// **********************************************************************
#endregion

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
//3种模式:水平竖直,水平,竖直
enum RotationAxes { MouseXAndY, MouseX, MouseY }

public class GyroController_01 : MonoBehaviour
{
    RotationAxes axes = RotationAxes.MouseXAndY;
    public GameObject target;//载体球体
    public float moveSpeed = 1;//球体自动旋转速度  
    public float gapTime = 5;//球体自动旋转时间  
    public float sensitivityX = 1;//竖直模式的灵敏度
    public float sensitivityY = 1;//水平模式的灵敏度
    public float minimumY = -80;//竖直俯角的最小值
    public float maximumY = 80;//竖直仰角的最大值
    private float rotationY = 0;//竖直分量
    private bool isRotate = true;  //是否自转

    float count = 0;
    void Start()
    {
        Vector3 angles = transform.eulerAngles;
    
        if (GetComponent<Rigidbody>())
            GetComponent<Rigidbody>().freezeRotation = true;
    }

    // Update is called once per frame  
    void Update()
    {
        if (isRotate)
        {
            target.transform.Rotate(Vector3.up, Time.deltaTime * moveSpeed, Space.World);
        }
        if (!isRotate)
        {
            count += Time.deltaTime;
            if (count > gapTime)
            {
                count = 0;
                isRotate = true;
            }
        }
#if UNITY_EDITOR
        if (Input.GetMouseButton(0))
#else 
        if ((Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved))
#endif
        {
            if (axes == RotationAxes.MouseXAndY)
            {
                float rotationX = transform.localEulerAngles.y - Input.GetAxis("Mouse X") * sensitivityX;
                rotationY -= Input.GetAxis("Mouse Y") * sensitivityY;
                rotationY = Mathf.Clamp(rotationY, minimumY, maximumY);
                transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
            }
            else if (axes == RotationAxes.MouseX)
            {
                transform.Rotate(Vector3.up * Input.GetAxis("Mouse X") * sensitivityY);
            }
            else
            {
                rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
                rotationY = Mathf.Clamp(rotationY, minimumY, maximumY);
                transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0);
            }
            isRotate = false;
        }
    }
}

调动陀螺仪:脚本直接挂在相机上即可

public class Gyroscope : MonoBehaviour {

    bool draw = false;
    bool gyinfo;
    UnityEngine.Gyroscope go;
    void Start()
    {
        gyinfo = SystemInfo.supportsGyroscope;
        go = Input.gyro;
        go.enabled = true;
    }
    void Update()
    {
        if (gyinfo)
        {
            Vector3 a = go.attitude.eulerAngles; //直接使用读取的欧拉角发现不对,于是自己调整一下符号
            this.transform.eulerAngles = a;
            this.transform.Rotate(Vector3.right * 90, Space.World);
        }
        else
        {
            //不支持陀螺仪
            Application.Quit();
        }
    }

工程源码:https://download.csdn.net/download/qq_37310110/10904464

​​​​​​​

猜你喜欢

转载自blog.csdn.net/qq_37310110/article/details/86082494
今日推荐