这个功能做了好久了,今天总结下,也不是复杂的功能,记录一下以后有需要就不用再写一遍了。
需要Dotween插件。
层次结构:和每个组件,下面这个不是全屏,所以加了Mask。 RawImage1和RawImage2放在你想展示的位置的左边(往右滑)或右边(往左滑) 下面的两个图片元素,添加VideoPlayer,两个VP上放同一个RenderTexture即可。 最后添加这个脚本:ImageAndVideoLoopPlay,放在哪都行,只需把暴露的Fist、Second图设置了,还有RenderTexture,其他参数代码里会说明。
using DG.Tweening;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;
public class ImgAndVideoLoopPlay : MonoBehaviour
{
public Transform first;
public Transform second;
[HideInInspector]
public float originalPos;
private double intervalTime = 1;
public float duration = 0.5f;
public Ease ease = Ease.Linear;
public RenderTexture video;
public double imageIntervalTime = 5;
public double videoIntervalTime = 10;
private Transform currentMoveTF;
private Transform willResetTF;
private int pictureCurrentIndex;
private int videoCurrentIndex;
private float maxWidth;
private float maxHeight;
public bool isOpenScreen = true;
private bool nextIsVideo;
void Start()
{
currentMoveTF = second;
willResetTF = first;
RectTransform rect = first as RectTransform;
maxHeight = rect.rect.height;
maxWidth = rect.rect.width;
originalPos = second.localPosition.x;
if (LoadResource.totalImgFiles.Count == 0)
{
if (LoadResource.videosPathList.Count == 0) return;
VideoPlayer vp = first.GetComponentInChildren<VideoPlayer>();
vp.url = LoadResource.videosPathList[0];
vp.Play();
first.GetComponentInChildren<RawImage>().texture = vp.targetTexture;
}
else
{
LoadResource.FirstPictureLoadCompleted = () =>
{
willResetTF.GetComponentInChildren<RawImage>().texture = LoadResource.picturesList[0].tex;
nextIsVideo = true;
};
}
}
float time;
void Update()
{
if (LoadResource.IsAllPictureLoadCompleted)
{
if (isOpenScreen)
{
time += Time.deltaTime;
if (time > intervalTime)
{
time = 0;
PlayPicturesAndVideos();
}
}
}
}
private void PlayPicturesAndVideos(bool isMoveLeft = true)
{
if (isMoveLeft)
{
currentMoveTF.localPosition = new Vector3(originalPos, currentMoveTF.localPosition.y, currentMoveTF.localPosition.z);
if (LoadResource.videosPathList.Count == 0 && LoadResource.picturesList.Count == 0)
{
Debug.LogError("没有图片和视频资源,屏保显示默认");
}
if (LoadResource.videosPathList.Count == 0)
{
nextIsVideo = false;
}
else if (LoadResource.picturesList.Count == 0)
{
nextIsVideo = true;
}
if (nextIsVideo)
{
nextIsVideo = false;
videoCurrentIndex = (videoCurrentIndex + 1) % LoadResource.videosPathList.Count;
SetVideo();
}
else
{
nextIsVideo = true;
pictureCurrentIndex = (pictureCurrentIndex + 1) % LoadResource.picturesList.Count;
SetPicture();
}
}
else
{
currentMoveTF.localPosition = new Vector3(-originalPos, currentMoveTF.localPosition.y, currentMoveTF.localPosition.z);
if (nextIsVideo)
{
nextIsVideo = false;
videoCurrentIndex = (videoCurrentIndex - 1 + LoadResource.videosPathList.Count) % LoadResource.videosPathList.Count;
SetVideo();
}
else
{
nextIsVideo = true;
pictureCurrentIndex = (pictureCurrentIndex - 1 + LoadResource.picturesList.Count) % LoadResource.picturesList.Count;
SetPicture();
}
}
currentMoveTF.DOLocalMoveX(0, duration).SetEase(ease).OnComplete(() =>
{
willResetTF.localPosition = new Vector3(originalPos, willResetTF.localPosition.y, willResetTF.localPosition.z);
willResetTF.SetAsLastSibling();
Transform temp = currentMoveTF;
currentMoveTF = willResetTF;
willResetTF = temp;
});
}
private void SetPicture()
{
Texture2D tex = LoadResource.picturesList[pictureCurrentIndex].tex;
float width = tex.width;
float height = tex.height;
RawImage raw = currentMoveTF.GetComponentInChildren<RawImage>();
raw.texture = tex;
intervalTime = imageIntervalTime;
}
private IEnumerator SetVideoIntervalTime(VideoPlayer vp)
{
for (int i = 0; i < 10; i++)
{
yield return new WaitForSeconds(0.5f);
if (vp.length > 0)
{
intervalTime = vp.length;
yield break;
}
}
}
private void SetVideo()
{
VideoPlayer vp = currentMoveTF.GetComponentInChildren<VideoPlayer>();
currentMoveTF.GetComponentInChildren<RawImage>().texture = vp.targetTexture;
vp.url = LoadResource.videosPathList[videoCurrentIndex];
vp.Play();
RectTransform rect = vp.transform as RectTransform;
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, maxWidth);
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, maxHeight);
intervalTime = videoIntervalTime;
StartCoroutine(SetVideoIntervalTime(vp));
}
}
还需要一个资源加载的脚本:如果不是加载的外部图片,可以不用,代码自己修改。 这个脚本挂哪都行,可以和上面的放一块。
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class PictureData
{
public string name;
public Texture2D tex;
}
public class LoadResource : MonoBehaviour
{
public static List<PictureData> picturesList;
public static List<string> totalImgFiles;
public static int pictureNum
{
get
{
return picturesList.Count;
}
}
public static List<string> videosPathList;
public static int videoNum
{
get
{
return videosPathList.Count;
}
}
public static Action FirstPictureLoadCompleted;
private string videoPath;
private string imgPath;
private string resourcePath = "/ImagesAndVideos/";
private void Awake()
{
resourcePath = Application.streamingAssetsPath + resourcePath;
if (!Directory.Exists(resourcePath))
Directory.CreateDirectory(resourcePath);
totalImgFiles = new List<string>();
picturesList = new List<PictureData>();
videosPathList = new List<string>();
}
void Start()
{
StartCoroutine(GetPictures());
GetVideoPath();
}
private void GetVideoPath()
{
string[] videos = Directory.GetFiles(resourcePath, "*.mp4");
Debug.Log("本地视频数量:" + videoNum);
videosPathList.AddRange(videos);
}
private IEnumerator GetPictures()
{
string[] jpgs = Directory.GetFiles(resourcePath, "*.jpg");
string[] pngs = Directory.GetFiles(resourcePath, "*.png");
totalImgFiles.AddRange(pngs);
totalImgFiles.AddRange(jpgs);
Debug.Log("本地图片数量:" + pictureNum);
for (int i = 0; i < totalImgFiles.Count; i++)
{
yield return StartCoroutine(LoadPicuture(totalImgFiles[i]));
FirstPictureLoadCompleted?.Invoke();
FirstPictureLoadCompleted = null;
}
}
private IEnumerator LoadPicuture(string filePath)
{
Debug.Log(filePath);
UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(filePath);
yield return uwr.SendWebRequest();
if (uwr.downloadHandler.isDone)
{
string fileName = Path.GetFileNameWithoutExtension(filePath);
Texture2D fileTex = DownloadHandlerTexture.GetContent(uwr);
picturesList.Add(new PictureData() { name = fileName, tex = fileTex });
}
}
public static bool IsAllPictureLoadCompleted
{
get
{
return pictureNum > 0 && pictureNum == picturesList.Count;
}
}
}
|