我正在制作视频播放示例的统一版本。我在inspecter中添加了Video Playback Event Handler脚本并检查了M全屏模式。默认情况下,方向为横向右侧。我试图在全屏播放时实现自动旋转,这样当我转动设备时,它会改变方向等等。我已经尝试过关于这个问题的建议,例如修改播放器设置等,但它没有用。
我的第二个问题是导航栏中的后退按钮。当我的视频正在播放时,我必须按两次后退按钮才能返回相机。我想在按下后退按钮时立即终止全屏播放。怎么做。
我尝试过修改以下代码(VideoPlaybackUIEventHandler.cs):
/*==============================================================================
* Copyright (c) 2012-2014 Qualcomm Connected Experiences, Inc. All Rights Reserved.
* ==============================================================================*/
using UnityEngine;
using System.Collections;
using Vuforia;
/// <summary>
/// UI Event Handler class that handles events generated by user-tap actions
/// over the UI Options Menu
/// </summary>
public class VideoPlaybackUIEventHandler : ISampleAppUIEventHandler
{
#region PUBLIC_MEMBER_VARIABLES
public override event System.Action CloseView;
public override event System.Action GoToAboutPage;
public bool mFullScreenMode;
#endregion PUBLIC_MEMBER_VARIABLES
#region PRIVATE_MEMBER_VARIABLES
private static bool sExtendedTrackingIsEnabled;
private VideoPlaybackUIView mView;
private bool mCameraFacingFront;
#endregion PRIVATE_MEMBER_VARIABLES
#region PUBLIC_MEMBER_PROPERTIES
public VideoPlaybackUIView View
{
get
{
if (mView == null)
{
mView = new VideoPlaybackUIView();
mView.LoadView();
}
return mView;
}
}
/// <summary>
/// Currently, there is no mechanism to query the SDK to know whether or not extended tracking is enabled/disabled.
/// Therefore, it needs to be handled at the app layer.
/// </value>
public static bool ExtendedTrackingIsEnabled
{
get
{
return sExtendedTrackingIsEnabled;
}
}
#endregion PUBLIC_MEMBER_PROPERTIES
#region PUBLIC_METHODS
public override void UpdateView(bool tf)
{
this.View.UpdateUI(tf);
}
public override void Bind()
{
this.View.mExtendedTracking.TappedOn += OnTappedToTurnOnTraking;
this.View.mCameraFlashSettings.TappedOn += OnTappedToTurnOnFlash;
this.View.mAutoFocusSetting.TappedOn += OnTappedToTurnOnAutoFocus;
this.View.mCameraFacing.TappedOnOption += OnTappedToTurnCameraFacing;
this.View.mCloseButton.TappedOn += OnTappedOnCloseButton;
this.View.mAboutLabel.TappedOn += OnTappedOnAboutButton;
this.View.mPlayFullscreeSettings.TappedOn += OnTappedOnFullscreenButton;
// register qcar started callback
QCARAbstractBehaviour qcarBehaviour = (QCARAbstractBehaviour)FindObjectOfType(typeof(QCARAbstractBehaviour));
if (qcarBehaviour)
{
qcarBehaviour.RegisterQCARStartedCallback(EnableContinuousAutoFocus);
qcarBehaviour.RegisterOnPauseCallback(OnPause);
}
}
public override void UnBind()
{
this.View.mExtendedTracking.TappedOn -= OnTappedToTurnOnTraking;
this.View.mCameraFlashSettings.TappedOn -= OnTappedToTurnOnFlash;
this.View.mAutoFocusSetting.TappedOn -= OnTappedToTurnOnAutoFocus;
this.View.mCameraFacing.TappedOnOption -= OnTappedToTurnCameraFacing;
this.View.mCloseButton.TappedOn -= OnTappedOnCloseButton;
this.View.mAboutLabel.TappedOn -= OnTappedOnAboutButton;
this.View.mPlayFullscreeSettings.TappedOn -= OnTappedOnFullscreenButton;
// unregister qcar started callback
QCARAbstractBehaviour qcarBehaviour = (QCARAbstractBehaviour)FindObjectOfType(typeof(QCARAbstractBehaviour));
if (qcarBehaviour)
{
qcarBehaviour.UnregisterQCARStartedCallback(EnableContinuousAutoFocus);
qcarBehaviour.UnregisterOnPauseCallback(OnPause);
}
this.View.UnLoadView();
}
//SingleTap Gestures are captured by AppManager and calls this method for TapToFocus
public override void TriggerAutoFocus()
{
StartCoroutine(TriggerAutoFocusAndEnableContinuousFocusIfSet());
}
#endregion PUBLIC_METHODS
#region PRIVATE_METHODS
/// <summary>
/// Activating trigger autofocus mode unsets continuous focus mode (if was previously enabled from the UI Options Menu)
/// So, we wait for a second and turn continuous focus back on (if options menu shows as enabled)
/// </returns>
private IEnumerator TriggerAutoFocusAndEnableContinuousFocusIfSet()
{
//triggers a single autofocus operation
if (CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_TRIGGERAUTO))
{
this.View.FocusMode = CameraDevice.FocusMode.FOCUS_MODE_TRIGGERAUTO;
}
yield return new WaitForSeconds(1.0f);
//continuous focus mode is turned back on if it was previously enabled from the options menu
if (this.View.mAutoFocusSetting.IsEnabled)
{
if (CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO))
{
this.View.FocusMode = CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO;
}
}
Debug.Log(this.View.FocusMode);
}
private void OnPause(bool pause)
{
if (!pause && this.View.mAutoFocusSetting.IsEnabled)
{
// set to continous autofocus
CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
}
//On hitting the home button, the app tends to turn off the flash
//So, setting the UI to reflect that
this.View.mCameraFlashSettings.Enable(pause);
}
private void OnTappedOnAboutButton(bool tf)
{
if (this.GoToAboutPage != null)
{
this.GoToAboutPage();
}
}
//We want autofocus to be enabled when the app starts
private void EnableContinuousAutoFocus()
{
if (CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO))
{
this.View.FocusMode = CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO;
this.View.mAutoFocusSetting.Enable(true);
}
}
private void OnTappedToTurnOnTraking(bool tf)
{
if (!ExtendedTracking(tf))
{
this.View.mExtendedTracking.Enable(false);
VideoPlaybackUIEventHandler.sExtendedTrackingIsEnabled = false;
}
else
{
this.View.mExtendedTracking.Enable(tf);
VideoPlaybackUIEventHandler.sExtendedTrackingIsEnabled = tf;
}
OnTappedToClose();
}
private void OnTappedToTurnOnFlash(bool tf)
{
if (tf)
{
if (!CameraDevice.Instance.SetFlashTorchMode(true) || mCameraFacingFront)
{
this.View.mCameraFlashSettings.Enable(false);
}
}
else
{
CameraDevice.Instance.SetFlashTorchMode(false);
}
OnTappedToClose();
}
/// <summary>
/// If the video is already playing on texture, enabling it will bring the video to full-screen
/// otherwise, the video will play on fullscreen the next time user taps on the texture.
/// </summary>
/// <param name="tf"></param>
private void OnTappedOnFullscreenButton(bool tf)
{
mFullScreenMode = tf;
if (tf)
{
VideoPlaybackBehaviour video = PickVideo();
if (video != null)
{
if (video.VideoPlayer.IsPlayableFullscreen())
{
//On Android, we use Unity's built in player, so Unity application pauses before going to fullscreen.
//So we have to handle the orientation from within Unity.
#if UNITY_ANDROID
Screen.orientation = ScreenOrientation.Portrait;
#endif
// Pause the video if it is currently playing
video.VideoPlayer.Pause();
// Seek the video to the beginning();
video.VideoPlayer.SeekTo(0.0f);
// Display the busy icon
video.ShowBusyIcon();
// Play the video full screen
StartCoroutine ( PlayVideo.PlayFullscreenVideoAtEndOfFrame(video) );
//Flash turns off automatically on fullscreen videoplayback mode, so we need to update the UI accordingly
this.View.mCameraFlashSettings.Enable(false);
}
}
}
OnTappedToClose();
}
private VideoPlaybackBehaviour PickVideo()
{
VideoPlaybackBehaviour[] behaviours = GameObject.FindObjectsOfType(typeof(VideoPlaybackBehaviour)) as VideoPlaybackBehaviour[];
VideoPlaybackBehaviour video = null;
foreach (VideoPlaybackBehaviour bhvr in behaviours)
{
if (bhvr.CurrentState == VideoPlayerHelper.MediaState.PLAYING)
{
video = bhvr;
}
}
return video;
}
private void OnTappedToTurnOnAutoFocus(bool tf)
{
if (tf)
{
if (CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO))
{
this.View.FocusMode = CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO;
}
else
{
this.View.mAutoFocusSetting.Enable(false);
}
}
else
{
if (CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_NORMAL))
{
this.View.FocusMode = CameraDevice.FocusMode.FOCUS_MODE_NORMAL;
}
}
OnTappedToClose();
}
private void OnTappedToTurnCameraFacing(int val)
{
if (val == 0)
{
//internally, flash is always turned off everytime it tries to switch to front camera
//so updating the UI options to reflect that.
this.View.mCameraFlashSettings.Enable(false);
if (ChangeCameraDirection(CameraDevice.CameraDirection.CAMERA_FRONT))
{
mCameraFacingFront = true;
}
else
{
ChangeCameraDirection(CameraDevice.CameraDirection.CAMERA_BACK);
mCameraFacingFront = false;
this.View.mCameraFacing.EnableIndex(1);
}
}
else
{
ChangeCameraDirection(CameraDevice.CameraDirection.CAMERA_BACK);
mCameraFacingFront = false;
}
OnTappedToClose();
}
private bool stopRunningObjectTracker()
{
bool needsObjectTrackerRestart = false;
ObjectTracker objectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
if (objectTracker != null)
{
if (objectTracker.IsActive)
{
objectTracker.Stop();
needsObjectTrackerRestart = true;
}
}
return needsObjectTrackerRestart;
}
private bool restartRunningObjectTracker()
{
bool hasObjectTrackerRestarted = false;
ObjectTracker objectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
if (objectTracker != null)
{
if (!objectTracker.IsActive)
{
hasObjectTrackerRestarted = objectTracker.Start();
}
}
return hasObjectTrackerRestarted;
}
private void ResetCameraFacingToBack()
{
bool needsObjectTrackerRestart = stopRunningObjectTracker();
CameraDevice.Instance.Stop();
CameraDevice.Instance.Init(CameraDevice.CameraDirection.CAMERA_BACK);
CameraDevice.Instance.Start();
mCameraFacingFront = false;
if (needsObjectTrackerRestart)
restartRunningObjectTracker();
}
private bool ChangeCameraDirection(CameraDevice.CameraDirection direction)
{
bool directionSupported = false;
bool needsObjectTrackerRestart = stopRunningObjectTracker();
CameraDevice.Instance.Stop();
CameraDevice.Instance.Deinit();
if (CameraDevice.Instance.Init(direction))
{
directionSupported = true;
}
CameraDevice.Instance.Start();
if (needsObjectTrackerRestart)
restartRunningObjectTracker();
return directionSupported;
}
private void OnTappedToClose()
{
if (this.CloseView != null)
{
this.CloseView();
}
}
private void OnTappedOnCloseButton()
{
OnTappedToClose();
}
/// <summary>
/// This method turns extended tracking on or off for all currently available targets.
/// Extended tracking allows to track targets when they are not in view.
/// Returns true of extended tracking is supported; false otherwise
/// </summary>
private bool ExtendedTracking(bool tf)
{
// the StateManager gives access to all available TrackableBehavours
StateManager stateManager = TrackerManager.Instance.GetStateManager();
// We iterate over all TrackableBehaviours to start or stop extended tracking for the targets they represent.
bool extendedTrackingStateChanged = true;
foreach (var behaviour in stateManager.GetTrackableBehaviours())
{
var imageBehaviour = behaviour as ImageTargetBehaviour;
if (imageBehaviour != null)
{
if (tf)
{
//only if extended tracking is supported
if (!imageBehaviour.ImageTarget.StartExtendedTracking())
{
extendedTrackingStateChanged = false;
}
}
else
{
if (!imageBehaviour.ImageTarget.StopExtendedTracking())
{
extendedTrackingStateChanged = false;
}
}
}
}
if (!extendedTrackingStateChanged)
{
Debug.LogWarning("Extended Tracking Failed!");
}
return extendedTrackingStateChanged;
}
#endregion PRIVATE_METHODS
}
以及此代码(PlayVideo.cs):
/*==============================================================================
* Copyright (c) 2012-2014 Qualcomm Connected Experiences, Inc. All Rights Reserved.
* ==============================================================================*/
using UnityEngine;
using System.Collections;
using Vuforia;
/// <summary>
/// Demonstrates how to play the video on texture and full-screen mode.
/// Single tapping on texture will play the video on texture (if the 'Play FullScreen' Mode in the UIMenu is turned off)
/// or play full screen (if the option is enabled in the UIMenu)
/// At any time during the video playback, it can be brought to full-screen by enabling the options from the UIMenu.
/// </summary>
public class PlayVideo : MonoBehaviour
{
private bool mVideoIsPlaying;
private VideoPlaybackBehaviour currentVideo;
#region UNITY_MONOBEHAVIOUR_METHODS
void Start()
{
InputController.SingleTapped += HandleSingleTap;
InputController.DoubleTapped += HandleDoubleTap;
}
void OnApplicationPause(bool tf)
{
//When the video finishes playing on fullscreen mode, Unity application unpauses and that's when we need to switch to potrait
//in order to display the UI menu options properly
#if UNITY_ANDROID
if(!tf) {
Screen.orientation = ScreenOrientation.Portrait;
}
#endif
}
#endregion UNITY_MONOBEHAVIOUR_METHODS
#region PRIVATE_METHODS
/// <summary>
/// Just in case the device is in any other mode at the time the user double taps to bring up the UI menu, we force it to go to potrait
/// because the UI menu supports only potrait for now.
/// </summary>
private void HandleDoubleTap()
{
if (Screen.orientation != ScreenOrientation.Portrait)
{
Screen.orientation = ScreenOrientation.Portrait;
}
}
/// <summary>
/// Handle single tap event
/// </summary>
private void HandleSingleTap()
{
if (QCARRuntimeUtilities.IsPlayMode())
{
if (PickVideo(Input.mousePosition) != null)
Debug.LogWarning("Playing videos is currently not supported in Play Mode.");
}
// Find out which video was tapped, if any
currentVideo = PickVideo(Input.mousePosition);
if (currentVideo != null)
{
if (IsFullScreenModeEnabled())
{
if (currentVideo.VideoPlayer.IsPlayableFullscreen())
{
//On Android, we use Unity's built in player, so Unity application pauses before going to fullscreen.
//So we have to handle the orientation from within Unity.
#if UNITY_ANDROID
Screen.autorotateToPortrait = true;
Screen.autorotateToPortraitUpsideDown = true;
Screen.orientation = ScreenOrientation.AutoRotation;
#endif
// Pause the video if it is currently playing
currentVideo.VideoPlayer.Pause();
// Seek the video to the beginning();
currentVideo.VideoPlayer.SeekTo(0.0f);
// Display the busy icon
currentVideo.ShowBusyIcon();
// Play the video full screen
StartCoroutine( PlayFullscreenVideoAtEndOfFrame(currentVideo) );
UpdateFlashSettingsInUIView();
}
}
else
{
if (currentVideo.VideoPlayer.IsPlayableOnTexture())
{
// This video is playable on a texture, toggle playing/paused
VideoPlayerHelper.MediaState state = currentVideo.VideoPlayer.GetStatus();
if (state == VideoPlayerHelper.MediaState.PAUSED ||
state == VideoPlayerHelper.MediaState.READY ||
state == VideoPlayerHelper.MediaState.STOPPED)
{
// Pause other videos before playing this one
PauseOtherVideos(currentVideo);
// Play this video on texture where it left off
currentVideo.VideoPlayer.Play(false, currentVideo.VideoPlayer.GetCurrentPosition());
}
else if (state == VideoPlayerHelper.MediaState.REACHED_END)
{
// Pause other videos before playing this one
PauseOtherVideos(currentVideo);
// Play this video from the beginning
currentVideo.VideoPlayer.Play(false, 0);
}
else if (state == VideoPlayerHelper.MediaState.PLAYING)
{
// Video is already playing, pause it
currentVideo.VideoPlayer.Pause();
}
}
else
{
// Display the busy icon
currentVideo.ShowBusyIcon();
// This video cannot be played on a texture, play it full screen
StartCoroutine( PlayFullscreenVideoAtEndOfFrame(currentVideo) );
}
}
}
}
public static IEnumerator PlayFullscreenVideoAtEndOfFrame(VideoPlaybackBehaviour video)
{
Screen.orientation = ScreenOrientation.AutoRotation;
Screen.autorotateToPortrait = true;
Screen.autorotateToPortraitUpsideDown = true;
Screen.autorotateToLandscapeLeft = true;
Screen.autorotateToLandscapeRight = true;
yield return new WaitForEndOfFrame ();
// we wait a bit to allow the ScreenOrientation.AutoRotation to become effective
yield return new WaitForSeconds (0.3f);
video.VideoPlayer.Play(true, 0);
}
//Flash turns off automatically on fullscreen videoplayback mode, so we need to update the UI accordingly
private void UpdateFlashSettingsInUIView()
{
VideoPlaybackUIEventHandler handler = GameObject.FindObjectOfType(typeof(VideoPlaybackUIEventHandler)) as VideoPlaybackUIEventHandler;
if (handler != null)
{
handler.View.mCameraFlashSettings.Enable(false);
}
}
/// <summary>
/// Checks to see if the 'Play FullScreen' Mode is enabled/disabled in the UI Menu
/// </summary>
/// <returns></returns>
private bool IsFullScreenModeEnabled()
{
VideoPlaybackUIEventHandler handler = FindObjectOfType(typeof(VideoPlaybackUIEventHandler)) as VideoPlaybackUIEventHandler;
if (handler != null)
{
return handler.mFullScreenMode;
}
return false;
}
/// <summary>
/// Find the video object under the screen point
/// </summary>
private VideoPlaybackBehaviour PickVideo(Vector3 screenPoint)
{
VideoPlaybackBehaviour[] videos = (VideoPlaybackBehaviour[])
FindObjectsOfType(typeof(VideoPlaybackBehaviour));
GameObject go = QCARManager.Instance.ARCameraTransform.gameObject;
Camera[] cam = go.GetComponentsInChildren<Camera> ();
Ray ray = cam[0].ScreenPointToRay(screenPoint);
RaycastHit hit = new RaycastHit();
foreach (VideoPlaybackBehaviour video in videos)
{
if (video.GetComponent<Collider>().Raycast(ray, out hit, 10000))
{
return video;
}
}
return null;
}
/// <summary>
/// Pause all videos except this one
/// </summary>
private void PauseOtherVideos(VideoPlaybackBehaviour currentVideo)
{
VideoPlaybackBehaviour[] videos = (VideoPlaybackBehaviour[])
FindObjectsOfType(typeof(VideoPlaybackBehaviour));
foreach (VideoPlaybackBehaviour video in videos)
{
if (video != currentVideo)
{
if (video.CurrentState == VideoPlayerHelper.MediaState.PLAYING)
{
video.VideoPlayer.Pause();
}
}
}
}
#endregion // PRIVATE_METHODS
}
在这两个代码中,您在HandleSingleTap方法和OnTappedOnFullScreen方法中看到#IF UNITY_ANDROID的部分,我尝试在Unity Scripting中使用Screen.orientation。具体来说,我尝试了以下方法来实现自动旋转,但它没有帮助:
Screen.autorotateToPortrait = true;
Screen.autorotateToPortraitUpsideDown = true;
Screen.autorotateToLandscapeLeft = true;
Screen.autorotateToLandscapeRight = true;
Screen.orientation = ScreenOrientation.AutoRotation;
当我只做一个方向时,就像他们在代码中所做的那样,例如:Screen.orientation = ScreenOrientation.LandscapeRight,方向已更改。但这不是我想要的。
任何帮助/提示都会被指定!
谢谢。
答案 0 :(得分:0)
为了解决您的第一个问题,我建议您为横向和纵向方向分别设置两个方向布局。因此,完成后,您可以使用脚本来检测设备是横向还是纵向,并相应地SetActive
该布局。
以下是示例代码的外观:
using UnityEngine;
using System.Collections;
public class MMOrient : MonoBehaviour {
public GameObject P;
public GameObject L;
// Use this for initialization
void Start () {
if (Input.deviceOrientation == DeviceOrientation.LandscapeLeft ||
Input.deviceOrientation == DeviceOrientation.LandscapeRight ) {
L.SetActive(true);
P.SetActive(false);
}
if (Input.deviceOrientation == DeviceOrientation.Portrait ||
Input.deviceOrientation == DeviceOrientation.PortraitUpsideDown ) {
P.SetActive(true);
L.SetActive(false);
}
}
// Update is called once per frame
void Update () {
if (Input.deviceOrientation == DeviceOrientation.LandscapeLeft ||
Input.deviceOrientation == DeviceOrientation.LandscapeRight ) {
L.SetActive(true);
P.SetActive(false);
}
if (Input.deviceOrientation == DeviceOrientation.Portrait ||
Input.deviceOrientation == DeviceOrientation.PortraitUpsideDown ) {
P.SetActive(true);
L.SetActive(false);
}
}
}
要在场景之间平滑,您需要确保未分配下一个脚本的对象,请使用:
void Awake() {
DontDestroyOnLoad(this.gameObject);
}
然后这个GameObject可以继续使用这个脚本,其中包含两种方法:
public class OrientationManger : MonoBehaviour
{
private OrientationType currentOrientation; ///////////////Method 1 (ENUM)
int orientationType = 1; ///////////////Method 2 (OR use Integer 1,2)
//Makes sure there is only once instance running
void Awake ()
{
// singleton
if (FindObjectsOfType (typeof(OrientationManger)).Length > 1) {
Debug.Log ("OrientationManger already exist");
DestroyImmediate (gameObject); //Destroy this gameobject because it already exist
} else {
DontDestroyOnLoad (this.gameObject); //Wont destroy when loading another level/scene
}
}
///////////////Method 1 Set (ENUM)
public void setOrientation (OrientationType orientType)
{
currentOrientation = orientType;
}
///////////////Method 1 Get (ENUM)
public OrientationType getOrientation ()
{
return currentOrientation;
}
///////////////Method 2 Set (OR use Integer 1,2)
public void setOrientation2 (int orientType)
{
if (orientType == 1) {
orientationType = orientType;
} else if (orientType == 2) {
orientationType = orientType;
}
}
///////////////Method 2 Get (OR use Integer 1,2)
public int getOrientation2 ()
{
if (orientationType == 1 || orientationType == 2) {
return orientationType;
} else {
return 0;
}
}
}
///////////////Method 1 (ENUM)
public enum OrientationType
{
UKNOWN,
Portrait,
Landscape
}
;
选择任何一个,你应该是金。
然后关于您的多重点击问题: -
检查附近是否有其他GUI或重叠。 In my question,我发现两个P
和L
GameObjects彼此重叠Raycasters
/ Colliders
,因此Unity似乎在闪烁之间两个。
答案 1 :(得分:0)