first commit
This commit is contained in:
9
Assets/AVProVideo/Extensions/Timeline.meta
Normal file
9
Assets/AVProVideo/Extensions/Timeline.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bdad1096e91a02f44bfdeb7ce4e8d8f7
|
||||
folderAsset: yes
|
||||
timeCreated: 1591790245
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
// You need to define AVPRO_PACKAGE_TIMELINE manually to use this script
|
||||
// We could set up the asmdef to reference the package, but the package doesn't
|
||||
// existing in Unity 2017 etc, and it throws an error due to missing reference
|
||||
//#define AVPRO_PACKAGE_TIMELINE
|
||||
#if (UNITY_2018_1_OR_NEWER && AVPRO_PACKAGE_TIMELINE)
|
||||
using UnityEngine;
|
||||
using UnityEngine.Playables;
|
||||
using UnityEngine.Timeline;
|
||||
using System.Collections.Generic;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2020-2021 RenderHeads Ltd. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace RenderHeads.Media.AVProVideo.Playables
|
||||
{
|
||||
[System.Serializable]
|
||||
public class MediaPlayerControlAsset : PlayableAsset
|
||||
{
|
||||
public Object binding { get; set; }
|
||||
//public ExposedReference<MediaPlayer> mediaPlayer;
|
||||
|
||||
public MediaReference mediaReference;
|
||||
|
||||
[Range(0f, 1f)]
|
||||
public float audioVolume = 1f;
|
||||
public double startTime = -1.0;
|
||||
public bool pauseOnEnd = true;
|
||||
|
||||
public override Playable CreatePlayable (PlayableGraph graph, GameObject owner)
|
||||
{
|
||||
var playable = ScriptPlayable<MediaPlayerControlBehaviour>.Create(graph);
|
||||
|
||||
var behaviour = playable.GetBehaviour();
|
||||
//behaviour.mediaPlayer = mediaPlayer.Resolve(graph.GetResolver());
|
||||
behaviour.audioVolume = audioVolume;
|
||||
behaviour.pauseOnEnd = pauseOnEnd;
|
||||
behaviour.startTime = startTime;
|
||||
behaviour.mediaReference = mediaReference;
|
||||
behaviour.mediaPlayer = (MediaPlayer)binding;
|
||||
|
||||
return playable;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 55976ecf17b24e6438718da0257699d3
|
||||
timeCreated: 1605888478
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,64 @@
|
||||
// You need to define AVPRO_PACKAGE_TIMELINE manually to use this script
|
||||
// We could set up the asmdef to reference the package, but the package doesn't
|
||||
// existing in Unity 2017 etc, and it throws an error due to missing reference
|
||||
//#define AVPRO_PACKAGE_TIMELINE
|
||||
#if (UNITY_2018_1_OR_NEWER && AVPRO_PACKAGE_TIMELINE)
|
||||
using UnityEngine;
|
||||
using UnityEngine.Playables;
|
||||
using UnityEngine.Timeline;
|
||||
using System.Collections.Generic;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2020-2021 RenderHeads Ltd. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace RenderHeads.Media.AVProVideo.Playables
|
||||
{
|
||||
public class MediaPlayerControlBehaviour : PlayableBehaviour
|
||||
{
|
||||
public MediaPlayer mediaPlayer = null;
|
||||
|
||||
public MediaReference mediaReference = null;
|
||||
public float audioVolume = 1f;
|
||||
public double startTime = -1.0;
|
||||
public bool pauseOnEnd = true;
|
||||
|
||||
public override void OnBehaviourPlay(Playable playable, FrameData info)
|
||||
{
|
||||
if (mediaPlayer != null)
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
if (mediaReference != null && mediaReference != mediaPlayer.MediaReference)
|
||||
{
|
||||
mediaPlayer.OpenMedia(mediaReference, true);
|
||||
if (mediaPlayer.Control != null)
|
||||
{
|
||||
mediaPlayer.Control.SeekFast(startTime);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mediaPlayer.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnBehaviourPause(Playable playable, FrameData info)
|
||||
{
|
||||
if (mediaPlayer != null)
|
||||
{
|
||||
if (pauseOnEnd)
|
||||
{
|
||||
mediaPlayer.Pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d76b1588cab8f6f4282ca316e24ea365
|
||||
timeCreated: 1605888480
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,52 @@
|
||||
// You need to define AVPRO_PACKAGE_TIMELINE manually to use this script
|
||||
// We could set up the asmdef to reference the package, but the package doesn't
|
||||
// existing in Unity 2017 etc, and it throws an error due to missing reference
|
||||
//#define AVPRO_PACKAGE_TIMELINE
|
||||
#if (UNITY_2018_1_OR_NEWER && AVPRO_PACKAGE_TIMELINE)
|
||||
using UnityEngine;
|
||||
using UnityEngine.Playables;
|
||||
using UnityEngine.Timeline;
|
||||
using System.Collections.Generic;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2020-2021 RenderHeads Ltd. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace RenderHeads.Media.AVProVideo.Playables
|
||||
{
|
||||
public class MediaPlayerControlMixerBehaviour : PlayableBehaviour
|
||||
{
|
||||
public float audioVolume = 1f;
|
||||
public string videoPath = null;
|
||||
|
||||
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
|
||||
{
|
||||
MediaPlayer mediaPlayer = playerData as MediaPlayer;
|
||||
float finalVolume = 0f;
|
||||
|
||||
if (!mediaPlayer)
|
||||
return;
|
||||
|
||||
int inputCount = playable.GetInputCount(); //get the number of all clips on this track
|
||||
for (int i = 0; i < inputCount; i++)
|
||||
{
|
||||
float inputWeight = playable.GetInputWeight(i);
|
||||
ScriptPlayable<MediaPlayerControlBehaviour> inputPlayable = (ScriptPlayable<MediaPlayerControlBehaviour>)playable.GetInput(i);
|
||||
MediaPlayerControlBehaviour input = inputPlayable.GetBehaviour();
|
||||
|
||||
// Use the above variables to process each frame of this playable.
|
||||
finalVolume += input.audioVolume * inputWeight;
|
||||
}
|
||||
|
||||
if (mediaPlayer != null)
|
||||
{
|
||||
mediaPlayer.AudioVolume = finalVolume;
|
||||
if (mediaPlayer.Control != null)
|
||||
{
|
||||
mediaPlayer.Control.SetVolume(finalVolume);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c390934e9ad7c29478a96808ee101c87
|
||||
timeCreated: 1605888480
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,41 @@
|
||||
// You need to define AVPRO_PACKAGE_TIMELINE manually to use this script
|
||||
// We could set up the asmdef to reference the package, but the package doesn't
|
||||
// existing in Unity 2017 etc, and it throws an error due to missing reference
|
||||
//#define AVPRO_PACKAGE_TIMELINE
|
||||
#if (UNITY_2018_1_OR_NEWER && AVPRO_PACKAGE_TIMELINE)
|
||||
using UnityEngine;
|
||||
using UnityEngine.Playables;
|
||||
using UnityEngine.Timeline;
|
||||
using System.Collections.Generic;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2020-2021 RenderHeads Ltd. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace RenderHeads.Media.AVProVideo.Playables
|
||||
{
|
||||
[TrackClipType(typeof(MediaPlayerControlAsset))]
|
||||
[TrackBindingType(typeof(MediaPlayer))]
|
||||
public class MediaPlayerControlTrack : TrackAsset
|
||||
{
|
||||
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
|
||||
{
|
||||
// before building, update the binding field in the clips assets;
|
||||
var director = go.GetComponent<PlayableDirector>();
|
||||
var binding = director.GetGenericBinding(this);
|
||||
|
||||
foreach (var c in GetClips())
|
||||
{
|
||||
var myAsset = c.asset as MediaPlayerControlAsset;
|
||||
if (myAsset != null)
|
||||
{
|
||||
myAsset.binding = binding;
|
||||
}
|
||||
}
|
||||
|
||||
//return base.CreateTrackMixer(graph, go, inputCount);
|
||||
return ScriptPlayable<MediaPlayerControlMixerBehaviour>.Create(graph, inputCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 971a512f8f09bfb4aa96fb25d0439255
|
||||
timeCreated: 1605888480
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "AVProVideo.Extensions.Timeline",
|
||||
"references": [
|
||||
"AVProVideo.Runtime"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 417edd1c17e270f4a9afe6e95eff9b6e
|
||||
timeCreated: 1591797492
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/AVProVideo/Extensions/UnityUI.meta
Normal file
8
Assets/AVProVideo/Extensions/UnityUI.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e82bc7b2e03389f44a7c4c7f38f0db58
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/AVProVideo/Extensions/UnityUI/Editor.meta
Normal file
9
Assets/AVProVideo/Extensions/UnityUI/Editor.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b801737c3821d6e438ecf2a742d4f04b
|
||||
folderAsset: yes
|
||||
timeCreated: 1591797492
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
172
Assets/AVProVideo/Extensions/UnityUI/Editor/DisplayUGUIEditor.cs
Normal file
172
Assets/AVProVideo/Extensions/UnityUI/Editor/DisplayUGUIEditor.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
// UnityEngine.UI was moved to a package in 2019.2.0
|
||||
// Unfortunately no way to test for this across all Unity versions yet
|
||||
// You can set up the asmdef to reference the new package, but the package doesn't
|
||||
// existing in Unity 2017 etc, and it throws an error due to missing reference
|
||||
#define AVPRO_PACKAGE_UNITYUI
|
||||
#if (UNITY_2019_2_OR_NEWER && AVPRO_PACKAGE_UNITYUI) || (!UNITY_2019_2_OR_NEWER)
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UI;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2015-2021 RenderHeads Ltd. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace RenderHeads.Media.AVProVideo.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Editor for the DisplayUGUI component
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(DisplayUGUI), true)]
|
||||
[CanEditMultipleObjects]
|
||||
public class DisplayUGUIEditor : GraphicEditor
|
||||
{
|
||||
// Note we have precedence for calling rectangle for just rect, even in the Inspector.
|
||||
// For example in the Camera component's Viewport Rect.
|
||||
// Hence sticking with Rect here to be consistent with corresponding property in the API.
|
||||
private static readonly GUIContent m_guiTextUVRectContent = new GUIContent("UV Rect");
|
||||
|
||||
private SerializedProperty _propMediaPlayer;
|
||||
private SerializedProperty _propUVRect;
|
||||
private SerializedProperty _propDefaultTexture;
|
||||
private SerializedProperty _propNoDefaultDisplay;
|
||||
private SerializedProperty _propDisplayInEditor;
|
||||
private SerializedProperty _propSetNativeSize;
|
||||
private SerializedProperty _propScaleMode;
|
||||
|
||||
[MenuItem("GameObject/UI/AVPro Video uGUI", false, 0)]
|
||||
public static void CreateGameObject()
|
||||
{
|
||||
GameObject parent = Selection.activeGameObject;
|
||||
RectTransform parentCanvasRenderer = ( parent != null ) ? parent.GetComponent<RectTransform>() : null;
|
||||
if( parentCanvasRenderer )
|
||||
{
|
||||
GameObject go = new GameObject("AVPro Video");
|
||||
go.transform.SetParent(parent.transform, false);
|
||||
go.AddComponent<RectTransform>();
|
||||
go.AddComponent<CanvasRenderer>();
|
||||
go.AddComponent<DisplayUGUI>();
|
||||
Selection.activeGameObject = go;
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("AVPro Video", "You must make the AVPro Video uGUI object as a child of a Canvas.", "Ok");
|
||||
}
|
||||
}
|
||||
|
||||
public override bool RequiresConstantRepaint()
|
||||
{
|
||||
DisplayUGUI displayComponent = target as DisplayUGUI;
|
||||
return (displayComponent != null && displayComponent.HasValidTexture());
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
|
||||
_propMediaPlayer = this.CheckFindProperty("_mediaPlayer");
|
||||
_propUVRect = this.CheckFindProperty("_uvRect");
|
||||
_propSetNativeSize = this.CheckFindProperty("_setNativeSize");
|
||||
_propScaleMode = this.CheckFindProperty("_scaleMode");
|
||||
_propNoDefaultDisplay = this.CheckFindProperty("_noDefaultDisplay");
|
||||
_propDisplayInEditor = this.CheckFindProperty("_displayInEditor");
|
||||
_propDefaultTexture = this.CheckFindProperty("_defaultTexture");
|
||||
|
||||
SetShowNativeSize(true);
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.PropertyField(_propMediaPlayer);
|
||||
EditorGUILayout.PropertyField(_propDisplayInEditor);
|
||||
EditorGUILayout.PropertyField(_propNoDefaultDisplay);
|
||||
if (!_propNoDefaultDisplay.boolValue)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propDefaultTexture);
|
||||
}
|
||||
AppearanceControlsGUI();
|
||||
RaycastControlsGUI();
|
||||
EditorGUILayout.PropertyField(_propUVRect, m_guiTextUVRectContent);
|
||||
|
||||
EditorGUILayout.PropertyField(_propSetNativeSize);
|
||||
EditorGUILayout.PropertyField(_propScaleMode);
|
||||
|
||||
SetShowNativeSize(false);
|
||||
NativeSizeButtonGUI();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void SetShowNativeSize(bool instant)
|
||||
{
|
||||
base.SetShowNativeSize(_propMediaPlayer.objectReferenceValue != null, instant);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow the texture to be previewed.
|
||||
/// </summary>
|
||||
public override bool HasPreviewGUI()
|
||||
{
|
||||
DisplayUGUI rawImage = target as DisplayUGUI;
|
||||
return rawImage != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw the Image preview.
|
||||
/// </summary>
|
||||
public override void OnPreviewGUI(Rect drawArea, GUIStyle background)
|
||||
{
|
||||
DisplayUGUI rawImage = target as DisplayUGUI;
|
||||
Texture tex = rawImage.mainTexture;
|
||||
|
||||
if (tex == null)
|
||||
return;
|
||||
|
||||
// Create the texture rectangle that is centered inside rect.
|
||||
Rect outerRect = drawArea;
|
||||
|
||||
Matrix4x4 m = GUI.matrix;
|
||||
// Flip the image vertically
|
||||
if (rawImage.HasValidTexture())
|
||||
{
|
||||
if (rawImage.Player.TextureProducer.RequiresVerticalFlip())
|
||||
{
|
||||
GUIUtility.ScaleAroundPivot(new Vector2(1f, -1f), new Vector2(0f, outerRect.y + (outerRect.height / 2f)));
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.DrawTextureTransparent(outerRect, tex, ScaleMode.ScaleToFit);//, outer.width / outer.height);
|
||||
//SpriteDrawUtility.DrawSprite(tex, rect, outer, rawImage.uvRect, rawImage.canvasRenderer.GetColor());
|
||||
|
||||
GUI.matrix = m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Info String drawn at the bottom of the Preview
|
||||
/// </summary>
|
||||
public override string GetInfoString()
|
||||
{
|
||||
DisplayUGUI rawImage = target as DisplayUGUI;
|
||||
|
||||
string text = string.Empty;
|
||||
if (rawImage.HasValidTexture())
|
||||
{
|
||||
text += string.Format("Video Size: {0}x{1}\n",
|
||||
Mathf.RoundToInt(Mathf.Abs(rawImage.mainTexture.width)),
|
||||
Mathf.RoundToInt(Mathf.Abs(rawImage.mainTexture.height)));
|
||||
}
|
||||
|
||||
// Image size Text
|
||||
text += string.Format("Display Size: {0}x{1}",
|
||||
Mathf.RoundToInt(Mathf.Abs(rawImage.rectTransform.rect.width)),
|
||||
Mathf.RoundToInt(Mathf.Abs(rawImage.rectTransform.rect.height)));
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e20933bfdb909544b98bc0de2926c4c
|
||||
timeCreated: 1438726873
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "AVProVideo.Extensions.UnityUI.Editor",
|
||||
"references": [
|
||||
"AVProVideo.Runtime",
|
||||
"AVProVideo.Editor",
|
||||
"AVProVideo.Extensions.UnityUI"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 163aa7dfc21664e47a9d1ce803fb3e3f
|
||||
timeCreated: 1591797492
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/AVProVideo/Extensions/UnityUI/Runtime.meta
Normal file
9
Assets/AVProVideo/Extensions/UnityUI/Runtime.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d60008e579848de489d8104d999e0afa
|
||||
folderAsset: yes
|
||||
timeCreated: 1591797614
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
715
Assets/AVProVideo/Extensions/UnityUI/Runtime/DisplayUGUI.cs
Normal file
715
Assets/AVProVideo/Extensions/UnityUI/Runtime/DisplayUGUI.cs
Normal file
@@ -0,0 +1,715 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2015-2025 RenderHeads Ltd. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// UnityEngine.UI was moved to a package in 2019.2.0
|
||||
// Unfortunately no way to test for this across all Unity versions yet
|
||||
// You can set up the asmdef to reference the new package, but the package doesn't
|
||||
// existing in Unity 2017 etc, and it throws an error due to missing reference
|
||||
#define AVPRO_PACKAGE_UNITYUI
|
||||
#if (UNITY_2019_2_OR_NEWER && AVPRO_PACKAGE_UNITYUI) || (!UNITY_2019_2_OR_NEWER)
|
||||
|
||||
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS || UNITY_TVOS
|
||||
#define UNITY_PLATFORM_SUPPORTS_YPCBCR
|
||||
#endif
|
||||
|
||||
#define UNITY_PLATFORM_SUPPORTS_LINEAR
|
||||
|
||||
#if (!UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN) && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS || UNITY_ANDROID)
|
||||
#define UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
|
||||
#endif
|
||||
|
||||
#if (UNITY_EDITOR_WIN || (!UNITY_EDITOR && UNITY_STANDALONE_WIN))
|
||||
#define UNITY_PLATFORM_SUPPORTS_VIDEOASPECTRATIO
|
||||
#endif
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace RenderHeads.Media.AVProVideo
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays the video from MediaPlayer component using uGUI
|
||||
/// </summary>
|
||||
[HelpURL("http://renderheads.com/products/avpro-video/")]
|
||||
[AddComponentMenu("AVPro Video/Display uGUI", 200)]
|
||||
[RequireComponent(typeof(CanvasRenderer))]
|
||||
//[ExecuteInEditMode]
|
||||
public class DisplayUGUI : MaskableGraphic
|
||||
{
|
||||
[SerializeField] MediaPlayer _mediaPlayer;
|
||||
|
||||
public MediaPlayer Player
|
||||
{
|
||||
get { return _mediaPlayer; }
|
||||
set { ChangeMediaPlayer(value); }
|
||||
}
|
||||
|
||||
[Tooltip("Default texture to display when the video texture is preparing")]
|
||||
[SerializeField] Texture _defaultTexture;
|
||||
|
||||
public Texture DefaultTexture
|
||||
{
|
||||
get { return _defaultTexture; }
|
||||
set { if (_defaultTexture != value) { _defaultTexture = value; } }
|
||||
}
|
||||
|
||||
[FormerlySerializedAs("m_UVRect")]
|
||||
[SerializeField] Rect _uvRect = new Rect(0f, 0f, 1f, 1f);
|
||||
|
||||
public Rect UVRect
|
||||
{
|
||||
get { return _uvRect; }
|
||||
set { _uvRect = value; }
|
||||
}
|
||||
|
||||
[SerializeField] bool _setNativeSize = false;
|
||||
|
||||
public bool ApplyNativeSize
|
||||
{
|
||||
get { return _setNativeSize; }
|
||||
set { _setNativeSize = value; }
|
||||
}
|
||||
|
||||
[SerializeField] ScaleMode _scaleMode = ScaleMode.ScaleToFit;
|
||||
|
||||
public ScaleMode ScaleMode
|
||||
{
|
||||
get { return _scaleMode; }
|
||||
set { _scaleMode = value; }
|
||||
}
|
||||
|
||||
[SerializeField] bool _noDefaultDisplay = true;
|
||||
|
||||
public bool NoDefaultDisplay
|
||||
{
|
||||
get { return _noDefaultDisplay; }
|
||||
set { _noDefaultDisplay = value; }
|
||||
}
|
||||
|
||||
[SerializeField] bool _displayInEditor = true;
|
||||
|
||||
public bool DisplayInEditor
|
||||
{
|
||||
get { return _displayInEditor; }
|
||||
set { _displayInEditor = value; }
|
||||
}
|
||||
|
||||
private int _lastWidth;
|
||||
private int _lastHeight;
|
||||
private Orientation _lastOrientation;
|
||||
private bool _flipY;
|
||||
private Texture _lastTexture;
|
||||
private static Shader _shaderStereoPacking;
|
||||
private static Shader _shaderAlphaPacking;
|
||||
private static Shader _shaderAndroidOES;
|
||||
private static Shader _shaderAndroidOESAlphaPacking;
|
||||
|
||||
private bool _isUserMaterial = true;
|
||||
private Material _material;
|
||||
|
||||
private List<UIVertex> _vertices = new List<UIVertex>(4);
|
||||
private static List<int> QuadIndices = new List<int>(new int[] { 0, 1, 2, 2, 3, 0 });
|
||||
|
||||
private Vector4 _drawingDimensions = Vector4.zero;
|
||||
|
||||
public Vector4 DrawingDimensions
|
||||
{
|
||||
get => _drawingDimensions;
|
||||
}
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
_mediaPlayer.Events.AddListener(OnMediaPlayerEvent);
|
||||
}
|
||||
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
// Callback function to handle events
|
||||
private void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
|
||||
{
|
||||
switch (et)
|
||||
{
|
||||
case MediaPlayerEvent.EventType.FirstFrameReady:
|
||||
if (_isUserMaterial && null != GetRequiredShader())
|
||||
{
|
||||
Debug.LogWarning("[AVProVideo] Custom material is being used but the video requires our internal shader for correct rendering. Consider removing custom shader or modifying it for AVPro Video support.", this);
|
||||
}
|
||||
LateUpdate();
|
||||
break;
|
||||
case MediaPlayerEvent.EventType.PropertiesChanged:
|
||||
case MediaPlayerEvent.EventType.ResolutionChanged:
|
||||
case MediaPlayerEvent.EventType.Closing:
|
||||
LateUpdate();
|
||||
break;
|
||||
}
|
||||
// TODO: remove this, we're just doing this so we can make sure texture is correct when running in EDIT mode
|
||||
LateUpdate();
|
||||
}
|
||||
|
||||
private void ChangeMediaPlayer(MediaPlayer player)
|
||||
{
|
||||
if (_mediaPlayer != player)
|
||||
{
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
_mediaPlayer.Events.RemoveListener(OnMediaPlayerEvent);
|
||||
}
|
||||
_mediaPlayer = player;
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
_mediaPlayer.Events.AddListener(OnMediaPlayerEvent);
|
||||
}
|
||||
LateUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private static Shader EnsureShader(Shader shader, string name)
|
||||
{
|
||||
if (shader == null)
|
||||
{
|
||||
shader = Shader.Find(name);
|
||||
if (shader == null)
|
||||
{
|
||||
Debug.LogWarning("[AVProVideo] Missing shader " + name);
|
||||
}
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
private static Shader EnsureAlphaPackingShader()
|
||||
{
|
||||
_shaderAlphaPacking = EnsureShader(_shaderAlphaPacking, "AVProVideo/Internal/UI/Transparent Packed (stereo)");
|
||||
return _shaderAlphaPacking;
|
||||
}
|
||||
|
||||
private static Shader EnsureStereoPackingShader()
|
||||
{
|
||||
_shaderStereoPacking = EnsureShader(_shaderStereoPacking, "AVProVideo/Internal/UI/Stereo");
|
||||
return _shaderStereoPacking;
|
||||
}
|
||||
|
||||
private Shader EnsureAndroidOESShader()
|
||||
{
|
||||
_shaderAndroidOES = EnsureShader(_shaderAndroidOES, "AVProVideo/Internal/UI/Stereo - AndroidOES");
|
||||
return _shaderAndroidOES;
|
||||
}
|
||||
|
||||
private static Shader EnsureAndroidOESAlphaPackingShader()
|
||||
{
|
||||
_shaderAndroidOESAlphaPacking = EnsureShader(_shaderAndroidOESAlphaPacking, "AVProVideo/Internal/UI/Transparent Packed (stereo) - AndroidOES");
|
||||
return _shaderAndroidOESAlphaPacking;
|
||||
}
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
_isUserMaterial = (this.m_Material != null);
|
||||
if (_isUserMaterial)
|
||||
{
|
||||
_material = new Material(this.material);
|
||||
this.material = _material;
|
||||
}
|
||||
base.Start();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
// Destroy existing material
|
||||
if (_material != null)
|
||||
{
|
||||
this.material = null;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
Material.DestroyImmediate(_material);
|
||||
#else
|
||||
Material.Destroy(_material);
|
||||
#endif
|
||||
_material = null;
|
||||
}
|
||||
ChangeMediaPlayer(null);
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
private Shader GetRequiredShader()
|
||||
{
|
||||
Shader result = null;
|
||||
|
||||
if (result == null && _mediaPlayer.TextureProducer != null)
|
||||
{
|
||||
switch (_mediaPlayer.TextureProducer.GetTextureStereoPacking())
|
||||
{
|
||||
case StereoPacking.Monoscopic:
|
||||
break;
|
||||
case StereoPacking.LeftRight:
|
||||
case StereoPacking.TopBottom:
|
||||
case StereoPacking.MultiviewLeftPrimary:
|
||||
case StereoPacking.MultiviewRightPrimary:
|
||||
result = EnsureStereoPackingShader();
|
||||
break;
|
||||
}
|
||||
|
||||
if (_mediaPlayer.TextureProducer.GetTextureTransparency() == TransparencyMode.Transparent)
|
||||
{
|
||||
result = EnsureAlphaPackingShader();
|
||||
}
|
||||
|
||||
switch (_mediaPlayer.TextureProducer.GetTextureAlphaPacking())
|
||||
{
|
||||
case AlphaPacking.None:
|
||||
break;
|
||||
case AlphaPacking.LeftRight:
|
||||
case AlphaPacking.TopBottom:
|
||||
result = EnsureAlphaPackingShader();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_PLATFORM_SUPPORTS_LINEAR
|
||||
if (result == null && _mediaPlayer.Info != null)
|
||||
{
|
||||
if (QualitySettings.activeColorSpace == ColorSpace.Linear && !_mediaPlayer.Info.PlayerSupportsLinearColorSpace())
|
||||
{
|
||||
result = EnsureAlphaPackingShader();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (result == null && _mediaPlayer.TextureProducer != null && _mediaPlayer.TextureProducer.GetTextureCount() == 2)
|
||||
{
|
||||
result = EnsureAlphaPackingShader();
|
||||
}
|
||||
|
||||
// if (_mediaPlayer.TextureProducer != null && _mediaPlayer.IsUsingAndroidOESPath() && (_defaultTexture == null || _lastTexture != _defaultTexture ))
|
||||
if (_mediaPlayer.TextureProducer != null && _mediaPlayer.IsUsingAndroidOESPath())
|
||||
{
|
||||
// This shader handles stereo too
|
||||
result = EnsureAndroidOESShader();
|
||||
|
||||
if (_mediaPlayer.TextureProducer.GetTextureTransparency() == TransparencyMode.Transparent)
|
||||
{
|
||||
result = EnsureAndroidOESAlphaPackingShader();
|
||||
}
|
||||
switch (_mediaPlayer.TextureProducer.GetTextureAlphaPacking())
|
||||
{
|
||||
case AlphaPacking.None:
|
||||
break;
|
||||
case AlphaPacking.LeftRight:
|
||||
case AlphaPacking.TopBottom:
|
||||
result = EnsureAndroidOESAlphaPackingShader();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the texture used to draw this Graphic.
|
||||
/// </summary>
|
||||
public override Texture mainTexture
|
||||
{
|
||||
get
|
||||
{
|
||||
Texture result = Texture2D.whiteTexture;
|
||||
if (HasValidTexture())
|
||||
{
|
||||
Texture resamplerTex = _mediaPlayer.FrameResampler == null || _mediaPlayer.FrameResampler.OutputTexture == null ? null : _mediaPlayer.FrameResampler.OutputTexture[0];
|
||||
result = _mediaPlayer.UseResampler ? resamplerTex : _mediaPlayer.TextureProducer.GetTexture();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_noDefaultDisplay)
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
else if (_defaultTexture != null)
|
||||
{
|
||||
result = _defaultTexture;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (result == null && _displayInEditor)
|
||||
{
|
||||
result = Resources.Load<Texture2D>("AVProVideoIcon");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasValidTexture()
|
||||
{
|
||||
return (Application.isPlaying && _mediaPlayer != null && _mediaPlayer.TextureProducer != null && _mediaPlayer.TextureProducer.GetTexture() != null);
|
||||
}
|
||||
|
||||
private void UpdateInternalMaterial()
|
||||
{
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
// Get required shader
|
||||
Shader currentShader = null;
|
||||
if (_material != null)
|
||||
{
|
||||
currentShader = _material.shader;
|
||||
}
|
||||
Shader nextShader = GetRequiredShader();
|
||||
|
||||
// If the shader requirement has changed
|
||||
if (currentShader != nextShader)
|
||||
{
|
||||
// Destroy existing material
|
||||
if (_material != null)
|
||||
{
|
||||
this.material = null;
|
||||
#if UNITY_EDITOR
|
||||
Material.DestroyImmediate(_material);
|
||||
#else
|
||||
Material.Destroy(_material);
|
||||
#endif
|
||||
_material = null;
|
||||
}
|
||||
|
||||
// Create new material
|
||||
if (nextShader != null)
|
||||
{
|
||||
_material = new Material(nextShader);
|
||||
}
|
||||
}
|
||||
|
||||
this.material = _material;
|
||||
}
|
||||
}
|
||||
|
||||
// We do a LateUpdate() to allow for any changes in the texture that may have happened in Update()
|
||||
void LateUpdate()
|
||||
{
|
||||
if (_setNativeSize)
|
||||
{
|
||||
SetNativeSize();
|
||||
}
|
||||
|
||||
if (_lastTexture != mainTexture)
|
||||
{
|
||||
_lastTexture = mainTexture;
|
||||
SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
}
|
||||
|
||||
if (HasValidTexture())
|
||||
{
|
||||
if (mainTexture != null)
|
||||
{
|
||||
Orientation orientation = Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform());
|
||||
if (mainTexture.width != _lastWidth || mainTexture.height != _lastHeight || orientation != _lastOrientation)
|
||||
{
|
||||
_lastWidth = mainTexture.width;
|
||||
_lastHeight = mainTexture.height;
|
||||
_lastOrientation = orientation;
|
||||
SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
if (!_isUserMaterial)
|
||||
{
|
||||
UpdateInternalMaterial();
|
||||
}
|
||||
}
|
||||
|
||||
if (material != null && _mediaPlayer != null)
|
||||
{
|
||||
// TODO: only run when dirty
|
||||
VideoRender.SetupMaterialForMedia(materialForRendering, _mediaPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Texture to be used.
|
||||
/// </summary>
|
||||
public MediaPlayer CurrentMediaPlayer
|
||||
{
|
||||
get
|
||||
{
|
||||
return _mediaPlayer;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_mediaPlayer != value)
|
||||
{
|
||||
_mediaPlayer = value;
|
||||
//SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UV rectangle used by the texture.
|
||||
/// </summary>
|
||||
public Rect uvRect
|
||||
{
|
||||
get
|
||||
{
|
||||
return _uvRect;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_uvRect == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_uvRect = value;
|
||||
SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjust the scale of the Graphic to make it pixel-perfect.
|
||||
/// </summary>
|
||||
[ContextMenu("Set Native Size")]
|
||||
public override void SetNativeSize()
|
||||
{
|
||||
Texture tex = mainTexture;
|
||||
if (tex != null)
|
||||
{
|
||||
int w = Mathf.RoundToInt(tex.width * uvRect.width);
|
||||
int h = Mathf.RoundToInt(tex.height * uvRect.height);
|
||||
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM && !(!UNITY_EDITOR && UNITY_ANDROID)
|
||||
if (_mediaPlayer.Info != null)
|
||||
{
|
||||
Orientation ori = Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform());
|
||||
if (ori == Orientation.Portrait || ori == Orientation.PortraitFlipped)
|
||||
{
|
||||
w = Mathf.RoundToInt(tex.height * uvRect.width);
|
||||
h = Mathf.RoundToInt(tex.width * uvRect.height);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (_mediaPlayer.TextureProducer != null)
|
||||
{
|
||||
if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.LeftRight ||
|
||||
_mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.LeftRight)
|
||||
{
|
||||
w /= 2;
|
||||
}
|
||||
else if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.TopBottom ||
|
||||
_mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.TopBottom)
|
||||
{
|
||||
h /= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rectTransform.anchorMax = rectTransform.anchorMin;
|
||||
rectTransform.sizeDelta = new Vector2(w, h);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPopulateMesh(VertexHelper vh)
|
||||
{
|
||||
vh.Clear();
|
||||
|
||||
_OnFillVBO(_vertices);
|
||||
|
||||
vh.AddUIVertexStream(_vertices, QuadIndices );
|
||||
}
|
||||
|
||||
private void _OnFillVBO(List<UIVertex> vbo)
|
||||
{
|
||||
_flipY = false;
|
||||
if (HasValidTexture())
|
||||
{
|
||||
_flipY = _mediaPlayer.TextureProducer.RequiresVerticalFlip();
|
||||
}
|
||||
|
||||
Rect uvRect = _uvRect;
|
||||
Vector4 v = GetDrawingDimensions(_scaleMode, ref uvRect);
|
||||
_drawingDimensions = v;
|
||||
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
|
||||
Matrix4x4 m = Matrix4x4.identity;
|
||||
if (HasValidTexture())
|
||||
{
|
||||
m = Helper.GetMatrixForOrientation(Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform()));
|
||||
}
|
||||
#endif
|
||||
|
||||
vbo.Clear();
|
||||
|
||||
var vert = UIVertex.simpleVert;
|
||||
vert.color = color;
|
||||
|
||||
vert.position = new Vector2(v.x, v.y);
|
||||
|
||||
vert.uv0 = new Vector2(uvRect.xMin, uvRect.yMin);
|
||||
if (_flipY)
|
||||
{
|
||||
vert.uv0 = new Vector2(uvRect.xMin, 1.0f - uvRect.yMin);
|
||||
}
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
|
||||
vert.uv0 = m.MultiplyPoint3x4(vert.uv0);
|
||||
#endif
|
||||
vbo.Add(vert);
|
||||
|
||||
vert.position = new Vector2(v.x, v.w);
|
||||
vert.uv0 = new Vector2(uvRect.xMin, uvRect.yMax);
|
||||
if (_flipY)
|
||||
{
|
||||
vert.uv0 = new Vector2(uvRect.xMin, 1.0f - uvRect.yMax);
|
||||
}
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
|
||||
vert.uv0 = m.MultiplyPoint3x4(vert.uv0);
|
||||
#endif
|
||||
vbo.Add(vert);
|
||||
|
||||
vert.position = new Vector2(v.z, v.w);
|
||||
vert.uv0 = new Vector2(uvRect.xMax, uvRect.yMax);
|
||||
if (_flipY)
|
||||
{
|
||||
vert.uv0 = new Vector2(uvRect.xMax, 1.0f - uvRect.yMax);
|
||||
}
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
|
||||
vert.uv0 = m.MultiplyPoint3x4(vert.uv0);
|
||||
#endif
|
||||
vbo.Add(vert);
|
||||
|
||||
vert.position = new Vector2(v.z, v.y);
|
||||
vert.uv0 = new Vector2(uvRect.xMax, uvRect.yMin);
|
||||
if (_flipY)
|
||||
{
|
||||
vert.uv0 = new Vector2(uvRect.xMax, 1.0f - uvRect.yMin);
|
||||
}
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
|
||||
vert.uv0 = m.MultiplyPoint3x4(vert.uv0);
|
||||
#endif
|
||||
vbo.Add(vert);
|
||||
}
|
||||
|
||||
private Vector4 GetDrawingDimensions(ScaleMode scaleMode, ref Rect uvRect)
|
||||
{
|
||||
Vector4 returnSize = Vector4.zero;
|
||||
|
||||
if (mainTexture != null)
|
||||
{
|
||||
var padding = Vector4.zero;
|
||||
|
||||
var textureSize = new Vector2(mainTexture.width, mainTexture.height);
|
||||
{
|
||||
// Adjust textureSize based on orientation
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM && !(!UNITY_EDITOR && UNITY_ANDROID)
|
||||
if (HasValidTexture())
|
||||
{
|
||||
Matrix4x4 m = Helper.GetMatrixForOrientation(Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform()));
|
||||
textureSize = m.MultiplyVector(textureSize);
|
||||
textureSize.x = Mathf.Abs(textureSize.x);
|
||||
textureSize.y = Mathf.Abs(textureSize.y);
|
||||
}
|
||||
#endif
|
||||
#if UNITY_PLATFORM_SUPPORTS_VIDEOASPECTRATIO
|
||||
if (HasValidTexture())
|
||||
{
|
||||
float par = _mediaPlayer.TextureProducer.GetTexturePixelAspectRatio();
|
||||
if (par > 0f)
|
||||
{
|
||||
if (par > 1f)
|
||||
{
|
||||
textureSize.x *= par;
|
||||
}
|
||||
else
|
||||
{
|
||||
textureSize.y /= par;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Adjust textureSize based on alpha/stereo packing
|
||||
if (_mediaPlayer != null && _mediaPlayer.TextureProducer != null)
|
||||
{
|
||||
if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.LeftRight ||
|
||||
_mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.LeftRight)
|
||||
{
|
||||
textureSize.x /= 2;
|
||||
}
|
||||
else if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.TopBottom ||
|
||||
_mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.TopBottom)
|
||||
{
|
||||
textureSize.y /= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rect r = GetPixelAdjustedRect();
|
||||
|
||||
// Fit the above textureSize into rectangle r
|
||||
int spriteW = Mathf.RoundToInt( textureSize.x );
|
||||
int spriteH = Mathf.RoundToInt( textureSize.y );
|
||||
|
||||
var size = new Vector4( padding.x / spriteW,
|
||||
padding.y / spriteH,
|
||||
(spriteW - padding.z) / spriteW,
|
||||
(spriteH - padding.w) / spriteH );
|
||||
|
||||
|
||||
{
|
||||
if (textureSize.sqrMagnitude > 0.0f)
|
||||
{
|
||||
if (scaleMode == ScaleMode.ScaleToFit)
|
||||
{
|
||||
float spriteRatio = textureSize.x / textureSize.y;
|
||||
float rectRatio = r.width / r.height;
|
||||
|
||||
if (spriteRatio > rectRatio)
|
||||
{
|
||||
float oldHeight = r.height;
|
||||
r.height = r.width * (1.0f / spriteRatio);
|
||||
r.y += (oldHeight - r.height) * rectTransform.pivot.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
float oldWidth = r.width;
|
||||
r.width = r.height * spriteRatio;
|
||||
r.x += (oldWidth - r.width) * rectTransform.pivot.x;
|
||||
}
|
||||
}
|
||||
else if (scaleMode == ScaleMode.ScaleAndCrop)
|
||||
{
|
||||
float aspectRatio = textureSize.x / textureSize.y;
|
||||
float screenRatio = r.width / r.height;
|
||||
if (screenRatio > aspectRatio)
|
||||
{
|
||||
float adjust = aspectRatio / screenRatio;
|
||||
uvRect = new Rect(uvRect.xMin, (uvRect.yMin * adjust) + (1f - adjust) * 0.5f, uvRect.width, adjust * uvRect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
float adjust = screenRatio / aspectRatio;
|
||||
uvRect = new Rect(uvRect.xMin * adjust + (0.5f - adjust * 0.5f), uvRect.yMin, adjust * uvRect.width, uvRect.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
returnSize = new Vector4( r.x + r.width * size.x,
|
||||
r.y + r.height * size.y,
|
||||
r.x + r.width * size.z,
|
||||
r.y + r.height * size.w );
|
||||
|
||||
}
|
||||
|
||||
return returnSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f17cdc186456a4469a139a104d2ca72
|
||||
timeCreated: 1544813301
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: bb83b41b53a59874692b83eab5873998, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
130
Assets/AVProVideo/Extensions/UnityUI/Runtime/SubtitlesUGUI.cs
Normal file
130
Assets/AVProVideo/Extensions/UnityUI/Runtime/SubtitlesUGUI.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2015-2021 RenderHeads Ltd. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace RenderHeads.Media.AVProVideo
|
||||
{
|
||||
/// <summary>
|
||||
/// Update a standard uGUI Text element with subtitle text as it plays from the MediaPlayer
|
||||
/// </summary>
|
||||
[AddComponentMenu("AVPro Video/Subtitles uGUI", 201)]
|
||||
[HelpURL("http://renderheads.com/products/avpro-video/")]
|
||||
public class SubtitlesUGUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] MediaPlayer _mediaPlayer = null;
|
||||
[SerializeField] Text _text = null;
|
||||
[SerializeField] Image _backgroundImage = null;
|
||||
[SerializeField] int _backgroundHorizontalPadding = 32;
|
||||
[SerializeField] int _backgroundVerticalPadding = 16;
|
||||
[SerializeField, Range(-1, 1024)] int _maxCharacters = 256;
|
||||
|
||||
public MediaPlayer Player
|
||||
{
|
||||
set { ChangeMediaPlayer(value); }
|
||||
get { return _mediaPlayer; }
|
||||
}
|
||||
|
||||
public Text Text
|
||||
{
|
||||
set { _text = value; }
|
||||
get { return _text; }
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
ChangeMediaPlayer(_mediaPlayer);
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
ChangeMediaPlayer(null);
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
// TODO: Currently we need to call this each frame, as when it is called right after SetText()
|
||||
// the ContentSizeFitter hasn't run yet, so effectively the box is a frame behind.
|
||||
UpdateBackgroundRect();
|
||||
}
|
||||
|
||||
public void ChangeMediaPlayer(MediaPlayer newPlayer)
|
||||
{
|
||||
// When changing the media player, handle event subscriptions
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
_mediaPlayer.Events.RemoveListener(OnMediaPlayerEvent);
|
||||
_mediaPlayer = null;
|
||||
}
|
||||
|
||||
SetText(string.Empty);
|
||||
|
||||
if (newPlayer != null)
|
||||
{
|
||||
newPlayer.Events.AddListener(OnMediaPlayerEvent);
|
||||
_mediaPlayer = newPlayer;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetText(string text)
|
||||
{
|
||||
_text.text = text;
|
||||
UpdateBackgroundRect();
|
||||
}
|
||||
|
||||
private string PrepareText(string text)
|
||||
{
|
||||
// Crop text that is too long
|
||||
if (_maxCharacters >= 0 && text.Length > _maxCharacters)
|
||||
{
|
||||
text = text.Substring(0, _maxCharacters);
|
||||
}
|
||||
|
||||
// Change RichText for Unity uGUI Text
|
||||
text = text.Replace("<font color=", "<color=");
|
||||
text = text.Replace("</font>", "</color>");
|
||||
text = text.Replace("<u>", string.Empty);
|
||||
text = text.Replace("</u>", string.Empty);
|
||||
return text;
|
||||
}
|
||||
|
||||
private void UpdateBackgroundRect()
|
||||
{
|
||||
if (_backgroundImage)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_text.text))
|
||||
{
|
||||
_backgroundImage.enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_backgroundImage.enabled = true;
|
||||
_backgroundImage.rectTransform.sizeDelta = _text.rectTransform.sizeDelta;
|
||||
_backgroundImage.rectTransform.anchoredPosition = _text.rectTransform.anchoredPosition;
|
||||
_backgroundImage.rectTransform.offsetMin -= new Vector2(_backgroundHorizontalPadding, _backgroundVerticalPadding);
|
||||
_backgroundImage.rectTransform.offsetMax += new Vector2(_backgroundHorizontalPadding, _backgroundVerticalPadding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Callback function to handle events
|
||||
private void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
|
||||
{
|
||||
switch (et)
|
||||
{
|
||||
case MediaPlayerEvent.EventType.Closing:
|
||||
{
|
||||
SetText(string.Empty);
|
||||
break;
|
||||
}
|
||||
case MediaPlayerEvent.EventType.SubtitleChange:
|
||||
{
|
||||
SetText(PrepareText(_mediaPlayer.Subtitles.GetSubtitleText()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d4bbe43657314a49a5f730e66dafebd
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: bb83b41b53a59874692b83eab5873998, type: 3}
|
||||
userData:
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "AVProVideo.Extensions.UnityUI",
|
||||
"references": [
|
||||
"AVProVideo.Runtime"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": []
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3bd657f68851a7f448c82186c6797ee0
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/AVProVideo/Extensions/VideoPlayer.meta
Normal file
8
Assets/AVProVideo/Extensions/VideoPlayer.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd124b806b72636469008bf42969d370
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/AVProVideo/Extensions/VideoPlayer/Editor.meta
Normal file
8
Assets/AVProVideo/Extensions/VideoPlayer/Editor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2aad57afcbe67ad4baddc85a2c4b8136
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,778 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AnimatedValues;
|
||||
using UnityEngine;
|
||||
using static RenderHeads.Media.AVProVideo.MediaPlayer;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2015-2024 RenderHeads Ltd. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace RenderHeads.Media.AVProVideo.Editor
|
||||
{
|
||||
[CanEditMultipleObjects]
|
||||
[CustomEditor(typeof(VideoPlayer_AVPro))]
|
||||
public partial class VideoPlayer_AVPro_Editor : UnityEditor.Editor
|
||||
{
|
||||
#region Variables
|
||||
SerializedProperty m_source;
|
||||
SerializedProperty m_clip;
|
||||
SerializedProperty m_url;
|
||||
SerializedProperty m_playOnAwake;
|
||||
SerializedProperty m_autoOpen;
|
||||
SerializedProperty m_loop;
|
||||
SerializedProperty m_skipOnDrop;
|
||||
SerializedProperty m_playbackSpeed;
|
||||
SerializedProperty m_renderMode;
|
||||
SerializedProperty m_targetMaterialRenderer;
|
||||
SerializedProperty m_targetMaterialName;
|
||||
SerializedProperty m_targetMaterial;
|
||||
SerializedProperty m_color;
|
||||
SerializedProperty m_aspectRatio;
|
||||
SerializedProperty m_aspectRatioRenderTexture;
|
||||
SerializedProperty m_fullscreen;
|
||||
SerializedProperty m_audioOutputMode;
|
||||
SerializedProperty m_controlledTracks;
|
||||
SerializedProperty m_volume;
|
||||
SerializedProperty m_muted;
|
||||
SerializedProperty m_audioSource;
|
||||
SerializedProperty m_canvas;
|
||||
SerializedProperty m_targetTexture;
|
||||
SerializedProperty m_uGUIComponent;
|
||||
SerializedProperty m_UVRect;
|
||||
SerializedProperty m_alpha;
|
||||
|
||||
|
||||
public readonly GUIContent sourceContent = EditorGUIUtility.TrTextContent("Source", "Type of source the media will be read from\n Reference - AVPro's VideoClip\n URL - Either path or URL");
|
||||
public readonly GUIContent clipContent = EditorGUIUtility.TrTextContent("Media Reference", "Can be created through the context menu. \n AVPro's VideoClip");
|
||||
public readonly GUIContent urlContent = EditorGUIUtility.TrTextContent("URL", "URLs\n Either URL or filepath");
|
||||
public readonly GUIContent playOnAwakeContent = EditorGUIUtility.TrTextContent("Play On Awake", "Start playback as soon as the game is started.");
|
||||
public readonly GUIContent autoOpenContent = EditorGUIUtility.TrTextContent("Auto Open", "Automatically opens the selected media as soon as the game is started");
|
||||
public readonly GUIContent loopContent = EditorGUIUtility.TrTextContent("Loop", "Start playback at the beginning when end is reached.");
|
||||
public readonly GUIContent playbackSpeedContent = EditorGUIUtility.TrTextContent("Playback Speed", "Increase or decrease the playback speed. 1.0 is the normal speed.");
|
||||
public readonly GUIContent renderModeContent = EditorGUIUtility.TrTextContent("Render Mode", "Type of object on which the played images will be drawn.");
|
||||
public readonly GUIContent rendererContent = EditorGUIUtility.TrTextContent("Renderer", "Renderer that the images will be displayed on");
|
||||
public readonly GUIContent texturePropertyContent = EditorGUIUtility.TrTextContent("Material Property", "Texture Property of the current material that will recive the images");
|
||||
public readonly GUIContent materialContent = EditorGUIUtility.TrTextContent("Material", "Material that the images will be writted to");
|
||||
public readonly GUIContent colorContent = EditorGUIUtility.TrTextContent("Color", "Default color");
|
||||
public readonly GUIContent aspectRatioContent = EditorGUIUtility.TrTextContent("Aspect Ratio", "How the video content will be fit into the target area");
|
||||
public readonly GUIContent fullscreenContent = EditorGUIUtility.TrTextContent("Fullscreen", "Force the video to take up the entire screen");
|
||||
public readonly GUIContent audioOutputModeContent = EditorGUIUtility.TrTextContent("Audio Output Mode", "where the audio of the video will be output");
|
||||
public readonly GUIContent volumeContent = EditorGUIUtility.TrTextContent("Volume", "Volume of the output audio");
|
||||
public readonly GUIContent mutedContent = EditorGUIUtility.TrTextContent("Mute", "Mute the audio");
|
||||
public readonly GUIContent audioSourceContent = EditorGUIUtility.TrTextContent("Audio Source", "AudioSource component that will recive this videos audio samples");
|
||||
public readonly GUIContent targetTextureContent = EditorGUIUtility.TrTextContent("Render Texture", "Render texture to draw the current frame to");
|
||||
public readonly GUIContent browseContent = EditorGUIUtility.TrTextContent("Browse...", "Click to set a file:// URL. http:// URLs have to be written or copy-pasted manually.");
|
||||
public readonly GUIContent uvRectContent = EditorGUIUtility.TrTextContent("UV", "Sets the UV rect of the image allowing, scaling and positioning of the image");
|
||||
public readonly GUIContent displayUGUIContent = EditorGUIUtility.TrTextContent("uGUI Component", "The UGUI componenet that will handle the rendering");
|
||||
public readonly GUIContent nativeSizeContent = EditorGUIUtility.TrTextContent("Set Native Size", "Sets the image to be its native size");
|
||||
public readonly GUIContent alphaContent = EditorGUIUtility.TrTextContent("Alpha", "Set the alpha of the video stream");
|
||||
//public readonly GUIContent = EditorGUIUtility.TrTextContent("", "");
|
||||
public readonly string uGUIUsageInformation = "Ensure you have placed a Display uGUI component on a GameObject containing a Canvas Renderer, and linked it with this";
|
||||
// local video path selection
|
||||
public readonly string selectMovieFile = "Select movie file.";
|
||||
public readonly string selectMovieFileRecentPath = "VideoPlayer_AVProSelectMovieFileRecentPath";
|
||||
public readonly string[] selectMovieFileFilter = {
|
||||
L10n.Tr("Movie files"), "asf,avi,dv,m4v,mp4,mov,mpg,mpeg,m4v,ogv,vp8,webm,wmv",
|
||||
L10n.Tr("All files"), "*"
|
||||
};
|
||||
|
||||
#if UNITY_STANDALONE_WIN
|
||||
// facebook 360 audio options
|
||||
private readonly string _optionAudio360ChannelModeName = ".audio360ChannelMode";
|
||||
#endif
|
||||
private readonly GUIContent _optionAudio360ChannelModeContent = new GUIContent("Channel Mode", "Specifies what channel mode Facebook Audio 360 needs to be initialised with");
|
||||
private readonly GUIContent[] _audio360ChannelMapGuiNames =
|
||||
{
|
||||
new GUIContent("(TBE_8_2) 8 channels of hybrid TBE ambisonics and 2 channels of head-locked stereo audio"),
|
||||
new GUIContent("(TBE_8) 8 channels of hybrid TBE ambisonics. NO head-locked stereo audio"),
|
||||
new GUIContent("(TBE_6_2) 6 channels of hybrid TBE ambisonics and 2 channels of head-locked stereo audio"),
|
||||
new GUIContent("(TBE_6) 6 channels of hybrid TBE ambisonics. NO head-locked stereo audio"),
|
||||
new GUIContent("(TBE_4_2) 4 channels of hybrid TBE ambisonics and 2 channels of head-locked stereo audio"),
|
||||
new GUIContent("(TBE_4) 4 channels of hybrid TBE ambisonics. NO head-locked stereo audio"),
|
||||
|
||||
new GUIContent("(TBE_8_PAIR0) Channels 1 and 2 of TBE hybrid ambisonics"),
|
||||
new GUIContent("(TBE_8_PAIR1) Channels 3 and 4 of TBE hybrid ambisonics"),
|
||||
new GUIContent("(TBE_8_PAIR2) Channels 5 and 6 of TBE hybrid ambisonics"),
|
||||
new GUIContent("(TBE_8_PAIR3) Channels 7 and 8 of TBE hybrid ambisonics"),
|
||||
|
||||
new GUIContent("(TBE_CHANNEL0) Channels 1 of TBE hybrid ambisonics"),
|
||||
new GUIContent("(TBE_CHANNEL1) Channels 2 of TBE hybrid ambisonics"),
|
||||
new GUIContent("(TBE_CHANNEL2) Channels 3 of TBE hybrid ambisonics"),
|
||||
new GUIContent("(TBE_CHANNEL3) Channels 4 of TBE hybrid ambisonics"),
|
||||
new GUIContent("(TBE_CHANNEL4) Channels 5 of TBE hybrid ambisonics"),
|
||||
new GUIContent("(TBE_CHANNEL5) Channels 6 of TBE hybrid ambisonics"),
|
||||
new GUIContent("(TBE_CHANNEL6) Channels 7 of TBE hybrid ambisonics"),
|
||||
new GUIContent("(TBE_CHANNEL7) Channels 8 of TBE hybrid ambisonics"),
|
||||
|
||||
new GUIContent("(HEADLOCKED_STEREO) Head-locked stereo audio"),
|
||||
new GUIContent("(HEADLOCKED_CHANNEL0) Channels 1 or left of head-locked stereo audio"),
|
||||
new GUIContent("(HEADLOCKED_CHANNEL1) Channels 2 or right of head-locked stereo audio"),
|
||||
|
||||
new GUIContent("(AMBIX_4) 4 channels of first order ambiX"),
|
||||
new GUIContent("(AMBIX_4_2) 4 channels of first order ambiX with 2 channels of head-locked audio"),
|
||||
new GUIContent("(AMBIX_9) 9 channels of second order ambiX"),
|
||||
new GUIContent("(AMBIX_9_2) 9 channels of second order ambiX with 2 channels of head-locked audio"),
|
||||
new GUIContent("(AMBIX_16) 16 channels of third order ambiX"),
|
||||
new GUIContent("(AMBIX_16_2) 16 channels of third order ambiX with 2 channels of head-locked audio"),
|
||||
|
||||
new GUIContent("(MONO) Mono audio"),
|
||||
new GUIContent("(STEREO) Stereo audio"),
|
||||
};
|
||||
|
||||
// material options
|
||||
private GUIContent[] _materialTextureProperties = new GUIContent[0];
|
||||
private readonly GUIContent _guiTextTextureProperty = new GUIContent("Texture Property", "Texture Property of the current material that will recive the images");
|
||||
|
||||
// animations
|
||||
readonly AnimBool m_SourceReference = new AnimBool();
|
||||
readonly AnimBool m_SourceUrl = new AnimBool();
|
||||
readonly AnimBool m_RenderMesh = new AnimBool();
|
||||
readonly AnimBool m_RenderMaterial = new AnimBool();
|
||||
readonly AnimBool m_RenderuGUI = new AnimBool();
|
||||
readonly AnimBool m_RenderIMGUI = new AnimBool();
|
||||
readonly AnimBool m_RenderFarPlane = new AnimBool();
|
||||
readonly AnimBool m_RenderTexture = new AnimBool();
|
||||
readonly AnimBool m_AudioOutSystem = new AnimBool();
|
||||
readonly AnimBool m_AudioOutUnity = new AnimBool();
|
||||
readonly AnimBool m_AudioOutFacebook = new AnimBool();
|
||||
readonly AnimBool m_AudioOutNone = new AnimBool();
|
||||
|
||||
#endregion Variables
|
||||
|
||||
#region Enable/Disable
|
||||
void OnEnable()
|
||||
{
|
||||
m_SourceReference.valueChanged.AddListener(Repaint);
|
||||
m_SourceUrl.valueChanged.AddListener(Repaint);
|
||||
m_RenderMesh.valueChanged.AddListener(Repaint);
|
||||
m_RenderMaterial.valueChanged.AddListener(Repaint);
|
||||
m_RenderuGUI.valueChanged.AddListener(Repaint);
|
||||
m_RenderIMGUI.valueChanged.AddListener(Repaint);
|
||||
m_RenderFarPlane.valueChanged.AddListener(Repaint);
|
||||
m_RenderTexture.valueChanged.AddListener(Repaint);
|
||||
m_AudioOutSystem.valueChanged.AddListener(Repaint);
|
||||
m_AudioOutUnity.valueChanged.AddListener(Repaint);
|
||||
m_AudioOutFacebook.valueChanged.AddListener(Repaint);
|
||||
m_AudioOutNone.valueChanged.AddListener(Repaint);
|
||||
|
||||
m_source = serializedObject.FindProperty("Source");
|
||||
m_clip = serializedObject.FindProperty("Clip");
|
||||
m_url = serializedObject.FindProperty("Url");
|
||||
m_playOnAwake = serializedObject.FindProperty("PlayOnAwake");
|
||||
m_autoOpen = serializedObject.FindProperty("AutoOpening");
|
||||
m_loop = serializedObject.FindProperty("IsLooping");
|
||||
m_skipOnDrop = serializedObject.FindProperty("SkipOnDrop");
|
||||
m_playbackSpeed = serializedObject.FindProperty("PlaybackSpeed");
|
||||
m_renderMode = serializedObject.FindProperty("RenderMode");
|
||||
m_targetMaterialRenderer = serializedObject.FindProperty("TargetMaterialRenderer");
|
||||
m_targetMaterialName = serializedObject.FindProperty("TargetMateralProperty");
|
||||
m_targetMaterial = serializedObject.FindProperty("TargetMaterial");
|
||||
m_color = serializedObject.FindProperty("Colour");
|
||||
m_aspectRatio = serializedObject.FindProperty("AspectRatio");
|
||||
m_aspectRatioRenderTexture = serializedObject.FindProperty("AspectRatioRenderTexture");
|
||||
m_fullscreen = serializedObject.FindProperty("Fullscreen");
|
||||
m_audioOutputMode = serializedObject.FindProperty("AudioOutputMode");
|
||||
m_controlledTracks = serializedObject.FindProperty("ControlledAudioTrackCount");
|
||||
m_volume = serializedObject.FindProperty("Volume");
|
||||
m_muted = serializedObject.FindProperty("Muted");
|
||||
m_audioSource = serializedObject.FindProperty("AudioSourceE");
|
||||
m_canvas = serializedObject.FindProperty("canvasObj");
|
||||
m_targetTexture = serializedObject.FindProperty("TargetTexture");
|
||||
m_uGUIComponent = serializedObject.FindProperty("displayUGUI");
|
||||
m_UVRect = serializedObject.FindProperty("UVRect");
|
||||
m_alpha = serializedObject.FindProperty("TargetCameraAlpha");
|
||||
|
||||
m_SourceReference.value = m_source.intValue == 0;
|
||||
m_SourceUrl.value = m_source.intValue == 1;
|
||||
m_RenderMesh.value = m_renderMode.intValue == 0;
|
||||
m_RenderMaterial.value = m_renderMode.intValue == 1;
|
||||
m_RenderuGUI.value = m_renderMode.intValue == 2;
|
||||
m_RenderIMGUI.value = m_renderMode.intValue == 3;
|
||||
m_RenderFarPlane.value = m_renderMode.intValue == 4;
|
||||
m_RenderTexture.value = m_renderMode.intValue == 5;
|
||||
m_AudioOutSystem.value = m_audioOutputMode.intValue == 0;
|
||||
m_AudioOutUnity.value = m_audioOutputMode.intValue == 1;
|
||||
m_AudioOutFacebook.value = m_audioOutputMode.intValue == 2;
|
||||
m_AudioOutNone.value = m_audioOutputMode.intValue == 3;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
m_SourceReference.valueChanged.RemoveListener(Repaint);
|
||||
m_SourceUrl.valueChanged.RemoveListener(Repaint);
|
||||
m_RenderMesh.valueChanged.RemoveListener(Repaint);
|
||||
m_RenderMaterial.valueChanged.RemoveListener(Repaint);
|
||||
m_RenderuGUI.valueChanged.RemoveListener(Repaint);
|
||||
m_RenderIMGUI.valueChanged.RemoveListener(Repaint);
|
||||
m_RenderFarPlane.valueChanged.RemoveListener(Repaint);
|
||||
m_RenderTexture.valueChanged.RemoveListener(Repaint);
|
||||
m_AudioOutSystem.valueChanged.RemoveListener(Repaint);
|
||||
m_AudioOutUnity.valueChanged.RemoveListener(Repaint);
|
||||
m_AudioOutFacebook.valueChanged.RemoveListener(Repaint);
|
||||
m_AudioOutNone.valueChanged.RemoveListener(Repaint);
|
||||
}
|
||||
|
||||
#endregion Enable/Disable
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
VideoPlayer_AVPro player = (VideoPlayer_AVPro)target;
|
||||
serializedObject.Update();
|
||||
|
||||
// Media Source
|
||||
HandleSourceField(player);
|
||||
|
||||
// Play on awake
|
||||
EditorGUILayout.PropertyField(m_playOnAwake, playOnAwakeContent);
|
||||
if (m_playOnAwake.serializedObject.ApplyModifiedProperties())
|
||||
player.playOnAwake = m_playOnAwake.boolValue;
|
||||
|
||||
// auto open
|
||||
EditorGUILayout.PropertyField(m_autoOpen, autoOpenContent);
|
||||
if (m_autoOpen.serializedObject.ApplyModifiedProperties())
|
||||
player.AutoOpen = m_autoOpen.boolValue;
|
||||
|
||||
// Loop
|
||||
EditorGUILayout.PropertyField(m_loop, loopContent);
|
||||
if (m_loop.serializedObject.ApplyModifiedProperties())
|
||||
player.isLooping = m_loop.boolValue;
|
||||
|
||||
// Playback Speed
|
||||
EditorGUILayout.Slider(m_playbackSpeed, -4f, 4f, playbackSpeedContent);
|
||||
if (m_playbackSpeed.serializedObject.ApplyModifiedProperties())
|
||||
player.playbackSpeed = m_playbackSpeed.floatValue;
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
|
||||
// Render Mode
|
||||
HandleRenderModeField(player);
|
||||
|
||||
// Audio Output Mode
|
||||
HandleAudioOutputModeField(player);
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
#region GUI Handlers
|
||||
|
||||
#region Source Field
|
||||
/// <summary>
|
||||
/// Draws the source field, giving functionality to both the Path/URL, <see cref="MediaReference"/> fields
|
||||
/// </summary>
|
||||
/// <param name="player"><see cref="VideoPlayer_AVPro"/> to use</param>
|
||||
public void HandleSourceField(VideoPlayer_AVPro player)
|
||||
{
|
||||
// to be used within the fadegroups, resulting in only the selected group being shown.
|
||||
m_SourceReference.target = m_source.intValue == 0;
|
||||
m_SourceUrl.target = m_source.intValue == 1;
|
||||
|
||||
// Source Type
|
||||
EditorGUILayout.PropertyField(m_source, sourceContent);
|
||||
// the below code will be used whenever we need to update the value on the target object
|
||||
// to reduce performnace cost, and infinite calls this is only updated when the UI for
|
||||
// that value is changed
|
||||
if (m_source.serializedObject.ApplyModifiedProperties())
|
||||
player.sourceAVPro = (MediaSource)m_source.enumValueIndex;
|
||||
|
||||
// Reference (MediaReference)
|
||||
EditorGUI.indentLevel++;
|
||||
if (EditorGUILayout.BeginFadeGroup(m_SourceReference.faded))
|
||||
{
|
||||
EditorGUILayout.PropertyField(m_clip, clipContent);
|
||||
if (m_clip.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
player.clip = (MediaReference)m_clip.objectReferenceValue;
|
||||
}
|
||||
|
||||
}
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
|
||||
// URL
|
||||
if (EditorGUILayout.BeginFadeGroup(m_SourceUrl.faded))
|
||||
{
|
||||
// URL (web)
|
||||
EditorGUILayout.PropertyField(m_url, urlContent);
|
||||
// BROWSE (local)
|
||||
Rect browseRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight);
|
||||
browseRect.xMin += EditorGUIUtility.labelWidth;
|
||||
browseRect.xMax = browseRect.xMin + GUI.skin.label.CalcSize(browseContent).x + 10;
|
||||
if (EditorGUI.DropdownButton(
|
||||
browseRect, browseContent, FocusType.Passive, GUI.skin.button))
|
||||
{
|
||||
string path = EditorUtility.OpenFilePanelWithFilters(
|
||||
selectMovieFile,
|
||||
EditorPrefs.GetString(selectMovieFileRecentPath),
|
||||
selectMovieFileFilter);
|
||||
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
m_url.stringValue = "file://" + path;
|
||||
EditorPrefs.SetString(selectMovieFileRecentPath, path);
|
||||
}
|
||||
if (m_url.serializedObject.ApplyModifiedProperties())
|
||||
player.url = new MediaPath(m_url.stringValue, MediaPathType.AbsolutePathOrURL);
|
||||
EditorGUIUtility.ExitGUI();
|
||||
}
|
||||
if (m_url.serializedObject.ApplyModifiedProperties())
|
||||
player.url = new MediaPath(m_url.stringValue, MediaPathType.AbsolutePathOrURL);
|
||||
}
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Render Mode Field
|
||||
/// <summary>
|
||||
/// Handles Drawing all the differernt rendering options to the inspector,
|
||||
/// with only the current selected being shown.
|
||||
/// </summary>
|
||||
/// <param name="player"><see cref="VideoPlayer_AVPro "/> to use</param>
|
||||
public void HandleRenderModeField(VideoPlayer_AVPro player)
|
||||
{
|
||||
// current rendering mode
|
||||
EditorGUILayout.PropertyField(m_renderMode, renderModeContent);
|
||||
if (m_renderMode.serializedObject.ApplyModifiedProperties())
|
||||
player.rendererMode = (DisplayType)m_renderMode.enumValueIndex;
|
||||
|
||||
// setup fade groups to only show the active render mode
|
||||
m_RenderMesh.target = m_renderMode.intValue == 0;
|
||||
m_RenderMaterial.target = m_renderMode.intValue == 1;
|
||||
m_RenderuGUI.target = m_renderMode.intValue == 2;
|
||||
m_RenderIMGUI.target = m_renderMode.intValue == 3;
|
||||
m_RenderFarPlane.target = m_renderMode.intValue == 4;
|
||||
m_RenderTexture.target = m_renderMode.intValue == 5;
|
||||
|
||||
// Note:
|
||||
// - the fade groups dont work here as the AddComponent breaks them (they dont fade), their does not seem to
|
||||
// be any way of fixing it
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
// render mesh
|
||||
if (EditorGUILayout.BeginFadeGroup(m_RenderMesh.faded))
|
||||
{
|
||||
if (player.applyToMesh)
|
||||
{
|
||||
// target remderer
|
||||
EditorGUILayout.PropertyField(m_targetMaterialRenderer, rendererContent);
|
||||
if (m_targetMaterialRenderer.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
Debug.Log("Sertting Target Renderer to: " + (Renderer)m_targetMaterialRenderer.objectReferenceValue);
|
||||
player.applyToMesh.MeshRenderer = (Renderer)m_targetMaterialRenderer.objectReferenceValue;
|
||||
player.targetMaterialRenderer = (Renderer)m_targetMaterialRenderer.objectReferenceValue;
|
||||
}
|
||||
// material properties
|
||||
DrawMaterialPropertieDropdown(m_targetMaterialRenderer, m_targetMaterialName, DisplayType.Mesh);
|
||||
if (m_targetMaterialName.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
player.applyToMesh.TexturePropertyName = m_targetMaterialName.stringValue;
|
||||
player.targetMateralProperty = m_targetMaterialName.stringValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
|
||||
// render material
|
||||
if (EditorGUILayout.BeginFadeGroup(m_RenderMaterial.faded))
|
||||
{
|
||||
if (player.applyToMaterial)
|
||||
{
|
||||
// target material
|
||||
EditorGUILayout.PropertyField(m_targetMaterial, materialContent);
|
||||
if (m_targetMaterial.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
player.applyToMaterial.Material = (Material)m_targetMaterial.objectReferenceValue;
|
||||
player.targetMaterial = (Material)m_targetMaterial.objectReferenceValue;
|
||||
}
|
||||
// material properties
|
||||
DrawMaterialPropertieDropdown(m_targetMaterial, m_targetMaterialName, DisplayType.Material);
|
||||
if (m_targetMaterialName.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
player.applyToMaterial.TexturePropertyName = m_targetMaterialName.stringValue;
|
||||
player.targetMateralProperty = m_targetMaterialName.stringValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
|
||||
// uGUI
|
||||
if (EditorGUILayout.BeginFadeGroup(m_RenderuGUI.faded))
|
||||
{
|
||||
EditorGUILayout.PropertyField(m_uGUIComponent, displayUGUIContent);
|
||||
// when the user has not set a the uGUI componenet, infom them that they need to set this component
|
||||
// and where they need to set it.
|
||||
if (!player.displayUGUI)
|
||||
{
|
||||
EditorGUILayout.HelpBox(uGUIUsageInformation, MessageType.Info, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// color
|
||||
EditorGUILayout.PropertyField(m_color, colorContent);
|
||||
if (m_color.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
player.displayUGUI.color = m_color.colorValue;
|
||||
player.color = m_color.colorValue;
|
||||
}
|
||||
// UV
|
||||
EditorGUILayout.PropertyField(m_UVRect, uvRectContent);
|
||||
if (m_UVRect.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
player.uvRect = m_UVRect.rectValue;
|
||||
}
|
||||
// Native (using full screen, as their is no need to create another serialized property,
|
||||
// so just use fullscreen)
|
||||
EditorGUILayout.PropertyField(m_fullscreen, nativeSizeContent);
|
||||
if (m_fullscreen.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
player.displayUGUI.ApplyNativeSize = m_fullscreen.boolValue;
|
||||
player.fullScreen = m_fullscreen.boolValue;
|
||||
}
|
||||
// Scale
|
||||
EditorGUILayout.PropertyField(m_aspectRatio, aspectRatioContent);
|
||||
if (m_aspectRatio.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
player.displayUGUI.ScaleMode = (ScaleMode)m_aspectRatio.enumValueIndex;
|
||||
player.aspectRatio = (ScaleMode)m_aspectRatio.enumValueIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
|
||||
// render IMGUI
|
||||
if (EditorGUILayout.BeginFadeGroup(m_RenderIMGUI.faded))
|
||||
{
|
||||
if (player.displayIMGUI)
|
||||
{
|
||||
// Fullscreen
|
||||
EditorGUILayout.PropertyField(m_fullscreen, fullscreenContent);
|
||||
if (m_fullscreen.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
player.displayIMGUI.IsAreaFullScreen = m_fullscreen.boolValue;
|
||||
player.fullScreen = m_fullscreen.boolValue;
|
||||
}
|
||||
// color
|
||||
EditorGUILayout.PropertyField(m_color, colorContent);
|
||||
if (m_color.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
player.displayIMGUI.Color = m_color.colorValue;
|
||||
player.color = m_color.colorValue;
|
||||
}
|
||||
// scale mode
|
||||
EditorGUILayout.PropertyField(m_aspectRatio, aspectRatioContent);
|
||||
if (m_aspectRatio.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
player.displayIMGUI.ScaleMode = (ScaleMode)m_aspectRatio.enumValueIndex;
|
||||
player.aspectRatio = (ScaleMode)m_aspectRatio.enumValueIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
|
||||
// render far plane
|
||||
if (EditorGUILayout.BeginFadeGroup(m_RenderFarPlane.faded))
|
||||
{
|
||||
if (player.applyToFarPlane)
|
||||
{
|
||||
// Color
|
||||
EditorGUILayout.PropertyField(m_color, colorContent);
|
||||
if (m_color.serializedObject.ApplyModifiedProperties())
|
||||
player.color = m_color.colorValue;
|
||||
// aspect ratio (scale mode)
|
||||
EditorGUILayout.PropertyField(m_aspectRatioRenderTexture, aspectRatioContent);
|
||||
if (m_aspectRatioRenderTexture.serializedObject.ApplyModifiedProperties())
|
||||
player.aspectRatioRenderTexture = (VideoResolveOptions.AspectRatio)m_aspectRatioRenderTexture.enumValueIndex;
|
||||
// alpha
|
||||
EditorGUILayout.Slider(m_alpha, 0, 1, alphaContent);
|
||||
if (m_alpha.serializedObject.ApplyModifiedProperties())
|
||||
player.targetCameraAlpha = m_alpha.floatValue;
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
|
||||
// render texture
|
||||
if (EditorGUILayout.BeginFadeGroup(m_RenderTexture.faded))
|
||||
{
|
||||
if (player.applyToTexture)
|
||||
{
|
||||
// target texture
|
||||
EditorGUILayout.PropertyField(m_targetTexture, targetTextureContent);
|
||||
if (m_targetTexture.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
player.applyToTexture.ExternalTexture = (RenderTexture)m_targetTexture.objectReferenceValue;
|
||||
player.targetTexture = (RenderTexture)m_targetTexture.objectReferenceValue;
|
||||
}
|
||||
// aspect ratio
|
||||
EditorGUILayout.PropertyField(m_aspectRatioRenderTexture, aspectRatioContent);
|
||||
if (m_aspectRatioRenderTexture.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
var options = player.applyToTexture.VideoResolveOptions;
|
||||
options.aspectRatio = (VideoResolveOptions.AspectRatio)m_aspectRatioRenderTexture.enumValueIndex;
|
||||
player.applyToTexture.VideoResolveOptions = options;
|
||||
player.aspectRatioRenderTexture = (VideoResolveOptions.AspectRatio)m_aspectRatioRenderTexture.enumValueIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
EditorGUILayout.Space(10);
|
||||
}
|
||||
#endregion Render Mode Field
|
||||
|
||||
#region Audio Output Field
|
||||
/// <summary>
|
||||
/// Handles drawing the Audio Output options for the inspector, based on the current
|
||||
/// output mode that has been selected
|
||||
/// </summary>
|
||||
/// <param name="player"><see cref="VideoPlayer_AVPro"/> that is being used</param>
|
||||
public void HandleAudioOutputModeField(VideoPlayer_AVPro player)
|
||||
{
|
||||
// output mode
|
||||
EditorGUILayout.PropertyField(m_audioOutputMode, audioOutputModeContent);
|
||||
if (m_audioOutputMode.serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
player.audioOutputModeAVPro = (Windows.AudioOutput)m_audioOutputMode.enumValueIndex;
|
||||
#elif UNITY_WSA_10_0
|
||||
player.audioOutputModeAVPro = (WindowsUWP.AudioOutput)m_audioOutputMode.enumValueIndex;
|
||||
#elif UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX || UNITY_TVOS || UNITY_VISIONOS
|
||||
player.audioOutputModeAVPro = (PlatformOptions.AudioMode)m_audioOutputMode.enumValueIndex;
|
||||
#endif
|
||||
}
|
||||
|
||||
// setup fade groups to only show the active audio mode
|
||||
m_AudioOutSystem.target = m_audioOutputMode.intValue == 0;
|
||||
m_AudioOutUnity.target = m_audioOutputMode.intValue == 1;
|
||||
m_AudioOutFacebook.target = m_audioOutputMode.intValue == 2;
|
||||
m_AudioOutNone.target = m_audioOutputMode.intValue == 3;
|
||||
|
||||
#if UNITY_STANDALONE_WIN
|
||||
EditorGUI.indentLevel++;
|
||||
// system audio
|
||||
if (EditorGUILayout.BeginFadeGroup(m_AudioOutSystem.faded))
|
||||
{
|
||||
// volume
|
||||
EditorGUILayout.Slider(m_volume, 0f, 1f, volumeContent);
|
||||
if (m_volume.serializedObject.ApplyModifiedProperties())
|
||||
player.volume = m_volume.floatValue;
|
||||
// muted
|
||||
EditorGUILayout.PropertyField(m_muted, mutedContent);
|
||||
if (m_muted.serializedObject.ApplyModifiedProperties())
|
||||
player.muted = m_muted.boolValue;
|
||||
}
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
|
||||
// unity audio
|
||||
if (EditorGUILayout.BeginFadeGroup(m_AudioOutUnity.faded))
|
||||
{
|
||||
// audio source
|
||||
EditorGUILayout.PropertyField(m_audioSource, audioSourceContent);
|
||||
if (m_audioSource.serializedObject.ApplyModifiedProperties())
|
||||
player.audioSource = (AudioSource)m_audioSource.objectReferenceValue;
|
||||
// vlumvolume
|
||||
EditorGUILayout.Slider(m_volume, 0f, 1f, volumeContent);
|
||||
if (m_volume.serializedObject.ApplyModifiedProperties())
|
||||
player.volume = m_volume.floatValue;
|
||||
// muted
|
||||
EditorGUILayout.PropertyField(m_muted, mutedContent);
|
||||
if (m_muted.serializedObject.ApplyModifiedProperties())
|
||||
player.muted = m_muted.boolValue;
|
||||
}
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
|
||||
// facebook audio
|
||||
if (EditorGUILayout.BeginFadeGroup(m_AudioOutFacebook.faded))
|
||||
{
|
||||
// Channel Mode (Only Windows and Android can change this value)
|
||||
#if UNITY_STANDALONE_WIN || UNITY_ANDROID
|
||||
var optionsVarName = "_optionsWindows";
|
||||
DisplayPlatformOptionEnum(this.serializedObject, optionsVarName + _optionAudio360ChannelModeName, _optionAudio360ChannelModeContent, _audio360ChannelMapGuiNames);
|
||||
#endif
|
||||
|
||||
// Device (Windows Only)
|
||||
#if UNITY_STANDALONE_WIN
|
||||
SerializedProperty propForceAudioOutputDeviceName = serializedObject.FindProperty(optionsVarName + ".forceAudioOutputDeviceName");
|
||||
if (propForceAudioOutputDeviceName != null)
|
||||
{
|
||||
string[] deviceNames = { "Default", Windows.AudioDeviceOutputName_Rift, Windows.AudioDeviceOutputName_Vive, "Custom" };
|
||||
int index = 0;
|
||||
if (!string.IsNullOrEmpty(propForceAudioOutputDeviceName.stringValue))
|
||||
{
|
||||
switch (propForceAudioOutputDeviceName.stringValue)
|
||||
{
|
||||
case Windows.AudioDeviceOutputName_Rift:
|
||||
index = 1;
|
||||
break;
|
||||
case Windows.AudioDeviceOutputName_Vive:
|
||||
index = 2;
|
||||
break;
|
||||
default:
|
||||
index = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int newIndex = EditorGUILayout.Popup("Audio Device Name", index, deviceNames);
|
||||
if (newIndex == 0)
|
||||
{
|
||||
propForceAudioOutputDeviceName.stringValue = string.Empty;
|
||||
}
|
||||
else if (newIndex == 3)
|
||||
{
|
||||
if (index != newIndex)
|
||||
{
|
||||
if (string.IsNullOrEmpty(propForceAudioOutputDeviceName.stringValue) ||
|
||||
propForceAudioOutputDeviceName.stringValue == Windows.AudioDeviceOutputName_Rift ||
|
||||
propForceAudioOutputDeviceName.stringValue == Windows.AudioDeviceOutputName_Vive)
|
||||
{
|
||||
propForceAudioOutputDeviceName.stringValue = "?";
|
||||
}
|
||||
}
|
||||
EditorGUILayout.PropertyField(propForceAudioOutputDeviceName, new GUIContent("Audio Device Name", "Useful for VR when you need to output to the VR audio device"));
|
||||
}
|
||||
else
|
||||
{
|
||||
propForceAudioOutputDeviceName.stringValue = deviceNames[newIndex];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// volume
|
||||
EditorGUILayout.Slider(m_volume, 0f, 1f, volumeContent);
|
||||
if (m_volume.serializedObject.ApplyModifiedProperties())
|
||||
player.volume = m_volume.floatValue;
|
||||
// muted
|
||||
EditorGUILayout.PropertyField(m_muted, mutedContent);
|
||||
if (m_muted.serializedObject.ApplyModifiedProperties())
|
||||
player.muted = m_muted.boolValue;
|
||||
}
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
|
||||
if (EditorGUILayout.BeginFadeGroup(m_AudioOutNone.faded))
|
||||
{
|
||||
// Nothing for this little guy
|
||||
}
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
#endif
|
||||
}
|
||||
#endregion Audio Output Field
|
||||
|
||||
#endregion GUI Handlers
|
||||
|
||||
#region Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Draws the material properties as a dropdown
|
||||
/// </summary>
|
||||
/// <param name="renderer"><see cref="SerializedProperty"/> containing either a <see cref="Renderer"/> or <see cref="Material"/> to get the list of materials from</param>
|
||||
/// <param name="name">the name of the current selected material propertie</param>
|
||||
/// <param name="type">what the current <see cref="DisplayType"/> is</param>
|
||||
public void DrawMaterialPropertieDropdown(SerializedProperty renderer, SerializedProperty name, DisplayType type)
|
||||
{
|
||||
bool hasKeywords = false;
|
||||
int materialCount = 0;
|
||||
int texturePropertyIndex = 0;
|
||||
_materialTextureProperties = new GUIContent[0];
|
||||
if (renderer.objectReferenceValue != null)
|
||||
{
|
||||
List<Material> nonNullMaterials = new List<Material>();
|
||||
if (type == DisplayType.Mesh || type == DisplayType.CameraFarPlane || type == DisplayType.RenderTexture)
|
||||
{
|
||||
Renderer r = (Renderer)(renderer.objectReferenceValue);
|
||||
materialCount = r.sharedMaterials.Length;
|
||||
nonNullMaterials = new List<Material>(r.sharedMaterials);
|
||||
}
|
||||
else if (type == DisplayType.Material)
|
||||
{
|
||||
Material m = (Material)renderer.objectReferenceValue;
|
||||
materialCount = 1;
|
||||
nonNullMaterials = new List<Material>() { m };
|
||||
}
|
||||
// Remove any null materials (otherwise MaterialEditor.GetMaterialProperties() errors)
|
||||
for (int i = 0; i < nonNullMaterials.Count; i++)
|
||||
{
|
||||
if (nonNullMaterials[i] == null)
|
||||
{
|
||||
nonNullMaterials.RemoveAt(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
if (nonNullMaterials.Count > 0)
|
||||
{
|
||||
// Detect if there are any keywords
|
||||
foreach (Material mat in nonNullMaterials)
|
||||
{
|
||||
if (mat.shaderKeywords.Length > 0)
|
||||
{
|
||||
hasKeywords = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get unique list of texture property names
|
||||
List<GUIContent> items = new List<GUIContent>(16);
|
||||
List<string> textureNames = new List<string>(8);
|
||||
foreach (Material mat in nonNullMaterials)
|
||||
{
|
||||
// NOTE: we process each material separately instead of passing them all into MaterialEditor.GetMaterialProperties() as it errors if the materials have different properties
|
||||
MaterialProperty[] matProps = MaterialEditor.GetMaterialProperties(new UnityEngine.Object[] { mat });
|
||||
foreach (MaterialProperty matProp in matProps)
|
||||
{
|
||||
#if UNITY_6000_2_OR_NEWER
|
||||
if (matProp.propertyType == UnityEngine.Rendering.ShaderPropertyType.Texture)
|
||||
#else
|
||||
if (matProp.type == MaterialProperty.PropType.Texture)
|
||||
#endif
|
||||
{
|
||||
if (!textureNames.Contains(matProp.name))
|
||||
{
|
||||
if (matProp.name == name.stringValue)
|
||||
{
|
||||
texturePropertyIndex = items.Count;
|
||||
}
|
||||
textureNames.Add(matProp.name);
|
||||
items.Add(new GUIContent(matProp.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_materialTextureProperties = items.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
int newTexturePropertyIndex = EditorGUILayout.Popup(_guiTextTextureProperty, texturePropertyIndex, _materialTextureProperties);
|
||||
if (newTexturePropertyIndex >= 0 && newTexturePropertyIndex < _materialTextureProperties.Length)
|
||||
{
|
||||
name.stringValue = _materialTextureProperties[newTexturePropertyIndex].text;
|
||||
}
|
||||
|
||||
if (hasKeywords && name.stringValue != Helper.UnityBaseTextureName)
|
||||
{
|
||||
EditorGUILayout.HelpBox("When using an uber shader you may need to enable the keywords on a material for certain texture slots to take effect. You can sometimes achieve this (eg with Standard shader) by putting a dummy texture into the texture slot.", MessageType.Info);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays the platform options as an enum, this is used by facebook audio to convert <see cref="_audio360ChannelMapGuiNames"/>
|
||||
/// to a selectable enum
|
||||
/// </summary>
|
||||
/// <param name="so">The <see cref="SerializedObject"/> to use </param>
|
||||
/// <param name="fieldName">Name of the propertie attatched to the <see cref="SerializedObject"/></param>
|
||||
/// <param name="description"><see cref="GUIContent"/> to show as description</param>
|
||||
/// <param name="enumNames">list of names to convert into enum <see cref="_audio360ChannelMapGuiNames"/></param>
|
||||
/// <returns>The created <see cref="SerializedProperty"/> Enum containing all of the data from the inputterd <c>enumNames</c></returns>
|
||||
private static SerializedProperty DisplayPlatformOptionEnum(SerializedObject so, string fieldName, GUIContent description, GUIContent[] enumNames)
|
||||
{
|
||||
SerializedProperty prop = so.FindProperty(fieldName);
|
||||
if (prop != null)
|
||||
prop.enumValueIndex = EditorGUILayout.Popup(description, prop.enumValueIndex, enumNames);
|
||||
else
|
||||
Debug.LogWarning("Can't find property `" + fieldName + "`");
|
||||
return prop;
|
||||
}
|
||||
|
||||
#endregion Helpers
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fe6468cd70ffae49aac59cdc8288ca7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "_AVProVideo.Extensions.VideoPlayer.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:367c3c6f75a457f40a6e4cc7207b4438",
|
||||
"GUID:3ca842002c51d0a43b73e45298809a13",
|
||||
"GUID:3bd657f68851a7f448c82186c6797ee0"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f8bc0448be4d1a429da6d5434966567
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/AVProVideo/Extensions/VideoPlayer/Runtime.meta
Normal file
8
Assets/AVProVideo/Extensions/VideoPlayer/Runtime.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d344cf7c252267542827c6e0f67ad60f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 948fd3d3ecd4d0543b363b933cccd957
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: bb83b41b53a59874692b83eab5873998, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/AVProVideo/Extensions/VideoPlayer/Shaders.meta
Normal file
8
Assets/AVProVideo/Extensions/VideoPlayer/Shaders.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d21d56e3a2281184ea7ab971ac27e705
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,196 @@
|
||||
Shader "AVProVideo/Background/AVProVideo-ApplyToFarPlane"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex ("Texture", 2D) = "white" {}
|
||||
_ChromaTex ("Chroma", 2D) = "gray" {}
|
||||
_Color("Main Color", Color) = (1,1,1,1)
|
||||
[Toggle(APPLY_GAMMA)] _ApplyGamma("Apply Gamma", Float) = 0
|
||||
[Toggle(USE_YPCBCR)] _UseYpCbCr("Use YpCbCr", Float) = 0
|
||||
_Alpha("Alpha", Float) = 1
|
||||
_DrawOffset("Draw Offset", Vector) = (0,0,0,0)
|
||||
_CustomScale("Custom Scaling", Vector) = (0,0,0,0)
|
||||
_Aspect("Aspect Ratio", Float) = 1
|
||||
//_TargetCamID("Target Camera", Float) = 0
|
||||
//_CurrentCamID("Current Rendering Camera", Float) = 0
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
// this is the important part that makes it render behind all of the other object, we set it to be 0 in the queue
|
||||
// Geometry is 2000 and you cant just put a number so Geometry-2000 it is
|
||||
Tags { "Queue" = "Geometry-2000" "RenderType"="Opaque" }
|
||||
LOD 100
|
||||
// then set ZWrite to off so all other items are drawn infront of this one, this is important as the actual object
|
||||
// for this is at the near clipping plane of the camera
|
||||
ZWrite Off
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
// TODO: replace use multi_compile_local instead (Unity 2019.1 feature)
|
||||
#pragma multi_compile __ APPLY_GAMMA
|
||||
#pragma multi_compile __ USE_YPCBCR
|
||||
|
||||
#pragma multi_compile_fog
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "../../../Runtime/Shaders/AVProVideo.cginc"
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 vertex : SV_POSITION;
|
||||
};
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
#if USE_YPCBCR
|
||||
uniform sampler2D _ChromaTex;
|
||||
uniform float4x4 _YpCbCrTransform;
|
||||
#endif
|
||||
uniform float4 _MainTex_ST;
|
||||
uniform float4 _MainTex_TexelSize;
|
||||
uniform fixed4 _Color;
|
||||
uniform float _Alpha;
|
||||
uniform float2 _DrawOffset;
|
||||
uniform float _Aspect;
|
||||
uniform float2 _CustomScale;
|
||||
uniform int _TargetCamID;
|
||||
uniform int _CurrentCamID;
|
||||
|
||||
v2f vert(appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
// if our position is within 2 unitys of the camera position that is being rendered to
|
||||
if (_TargetCamID == _CurrentCamID)
|
||||
{
|
||||
// scaling
|
||||
float height = 1;
|
||||
float width = 1;
|
||||
// only use AspectRatio scaling if a custom scale has not been set
|
||||
if (_CustomScale.x == 0 || _CustomScale.y == 0)
|
||||
{
|
||||
float2 targetSize = float2(_MainTex_TexelSize.z, _MainTex_TexelSize.w);
|
||||
float2 currentSize = float2(_ScreenParams.x / 2, _ScreenParams.y / 2);
|
||||
float2 targetAreaSize = float2(_ScreenParams.x, _ScreenParams.y);
|
||||
float originalAspectRatio = targetSize.x / targetSize.y;
|
||||
float baseTextureAspectRatio = currentSize.x / currentSize.y;
|
||||
float targetAspectRatio = baseTextureAspectRatio;
|
||||
int finalWidth, finalHeight;
|
||||
|
||||
if (_Aspect == 0) // No Scaling
|
||||
{
|
||||
// no change wanted here so set the final size to be the size
|
||||
// of the orignal image
|
||||
finalWidth = (int)targetSize.x;
|
||||
finalHeight = (int)targetSize.y;
|
||||
}
|
||||
else if (_Aspect == 1) // Fit Vertically
|
||||
{
|
||||
// set the height to that of the target area then mutliply
|
||||
// the height by the orignal aspect ratio to ensure that the image
|
||||
// stays with the correct aspect.
|
||||
finalHeight = (int)targetAreaSize.y;
|
||||
finalWidth = round(finalHeight * originalAspectRatio);
|
||||
}
|
||||
else if (_Aspect == 2) // Fit Horizontally
|
||||
{
|
||||
// do the same as with FitVertically, just replace the width and heights
|
||||
finalWidth = (int)targetAreaSize.x;
|
||||
finalHeight = round(finalWidth / originalAspectRatio);
|
||||
}
|
||||
else if (_Aspect == 3) // Fit Inside
|
||||
{
|
||||
// if the width is larger then expand to be the same as the target area,
|
||||
// cropping the height
|
||||
if (targetAspectRatio < originalAspectRatio)
|
||||
{
|
||||
finalWidth = (int)targetAreaSize.x;
|
||||
finalHeight = round(finalWidth / originalAspectRatio);
|
||||
}
|
||||
// if the height is larger then expand to be the same as the target area,
|
||||
// cropping the width
|
||||
else
|
||||
{
|
||||
finalHeight = (int)targetAreaSize.y;
|
||||
finalWidth = round(finalHeight * originalAspectRatio);
|
||||
}
|
||||
}
|
||||
else if (_Aspect == 4) // Fit Outside
|
||||
{
|
||||
// if the width is smaller, then expand the width to be the same
|
||||
// size as the target then expand the height much like above to ensure
|
||||
// that the correct aspect ratio is kept
|
||||
if (targetAspectRatio > originalAspectRatio)
|
||||
{
|
||||
finalWidth = (int)targetAreaSize.x;
|
||||
finalHeight = round(finalWidth / originalAspectRatio);
|
||||
}
|
||||
// if the hight is small, expand that first then make the width follow
|
||||
else
|
||||
{
|
||||
finalHeight = (int)targetAreaSize.y;
|
||||
finalWidth = round(finalHeight * originalAspectRatio);
|
||||
}
|
||||
}
|
||||
else if (_Aspect == 5) // Stretch
|
||||
{
|
||||
// set the width and the height to be the same size as the target area
|
||||
finalWidth = (int)targetAreaSize.x;
|
||||
finalHeight = (int)targetAreaSize.y;
|
||||
}
|
||||
else // No Scalling
|
||||
{
|
||||
// make no change keeping them as the orignal texture size (1/4) of the screen
|
||||
finalWidth = (int)currentSize.x;
|
||||
finalHeight = (int)currentSize.y;
|
||||
}
|
||||
|
||||
height = (float)finalHeight / (float)_ScreenParams.y;
|
||||
width = (float)finalWidth / (float)_ScreenParams.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use custom scaling
|
||||
width = _CustomScale.x / (float)_ScreenParams.x;
|
||||
height = _CustomScale.y / (float)_ScreenParams.y;
|
||||
}
|
||||
float2 pos = (v.vertex.xy - float2(0.5, 0.5) + _DrawOffset.xy) * 2.0;
|
||||
pos.x *= width;
|
||||
pos.y *= height;
|
||||
|
||||
// flip if needed then done
|
||||
if (_ProjectionParams.x < 0.0)
|
||||
{
|
||||
pos.y = (1.0 - pos.y) - 1.0;
|
||||
}
|
||||
o.vertex = float4(pos.xy, UNITY_NEAR_CLIP_VALUE, 1.0);
|
||||
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
|
||||
return o;
|
||||
}
|
||||
else
|
||||
{
|
||||
o.vertex = UnityObjectToClipPos(float4(0,0,0,0));
|
||||
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
fixed4 frag (v2f i) : SV_Target
|
||||
{
|
||||
fixed4 col;
|
||||
#if USE_YPCBCR
|
||||
col = SampleYpCbCr(_MainTex, _ChromaTex, i.uv, _YpCbCrTransform);
|
||||
#else
|
||||
col = SampleRGBA(_MainTex, i.uv);
|
||||
#endif
|
||||
col *= _Color;
|
||||
// alpha now avaialbe to be controleld via user
|
||||
return fixed4(col.rgb, _Alpha);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7a0d37aa7b09cb418a93251d226558a
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "_AVProVideo.Extensions.VideoPlayer",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:3ca842002c51d0a43b73e45298809a13",
|
||||
"GUID:3bd657f68851a7f448c82186c6797ee0"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 367c3c6f75a457f40a6e4cc7207b4438
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/AVProVideo/Extensions/VisualEffectGraph.meta
Normal file
9
Assets/AVProVideo/Extensions/VisualEffectGraph.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 017104cd07f4a72439b9bb8ffd34b807
|
||||
folderAsset: yes
|
||||
timeCreated: 1587506896
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,152 @@
|
||||
// You need to define AVPRO_PACKAGE_VFXGRAPH manually to use this script
|
||||
// We could set up the asmdef to reference the package, but the package doesn't
|
||||
// existing in Unity 2017 etc, and it throws an error due to missing reference
|
||||
//#define AVPRO_PACKAGE_VFXGRAPH
|
||||
#if (UNITY_2018_3_OR_NEWER && AVPRO_PACKAGE_VFXGRAPH)
|
||||
using UnityEngine;
|
||||
using UnityEngine.VFX;
|
||||
using RenderHeads.Media.AVProVideo;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2019-2021 RenderHeads Ltd. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace RenderHeads.Media.AVProVideo
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the texture from the MediaPlayer to a texture parameter in a VFX Graph
|
||||
/// </summary>
|
||||
[AddComponentMenu("AVPro Video/Apply To VFX Graph", 300)]
|
||||
[HelpURL("http://renderheads.com/products/avpro-video/")]
|
||||
public class ApplyToVfxGraph : MonoBehaviour
|
||||
{
|
||||
[Header("Media Source")]
|
||||
|
||||
[SerializeField] MediaPlayer _mediaPlayer = null;
|
||||
|
||||
[Tooltip("Default texture to display when the video texture is preparing")]
|
||||
[SerializeField] Texture2D _defaultTexture = null;
|
||||
|
||||
[Space(8f)]
|
||||
[Header("VFX Target")]
|
||||
|
||||
[SerializeField] VisualEffect _visualEffect = null;
|
||||
[SerializeField] string _texturePropertyName = string.Empty;
|
||||
|
||||
public Texture2D DefaultTexture
|
||||
{
|
||||
get { return _defaultTexture; }
|
||||
set { if (_defaultTexture != value) { _defaultTexture = value; _isDirty = true; } }
|
||||
}
|
||||
|
||||
public VisualEffect VisualEffect
|
||||
{
|
||||
get { return _visualEffect; }
|
||||
set { _visualEffect = value; _isDirty = true; }
|
||||
}
|
||||
|
||||
public string TexturePropertyName
|
||||
{
|
||||
get { return _texturePropertyName; }
|
||||
set { _texturePropertyName = value; _textureProp = Shader.PropertyToID(_texturePropertyName); _isDirty = true; }
|
||||
}
|
||||
|
||||
public MediaPlayer MediaPlayer
|
||||
{
|
||||
get { return _mediaPlayer; }
|
||||
set { ChangeMediaPlayer(value); }
|
||||
}
|
||||
|
||||
private bool _isDirty = true;
|
||||
private int _textureProp = 0;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
// Force evaluations
|
||||
TexturePropertyName = _texturePropertyName;
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
_mediaPlayer.Events.AddListener(OnMediaPlayerEvent);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
void OnValidate()
|
||||
{
|
||||
_isDirty = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
_mediaPlayer.Events.RemoveListener(OnMediaPlayerEvent);
|
||||
}
|
||||
}
|
||||
|
||||
// Callback function to handle events
|
||||
private void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
|
||||
{
|
||||
switch (et)
|
||||
{
|
||||
case MediaPlayerEvent.EventType.FirstFrameReady:
|
||||
case MediaPlayerEvent.EventType.PropertiesChanged:
|
||||
ForceUpdate();
|
||||
break;
|
||||
case MediaPlayerEvent.EventType.Closing:
|
||||
_isDirty = true; // Allow the update to happen on the next frame, as the video is still closing
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeMediaPlayer(MediaPlayer player)
|
||||
{
|
||||
if (_mediaPlayer != player)
|
||||
{
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
_mediaPlayer.Events.RemoveListener(OnMediaPlayerEvent);
|
||||
}
|
||||
_mediaPlayer = player;
|
||||
if (_mediaPlayer != null)
|
||||
{
|
||||
_mediaPlayer.Events.AddListener(OnMediaPlayerEvent);
|
||||
}
|
||||
_isDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void ForceUpdate()
|
||||
{
|
||||
_isDirty = true;
|
||||
LateUpdate();
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
if (_isDirty)
|
||||
{
|
||||
ApplyMapping();
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyMapping()
|
||||
{
|
||||
if (_visualEffect != null && !string.IsNullOrEmpty(_texturePropertyName))
|
||||
{
|
||||
if (_mediaPlayer != null && _mediaPlayer.TextureProducer != null && _mediaPlayer.TextureProducer.GetTexture() != null)
|
||||
{
|
||||
_visualEffect.SetTexture(_textureProp, _mediaPlayer.TextureProducer.GetTexture());
|
||||
_isDirty = false;
|
||||
}
|
||||
else if (_defaultTexture != null)
|
||||
{
|
||||
_visualEffect.SetTexture(_textureProp, _defaultTexture);
|
||||
_isDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 876043e54db05b045a4c75425318e3f1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "AVProVideo.Extensions.VisualEffectGraph",
|
||||
"references": [
|
||||
"AVProVideo.Runtime"
|
||||
],
|
||||
"optionalUnityReferences": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": []
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 00c900f8a139a2540ab354c9ce09ac0e
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user