private void ActivateInteractionPoint(InteractionPointPlayer point) { float pointAngle = Mathf.Rad2Deg * Mathf.Atan2(point.position.x, point.position.z) - 90; Canvass.sphereUIRenderer.GetComponent <UISphere>().Activate(pointAngle); point.panel.SetActive(true); //NOTE(Simon): We do this here, because each interactionType has its own script. So that mean adding the event in many places var button = point.panel.transform.Find("CloseSpherePanelButton").GetComponent <Button>(); button.onClick.RemoveAllListeners(); button.onClick.AddListener(DeactivateActiveInteractionPoint); activeInteractionPoint = point; point.isSeen = true; videoController.Pause(); InteractionPointers.Instance.ShouldRender(false); //NOTE(Simon): No two eventsystems can be active at the same, so disable the main one. The main one is used for all screenspace UI. //NOTE(Simon): The other eventsystem, that remains active, handles input for the spherical UI. mainEventSystem.enabled = false; }
private void RemoveInteractionPoint(InteractionPointPlayer point) { interactionPoints.Remove(point); Destroy(point.point); if (point.panel != null) { Destroy(point.panel); } }
public void DeactivateActiveInteractionPoint() { Canvass.sphereUIRenderer.GetComponent <UISphere>().Deactivate(); activeInteractionPoint.panel.SetActive(false); activeInteractionPoint = null; videoController.Play(); mainEventSystem.enabled = true; }
private bool OpenFile(string path) { var data = SaveFile.OpenFile(path); openVideo = Path.Combine(Application.persistentDataPath, Path.Combine(data.meta.guid.ToString(), SaveFile.videoFilename)); fileLoader.LoadFile(openVideo); for (var j = interactionPoints.Count - 1; j >= 0; j--) { RemoveInteractionPoint(interactionPoints[j]); } interactionPoints.Clear(); foreach (var point in data.points) { var newPoint = Instantiate(interactionPointPrefab, point.position, point.rotation); var newInteractionPoint = new InteractionPointPlayer { startTime = point.startTime, endTime = point.endTime, title = point.title, body = point.body, filename = "file:///" + Path.Combine(Application.persistentDataPath, Path.Combine(data.meta.guid.ToString(), point.filename)), type = point.type, point = newPoint }; switch (newInteractionPoint.type) { case InteractionType.Text: { var panel = Instantiate(textPanelPrefab); panel.GetComponent <TextPanel>().Init(point.position, newInteractionPoint.title, newInteractionPoint.body); newInteractionPoint.panel = panel; break; } case InteractionType.Image: { var panel = Instantiate(imagePanelPrefab); panel.GetComponent <ImagePanel>().Init(point.position, newInteractionPoint.title, newInteractionPoint.filename, false); newInteractionPoint.panel = panel; break; } default: throw new ArgumentOutOfRangeException(); } AddInteractionPoint(newInteractionPoint); } return(true); }
private void SetInteractionPointTag(InteractionPointPlayer point) { var shape = point.point.GetComponent <SpriteRenderer>(); var interactionTypeRenderer = point.point.GetComponentInChildren <SpriteRenderer>(excludeSelf: true); var tag = TagManager.Instance.GetTagById(point.tagId); shape.sprite = TagManager.Instance.ShapeForIndex(tag.shapeIndex); shape.color = tag.color; interactionTypeRenderer.color = tag.color.IdealTextColor(); }
private void AddInteractionPoint(InteractionPointPlayer point) { point.point.transform.LookAt(Vector3.zero, Vector3.up); point.point.transform.RotateAround(point.point.transform.position, point.point.transform.up, 180); //NOTE(Simon): Add a number to interaction points //TODO(Simon): Make sure these are numbered chronologically point.point.transform.GetChild(0).gameObject.SetActive(true); point.point.GetComponentInChildren <TextMesh>().text = (++interactionPointCount).ToString(); point.panel.SetActive(false); interactionPoints.Add(point); }
private void AddInteractionPoint(InteractionPointPlayer point) { point.point.transform.LookAt(Vector3.zero, Vector3.up); point.point.transform.RotateAround(point.point.transform.position, point.point.transform.up, 180); //NOTE(Simon): Add a sprite to interaction points, indicating InteractionType point.point.GetComponentInChildren <SpriteRenderer>(excludeSelf: true).sprite = InteractionTypeSprites.GetSprite(point.type); point.point.transform.GetChild(0).gameObject.SetActive(true); point.panel.SetActive(false); interactionPoints.Add(point); SetInteractionPointTag(point); }
public void Init(InteractionPointPlayer point) { point.point.transform.LookAt(Vector3.zero, Vector3.up); point.point.transform.RotateAround(point.point.transform.position, point.point.transform.up, 180); //NOTE(Simon): Add a sprite to interaction points, indicating InteractionType interactionType.sprite = InteractionTypeSprites.GetSprite(point.type); ping.SetActive(false); point.panel.SetActive(false); mandatory.enabled = point.mandatory; SetInteractionPointTag(point.point, point.tagId); }
private void AddInteractionPoint(InteractionPointPlayer point) { point.point.GetComponent <InteractionPointRenderer>().Init(point); interactionPoints.Add(point); }
private bool OpenFile(string projectPath) { data = SaveFile.OpenFile(projectPath); openVideo = Path.Combine(Application.persistentDataPath, Path.Combine(data.meta.guid.ToString(), SaveFile.videoFilename)); fileLoader.LoadFile(openVideo); var tagsPath = Path.Combine(Application.persistentDataPath, data.meta.guid.ToString()); var tags = SaveFile.ReadTags(tagsPath); TagManager.Instance.SetTags(tags); var chaptersPath = Path.Combine(Application.persistentDataPath, data.meta.guid.ToString()); var chapters = SaveFile.ReadChapters(chaptersPath); ChapterManager.Instance.SetChapters(chapters); //NOTE(Simon): Sort all interactionpoints based on their timing data.points.Sort((x, y) => x.startTime != y.startTime ? x.startTime.CompareTo(y.startTime) : x.endTime.CompareTo(y.endTime)); foreach (var point in data.points) { var newPoint = Instantiate(interactionPointPrefab); var newInteractionPoint = new InteractionPointPlayer { startTime = point.startTime, endTime = point.endTime, title = point.title, body = point.body, filename = point.filename, type = point.type, point = newPoint, tagId = point.tagId, mandatory = point.mandatory, returnRayOrigin = point.returnRayOrigin, returnRayDirection = point.returnRayDirection }; bool isValidPoint = true; switch (newInteractionPoint.type) { case InteractionType.None: { isValidPoint = false; Debug.Log("InteractionPoint with Type None encountered"); break; } case InteractionType.Text: { var panel = Instantiate(textPanelPrefab, Canvass.sphereUIPanelWrapper.transform); panel.GetComponent <TextPanel>().Init(newInteractionPoint.title, newInteractionPoint.body); newInteractionPoint.panel = panel; break; } case InteractionType.Image: { var panel = Instantiate(imagePanelPrefab, Canvass.sphereUIPanelWrapper.transform); var filenames = newInteractionPoint.filename.Split('\f'); var urls = new List <string>(); foreach (var file in filenames) { string url = Path.Combine(Application.persistentDataPath, Path.Combine(data.meta.guid.ToString(), file)); urls.Add(url); } panel.GetComponent <ImagePanel>().Init(newInteractionPoint.title, urls); newInteractionPoint.panel = panel; break; } case InteractionType.Video: { var panel = Instantiate(videoPanelPrefab, Canvass.sphereUIPanelWrapper.transform); string url = Path.Combine(Application.persistentDataPath, data.meta.guid.ToString(), newInteractionPoint.filename); panel.GetComponent <VideoPanel>().Init(newInteractionPoint.title, url); newInteractionPoint.panel = panel; break; } case InteractionType.MultipleChoice: { var split = newInteractionPoint.body.Split(new[] { '\f' }, 2); int correct = Int32.Parse(split[0]); var panel = Instantiate(multipleChoicePrefab, Canvass.sphereUIPanelWrapper.transform); panel.GetComponent <MultipleChoicePanelSphere>().Init(newInteractionPoint.title, correct, split[1].Split('\f')); newInteractionPoint.panel = panel; break; } case InteractionType.Audio: { var panel = Instantiate(audioPanelPrefab, Canvass.sphereUIPanelWrapper.transform); string url = Path.Combine(Application.persistentDataPath, data.meta.guid.ToString(), newInteractionPoint.filename); panel.GetComponent <AudioPanel>().Init(newInteractionPoint.title, url); newInteractionPoint.panel = panel; break; } case InteractionType.FindArea: { var panel = Instantiate(findAreaPanelPrefab, Canvass.sphereUIPanelWrapper.transform); var areas = Area.ParseFromSave(newInteractionPoint.filename, newInteractionPoint.body); panel.GetComponent <FindAreaPanelSphere>().Init(newInteractionPoint.title, areas); newInteractionPoint.panel = panel; break; } case InteractionType.MultipleChoiceArea: { var split = newInteractionPoint.body.Split(new[] { '\f' }, 2); int correct = Int32.Parse(split[0]); string areaJson = split[1]; var panel = Instantiate(multipleChoiceAreaPanelPrefab, Canvass.sphereUIPanelWrapper.transform); var areas = Area.ParseFromSave(newInteractionPoint.filename, areaJson); panel.GetComponent <MultipleChoiceAreaPanelSphere>().Init(newInteractionPoint.title, areas, correct); newInteractionPoint.panel = panel; break; } case InteractionType.MultipleChoiceImage: { var panel = Instantiate(multipleChoiceImagePanelPrefab, Canvass.sphereUIPanelWrapper.transform); var filenames = newInteractionPoint.filename.Split('\f'); int correct = Int32.Parse(newInteractionPoint.body); var urls = new List <string>(); foreach (string file in filenames) { string url = Path.Combine(Application.persistentDataPath, Path.Combine(data.meta.guid.ToString(), file)); urls.Add(url); } panel.GetComponent <MultipleChoiceImagePanelSphere>().Init(newInteractionPoint.title, urls, correct); newInteractionPoint.panel = panel; break; } case InteractionType.TabularData: { var panel = Instantiate(tabularDataPanelPrefab, Canvass.sphereUIPanelWrapper.transform); string[] body = newInteractionPoint.body.Split(new[] { '\f' }, 3); int rows = Int32.Parse(body[0]); int columns = Int32.Parse(body[1]); panel.GetComponent <TabularDataPanelSphere>().Init(newInteractionPoint.title, rows, columns, body[2].Split('\f')); newInteractionPoint.panel = panel; break; } case InteractionType.Chapter: { var panel = Instantiate(chapterPanelPrefab, Canvass.sphereUIPanelWrapper.transform); int chapterId = Int32.Parse(newInteractionPoint.body); panel.GetComponent <ChapterPanelSphere>().Init(newInteractionPoint.title, chapterId, this); newInteractionPoint.panel = panel; break; } default: { isValidPoint = false; Debug.LogError("Invalid interactionPoint encountered"); break; } } if (isValidPoint) { if (newInteractionPoint.mandatory) { mandatoryInteractionPoints.Add(newInteractionPoint); } AddInteractionPoint(newInteractionPoint); } else { Destroy(newPoint); } } //NOTE(Simon): For mandatoryInteractionPoints it makes more sense to sort by endTime mandatoryInteractionPoints.Sort((x, y) => x.endTime.CompareTo(y.endTime)); StartCoroutine(UpdatePointPositions()); if (VRDevices.loadedSdk == VRDevices.LoadedSdk.None) { Seekbar.instance.compass.SetActive(true); } else { Seekbar.instanceVR.compass.SetActive(true); } return(true); }
void Update() { bool isVR = VRDevices.loadedSdk != VRDevices.LoadedSdk.None; Seekbar.instance.gameObject.SetActive(!isVR); Seekbar.instanceVR.gameObject.SetActive(isVR); //NOTE(Simon): Sync videoController/videoMesh pos with camera pos. videoController.transform.position = Camera.main.transform.position; var interactionpointRay = new Ray(); //NOTE(Kristof): Deciding on which object the Ray will be based on //NOTE(Simon): Prefers right over left controller { if (trackedControllerLeft != null && trackedControllerLeft.triggerPressed) { interactionpointRay = trackedControllerLeft.CastRay(); } if (trackedControllerRight != null && trackedControllerRight.triggerPressed) { interactionpointRay = trackedControllerRight.CastRay(); } if (VRDevices.hasNoControllers && Input.GetMouseButtonUp(0)) { interactionpointRay = Camera.main.ScreenPointToRay(Input.mousePosition); } } if (playerState == PlayerState.Watching) { RefreshShownInteractionPoints(); if (Input.GetKeyDown(KeyCode.Space) && !isVR) { videoController.TogglePlay(); } if (isVR) { Seekbar.instanceVR.RenderBlips(shownInteractionPoints); } else { Seekbar.instance.RenderBlips(shownInteractionPoints); } //Note(Simon): Interaction with points if (!chapterTransitionActive) { var reversedRay = interactionpointRay.ReverseRay(); //Note(Simon): Create a reversed raycast to find positions on the sphere with Physics.Raycast(reversedRay, out var hit, 100, 1 << LayerMask.NameToLayer("interactionPoints")); //NOTE(Simon): Update visible interactionpoints foreach (var point in shownInteractionPoints) { point.point.SetActive(true); point.point.GetComponent <InteractionPointRenderer>().SetPingActive(!point.isSeen); } foreach (var point in GetInactiveInteractionPoints()) { point.point.SetActive(false); } //NOTE(Simon): Activate hit interactionPoint if (activeInteractionPoint == null && hit.transform != null) { var pointGO = hit.transform.gameObject; InteractionPointPlayer point = null; for (int i = 0; i < interactionPoints.Count; i++) { if (pointGO == interactionPoints[i].point) { point = interactionPoints[i]; break; } } ActivateInteractionPoint(point); } //NOTE(Simon): Disable active interactionPoint if playback was started through seekbar if (videoController.playing && activeInteractionPoint != null) { DeactivateActiveInteractionPoint(); } } //NOTE(Simon): Handle mandatory interactionPoints if (!chapterTransitionActive) { double timeToNextPause = Double.MaxValue; var interactionsInChapter = MandatoryInteractionsForTime(videoController.currentTime); //NOTE(Simon): Find the next unseen mandatory interaction in this chapter for (int i = 0; i < interactionsInChapter.Count; i++) { if (!interactionsInChapter[i].isSeen && interactionsInChapter[i].endTime > videoController.currentTime) { timeToNextPause = interactionsInChapter[i].endTime - videoController.currentTime; break; } } if (timeToNextPause < pauseFadeTime) { videoController.SetPlaybackSpeed(0f); if (!mandatoryPauseActive) { ShowMandatoryInteractionMessage(); mandatoryPauseActive = true; } } else { if (mandatoryPauseActive) { mandatoryPauseActive = false; HideMandatoryInteractionMessage(); } videoController.SetPlaybackSpeed(1f); } } //NOTE(Simon): Handle chapter transitions if (!chapterTransitionActive && !mandatoryPauseActive) { var currentChapter = ChapterManager.Instance.ChapterForTime(videoController.currentTime); if (currentChapter != previousChapter) { videoController.SetPlaybackSpeed(0); chapterTransitionActive = true; chapterTransitionPanel.SetChapter(currentChapter); chapterTransitionPanel.StartTransition(OnChapterTransitionFinish); previousChapter = currentChapter; } } } if (playerState == PlayerState.Opening) { var panel = indexPanel.GetComponent <IndexPanel>(); if (panel.answered) { var projectPath = Path.Combine(Application.persistentDataPath, panel.answerVideoId); if (OpenFile(projectPath)) { Destroy(indexPanel); playerState = PlayerState.Watching; Canvass.modalBackground.SetActive(false); chapterTransitionActive = false; chapterSelector = Instantiate(chapterSelectorPrefab, Canvass.main.transform, false).GetComponent <ChapterSelectorPanel>(); if (isVR) { chapterSelector.transform.SetParent(chapterSelectorHolderVR.transform, false); chapterSelector.transform.localPosition = Vector3.zero; } chapterSelector.Init(videoController); } else { Debug.LogError("Couldn't open savefile"); } } } //NOTE(Simon): Interaction with Hittables { Physics.Raycast(interactionpointRay, out var hit, 100, LayerMask.GetMask("UI", "WorldUI")); var controllerList = new List <Controller> { trackedControllerLeft, trackedControllerRight }; //NOTE(Simon): Reset all hittables foreach (var hittable in hittables) { if (hittable == null) { continue; } //NOTE(Jitse): Check if a hittable is being held down if (!(controllerList[0].triggerDown || controllerList[1].triggerDown)) { hittable.hitting = false; } hittable.hovering = false; } //NOTE(Simon): Set hover state when hovered by controllers foreach (var con in controllerList) { if (con.uiHovering && con.hoveredGo != null) { var hittable = con.hoveredGo.GetComponent <Hittable>(); if (hittable != null) { hittable.hovering = true; } } } //NOTE(Simon): Set hitting and hovering in hittables if (hit.transform != null) { var hittable = hit.transform.GetComponent <Hittable>(); if (hittable != null) { hittable.hitting = true; } } } }
private bool OpenFile(string path) { data = SaveFile.OpenFile(path); openVideo = Path.Combine(Application.persistentDataPath, Path.Combine(data.meta.guid.ToString(), SaveFile.videoFilename)); fileLoader.LoadFile(openVideo); //NOTE(Kristof): Add the 4 interactionpoints used for the mini-tutorial and starting the video, then load the InteractionPoints { startPointGroup.SetActive(true); foreach (var startPoint in startPoints) { interactionPoints.Add(new InteractionPointPlayer { point = startPoint, isStartPoint = true, startTime = -1, endTime = -1, isTouched = false }); var content = startPoint.GetComponentInChildren <Text>(); if (VRDevices.loadedControllerSet > VRDevices.LoadedControllerSet.NoControllers) { content.text = "Aim at the white point below and press the trigger"; } else { content.text = "Align the central circle with the white point below"; } } } data.points.Sort((x, y) => x.startTime != y.startTime ? x.startTime.CompareTo(y.startTime) : x.endTime.CompareTo(y.endTime)); foreach (var point in data.points) { var newPoint = Instantiate(interactionPointPrefab /*, point.position, Quaternion.identity*/); var newInteractionPoint = new InteractionPointPlayer { startTime = point.startTime, endTime = point.endTime, title = point.title, body = point.body, filename = Path.Combine(Application.persistentDataPath, Path.Combine(data.meta.guid.ToString(), point.filename)), type = point.type, point = newPoint, returnRayOrigin = point.returnRayOrigin, returnRayDirection = point.returnRayDirection }; // NOTE(Lander): Add file protocol for images, ignore for the rest. newInteractionPoint.filename = (newInteractionPoint.type == InteractionType.Image ? "file:///" : "") + newInteractionPoint.filename; switch (newInteractionPoint.type) { case InteractionType.Text: { var panel = Instantiate(textPanelPrefab); panel.GetComponent <TextPanel>().Init(newInteractionPoint.title, newInteractionPoint.body); newInteractionPoint.panel = panel; break; } case InteractionType.Image: { var panel = Instantiate(imagePanelPrefab); panel.GetComponent <ImagePanel>().Init(newInteractionPoint.title, newInteractionPoint.filename, false); newInteractionPoint.panel = panel; break; } case InteractionType.Video: { var panel = Instantiate(videoPanelPrefab); panel.GetComponent <VideoPanel>().Init(newInteractionPoint.title, newInteractionPoint.filename, data.meta.guid.ToString(), false); newInteractionPoint.panel = panel; break; } case InteractionType.MultipleChoice: { var panel = Instantiate(multipleChoicePrefab); panel.GetComponent <MultipleChoicePanel>().Init(newInteractionPoint.title, newInteractionPoint.body.Split('\f')); newInteractionPoint.panel = panel; break; } default: throw new ArgumentOutOfRangeException(); } AddInteractionPoint(newInteractionPoint); } StartCoroutine(UpdatePointPositions()); return(true); }
void Update() { //NOTE(Kristof): VR specific behaviour { if (XRSettings.enabled) { videoController.transform.position = Camera.main.transform.position; Canvass.seekbar.gameObject.SetActive(true); //NOTE(Kristof): Rotating the seekbar { //NOTE(Kristof): Seekbar rotation is the same as the seekbar's angle on the circle var seekbarAngle = Vector2.SignedAngle(new Vector2(Canvass.seekbar.transform.position.x, Canvass.seekbar.transform.position.z), Vector2.up); var fov = Camera.main.fieldOfView; //NOTE(Kristof): Camera rotation tells you to which angle on the circle the camera is looking towards var cameraAngle = Camera.main.transform.eulerAngles.y; //NOTE(Kristof): Calculate the absolute degree angle from the camera to the seekbar var distanceLeft = Mathf.Abs((cameraAngle - seekbarAngle + 360) % 360); var distanceRight = Mathf.Abs((cameraAngle - seekbarAngle - 360) % 360); var angle = Mathf.Min(distanceLeft, distanceRight); if (isSeekbarOutOfView) { if (angle < 2.5f) { isSeekbarOutOfView = false; } } else { if (angle > fov) { isSeekbarOutOfView = true; } } if (isSeekbarOutOfView) { float newAngle = Mathf.LerpAngle(seekbarAngle, cameraAngle, 0.025f); //NOTE(Kristof): Angle needs to be reversed, in Unity postive angles go clockwise while they go counterclockwise in the unit circle (cos and sin) //NOTE(Kristof): We also need to add an offset of 90 degrees because in Unity 0 degrees is in front of you, in the unit circle it is (1,0) on the axis float radianAngle = (-newAngle + 90) * Mathf.PI / 180; float x = 1.8f * Mathf.Cos(radianAngle); float y = Camera.main.transform.position.y - 2f; float z = 1.8f * Mathf.Sin(radianAngle); Canvass.seekbar.transform.position = new Vector3(x, y, z); Canvass.seekbar.transform.eulerAngles = new Vector3(30, newAngle, 0); } } } else { Canvass.seekbar.gameObject.SetActive(false); } } //NOTE(Simon): Zoom when not using HMD if (!XRSettings.enabled) { if (Input.mouseScrollDelta.y != 0) { Camera.main.fieldOfView = Mathf.Clamp(Camera.main.fieldOfView - Input.mouseScrollDelta.y * 5, 20, 120); } } Ray interactionpointRay = new Ray(); //NOTE(Kristof): Deciding on which object the Ray will be based on //TODO(Simon): Prefers right over left controller { if (trackedControllerLeft != null && trackedControllerLeft.triggerPressed) { interactionpointRay = trackedControllerLeft.CastRay(); } if (trackedControllerRight != null && trackedControllerRight.triggerPressed) { interactionpointRay = trackedControllerRight.CastRay(); } if (VRDevices.loadedControllerSet == VRDevices.LoadedControllerSet.NoControllers && Input.GetMouseButtonUp(0)) { interactionpointRay = Camera.main.ScreenPointToRay(Input.mousePosition); } } if (playerState == PlayerState.Watching) { if (Input.GetKeyDown(KeyCode.Space) && VRDevices.loadedSdk == VRDevices.LoadedSdk.None) { videoController.TogglePlay(); } Seekbar.instance.RenderBlips(interactionPoints, trackedControllerLeft, trackedControllerRight); //Note(Simon): Interaction with points { var reversedRay = interactionpointRay.ReverseRay(); //Note(Simon): Create a reversed raycast to find positions on the sphere with Physics.Raycast(reversedRay, out var hit, 100, 1 << LayerMask.NameToLayer("interactionPoints")); //NOTE(Simon): Update visible interactionpoints for (int i = 0; i < interactionPoints.Count; i++) { bool pointActive = videoController.currentTime >= interactionPoints[i].startTime && videoController.currentTime <= interactionPoints[i].endTime; interactionPoints[i].point.SetActive(pointActive); interactionPoints[i].point.GetComponentInChildren <MeshRenderer>(includeInactive: true).gameObject.SetActive(!interactionPoints[i].isSeen); } //NOTE(Simon): Interact with inactive interactionpoints if (activeInteractionPoint == null && hit.transform != null) { var pointGO = hit.transform.gameObject; InteractionPointPlayer point = null; for (int i = 0; i < interactionPoints.Count; i++) { if (pointGO == interactionPoints[i].point) { point = interactionPoints[i]; break; } } ActivateInteractionPoint(point); } //NOTE(Simon): Disable active interactionPoint if playback was started through seekbar if (videoController.playing && activeInteractionPoint != null) { DeactivateActiveInteractionPoint(); } } //NOTE(Simon): Handle mandatory interactionPoints { double timeToNextPause = Double.MaxValue; var interactionsInChapter = MandatoryInteractionsForTime(videoController.currentTime); //NOTE(Simon): Find the next unseen mandatory interaction in this chapter for (int i = 0; i < interactionsInChapter.Count; i++) { if (!interactionsInChapter[i].isSeen && interactionsInChapter[i].endTime > videoController.currentTime) { timeToNextPause = interactionsInChapter[i].endTime - videoController.currentTime; break; } } //NOTE(Simon): Set the playbackspeed. Speed will get lower the closer to the next pause we are. if (timeToNextPause < mandatoryPauseFadeTime) { float speed = (float)(timeToNextPause / mandatoryPauseFadeTime); if (timeToNextPause < .05f) { speed = 0; } videoController.SetPlaybackSpeed(speed); if (!mandatoryPauseActive) { ShowMandatoryInteractionMessage(); mandatoryPauseActive = true; } } else { if (mandatoryPauseActive) { mandatoryPauseActive = false; HideMandatoryInteractionMessage(); } videoController.SetPlaybackSpeed(1f); } } } if (playerState == PlayerState.Opening) { var panel = indexPanel.GetComponent <IndexPanel>(); if (panel.answered) { var projectPath = Path.Combine(Application.persistentDataPath, panel.answerVideoId); if (OpenFile(projectPath)) { Destroy(indexPanel); playerState = PlayerState.Watching; Canvass.modalBackground.SetActive(false); SetCanvasesActive(true); chapterSelector = Instantiate(chapterSelectorPrefab, Canvass.main.transform, false).GetComponent <ChapterSelectorPanel>(); if (VRDevices.loadedSdk > VRDevices.LoadedSdk.None) { StartCoroutine(FadevideoCanvasOut(videoCanvas)); EventManager.OnSpace(); videoPositions.Clear(); Seekbar.ReattachCompass(); } } else { Debug.LogError("Couldn't open savefile"); } } } //NOTE(Simon): Interaction with Hittables { Physics.Raycast(interactionpointRay, out var hit, 100, LayerMask.GetMask("UI", "WorldUI")); var controllerList = new List <Controller> { trackedControllerLeft, trackedControllerRight }; //NOTE(Simon): Reset all hittables foreach (var hittable in hittables) { if (hittable == null) { continue; } //NOTE(Jitse): Check if a hittable is being held down if (!(controllerList[0].triggerDown || controllerList[1].triggerDown)) { hittable.hitting = false; } hittable.hovering = false; } //NOTE(Simon): Set hover state when hovered by controllers foreach (var con in controllerList) { if (con.uiHovering && con.hoveredGo != null) { var hittable = con.hoveredGo.GetComponent <Hittable>(); if (hittable != null) { hittable.hovering = true; } } } //NOTE(Simon): Set hitting and hovering in hittables if (hit.transform != null) { hit.transform.GetComponent <Hittable>().hitting = true; } } }
private void AddInteractionPoint(InteractionPointPlayer point) { interactionPoints.Add(point); }