Create a folder Editor with the script : "InvertedSphere". This sphere will blend a movie inside the sphere.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class InvertedSphere : EditorWindow
{
private string st = "1.0";
[MenuItem("GameObject/Create Other/Inverted Sphere...")]
public static void ShowWindow()
{
EditorWindow.GetWindow(typeof(InvertedSphere));
}
public void OnGUI()
{
GUILayout.Label("Enter sphere size:");
st = GUILayout.TextField(st);
float f;
if (!float.TryParse(st, out f))
f = 1.0f;
if (GUILayout.Button("Create Inverted Sphere"))
{
CreateInvertedSphere(f);
}
}
private void CreateInvertedSphere(float size)
{
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Sphere);
MeshFilter mf = go.GetComponent<MeshFilter>();
Mesh mesh = mf.sharedMesh;
GameObject goNew = new GameObject();
goNew.name = "Inverted Sphere";
MeshFilter mfNew = goNew.AddComponent<MeshFilter>();
mfNew.sharedMesh = new Mesh();
//Scale the vertices;
Vector3[] vertices = mesh.vertices;
for (int i = 0; i < vertices.Length; i++)
vertices[i] = vertices[i] * size;
mfNew.sharedMesh.vertices = vertices;
// Reverse the triangles
int[] triangles = mesh.triangles;
for (int i = 0; i < triangles.Length; i += 3)
{
int t = triangles[i];
triangles[i] = triangles[i + 2];
triangles[i + 2] = t;
}
mfNew.sharedMesh.triangles = triangles;
// Reverse the normals;
Vector3[] normals = mesh.normals;
for (int i = 0; i < normals.Length; i++)
normals[i] = -normals[i];
mfNew.sharedMesh.normals = normals;
mfNew.sharedMesh.uv = mesh.uv;
mfNew.sharedMesh.uv2 = mesh.uv2;
mfNew.sharedMesh.RecalculateBounds();
// Add the same material that the original sphere used
MeshRenderer mr = goNew.AddComponent<MeshRenderer>();
mr.sharedMaterial = go.GetComponent<Renderer>().sharedMaterial;
DestroyImmediate(go);
}
}
Create a new material e.g. 360Mat. Use the unlit/transparant shader.
Create a render texture with the dimensions of the 360 video (3840 x 2160 )
Drag the render texture to the created material
Add the material to the inverted sphere
Add a videoplayer component to the inverted sphere
Following script measures the vr camera rotation and fires an event when a threshold is reached
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
public class LookAtInVR : MonoBehaviour
{
// Start is called before the first frame update
public event EventHandler<ThresholdReachedEventArgs> ThresholdReached;
public Camera lookAtCamera;
private Transform t;
void Start()
{
lookAtCamera = Camera.main;
print(lookAtCamera);
}
// Update is called once per frame
void Update()
{
print(lookAtCamera.transform.eulerAngles.y);
if(lookAtCamera.transform.eulerAngles.y > 275 && lookAtCamera.transform.eulerAngles.y < 300)
{
print("change video");
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = 1;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
}
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
if (ThresholdReached != null)
{
ThresholdReached(this, e);
}
}
}
Following script will listen to the Threshold-event and takes action. The action is a new video on the inside of the inverted sphere.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
public class VideoChanger : MonoBehaviour
{
private VideoPlayer video;
public List<string> videos;
public VideoClip videoToPlay1;
public VideoClip videoToPlay2;
public GameObject sphere1;
public GameObject sphere2;
private LookAtInVR lookAtInVr;
public GameObject Environment;
// Start is called before the first frame update
void Start()
{
sphere1.GetComponent<VideoPlayer>().Prepare();
sphere2.GetComponent<VideoPlayer>().Prepare();
sphere1.GetComponent<VideoPlayer>().prepareCompleted += VideoChanger_prepareCompleted;
lookAtInVr = Environment.GetComponent<LookAtInVR>();
lookAtInVr.ThresholdReached += LookAtInVr_ThresholdReached;
}
private void VideoChanger_prepareCompleted(VideoPlayer source)
{
source.Play();
}
private void LookAtInVr_ThresholdReached(object sender, ThresholdReachedEventArgs e)
{
print(e);
sphere2.transform.position = new Vector3(0, 0, 0);
sphere1.transform.position = new Vector3(0, 0, 10);
sphere1.GetComponent<VideoPlayer>().Stop();
sphere2.GetComponent<VideoPlayer>().Play();
}
}
Check grip
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class Grip : MonoBehaviour
{
public InputActionReference grip;
void Start()
{
grip.action.performed += Action_performed;
}
private void Action_performed(InputAction.CallbackContext obj)
{
print("press grip");
}
}
Assign e.g. the xri lefthand interaction / select to in grip public variable.