Unity - 如何旋转和全屏视频,使用RawImage上的VideoPlayer API播放

问题描述 投票:9回答:1

由于MovieTexture在Unity 5.6.0b1之后已经被弃用,我正在使用VideoPlayer Api在RawImage for Android上播放视频,参考here。我正在尝试添加一个切换按钮,从RawImage Texture上播放的视频的初始大小切换到全屏,并在视频停止后返回原始状态。

我有一个完美播放的视频,到目前为止,我可以使用此代码将视频的变换更改为全屏。

void Update () {
    if (Input.GetButtonDown("Jump"))
    {
        image.rectTransform.offsetMax = Vector2.Lerp(Vector2.up, Vector2.down, 100);
        image.rectTransform.offsetMin = Vector2.Lerp(Vector2.left, Vector2.right, 100);
        image.rectTransform.rotation = Quaternion.AngleAxis(Mathf.Lerp(0f, 90f, 50), Vector3.forward);
    }
}

if块内的前两行能够全屏显示播放视频的RawImage,如图2的第2部分所示。这是Vector2的文档。

对于第三行旋转代码,我从this discussion on Unity Forum获取了参考,但我仍然没有得到我想要的效果,结果在第3节。我想旋转RawImage的内容,但我正在旋转RawImage本身,它可能是因为引用没有描述旋转内容。

任何人都可以帮我找出如何解决它。如果它帮助我使用的Unity版本是Unity 5.6.0b11 Beta,并且如果要在您的设备上测试,请下载示例项目。 Unity Video Player.zip 18.33MB你也可以关注这个Video Tutorial on new VideoPlayer from YouTube

Full Screen and Rotate Video Played using Unity VideoPlayer on RawImage

更新1

到目前为止,我唯一得到的是,我只尝试使用旋转代码并通过删除if块中的前两行,我能够旋转视频,但是当我尝试拉伸RawImage时,它是拉伸到外面的屏幕。 See here for the image

更新2

经过大量的研究,打击和试验。我终于使用此代码完成了RawImage的全屏和旋转,以在Unity上播放全屏视频。

image.rectTransform.offsetMin = new Vector2(-560, 560);            
image.rectTransform.offsetMax = new Vector2(560, -560);

但是,如您所见,我向矢量提供的值是静态数字,并不保证可以在多种屏幕尺寸上工作。好吧,当RawImage与RawImage一起旋转时,旋转RawImage会让人感到困惑,但是一些组件没有被改变或旋转,并且当改变偏移值时,RawImage在引用旧的Rect时改变了它的值(我真的不知道是什么正在这里发生)。 enter image description here

旋转RawImage旋转连接到它的轴。在上图中,您可以看到RawImage旋转,然后旋转轴。但即使图像旋转,您也可以看到有一些参考线。

enter image description here

我是怎么解决这个问题的? [失败]

我尝试以新的方式解决问题,我创建了一个适合画布的新RawImage,并且已经旋转并附加到脚本StreamVideo.cs作为之前的RawImage。最初它处于非活动模式,并在用户命令全屏时切换为活动状态。当它进入全屏时,视频以新的RawImage播放。

public void playFullScreen() {
    isFullScreen = true;
    imageFullScreen.gameObject.SetActive(true);
    imageFullScreen.texture = videoPlayer.texture;
    image.gameObject.SetActive(false);
}

但是,有了这个问题,我在新的RawImage上切换到全屏时从同一帧开始播放视频的问题,以及切换回小屏幕时的同样问题。

摘要:

看看更新2,我能够播放,暂停,全屏和旋转视频,但是,使用offsetMaxoffsetMin上的简单数值。我试图了解是否有办法通过脚本策划这些值以适应多种屏幕尺寸。我知道这可能听起来很简单,但棘手的部分是,对于我需要的屏幕,我提供的值的引用就像这样。注意图中的虚线矩形。 enter image description here

c# android unity3d video
1个回答
3
投票

我想做同样的事情,但遇到了同样的问题。我确实认为这是一个错误,但确实设法提出了解决方案。

这可以通过锚点,枢轴点和屏幕大小(Screen.width,Screen.height)或Canvas的大小来完成。在我的情况下,我将使用Canvas的大小。

当您按住Alt键并单击RawImage RectTransform的拉伸图标时,RawImage将全屏显示。您可以通过代码执行相同的操作,使用编辑器中更改的值,如下所示:

rectTrfm.anchoredPosition3D = new Vector3(0, 0, 0);
//Stretch the Image so that the whole screen is totally covered
rectTrfm.anchorMin = new Vector2(0, 0);
rectTrfm.anchorMax = new Vector2(1, 1);
rectTrfm.pivot = new Vector2(0.5f, 0.5f);
rectTrfm.offsetMin = Vector2.zero;
rectTrfm.offsetMax = Vector2.zero;

它的工作原理,应该给你全屏RawImage。问题是,当旋转位于0时,它可以工作,只有180或者当旋转颠倒时也可以知道。当旋转是-9090270时,它不起作用。如果RawImage向右或向左旋转,这些角度通常是你得到的。我怀疑这是一个错误。

要解决这个问题,你可以从Canvas RectTransform的大小计算纵横比,然后用它来创建anchorMinanchorMax。其余的代码应保持相同。

RectTransform canvasRectTrfm = rawImage.canvas.GetComponent<RectTransform>();
float aspRatio = canvasRectTrfm.rect.size.x / canvasRectTrfm.rect.size.y;
float halfAspRatio = aspRatio / 2.0f;
float halfAspRatioInvert = (1.0f / aspRatio) / 2.0f;

rectTrfm.anchorMin = new Vector2(0.5f - halfAspRatioInvert, 0.5f - halfAspRatio);
rectTrfm.anchorMax = new Vector2(0.5f + halfAspRatioInvert, 0.5f + halfAspRatio);
rectTrfm.anchoredPosition3D = Vector3.zero;
rectTrfm.pivot = new Vector2(0.5f, 0.5f);
rectTrfm.offsetMin = Vector2.zero;
rectTrfm.offsetMax = Vector2.zero;

这适用于-9090270角度,但不适用于0180。这不是问题,因为我们的第一个代码与0180角度一起使用。我们可以在运行时检测角度,并根据RawImage的当前角度执行代码。

您可以在下面的代码中看到将两个代码组合为StretchImageFullScreen的完整函数。下面是一个示例代码,用于在完成Space键时在全屏和RawImage的原始大小之间切换视频。要退出切换模式,请按R键。 RawImageInfo结构用于在切换到全屏之前复制RectTransform信息,以便在使用Space键再次切换或按下R键时可以恢复默认位置/旋转。

将以下代码添加到other答案的代码中,您应该能够在全屏视频和默认的RawImage大小之间切换,并且应该能够使用StretchImageFullScreen函数中的第二个参数旋转它。

//Used to store RectTransform information so that original RawImage settings can be restored
public struct RawImageInfo
{
    public Vector3 anchorPos;
    public Vector2 widthAndHeight;
    public Vector2 anchorMin;
    public Vector2 anchorMax;
    public Vector2 pivot;

    public Vector2 offsetMin;
    public Vector2 offsetMax;

    public Quaternion rot;
    public Vector3 scale;
}

RawImageInfo originalImgInfo;
bool fullSclreen = false;

void Awake()
{
    //Get the default RawImage RectTransform settings
    originalImgInfo = GetImageSettings(image);
}

void Update()
{
    //Toggle fullscreen when Space key is pressed
    if (Input.GetKeyDown(KeyCode.Space))
    {
        //Toggle
        fullSclreen = !fullSclreen;
        if (fullSclreen)
            StretchImageFullScreen(image, 90);
        else
            ApplyImageSettings(image, originalImgInfo);
    }

    //Restore RawImage default settings when R key is pressed
    if (Input.GetKeyDown(KeyCode.R))
    {
        ApplyImageSettings(image, originalImgInfo);
        fullSclreen = false;
    }
}

private void StretchImageFullScreen(RawImage rawImage, int rotAngle = 0)
{
    RectTransform rectTrfm = rawImage.rectTransform;

    //Get angle and change z-axis
    Vector3 rot = rectTrfm.rotation.eulerAngles;
    rot.z = rotAngle; //Set Z rotation to rotAngle
    rectTrfm.rotation = Quaternion.Euler(rot);

    //Get current angle after changing it
    rot = rectTrfm.rotation.eulerAngles;

    if (Mathf.Approximately(rot.z, 0) || Mathf.Approximately(rot.z, 180))
    {
        rectTrfm.anchoredPosition3D = new Vector3(0, 0, 0);
        //Stretch the Image so that the whole screen is totally covered
        rectTrfm.anchorMin = new Vector2(0, 0);
        rectTrfm.anchorMax = new Vector2(1, 1);
        rectTrfm.pivot = new Vector2(0.5f, 0.5f);
        rectTrfm.offsetMin = Vector2.zero;
        rectTrfm.offsetMax = Vector2.zero;
    }

    else if (Mathf.Approximately(rot.z, -90) || Mathf.Approximately(rot.z, 90)
         || Mathf.Approximately(rot.z, 270))
    {

        //Get the Canvas RectTransform
        RectTransform canvasRectTrfm = rawImage.canvas.GetComponent<RectTransform>();
        float aspRatio = canvasRectTrfm.rect.size.x / canvasRectTrfm.rect.size.y;
        float halfAspRatio = aspRatio / 2.0f;
        float halfAspRatioInvert = (1.0f / aspRatio) / 2.0f;

        rectTrfm.anchorMin = new Vector2(0.5f - halfAspRatioInvert, 0.5f - halfAspRatio);
        rectTrfm.anchorMax = new Vector2(0.5f + halfAspRatioInvert, 0.5f + halfAspRatio);
        rectTrfm.anchoredPosition3D = Vector3.zero;
        rectTrfm.pivot = new Vector2(0.5f, 0.5f);
        rectTrfm.offsetMin = Vector2.zero;
        rectTrfm.offsetMax = Vector2.zero;
    }
}

RawImageInfo GetImageSettings(RawImage rawImage)
{
    RectTransform rectTrfm = rawImage.rectTransform;

    RawImageInfo rawImgInfo = new RawImageInfo();

    //Get settings from RawImage and store as RawImageInfo 
    rawImgInfo.anchorPos = rectTrfm.anchoredPosition3D;
    rawImgInfo.widthAndHeight = rectTrfm.sizeDelta;

    rawImgInfo.anchorMin = rectTrfm.anchorMin;
    rawImgInfo.anchorMax = rectTrfm.anchorMax;
    rawImgInfo.pivot = rectTrfm.pivot;

    rawImgInfo.offsetMin = rectTrfm.offsetMin;
    rawImgInfo.offsetMax = rectTrfm.offsetMax;

    rawImgInfo.rot = rectTrfm.rotation;
    rawImgInfo.scale = rectTrfm.localScale;

    return rawImgInfo;
}

private void ApplyImageSettings(RawImage rawImage, RawImageInfo rawImgInfo)
{
    RectTransform rectTrfm = rawImage.rectTransform;

    //Apply settings from RawImageInfo to RawImage RectTransform
    rectTrfm.anchoredPosition3D = rawImgInfo.anchorPos;
    rectTrfm.sizeDelta = rawImgInfo.widthAndHeight;

    rectTrfm.anchorMin = rawImgInfo.anchorMin;
    rectTrfm.anchorMax = rawImgInfo.anchorMax;
    rectTrfm.pivot = rawImgInfo.pivot;

    rectTrfm.offsetMin = rawImgInfo.offsetMin;
    rectTrfm.offsetMax = rawImgInfo.offsetMax;

    rectTrfm.rotation = rawImgInfo.rot;
    rectTrfm.localScale = rawImgInfo.scale;
}
© www.soinside.com 2019 - 2024. All rights reserved.