📱

Unityで360度画像のViewerを作り方

2022/03/26に公開1

UnityProjectセットアップ

サンプルプロジェクトはこちら
https://github.com/yishizu/TAEC_GyroViewer

Packageを追加する

歪みの少ないICO球を利用して歪みの少ないViewerを作ります。
UnityのSphereでは、マテリアルを張っても上下の部分がずれて汚くなってしまいます。
そこで、MeshをUnityの球ではなく、ICO球を用います。Blenderなどでも作れますが、こちらのパッケージが早いので、これをダウンロードしてパッケージを追加します。

https://catlikecoding.com/unity/tutorials/octahedron-sphere/

ダウンロードしたパッケージを追加します。

画像を用意します


今回はここからダウンロードしました。
https://pixexid.com/image/jr0urb7-360-photo-park

Objectをセットアップします

ICOSphereとカメラを用意します。

キャンバスにパネルを作ります

ドラッグを認識するためのパネルを作り、そこにコードを貼り付けます。

パネルにつけるコード

VRCameraController.cs
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityEngine;

public class VRCameraController : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    [SerializeField] private Transform container;
    [SerializeField] private Transform camera;
    [SerializeField] private List<Texture2D> textures = new List<Texture2D>();
    [SerializeField] private TMP_Dropdown dropdown;
    [SerializeField] private Slider slider;
    private Quaternion rot;
    private float turnSpeedMouse = 1f;
    private bool gyroEnable = false;
    private static VRCameraController instance;
    public static VRCameraController Instance()
    {
        if (instance == null)
        {
            instance = FindObjectOfType<VRCameraController>();
        }

        return instance;
    }
    private void Start()
    {

        instance = this;
        UpdateSlider(100);
        Resources.UnloadUnusedAssets();
        
    }

    private void Update()
    {
        if(!gyroEnable) return;
        Quaternion q = Input.gyro.attitude;
        Quaternion qq = Quaternion.AngleAxis(90f, Vector3.right);
        camera.transform.localRotation =qq* q*rot;

    }


    public void GyroON(bool value)
    {
        Input.gyro.enabled = value;
        if (value)
        {
            rot = new Quaternion(0, 0, 1, 0);
        }
        gyroEnable = value;
        
    }
    
    
    public void OnBeginDrag(PointerEventData eventData)
    {

    }
    
    public void OnDrag(PointerEventData eventData)
    {
        container.Rotate(new Vector3(0, eventData.delta.x, 0) * Time.deltaTime * turnMouseDrag);
        camera.Rotate(new Vector3(eventData.delta.y, 0, 0) * Time.deltaTime * turnMouseDrag);
        
        float dotval = Vector3.Dot(camera.transform.forward, new Vector3(0,0,1));

        if (dotval < 0 || dotval > 1f)
        {
            camera.transform.Rotate(new Vector3(-eventData.delta.y, 0, 0) * Time.deltaTime * turnMouseDrag);
        }

    }
    
    public void OnEndDrag(PointerEventData eventData)
    {
        
    }

    public void ChangeTex(int val)
    {
        if (textures.Count > val)
        {
            var renderer = container.gameObject.GetComponent<Renderer>();
            var material = renderer.material;
            Debug.Log(material.GetTexture("_BaseMap"));
        
            material.SetTexture("_BaseMap",textures[val]);

            Debug.Log(textures[val].name);
            Resources.UnloadUnusedAssets();
        }
        
    }

    public void UpdateSlider(float val)
    {
        camera.gameObject.GetComponent<Camera>().fieldOfView = val;
    }
}


UIをセットアップします

スライダーとトグル、ドロップダウンを用意します。

Gyroscope

ジャイロスコープの軸の考え方は、こちらです。

https://jp.mathworks.com/help/supportpkg/android/ref/gyroscope.html

Discussion

yuki2006yuki2006

こんにちは。

GitHubにプロジェクトがあって助かりました。
この記事にはられているコードは turnMouseDrag ->turnSpeedMouse
が正しそうですね。

またこの記事の肝としては、ICOSphereのShaderはプロジェクト同梱の
SphereShader を使うことが大事のようですね。

標準のシェーダーを使う場合はカリングモードを変更できるもの(SkyBox/Panoramicなど)を選んだりすると
良いようです。