This commit is contained in:
parent
f6a5646d44
commit
bf0efcd1a2
|
@ -1 +1 @@
|
|||
Build from ADAM at 2024/5/22 16:57:32
|
||||
Build from LGZN_H at 2024/5/23 10:13:34
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e1af6d7538e0c4382940c502ac857197
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3f61b635b575947e9abfac04cb82067f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d81ee1045c91f4c79852f85367eb106a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e419cc8c4878947a5971402dbdec76f0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1038a3399a6af4c639c0851aede5495f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,78 +0,0 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: MockViewportMaterial
|
||||
m_Shader: {fileID: 10750, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords: _ALPHAPREMULTIPLY_ON _GLOSSYREFLECTIONS_OFF _SPECULARHIGHLIGHTS_OFF
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: -1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: 9f7b60728c99d4fe6b67e0d86b1e7b5e, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 10
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 0
|
||||
- _Metallic: 0
|
||||
- _Mode: 3
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 0
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 0
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_BuildTextureStacks: []
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1b0611231af614f7b91169ff83a790cd
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cc28f1f6b8abe41dba1a8aba8c0b501d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,196 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#if UNITY_ANDROID
|
||||
#pragma warning disable CS0618
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using Vuplex.WebView.Internal;
|
||||
|
||||
namespace Vuplex.WebView.Editor {
|
||||
|
||||
public static class AndroidEditorUtils {
|
||||
|
||||
public static void PreprocessBuild(string productName, string proguardRulesExpectedRelativePath, string nativeLibraryName, bool native2DSupported) {
|
||||
|
||||
_validateGraphicsApi(native2DSupported);
|
||||
_forceInternetPermission();
|
||||
_assertThatOculusLowOverheadModeIsDisabled();
|
||||
_assertThatSrpBatcherIsDisabled();
|
||||
_updateNativePluginSettings(nativeLibraryName);
|
||||
_updateProguardFileIfNeeded(productName, proguardRulesExpectedRelativePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the proguard-user.txt file if needed to prevent the names of 3D WebView's Java classes from being obfuscated.
|
||||
/// https://support.vuplex.com/articles/android-minification
|
||||
/// </summary>
|
||||
static void _updateProguardFileIfNeeded(string productName, string neededProguardRulesExpectedRelativePath) {
|
||||
|
||||
var minificationEnabled = false;
|
||||
// minifyDebug and minifyRelease were added in 2020.1.
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
minificationEnabled = EditorUserBuildSettings.development ? PlayerSettings.Android.minifyDebug : PlayerSettings.Android.minifyRelease;
|
||||
#endif
|
||||
if (!minificationEnabled) {
|
||||
return;
|
||||
}
|
||||
var neededProguardRulesFilePath = EditorUtils.FindFile(Path.Combine(Application.dataPath, neededProguardRulesExpectedRelativePath));
|
||||
var neededProguardRules = File.ReadAllText(neededProguardRulesFilePath);
|
||||
// Note: the prefix and suffix avoid using characters considered special characters in regexes, like parentheses.
|
||||
var prefix = $"# --- Start of section automatically included for {productName} - PLEASE DO NOT EDIT ---";
|
||||
var suffix = $"# --- End of section for {productName} ---";
|
||||
var fullTextToAdd = $"{prefix}\n{neededProguardRules}\n{suffix}";
|
||||
var androidPluginsFolderPath = Path.Combine(Application.dataPath, "Plugins", "Android");
|
||||
var proguardUserFilePath = Path.Combine(androidPluginsFolderPath, "proguard-user.txt");
|
||||
var proguardUserFileExists = File.Exists(proguardUserFilePath);
|
||||
if (proguardUserFileExists) {
|
||||
var existingFileText = File.ReadAllText(proguardUserFilePath);
|
||||
var existingWebViewProguardRulesRegex = new Regex($"{prefix}.*{suffix}", RegexOptions.Singleline);
|
||||
var existingWebViewProguardRulesResult = existingWebViewProguardRulesRegex.Match(existingFileText);
|
||||
if (existingWebViewProguardRulesResult.Success) {
|
||||
if (existingWebViewProguardRulesResult.Value != fullTextToAdd) {
|
||||
// The proguard-user.txt file contains an older version of the rules, so update them.
|
||||
var newFileText = existingFileText.Replace(existingWebViewProguardRulesResult.Value, fullTextToAdd);
|
||||
File.WriteAllText(proguardUserFilePath, newFileText);
|
||||
}
|
||||
} else {
|
||||
// A proguard-user.txt file exists, but it doesn't include the rules yet, so add them.
|
||||
var newFileText = existingFileText + "\n\n" + fullTextToAdd;
|
||||
File.WriteAllText(proguardUserFilePath, newFileText);
|
||||
}
|
||||
} else {
|
||||
// No proguard-user.txt file exists yet, so create the file.
|
||||
Directory.CreateDirectory(androidPluginsFolderPath);
|
||||
File.WriteAllText(proguardUserFilePath, fullTextToAdd);
|
||||
}
|
||||
}
|
||||
|
||||
static void _assertThatSrpBatcherIsDisabled() {
|
||||
|
||||
#if UNITY_2018_2_OR_NEWER && !VUPLEX_DISABLE_SRP_WARNING
|
||||
// Checking renderPipelineAsset is needed to verify that URP is enabled because useScriptableRenderPipelineBatching
|
||||
// can sometimes be true even when the built-in render pipeline is in use.
|
||||
if (GraphicsSettings.useScriptableRenderPipelineBatching && GraphicsSettings.renderPipelineAsset != null) {
|
||||
throw new BuildFailedException("URP settings error: \"SRP Batcher\" is enabled in Universal Render Pipeline (URP) settings, but URP for Android has an issue that prevents 3D WebView's textures from showing up outside of a Canvas. If the project uses a WebViewPrefab, please go to the URP Asset and disable \"SRP Batcher\". In newer versions of URP, it's necessary to click \"Show Additional Properties\" in order to show the SRP Batcher option, like described here: https://docs.unity3d.com/2021.3/Documentation/Manual/SRPBatcher.html . If the project only uses CanvasWebViewPrefab and not WebViewPrefab, you can instead add the scripting symbol VUPLEX_DISABLE_SRP_WARNING to the project to ignore this warning.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _assertThatOculusLowOverheadModeIsDisabled() {
|
||||
|
||||
if (!EditorUtils.XRSdkIsEnabled("oculus")) {
|
||||
return;
|
||||
}
|
||||
var lowOverheadModeEnabled = false;
|
||||
#if VUPLEX_OCULUS
|
||||
// The Oculus XR plugin is installed
|
||||
Unity.XR.Oculus.OculusLoader oculusLoader = Unity.XR.Oculus.OculusSettings.CreateInstance<Unity.XR.Oculus.OculusLoader>();
|
||||
Unity.XR.Oculus.OculusSettings oculusSettings = oculusLoader.GetSettings();
|
||||
lowOverheadModeEnabled = oculusSettings.LowOverheadMode;
|
||||
#elif UNITY_2019_2_OR_NEWER && !UNITY_2020_1_OR_NEWER
|
||||
// VROculus.lowOverheadMode is only supported from Unity 2019.2 - 2019.4
|
||||
lowOverheadModeEnabled = PlayerSettings.VROculus.lowOverheadMode;
|
||||
#endif
|
||||
if (lowOverheadModeEnabled) {
|
||||
throw new BuildFailedException("XR settings error: Vuplex 3D WebView requires that \"Low Overhead Mode\" be disabled in Oculus XR settings. Please disable Low Overhead Mode in Oculus XR settings.");
|
||||
}
|
||||
}
|
||||
|
||||
static void _forceInternetPermission() {
|
||||
|
||||
#if !VUPLEX_ANDROID_DISABLE_REQUIRE_INTERNET
|
||||
if (!PlayerSettings.Android.forceInternetPermission) {
|
||||
PlayerSettings.Android.forceInternetPermission = true;
|
||||
WebViewLogger.LogWarning("Just a heads-up: 3D WebView changed the Android player setting \"Internet Access\" to \"Require\" to ensure that it can fetch web pages from the internet. (This message will only be logged once.)");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _updateNativePluginSettings(string fileName) {
|
||||
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
var pluginAbsolutePaths = Directory.GetFiles(Application.dataPath, fileName, SearchOption.AllDirectories).ToList();
|
||||
// PluginImporter.GetAtPath() requires a relative path and doesn't support absolute paths.
|
||||
var pluginRelativePaths = pluginAbsolutePaths.Select(path => path.Replace(Application.dataPath, "Assets"));
|
||||
foreach (var filePath in pluginRelativePaths) {
|
||||
var pluginImporter = (PluginImporter)PluginImporter.GetAtPath(filePath);
|
||||
var changedSettings = false;
|
||||
// Set the libVuplexWebViewAndroid.so or libVuplexWebViewAndroidGecko.so plugin files to be preloaded, which is equivalent to
|
||||
// enabling their "Load on Startup" checkbox. This is done via a script because the .meta files
|
||||
// for these plugins was generated with an older version of Unity in order to be compatible with
|
||||
// 2018.4, which doesn't support the preload option. Enabling preloading is required for Vulkan support.
|
||||
if (!pluginImporter.isPreloaded) {
|
||||
pluginImporter.isPreloaded = true;
|
||||
changedSettings = true;
|
||||
}
|
||||
// Unity 2020.3 and newer support x86_64 for Chrome OS. 3D WebView ships x86_64 libraries, but they
|
||||
// are initially disabled because older versions of Unity can't handle if "CPU" is set to "X86_64".
|
||||
// So, we enable those x86_64 libraries dynamically here.
|
||||
#if UNITY_2020_3_OR_NEWER
|
||||
if (filePath.Contains("x86_64")) {
|
||||
if (!pluginImporter.GetCompatibleWithPlatform(BuildTarget.Android)) {
|
||||
pluginImporter.SetCompatibleWithPlatform(BuildTarget.Android, true);
|
||||
changedSettings = true;
|
||||
}
|
||||
if (pluginImporter.GetPlatformData(BuildTarget.Android, "CPU") != "X86_64") {
|
||||
pluginImporter.SetPlatformData(BuildTarget.Android, "CPU", "X86_64");
|
||||
changedSettings = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (changedSettings) {
|
||||
pluginImporter.SaveAndReimport();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _validateGraphicsApi(bool native2DSupported) {
|
||||
|
||||
#if !VUPLEX_DISABLE_GRAPHICS_API_WARNING
|
||||
var autoGraphicsApiEnabled = PlayerSettings.GetUseDefaultGraphicsAPIs(BuildTarget.Android);
|
||||
var selectedGraphicsApi = PlayerSettings.GetGraphicsAPIs(BuildTarget.Android)[0];
|
||||
var vulkanEnabled = selectedGraphicsApi == GraphicsDeviceType.Vulkan;
|
||||
if (!(vulkanEnabled || autoGraphicsApiEnabled)) {
|
||||
// OpenGLES is selected, so nothing to warn about.
|
||||
return;
|
||||
}
|
||||
var warningPrefix = autoGraphicsApiEnabled ? "Auto Graphics API is enabled in Player Settings, which means that the Vulkan Graphics API may be used."
|
||||
: "The Vulkan Graphics API is enabled in Player Settings.";
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
// At build time, XRSettings.enabled is always false, so to check if XR is enabled,
|
||||
// we must instead check whether XRSettings.supportedDevices[0] != "None".
|
||||
var xrDevices = VXUtils.XRSettings.supportedDevices;
|
||||
var xrIsEnabled = xrDevices.Length > 0 && xrDevices[0] != "None";
|
||||
if (!xrIsEnabled) {
|
||||
WebViewLogger.LogWarning($"{warningPrefix} 3D WebView for Android supports Vulkan, but{(native2DSupported ? " unless the application only uses webviews in Native 2D Mode, then" : "")} the target Android devices must support the Vulkan extension VK_ANDROID_external_memory_android_hardware_buffer. That extension is supported on newer devices like Oculus Quest but isn't supported on all Android phones that support Vulkan. If your application is intended for general Android phones, it's recommended to{(native2DSupported ? " either only use Native 2D Mode or to" : "")} change the project's selected Graphics API to OpenGLES in Player Settings.{(native2DSupported ? " If your application is already only using Native 2D Mode, then please ignore this message." : "")} For more details, please see this page: <em>https://support.vuplex.com/articles/vulkan#android</em>");
|
||||
}
|
||||
#if !UNITY_2022_1_OR_NEWER
|
||||
if (PlayerSettings.GetMobileMTRendering(BuildTargetGroup.Android)) {
|
||||
WebViewLogger.LogWarning("Your project has Multithreaded Rendering and Vulkan enabled with a version of Unity older than 2022.1, which may cause web rendering to appear jittery. Unity 2022.1 or newer is recommended if your project requires Multithreaded Rendering to be enabled. For more details, please see this page: <em>https://support.vuplex.com/articles/vulkan</em>");
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
throw new BuildFailedException(warningPrefix + " 3D WebView for Android requires Unity 2020.2 or newer in order to support Vulkan. So, please either upgrade to a newer version of Unity or change the selected Graphics API to OpenGLES in Player Settings.");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: dd041d4a8ab324bc2899621ed1b3e5d9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,108 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using UnityEditor;
|
||||
|
||||
namespace Vuplex.WebView.Editor {
|
||||
|
||||
public abstract class BaseWebViewPrefabInspector : UnityEditor.Editor {
|
||||
|
||||
public virtual void OnEnable() {
|
||||
|
||||
_clickingEnabled = serializedObject.FindProperty("ClickingEnabled");
|
||||
_cursorIconsEnabled = serializedObject.FindProperty("CursorIconsEnabled");
|
||||
_dragMode = serializedObject.FindProperty("DragMode");
|
||||
_dragThreshold = serializedObject.FindProperty("DragThreshold");
|
||||
_hoveringEnabled = serializedObject.FindProperty("HoveringEnabled");
|
||||
_keyboardEnabled = serializedObject.FindProperty("KeyboardEnabled");
|
||||
_logConsoleMessages = serializedObject.FindProperty("LogConsoleMessages");
|
||||
_resolution = serializedObject.FindProperty("Resolution");
|
||||
_initialUrl = serializedObject.FindProperty("InitialUrl");
|
||||
_nativeOnScreenKeyboardEnabled = serializedObject.FindProperty("NativeOnScreenKeyboardEnabled");
|
||||
_pixelDensity = serializedObject.FindProperty("PixelDensity");
|
||||
_remoteDebuggingEnabled = serializedObject.FindProperty("RemoteDebuggingEnabled");
|
||||
_scrollingEnabled = serializedObject.FindProperty("ScrollingEnabled");
|
||||
_scrollingSensitivity = serializedObject.FindProperty("ScrollingSensitivity");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
|
||||
DocumentationLinkDrawer.DrawDocumentationLink(_getDocumentationLink());
|
||||
EditorGUILayout.Space();
|
||||
serializedObject.Update();
|
||||
EditorGUILayout.PropertyField(_initialUrl);
|
||||
EditorGUILayout.PropertyField(_resolution);
|
||||
EditorGUILayout.PropertyField(_dragMode);
|
||||
EditorGUILayout.PropertyField(_keyboardEnabled);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
_renderCustomPlatformSpecificSettings();
|
||||
EditorGUILayout.PropertyField(_nativeOnScreenKeyboardEnabled);
|
||||
EditorGUILayout.PropertyField(_pixelDensity);
|
||||
EditorGUILayout.PropertyField(_cursorIconsEnabled);
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.PropertyField(_remoteDebuggingEnabled);
|
||||
EditorGUILayout.PropertyField(_logConsoleMessages);
|
||||
EditorUtils.DrawLink("Troubleshooting help", "https://developer.vuplex.com/webview/troubleshooting", 24);
|
||||
EditorUtils.DrawLink("Remote debugging help", "https://support.vuplex.com/articles/how-to-debug-web-content", 27);
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.Space();
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
// BeginFoldoutHeaderGroup and EndFoldoutHeaderGroup only exist in Unity 2019.1 and newer.
|
||||
_showOtherSettings = EditorGUILayout.BeginFoldoutHeaderGroup(_showOtherSettings, "Other settings");
|
||||
#else
|
||||
// Fallback to creating a label for the section.
|
||||
_showOtherSettings = true;
|
||||
var style = new UnityEngine.GUIStyle { fontStyle = UnityEngine.FontStyle.Bold };
|
||||
style.normal.textColor = EditorGUIUtility.isProSkin ? new UnityEngine.Color(0.77f, 0.77f, 0.77f) : UnityEngine.Color.black;
|
||||
EditorGUILayout.LabelField("Other settings", style);
|
||||
#endif
|
||||
if (_showOtherSettings) {
|
||||
_renderCustomOtherSettings();
|
||||
EditorGUILayout.PropertyField(_clickingEnabled);
|
||||
EditorGUILayout.PropertyField(_hoveringEnabled);
|
||||
EditorGUILayout.PropertyField(_scrollingEnabled);
|
||||
EditorGUILayout.PropertyField(_scrollingSensitivity);
|
||||
EditorGUILayout.PropertyField(_dragThreshold);
|
||||
}
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
EditorGUILayout.EndFoldoutHeaderGroup();
|
||||
#endif
|
||||
EditorGUILayout.Space();
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
SerializedProperty _clickingEnabled;
|
||||
SerializedProperty _cursorIconsEnabled;
|
||||
SerializedProperty _dragMode;
|
||||
SerializedProperty _dragThreshold;
|
||||
SerializedProperty _hoveringEnabled;
|
||||
SerializedProperty _keyboardEnabled;
|
||||
SerializedProperty _logConsoleMessages;
|
||||
SerializedProperty _resolution;
|
||||
SerializedProperty _initialUrl;
|
||||
SerializedProperty _nativeOnScreenKeyboardEnabled;
|
||||
SerializedProperty _pixelDensity;
|
||||
SerializedProperty _remoteDebuggingEnabled;
|
||||
SerializedProperty _scrollingEnabled;
|
||||
SerializedProperty _scrollingSensitivity;
|
||||
bool _showOtherSettings;
|
||||
|
||||
protected abstract string _getDocumentationLink();
|
||||
|
||||
protected virtual void _renderCustomOtherSettings() {}
|
||||
|
||||
protected virtual void _renderCustomPlatformSpecificSettings() {}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 12235521ed9354bd29154cb73f4a7c9d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using UnityEditor;
|
||||
|
||||
namespace Vuplex.WebView.Editor {
|
||||
|
||||
/// <summary>
|
||||
/// Adds a "View documentation" link to the inspector.
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(CanvasPointerInputDetector))]
|
||||
public class CanvasPointerInputDetectorInspector : UnityEditor.Editor {
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
|
||||
DocumentationLinkDrawer.DrawDocumentationLink("https://developer.vuplex.com/webview/IPointerInputDetector");
|
||||
DrawDefaultInspector();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a629eb6a80da745468dc349f3d92563f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using UnityEditor;
|
||||
|
||||
namespace Vuplex.WebView.Editor {
|
||||
|
||||
[CustomEditor(typeof(CanvasWebViewPrefab))]
|
||||
public class CanvasWebViewPrefabInspector : BaseWebViewPrefabInspector {
|
||||
|
||||
public override void OnEnable() {
|
||||
|
||||
base.OnEnable();
|
||||
serializedObject.Update();
|
||||
_native2DModeEnabled = serializedObject.FindProperty("Native2DModeEnabled");
|
||||
}
|
||||
|
||||
SerializedProperty _native2DModeEnabled;
|
||||
|
||||
protected override string _getDocumentationLink() {
|
||||
return "https://developer.vuplex.com/webview/CanvasWebViewPrefab";
|
||||
}
|
||||
|
||||
protected override void _renderCustomOtherSettings() {
|
||||
|
||||
EditorGUILayout.HelpBox("These settings are used with the default rendering mode but are ignored when running in native 2D mode.", MessageType.Info);
|
||||
}
|
||||
|
||||
protected override void _renderCustomPlatformSpecificSettings() {
|
||||
|
||||
EditorGUILayout.PropertyField(_native2DModeEnabled);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bf1bcc6f301554381be0e9bdbbaf04b8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,241 +0,0 @@
|
|||
/*
|
||||
* This file is a copy of Unity's [ConditionalCompilationUtility](https://github.com/Unity-Technologies/ConditionalCompilationUtility/tree/f364090bbda3728e1662074c969c2b7c3c34199b)
|
||||
* with the following modifications:
|
||||
* - Changed the namespace.
|
||||
* - Removed the usage of k_EnableCCU and instead hardcoded the use of the Vuplex OptionalDependencyAttribute class.
|
||||
* - Pasted the license below.
|
||||
* - Updated ForEachAssembly() to catch TypeLoadException in addition to ReflectionTypeLoadException.
|
||||
* - Made it so that if an optional dependency is removed, the scripting symbol for it is removed.
|
||||
* - Made it so that the legacy VUPLEX_CCU scripting symbol previously used by this script is automatically removed from the project.
|
||||
*
|
||||
* Unity Companion License 1.0 ("License")
|
||||
* Copyright (C) 2017-2018 Unity Technologies ApS ("Unity")
|
||||
*
|
||||
* Unity hereby grants to you a worldwide, non-exclusive, no-charge, and royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute the software that is made available with this License ("Software"), subject to the following terms and conditions:
|
||||
*
|
||||
* 1. Unity Companion Use Only. Exercise of the license granted herein is limited to exercise for the creation, use, and/or distribution of applications, software, or other content pursuant to a valid Unity development engine software license ("Engine License"). That means while use of the Software is not limited to use in the software licensed under the Engine License, the Software may not be used for any purpose other than the creation, use, and/or distribution of Engine License-dependent applications, software, or other content. No other exercise of the license granted herein is permitted.
|
||||
*
|
||||
* 2. No Modification of Engine License. Neither this License nor any exercise of the license granted herein modifies the Engine License in any way.
|
||||
*
|
||||
* 3. Ownership & Grant Back to You.
|
||||
*
|
||||
* 3.1 You own your content. In this License, "derivative works" means derivatives of the Software itself--works derived only from the Software by you under this License (for example, modifying the code of the Software itself to improve its efficacy); "derivative works" of the Software do not include, for example, games, apps, or content that you create using the Software. You keep all right, title, and interest to your own content.
|
||||
*
|
||||
* 3.2 Unity owns its content. While you keep all right, title, and interest to your own content per the above, as between Unity and you, Unity will own all right, title, and interest to all intellectual property rights (including patent, trademark, and copyright) in the Software and derivative works of the Software, and you hereby assign and agree to assign all such rights in those derivative works to Unity.
|
||||
*
|
||||
* 3.3 You have a license to those derivative works. Subject to this License, Unity grants to you the same worldwide, non-exclusive, no-charge, and royalty-free copyright license to derivative works of the Software you create as is granted to you for the Software under this License.
|
||||
*
|
||||
* 4. Trademarks. You are not granted any right or license under this License to use any trademarks, service marks, trade names, products names, or branding of Unity or its affiliates ("Trademarks"). Descriptive uses of Trademarks are permitted; see, for example, Unity's Branding Usage Guidelines at https://unity3d.com/public-relations/brand.
|
||||
*
|
||||
* 5. Notices & Third-Party Rights. This License, including the copyright notice above, must be provided in all substantial portions of the Software and derivative works thereof (or, if that is impracticable, in any other location where such notices are customarily placed). Further, if the Software is accompanied by a Unity "third-party notices" or similar file, you acknowledge and agree that software identified in that file is governed by those separate license terms.
|
||||
*
|
||||
* 6. DISCLAIMER, LIMITATION OF LIABILITY. THE SOFTWARE AND ANY DERIVATIVE WORKS THEREOF IS PROVIDED ON AN "AS IS" BASIS, AND IS PROVIDED WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR NONINFRINGEMENT. IN NO EVENT SHALL ANY COPYRIGHT HOLDER OR AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES (WHETHER DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL, INCLUDING PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS, AND BUSINESS INTERRUPTION), OR OTHER LIABILITY WHATSOEVER, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM OR OUT OF, OR IN CONNECTION WITH, THE SOFTWARE OR ANY DERIVATIVE WORKS THEREOF OR THE USE OF OR OTHER DEALINGS IN SAME, EVEN WHERE ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* 7. USE IS ACCEPTANCE and License Versions. Your receipt and use of the Software constitutes your acceptance of this License and its terms and conditions. Software released by Unity under this License may be modified or updated and the License with it; upon any such modification or update, you will comply with the terms of the updated License for any use of any of the Software under the updated License.
|
||||
*
|
||||
* 8. Use in Compliance with Law and Termination. Your exercise of the license granted herein will at all times be in compliance with applicable law and will not infringe any proprietary rights (including intellectual property rights); this License will terminate immediately on any breach by you of this License.
|
||||
*
|
||||
* 9. Severability. If any provision of this License is held to be unenforceable or invalid, that provision will be enforced to the maximum extent possible and the other provisions will remain in full force and effect.
|
||||
*
|
||||
* 10. Governing Law and Venue. This License is governed by and construed in accordance with the laws of Denmark, except for its conflict of laws rules; the United Nations Convention on Contracts for the International Sale of Goods will not apply. If you reside (or your principal place of business is) within the United States, you and Unity agree to submit to the personal and exclusive jurisdiction of and venue in the state and federal courts located in San Francisco County, California concerning any dispute arising out of this License ("Dispute"). If you reside (or your principal place of business is) outside the United States, you and Unity agree to submit to the personal and exclusive jurisdiction of and venue in the courts located in Copenhagen, Denmark concerning any Dispute.
|
||||
*/
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Compilation;
|
||||
using Assembly = System.Reflection.Assembly;
|
||||
using Debug = UnityEngine.Debug;
|
||||
using System.Threading;
|
||||
using VuplexOptionalDependencyAttribute = Vuplex.WebView.Editor.OptionalDependencyAttribute;
|
||||
|
||||
namespace Vuplex.WebView.ConditionalCompilation
|
||||
{
|
||||
/// <summary>
|
||||
/// The Conditional Compilation Utility (CCU) will add defines to the build settings once dependendent classes have been detected.
|
||||
/// A goal of the CCU was to not require the CCU itself for other libraries to specify optional dependencies. So, it relies on the
|
||||
/// specification of at least one custom attribute in a project that makes use of it. Here is an example:
|
||||
///
|
||||
/// [Conditional(UNITY_CCU)] // | This is necessary for CCU to pick up the right attributes
|
||||
/// public class OptionalDependencyAttribute : Attribute // | Must derive from System.Attribute
|
||||
/// {
|
||||
/// public string dependentClass; // | Required field specifying the fully qualified dependent class
|
||||
/// public string define; // | Required field specifying the define to add
|
||||
/// }
|
||||
///
|
||||
/// Then, simply specify the assembly attribute(s) you created in any of your C# files:
|
||||
/// [assembly: OptionalDependency("UnityEngine.InputNew.InputSystem", "USE_NEW_INPUT")]
|
||||
/// [assembly: OptionalDependency("Valve.VR.IVRSystem", "ENABLE_STEAMVR_INPUT")]
|
||||
///
|
||||
/// namespace Foo
|
||||
/// {
|
||||
/// ...
|
||||
/// }
|
||||
/// </summary>
|
||||
[InitializeOnLoad]
|
||||
static class ConditionalCompilationUtility
|
||||
{
|
||||
const string k_PreviousUnsuccessfulDefines = "ConditionalCompilationUtility.PreviousUnsuccessfulDefines";
|
||||
|
||||
public static string[] defines { private set; get; }
|
||||
|
||||
static Type _dependencyAttributeType = typeof(VuplexOptionalDependencyAttribute);
|
||||
|
||||
static ConditionalCompilationUtility()
|
||||
{
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
var errorsFound = false;
|
||||
CompilationPipeline.assemblyCompilationFinished += (outputPath, compilerMessages) =>
|
||||
{
|
||||
var errorCount = compilerMessages.Count(m => m.type == CompilerMessageType.Error && m.message.Contains("CS0246"));
|
||||
if (errorCount > 0 && !errorsFound)
|
||||
{
|
||||
var previousDefines = EditorPrefs.GetString(k_PreviousUnsuccessfulDefines);
|
||||
var currentDefines = string.Join(";", defines);
|
||||
if (currentDefines != previousDefines)
|
||||
{
|
||||
// Store the last set of unsuccessful defines to avoid ping-ponging
|
||||
EditorPrefs.SetString(k_PreviousUnsuccessfulDefines, currentDefines);
|
||||
|
||||
// Since there were errors in compilation, try removing any dependency defines
|
||||
UpdateDependencies(true);
|
||||
}
|
||||
errorsFound = true;
|
||||
}
|
||||
};
|
||||
|
||||
AssemblyReloadEvents.afterAssemblyReload += () =>
|
||||
{
|
||||
if (!errorsFound)
|
||||
UpdateDependencies();
|
||||
};
|
||||
#else
|
||||
UpdateDependencies();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void UpdateDependencies(bool reset = false)
|
||||
{
|
||||
var buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup;
|
||||
if (buildTargetGroup == BuildTargetGroup.Unknown)
|
||||
{
|
||||
var propertyInfo = typeof(EditorUserBuildSettings).GetProperty("activeBuildTargetGroup", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
if (propertyInfo != null)
|
||||
buildTargetGroup = (BuildTargetGroup)propertyInfo.GetValue(null, null);
|
||||
}
|
||||
|
||||
var previousProjectDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
|
||||
var projectDefines = previousProjectDefines.Split(';').ToList();
|
||||
var ccuDefines = new List<string>();
|
||||
|
||||
var conditionalAttributeType = typeof(ConditionalAttribute);
|
||||
|
||||
const string kDependentClass = "dependentClass";
|
||||
const string kDefine = "define";
|
||||
|
||||
var dependencies = new Dictionary<string, string>();
|
||||
ForEachAssembly(assembly =>
|
||||
{
|
||||
var typeAttributes = assembly.GetCustomAttributes(_dependencyAttributeType, false);
|
||||
foreach (var typeAttribute in typeAttributes)
|
||||
{
|
||||
// These fields were already validated in a previous step
|
||||
var dependentClass = _dependencyAttributeType.GetField(kDependentClass).GetValue(typeAttribute) as string;
|
||||
var define = _dependencyAttributeType.GetField(kDefine).GetValue(typeAttribute) as string;
|
||||
|
||||
if (!string.IsNullOrEmpty(dependentClass) && !string.IsNullOrEmpty(define) && !dependencies.ContainsKey(dependentClass))
|
||||
dependencies.Add(dependentClass, define);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
ForEachAssembly(assembly =>
|
||||
{
|
||||
foreach (var dependency in dependencies)
|
||||
{
|
||||
var typeName = dependency.Key;
|
||||
var define = dependency.Value;
|
||||
|
||||
var type = assembly.GetType(typeName);
|
||||
if (type != null)
|
||||
{
|
||||
if (!projectDefines.Contains(define, StringComparer.OrdinalIgnoreCase))
|
||||
projectDefines.Add(define);
|
||||
|
||||
ccuDefines.Add(define);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Remove scripting symbols for optional dependencies that have been removed.
|
||||
foreach (var define in dependencies.Values)
|
||||
{
|
||||
if (projectDefines.Contains(define) && !ccuDefines.Contains(define))
|
||||
projectDefines.Remove(define);
|
||||
}
|
||||
|
||||
// Remove the legacy VUPLEX_CCU scripting symbol that this script used to add.
|
||||
if (projectDefines.Contains("VUPLEX_CCU"))
|
||||
projectDefines.Remove("VUPLEX_CCU");
|
||||
|
||||
if (reset)
|
||||
{
|
||||
foreach (var define in dependencies.Values)
|
||||
{
|
||||
projectDefines.Remove(define);
|
||||
}
|
||||
|
||||
ccuDefines.Clear();
|
||||
}
|
||||
|
||||
ConditionalCompilationUtility.defines = ccuDefines.ToArray();
|
||||
|
||||
var newDefines = string.Join(";", projectDefines.ToArray());
|
||||
if (previousProjectDefines != newDefines)
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, newDefines);
|
||||
}
|
||||
|
||||
static void ForEachAssembly(Action<Assembly> callback)
|
||||
{
|
||||
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
try
|
||||
{
|
||||
callback(assembly);
|
||||
}
|
||||
catch (Exception ex) when (ex is ReflectionTypeLoadException || ex is TypeLoadException)
|
||||
{
|
||||
// Skip any assemblies that don't load properly
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ForEachType(Action<Type> callback)
|
||||
{
|
||||
ForEachAssembly(assembly =>
|
||||
{
|
||||
var types = assembly.GetTypes();
|
||||
foreach (var t in types)
|
||||
callback(t);
|
||||
});
|
||||
}
|
||||
|
||||
static IEnumerable<Type> GetAssignableTypes(Type type, Func<Type, bool> predicate = null)
|
||||
{
|
||||
var list = new List<Type>();
|
||||
ForEachType(t =>
|
||||
{
|
||||
if (type.IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract && (predicate == null || predicate(t)))
|
||||
list.Add(t);
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 55a3f084f6ac84e1db970f412e251da0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using UnityEditor;
|
||||
|
||||
namespace Vuplex.WebView.Editor {
|
||||
|
||||
/// <summary>
|
||||
/// Adds a "View documentation" link to the inspector.
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(DefaultPointerInputDetector))]
|
||||
public class DefaultPointerInputDetectorInspector : UnityEditor.Editor {
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
|
||||
DocumentationLinkDrawer.DrawDocumentationLink("https://developer.vuplex.com/webview/IPointerInputDetector");
|
||||
DrawDefaultInspector();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a4161c7b2198c4efcbd3123708e4091a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Vuplex.WebView.Editor {
|
||||
|
||||
public static class DocumentationLinkDrawer {
|
||||
|
||||
/// <summary>
|
||||
/// Draws a "View documentation" link.
|
||||
/// </summary>
|
||||
public static void DrawDocumentationLink(string url) {
|
||||
|
||||
EditorUtils.DrawLink("View documentation", url, 23);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 15705ab5708a341e0a98cb0af0b6fa84
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,154 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using Vuplex.WebView.Internal;
|
||||
|
||||
namespace Vuplex.WebView.Editor {
|
||||
|
||||
public static class EditorUtils {
|
||||
|
||||
public static void CopyAndReplaceDirectory(string srcPath, string dstPath, bool ignoreMetaFiles = true) {
|
||||
|
||||
if (Directory.Exists(dstPath)) {
|
||||
Directory.Delete(dstPath, true);
|
||||
}
|
||||
if (File.Exists(dstPath)) {
|
||||
File.Delete(dstPath);
|
||||
}
|
||||
Directory.CreateDirectory(dstPath);
|
||||
|
||||
foreach (var file in Directory.GetFiles(srcPath)) {
|
||||
if (!ignoreMetaFiles || Path.GetExtension(file) != ".meta") {
|
||||
File.Copy(file, Path.Combine(dstPath, Path.GetFileName(file)));
|
||||
}
|
||||
}
|
||||
foreach (var dir in Directory.GetDirectories(srcPath)) {
|
||||
CopyAndReplaceDirectory(dir, Path.Combine(dstPath, Path.GetFileName(dir)), ignoreMetaFiles);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawLink(string linkText, string url, int underlineLength) {
|
||||
|
||||
var linkStyle = new GUIStyle {
|
||||
richText = true,
|
||||
padding = new RectOffset {
|
||||
top = 2,
|
||||
bottom = 2
|
||||
}
|
||||
};
|
||||
var linkClicked = GUILayout.Button(
|
||||
EditorUtils.TextWithColor(linkText, EditorUtils.GetLinkColor()),
|
||||
linkStyle
|
||||
);
|
||||
var linkRect = GUILayoutUtility.GetLastRect();
|
||||
EditorGUIUtility.AddCursorRect(linkRect, MouseCursor.Link);
|
||||
|
||||
// Unity's editor GUI doesn't support underlines, so fake it.
|
||||
var underscores = new string[underlineLength];
|
||||
for (var i = 0; i < underlineLength; i++) {
|
||||
underscores[i] = "_";
|
||||
}
|
||||
var underline = String.Join("", underscores);
|
||||
|
||||
GUI.Label(
|
||||
linkRect,
|
||||
EditorUtils.TextWithColor(underline, EditorUtils.GetLinkColor()),
|
||||
new GUIStyle {
|
||||
richText = true,
|
||||
padding = new RectOffset {
|
||||
top = 4,
|
||||
bottom = 2
|
||||
}
|
||||
});
|
||||
if (linkClicked) {
|
||||
Application.OpenURL(url);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the path to a given directory, searching for it if needed.
|
||||
/// If `directoryToSearch` isn't provided, `Application.dataPath` is used.
|
||||
/// </summary>
|
||||
public static string FindDirectory(string expectedPath, string directoryToSearch = null, string[] ignorePaths = null) {
|
||||
|
||||
if (Directory.Exists(expectedPath)) {
|
||||
return expectedPath;
|
||||
}
|
||||
// The directory isn't in the expected location, so fall back to finding it.
|
||||
var directoryName = Path.GetFileName(expectedPath);
|
||||
if (directoryToSearch == null) {
|
||||
directoryToSearch = Application.dataPath;
|
||||
}
|
||||
var directories = Directory.GetDirectories(directoryToSearch, directoryName, SearchOption.AllDirectories);
|
||||
if (ignorePaths != null) {
|
||||
directories = directories.ToList().Where(d => !ignorePaths.Contains(d)).ToArray();
|
||||
}
|
||||
return _returnOnePathOrThrow(directories, expectedPath, directoryToSearch, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the path to a given file, searching for it if needed.
|
||||
/// If `directoryToSearch` isn't provided, `Application.dataPath` is used.
|
||||
/// </summary>
|
||||
public static string FindFile(string expectedPath, string directoryToSearch = null) {
|
||||
|
||||
if (File.Exists(expectedPath)) {
|
||||
return expectedPath;
|
||||
}
|
||||
// The file isn't in the expected location, so fall back to finding it.
|
||||
var fileName = Path.GetFileName(expectedPath);
|
||||
if (directoryToSearch == null) {
|
||||
directoryToSearch = Application.dataPath;
|
||||
}
|
||||
var files = Directory.GetFiles(directoryToSearch, fileName, SearchOption.AllDirectories);
|
||||
return _returnOnePathOrThrow(files, expectedPath, directoryToSearch);
|
||||
}
|
||||
|
||||
public static string GetLinkColor() => EditorGUIUtility.isProSkin ? "#7faef0ff" : "#11468aff";
|
||||
|
||||
public static string TextWithColor(string text, string color) => $"<color={color}>{text}</color>";
|
||||
|
||||
public static bool XRSdkIsEnabled(string sdkNameFragment) {
|
||||
|
||||
// This approach is taken because the legacy Oculus XR plugin identifies itself as "Oculus", but
|
||||
// the new XR plugin shows up as two devices named "oculus input" and "oculus display". Similarly,
|
||||
// the MockHMD plugin used to identify itself as "MockHMD" but now it shows up as "MockHMD Head Tracking"
|
||||
// and "MockHMD Display".
|
||||
foreach (var sdkName in VXUtils.XRSettings.supportedDevices) {
|
||||
if (sdkName.ToLowerInvariant().Contains(sdkNameFragment.ToLowerInvariant())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static string _returnOnePathOrThrow(string[] paths, string expectedPath, string directorySearched, bool isDirectory = false) {
|
||||
|
||||
var itemName = isDirectory ? "directory" : "file";
|
||||
if (paths.Length == 1) {
|
||||
return paths[0];
|
||||
}
|
||||
var targetFileOrDirectoryName = Path.GetFileName(expectedPath);
|
||||
if (paths.Length > 1) {
|
||||
var joinedPaths = String.Join(", ", paths);
|
||||
throw new Exception($"Unable to determine which version of the {itemName} {targetFileOrDirectoryName} to use because multiple instances ({paths.Length}) were unexpectedly found in the directory {directorySearched}. Please review the list of instances found and remove duplicates so that there is only one: {joinedPaths}");
|
||||
}
|
||||
throw new Exception($"Unable to locate the {itemName} {targetFileOrDirectoryName}. It's not in the expected location ({expectedPath}), and no instances were found in the directory {directorySearched}. To resolve this issue, please try deleting your existing Assets/Vuplex directory and reinstalling 3D WebView.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 70f8251b128d6ed4fb9dfd2c185496cc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,28 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using Vuplex.WebView.Internal;
|
||||
|
||||
namespace Vuplex.WebView.Editor {
|
||||
|
||||
[CustomPropertyDrawer(typeof(LabelAttribute))]
|
||||
class LabelDrawer : PropertyDrawer {
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
|
||||
|
||||
EditorGUI.PropertyField(position, property, new GUIContent((attribute as LabelAttribute).Label, property.tooltip));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f7cc4d471c1d54e75b87468526b602cd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,37 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Vuplex.WebView.ConditionalCompilation;
|
||||
|
||||
namespace Vuplex.WebView.Editor {
|
||||
|
||||
/// <summary>
|
||||
/// From the example of how to use Unity's ConditionalCompilationUtility:
|
||||
/// https://github.com/Unity-Technologies/ConditionalCompilationUtility/tree/f364090bbda3728e1662074c969c2b7c3c34199b
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
||||
// Refer to System.Attribute by its full name in case the project has a class named "Attribute" in the global namespace.
|
||||
public class OptionalDependencyAttribute : System.Attribute {
|
||||
public string dependentClass;
|
||||
public string define;
|
||||
|
||||
public OptionalDependencyAttribute(string dependentClass, string define) {
|
||||
this.dependentClass = dependentClass;
|
||||
this.define = define;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 36b97f9b079074ee685a6ee41adc0f3b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// This can't be imported as just OptionalDependencyAttribute because
|
||||
// it would clash with other packages that define that attribute, like
|
||||
// XR Interaction Toolkit.
|
||||
#if UNITY_EDITOR
|
||||
using VuplexOptionalDependencyAttribute = Vuplex.WebView.Editor.OptionalDependencyAttribute;
|
||||
|
||||
// Detect if specific packages are installed and, if so,
|
||||
// define scripting symbols so that 3D WebView can handle them.
|
||||
[assembly: VuplexOptionalDependency("Unity.XR.Oculus.OculusLoader", "VUPLEX_OCULUS")]
|
||||
[assembly: VuplexOptionalDependency("OVRProjectConfig", "VUPLEX_OCULUS_PROJECT_CONFIG")]
|
||||
[assembly: VuplexOptionalDependency("UnityEngine.XR.Interaction.Toolkit.XRBaseInteractor", "VUPLEX_XR_INTERACTION_TOOLKIT")]
|
||||
[assembly: VuplexOptionalDependency("Microsoft.MixedReality.Toolkit.MixedRealityToolkit", "VUPLEX_MRTK")]
|
||||
[assembly: VuplexOptionalDependency("Vuplex.WebView.StandaloneWebPlugin", "VUPLEX_STANDALONE")]
|
||||
#endif
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e6ee0f86057d9439896db7eb0e9cf5da
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using UnityEditor;
|
||||
|
||||
namespace Vuplex.WebView.Editor {
|
||||
|
||||
[CustomEditor(typeof(WebViewPrefab))]
|
||||
public class WebViewPrefabInspector : BaseWebViewPrefabInspector {
|
||||
|
||||
protected override string _getDocumentationLink() {
|
||||
return "https://developer.vuplex.com/webview/WebViewPrefab";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b88a73aa4eea34b3eb0c643e900629a0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7db53a5c7645d49dc9cb47325b1c4c44
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c9e0722a5d73544aea97fc9f27d57a28
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
Before Width: | Height: | Size: 412 KiB |
|
@ -1,140 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9f7b60728c99d4fe6b67e0d86b1e7b5e
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 1
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
applyGammaDecoding: 1
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 3
|
||||
buildTarget: Windows Store Apps
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e215f6e969624419f9f78abee1aacc76
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d50ed4d84413b4b38aef9d7a59ed5f22
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,91 +0,0 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: AndroidWebMaterial
|
||||
m_Shader: {fileID: 4800000, guid: 6e30a287c37c64ea8a78626f476223bb, type: 3}
|
||||
m_ShaderKeywords: FLIP_Y _ALPHATEST_ON _STEREOMODE_NONE
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: 3000
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: -1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _ColorMask: 15
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _EnableGammaCorrection: 0
|
||||
- _FlipX: 0
|
||||
- _FlipY: 1
|
||||
- _Gamma: 0.6
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 1
|
||||
- _OcclusionStrength: 1
|
||||
- _OverrideStereoToMono: 0
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _Stencil: 0
|
||||
- _StencilComp: 8
|
||||
- _StencilOp: 0
|
||||
- _StencilReadMask: 255
|
||||
- _StencilWriteMask: 255
|
||||
- _StereoMode: 0
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _CropRect: {r: 0, g: 0, b: 0, a: 0}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _VideoCutoutRect: {r: 0, g: 0, b: 0, a: 0}
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b330f1b65a93d4b708726acb581f07b0
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,91 +0,0 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: DefaultWebMaterial
|
||||
m_Shader: {fileID: 4800000, guid: 4e653f72759f94e82b22355692823efe, type: 3}
|
||||
m_ShaderKeywords: FLIP_Y _ALPHATEST_ON _STEREOMODE_NONE
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: 3000
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: -1, y: -1}
|
||||
m_Offset: {x: 1, y: 1}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _ColorMask: 15
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _EnableGammaCorrection: 0
|
||||
- _FlipX: 0
|
||||
- _FlipY: 1
|
||||
- _Gamma: 0.6
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 1
|
||||
- _OcclusionStrength: 1
|
||||
- _OverrideStereoToMono: 0
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _Stencil: 0
|
||||
- _StencilComp: 8
|
||||
- _StencilOp: 0
|
||||
- _StencilReadMask: 255
|
||||
- _StencilWriteMask: 255
|
||||
- _StereoMode: 0
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _CropRect: {r: 0, g: 0, b: 0, a: 0}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _VideoCutoutRect: {r: 0, g: 0, b: 0, a: 0}
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c1ebc368a4559473c933b46a16a9cc9e
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 359a5662a859d4d0aa134fa4450a03cf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 36aa5171762764850acf79d6b107e3fd
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,111 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Vuplex.WebViewUpgrade {
|
||||
|
||||
/// <summary>
|
||||
/// Detects if the Vuplex/WebView folder needs to be deleted
|
||||
/// because it contains subdirectories from old versions of
|
||||
/// 3D WebView:
|
||||
/// https://support.vuplex.com/articles/v4-changes#directory
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This script is located in Plugins/Editor so that it's included in the assembly Assembly-CSharp-Editor-firstpass
|
||||
/// and can still function if there are C# compiler errors in other scripts:
|
||||
/// https://docs.unity3d.com/Manual/ScriptCompileOrderFolders.html
|
||||
/// </remarks>
|
||||
[InitializeOnLoad]
|
||||
class OldWebViewDirectoryDeleter {
|
||||
|
||||
static OldWebViewDirectoryDeleter() => _askPermissionToDeleteWebViewDirectoryIfNeeded();
|
||||
|
||||
static string[] _oldSubdirectoryNames = new string[] { "Editor", "Licenses", "Materials", "Plugins", "Prefabs", "Scripts", "Shaders" };
|
||||
|
||||
static void _askPermissionToDeleteWebViewDirectoryIfNeeded() {
|
||||
|
||||
var vuplexDirectoryPath = DirectoryDeleterUtils.FindDirectory(Path.Combine(Application.dataPath, "Vuplex"));
|
||||
if (vuplexDirectoryPath == null) {
|
||||
// The Vuplex directory couldn't be found. This can happen if the user renamed the Vuplex directory or
|
||||
// moved it to the Packages folder.
|
||||
return;
|
||||
}
|
||||
var webViewDirectoryPath = Path.Combine(vuplexDirectoryPath, "WebView");
|
||||
var oldSubdirectoriesExist = _oldSubdirectoryNames.Any(dirName => Directory.Exists(Path.Combine(webViewDirectoryPath, dirName)));
|
||||
if (!oldSubdirectoriesExist) {
|
||||
return;
|
||||
}
|
||||
var userApprovedDeletingWebViewDirectory = EditorUtility.DisplayDialog(
|
||||
"3D WebView v4 Upgrade",
|
||||
$"Thank you for upgrading to 3D WebView v4! In v4, 3D WebView changed its directory structure compared to past versions. To upgrade, we need to delete your project's existing Vuplex/WebView folder, and then you'll need to reimport this new version of 3D WebView. Do you want 3D WebView to go ahead and delete the existing Vuplex/WebView folder so that you can reimport the new version?\n\nDirectory that will be deleted: {webViewDirectoryPath}\n\nMore info: https://support.vuplex.com/articles/v4-changes#directory\n",
|
||||
"Yes, delete the old WebView folder, and then I'll reimport",
|
||||
"Cancel"
|
||||
);
|
||||
if (!userApprovedDeletingWebViewDirectory) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Directory.Delete(webViewDirectoryPath, true);
|
||||
var metaFilePath = webViewDirectoryPath + ".meta";
|
||||
if (File.Exists(metaFilePath)) {
|
||||
File.Delete(metaFilePath);
|
||||
}
|
||||
Debug.Log("[3D WebView] Successfully finished deleting the old Vuplex/WebView directory. To finish upgrading, please reimport the new 3D WebView package.");
|
||||
} catch (Exception ex) {
|
||||
Debug.LogError($"[3D WebView] An exception occurred while deleting the old Vuplex/WebView directory. Please manually delete the directory {webViewDirectoryPath} and then reimport the new 3D WebView package. Exception: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
// Methods copied from EditorUtils.cs so that this script has no dependencies
|
||||
// on classes in the Assembly-CSharp-Editor assembly.
|
||||
static class DirectoryDeleterUtils {
|
||||
|
||||
public static string FindDirectory(string expectedPath, string directoryToSearch = null, string[] ignorePaths = null) {
|
||||
|
||||
if (Directory.Exists(expectedPath)) {
|
||||
return expectedPath;
|
||||
}
|
||||
// The directory isn't in the expected location, so fall back to finding it.
|
||||
var directoryName = Path.GetFileName(expectedPath);
|
||||
if (directoryToSearch == null) {
|
||||
directoryToSearch = Application.dataPath;
|
||||
}
|
||||
var directories = Directory.GetDirectories(directoryToSearch, directoryName, SearchOption.AllDirectories);
|
||||
if (ignorePaths != null) {
|
||||
directories = directories.ToList().Where(d => !ignorePaths.Contains(d)).ToArray();
|
||||
}
|
||||
return _returnOnePath(directories, expectedPath, directoryToSearch, true);
|
||||
}
|
||||
|
||||
static string _returnOnePath(string[] paths, string expectedPath, string directorySearched, bool isDirectory = false) {
|
||||
|
||||
var itemName = isDirectory ? "directory" : "file";
|
||||
if (paths.Length == 1) {
|
||||
return paths[0];
|
||||
}
|
||||
var targetFileOrDirectoryName = Path.GetFileName(expectedPath);
|
||||
if (paths.Length > 1) {
|
||||
var joinedPaths = String.Join(", ", paths);
|
||||
throw new Exception($"Unable to determine which version of the {itemName} {targetFileOrDirectoryName} to use because multiple instances ({paths.Length}) were unexpectedly found in the directory {directorySearched}. Please review the list of instances found and remove duplicates so that there is only one: {joinedPaths}");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 28cf2cac9522d4214b26b3627f49f164
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bf0ae6d90515142cd9ce04eea8ff11cc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9bb640a76f5114841a21c052f5e9675b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,95 +0,0 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 1077352107545268}
|
||||
m_IsPrefabParent: 1
|
||||
--- !u!1 &1077352107545268
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224209101858263596}
|
||||
- component: {fileID: 114444086270251362}
|
||||
- component: {fileID: 222742886503075740}
|
||||
- component: {fileID: 114569966070787602}
|
||||
m_Layer: 5
|
||||
m_Name: CanvasKeyboard
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &114444086270251362
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1077352107545268}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: bf3530b75f6314cc9a2e4796f3195ca2, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_webViewPrefab: {fileID: 0}
|
||||
InitialResolution: 1
|
||||
--- !u!114 &114569966070787602
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1077352107545268}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!222 &222742886503075740
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1077352107545268}
|
||||
--- !u!224 &224209101858263596
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1077352107545268}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0}
|
||||
m_AnchorMax: {x: 0.5, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 650, y: 162}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8f67f2d646b0a4cc58c56790b3f53ef4
|
||||
timeCreated: 1618101293
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,253 +0,0 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 1535822479614194}
|
||||
m_IsPrefabParent: 1
|
||||
--- !u!1 &1255051872871948
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224970607326042290}
|
||||
- component: {fileID: 222573612747050694}
|
||||
- component: {fileID: 114113553939285968}
|
||||
- component: {fileID: 114138872472689322}
|
||||
m_Layer: 5
|
||||
m_Name: VideoLayer
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1535822479614194
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224179541092979990}
|
||||
- component: {fileID: 222163621197708754}
|
||||
- component: {fileID: 114949863196309792}
|
||||
m_Layer: 5
|
||||
m_Name: CanvasWebViewPrefab
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1589489459947714
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 224664686071158562}
|
||||
- component: {fileID: 222540676635965858}
|
||||
- component: {fileID: 114031267652868270}
|
||||
- component: {fileID: 114349837030292576}
|
||||
- component: {fileID: 114451593925140236}
|
||||
m_Layer: 5
|
||||
m_Name: CanvasWebViewPrefabView
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &114031267652868270
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1589489459947714}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -98529514, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Texture: {fileID: 0}
|
||||
m_UVRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
--- !u!114 &114113553939285968
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1255051872871948}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -98529514, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Texture: {fileID: 0}
|
||||
m_UVRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
--- !u!114 &114138872472689322
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1255051872871948}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5494d9d7c39544539adab71793f4a16a, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &114349837030292576
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1589489459947714}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5494d9d7c39544539adab71793f4a16a, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &114451593925140236
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1589489459947714}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 70d2e4700f40744fe8b999f209d0253b, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &114949863196309792
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1535822479614194}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 879d31ebe92b040cbb3ef97e98278140, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
InitialUrl:
|
||||
DragMode: 0
|
||||
ClickingEnabled: 1
|
||||
HoveringEnabled: 1
|
||||
ScrollingEnabled: 1
|
||||
DragThreshold: 20
|
||||
RemoteDebuggingEnabled: 0
|
||||
LogConsoleMessages: 0
|
||||
_cachedVideoLayer: {fileID: 0}
|
||||
_cachedView: {fileID: 0}
|
||||
_pointerInputDetectorMonoBehaviour: {fileID: 0}
|
||||
_webViewGameObject: {fileID: 0}
|
||||
Native2DModeEnabled: 0
|
||||
NativeOnScreenKeyboardEnabled: 1
|
||||
InitialResolution: 1
|
||||
ScrollingSensitivity: 15
|
||||
--- !u!222 &222163621197708754
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1535822479614194}
|
||||
--- !u!222 &222540676635965858
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1589489459947714}
|
||||
--- !u!222 &222573612747050694
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1255051872871948}
|
||||
--- !u!224 &224179541092979990
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1535822479614194}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 224970607326042290}
|
||||
- {fileID: 224664686071158562}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!224 &224664686071158562
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1589489459947714}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 224179541092979990}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!224 &224970607326042290
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1255051872871948}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 224179541092979990}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0, y: 1}
|
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3e10f3b6a733e441c8352020cff2f1f6
|
||||
timeCreated: 1583351967
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,142 +0,0 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 1174278342477064}
|
||||
m_IsPrefabParent: 1
|
||||
--- !u!1 &1063265092234352
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 4875497843849992}
|
||||
- component: {fileID: 33464908079229110}
|
||||
- component: {fileID: 64244334316161624}
|
||||
- component: {fileID: 23636716548355268}
|
||||
m_Layer: 0
|
||||
m_Name: Placeholder
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1174278342477064
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 4402545345664314}
|
||||
- component: {fileID: 114039135475586158}
|
||||
m_Layer: 0
|
||||
m_Name: Keyboard
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4402545345664314
|
||||
Transform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1174278342477064}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0.5, y: 0.125, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 4875497843849992}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!4 &4875497843849992
|
||||
Transform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1063265092234352}
|
||||
m_LocalRotation: {x: 0, y: 1, z: 0, w: 0}
|
||||
m_LocalPosition: {x: 0, y: -0.5, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4402545345664314}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0}
|
||||
--- !u!23 &23636716548355268
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1063265092234352}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_Materials:
|
||||
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_PreserveUVs: 1
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 0
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
--- !u!33 &33464908079229110
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1063265092234352}
|
||||
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!64 &64244334316161624
|
||||
MeshCollider:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1063265092234352}
|
||||
m_Material: {fileID: 0}
|
||||
m_IsTrigger: 0
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Convex: 0
|
||||
m_CookingOptions: 14
|
||||
m_SkinWidth: 0.01
|
||||
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!114 &114039135475586158
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1174278342477064}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e6d8eb3193741445b822bfa85a0b39a6, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_webViewPrefab: {fileID: 0}
|
||||
InitialResolution: 1300
|
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 309109dc3a1d64a9ebdb676ae99065ac
|
||||
timeCreated: 1618100751
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,314 +0,0 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 1469133279829300}
|
||||
m_IsPrefabParent: 1
|
||||
--- !u!1 &1257759606553584
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 4904221104159722}
|
||||
m_Layer: 0
|
||||
m_Name: WebViewPrefabResizer
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1381583133826408
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 4495929391779928}
|
||||
- component: {fileID: 33813818586652990}
|
||||
- component: {fileID: 23178964100232268}
|
||||
- component: {fileID: 114330170337970978}
|
||||
- component: {fileID: 114810858755358174}
|
||||
- component: {fileID: 64922995877070972}
|
||||
m_Layer: 0
|
||||
m_Name: WebViewPrefabView
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1469133279829300
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 4307528708891540}
|
||||
- component: {fileID: 114949350411584270}
|
||||
m_Layer: 0
|
||||
m_Name: WebViewPrefab
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1611328938895142
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 4249276903644494}
|
||||
m_Layer: 0
|
||||
m_Name: VideoRectPositioner
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &1840072142318122
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 4747229143573016}
|
||||
- component: {fileID: 33036464261626858}
|
||||
- component: {fileID: 23654077301984142}
|
||||
- component: {fileID: 114558935537698590}
|
||||
m_Layer: 0
|
||||
m_Name: VideoLayer
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4249276903644494
|
||||
Transform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1611328938895142}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0.001}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 4747229143573016}
|
||||
m_Father: {fileID: 4904221104159722}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!4 &4307528708891540
|
||||
Transform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1469133279829300}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 4904221104159722}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!4 &4495929391779928
|
||||
Transform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1381583133826408}
|
||||
m_LocalRotation: {x: 0, y: 1, z: 0, w: 0}
|
||||
m_LocalPosition: {x: 0.5, y: -0.5, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4904221104159722}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0}
|
||||
--- !u!4 &4747229143573016
|
||||
Transform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1840072142318122}
|
||||
m_LocalRotation: {x: 0, y: 1, z: 0, w: 0}
|
||||
m_LocalPosition: {x: 0.5, y: -0.5, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4249276903644494}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0}
|
||||
--- !u!4 &4904221104159722
|
||||
Transform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1257759606553584}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 4495929391779928}
|
||||
- {fileID: 4249276903644494}
|
||||
m_Father: {fileID: 4307528708891540}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!23 &23178964100232268
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1381583133826408}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: c1ebc368a4559473c933b46a16a9cc9e, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_PreserveUVs: 1
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 0
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
--- !u!23 &23654077301984142
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1840072142318122}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: c1ebc368a4559473c933b46a16a9cc9e, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 0
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
--- !u!33 &33036464261626858
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1840072142318122}
|
||||
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!33 &33813818586652990
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1381583133826408}
|
||||
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!64 &64922995877070972
|
||||
MeshCollider:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1381583133826408}
|
||||
m_Material: {fileID: 0}
|
||||
m_IsTrigger: 0
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Convex: 0
|
||||
m_CookingOptions: 14
|
||||
m_SkinWidth: 0.01
|
||||
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!114 &114330170337970978
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1381583133826408}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: acac58dff315c4e35bda0776f2daf873, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &114558935537698590
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1840072142318122}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: acac58dff315c4e35bda0776f2daf873, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &114810858755358174
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1381583133826408}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 9b5d2e4670d86405386a27a4b18941bf, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &114949350411584270
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1469133279829300}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f5e34c9f38a6c46db8c1b510a6090e8c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
InitialUrl:
|
||||
DragMode: 0
|
||||
InitialResolution: 1300
|
||||
ClickingEnabled: 1
|
||||
HoveringEnabled: 1
|
||||
ScrollingEnabled: 1
|
||||
DragToScrollThreshold: 0.15
|
||||
ScrollingSensitivity: 0.005
|
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d704fe1266adf446ebcfa350586e1bc7
|
||||
timeCreated: 1583351880
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1ce6fd89ece294d2fb7770f9ef2fb382
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,49 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// Event args for AuthRequested. Either Continue() or Cancel() must be called in order
|
||||
/// to resume the page.
|
||||
/// </summary>
|
||||
public class AuthRequestedEventArgs : EventArgs {
|
||||
|
||||
public AuthRequestedEventArgs(string host, Action<string, string> continueCallback, Action cancelCallback) {
|
||||
Host = host;
|
||||
_continueCallback = continueCallback;
|
||||
_cancelCallback = cancelCallback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The host that requested authentication.
|
||||
/// </summary>
|
||||
public readonly string Host;
|
||||
|
||||
/// <summary>
|
||||
/// Declines authentication and resumes the page.
|
||||
/// </summary>
|
||||
public void Cancel() => _cancelCallback();
|
||||
|
||||
/// <summary>
|
||||
/// Sends an authentication request to the host.
|
||||
/// </summary>
|
||||
public void Continue(string username, string password) => _continueCallback(username, password);
|
||||
|
||||
Action _cancelCallback;
|
||||
Action<string, string> _continueCallback;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6f309a6e65c0543618a6d7b49692ab97
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,189 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#pragma warning disable CS0067
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using Vuplex.WebView.Internal;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
public abstract class BaseKeyboard : MonoBehaviour {
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the user pressed a key on the keyboard.
|
||||
/// </summary>
|
||||
public event EventHandler<EventArgs<string>> KeyPressed;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the keyboard finished initializing.
|
||||
/// </summary>
|
||||
public event EventHandler Initialized;
|
||||
|
||||
/// <summary>
|
||||
/// If you want to load a customized version of the Keyboard UI, you can
|
||||
/// do so by setting this field. For example, you could load a customized
|
||||
/// Keyboard UI from StreamingAssets by using a URL like "streaming-assets://keyboard/index.html".
|
||||
/// <summary>
|
||||
[Label("Custom Keyboard URL (optional)")]
|
||||
[Tooltip("If you want to load a customized version of the Keyboard UI, you can do so by setting this field. For example, you could load a customized Keyboard UI from StreamingAssets by using a URL like \"streaming-assets://keyboard/index.html\".")]
|
||||
public string CustomKeyboardUrl;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a task that completes when the keyboard is initialized,
|
||||
/// which means that its WebViewPrefab property is ready for use.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await keyboard.WaitUntilInitialized();
|
||||
/// keyboard.WebViewPrefab.Clicked += (sender, eventArgs) => {
|
||||
/// Debug.Log("Keyboard was clicked");
|
||||
/// };
|
||||
/// </code>
|
||||
/// </example>
|
||||
public Task WaitUntilInitialized() {
|
||||
|
||||
var taskSource = new TaskCompletionSource<bool>();
|
||||
if (_isInitialized) {
|
||||
taskSource.SetResult(true);
|
||||
} else {
|
||||
Initialized += (sender, e) => taskSource.SetResult(true);
|
||||
}
|
||||
return taskSource.Task;
|
||||
}
|
||||
|
||||
internal BaseWebViewPrefab BaseWebViewPrefab { get { return _webViewPrefab; }}
|
||||
|
||||
bool _isInitialized;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected BaseWebViewPrefab _webViewPrefab;
|
||||
|
||||
protected static readonly WebViewOptions _webViewOptions = new WebViewOptions {
|
||||
clickWithoutStealingFocus = true,
|
||||
disableVideo = true,
|
||||
// If both Android plugins are installed, prefer the original Chromium
|
||||
// plugin for the keyboard, since the Gecko plugin doesn't support
|
||||
// transparent backgrounds.
|
||||
preferredPlugins = new WebPluginType[] { WebPluginType.Android }
|
||||
};
|
||||
|
||||
async protected void _init() {
|
||||
|
||||
_webViewPrefab.CursorIconsEnabled = false;
|
||||
_webViewPrefab.KeyboardEnabled = false;
|
||||
// Reset InitialUrl to null in case the developer modified WebViewPrefab.prefab to set a default InitialUrl.
|
||||
_webViewPrefab.InitialUrl = null;
|
||||
await _webViewPrefab.WaitUntilInitialized();
|
||||
var pluginType = _webViewPrefab.WebView.PluginType;
|
||||
if (pluginType == WebPluginType.AndroidGecko) {
|
||||
// On Android Gecko, hovering steals focus.
|
||||
_webViewPrefab.HoveringEnabled = false;
|
||||
}
|
||||
// Scrolling and dragging can also cause the keyboard
|
||||
// to steal focus on Android Gecko, so just disable them.
|
||||
_webViewPrefab.ScrollingEnabled = false;
|
||||
_webViewPrefab.DragMode = DragMode.Disabled;
|
||||
_webViewPrefab.WebView.MessageEmitted += WebView_MessageEmitted;
|
||||
// Android Gecko and Hololens don't support transparent webviews, so set the cutout
|
||||
// rect to the entire view so that the shader makes its black background
|
||||
// pixels transparent.
|
||||
if (pluginType == WebPluginType.AndroidGecko || pluginType == WebPluginType.UniversalWindowsPlatform) {
|
||||
_webViewPrefab.SetCutoutRect(new Rect(0, 0, 1, 1));
|
||||
}
|
||||
if (!String.IsNullOrWhiteSpace(CustomKeyboardUrl)) {
|
||||
_webViewPrefab.WebView.LoadUrl(CustomKeyboardUrl.Trim());
|
||||
} else {
|
||||
_webViewPrefab.WebView.LoadHtml(KeyboardUI.Html);
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy() {
|
||||
|
||||
var keyboardInstance = Internal.KeyboardManager.Instance;
|
||||
if (keyboardInstance != null) {
|
||||
keyboardInstance.RemoveKeyboard(this);
|
||||
}
|
||||
}
|
||||
|
||||
void WebView_MessageEmitted(object sender, EventArgs<string> e) {
|
||||
|
||||
var serializedMessage = e.Value;
|
||||
var messageType = JsonUtility.FromJson<BridgeMessage>(serializedMessage).type;
|
||||
switch (messageType) {
|
||||
case "keyboard.inputReceived":
|
||||
var input = StringBridgeMessage.ParseValue(serializedMessage);
|
||||
KeyPressed?.Invoke(this, new EventArgs<string>(input));
|
||||
break;
|
||||
case "keyboard.initialized":
|
||||
_sendKeyboardLanguageMessage();
|
||||
_isInitialized = true;
|
||||
Internal.KeyboardManager.Instance.AddKeyboard(this);
|
||||
Initialized?.Invoke(this, EventArgs.Empty);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
string _getKeyboardLanguage() {
|
||||
switch (Application.systemLanguage) {
|
||||
case SystemLanguage.Danish:
|
||||
return "da";
|
||||
case SystemLanguage.French:
|
||||
return "fr";
|
||||
case SystemLanguage.German:
|
||||
return "de";
|
||||
case SystemLanguage.Norwegian:
|
||||
return "no";
|
||||
case SystemLanguage.Russian:
|
||||
return "ru";
|
||||
case SystemLanguage.Spanish:
|
||||
return "es";
|
||||
case SystemLanguage.Swedish:
|
||||
return "sv";
|
||||
default:
|
||||
return "en";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the keyboard language based on the system language.
|
||||
/// </summary>
|
||||
void _sendKeyboardLanguageMessage() {
|
||||
|
||||
var message = new StringBridgeMessage {
|
||||
type = "keyboard.setLanguage",
|
||||
value = _getKeyboardLanguage()
|
||||
};
|
||||
var serializedMessage = JsonUtility.ToJson(message);
|
||||
_webViewPrefab.WebView.PostMessage(serializedMessage);
|
||||
}
|
||||
|
||||
protected static void _setLayerRecursively(GameObject gameObject, int layer) {
|
||||
|
||||
if (gameObject == null) {
|
||||
return;
|
||||
}
|
||||
gameObject.layer = layer;
|
||||
foreach (Transform child in gameObject.transform) {
|
||||
if (child != null) {
|
||||
_setLayerRecursively(child.gameObject, layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Added in v1.0, removed in v4.3.
|
||||
[Obsolete("Keyboard.InputReceived was removed in v4.3 because WebViewPrefab and CanvasWebViewPrefab now automatically handle keyboard input by default. Please remove your code that references Keyboard.InputReceived, and keyboard support will still work. For more info, including details about how you can still access keyboard input programmatically, please see this article: https://support.vuplex.com/articles/keyboard", true)]
|
||||
public event EventHandler<EventArgs<string>> InputReceived;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 788d71bb8b006463bb656f92b1874908
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2514da53fdefd4d0cbece1e3b339470b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,107 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.UI;
|
||||
using Vuplex.WebView.Internal;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// Like the Keyboard prefab, except optimized for use in a Canvas.
|
||||
/// You can add a CanvasKeyboard to your scene either by dragging the CanvasKeyboard.prefab file
|
||||
/// into a Canvas via the editor or by programmatically calling CanvasKeyboard.Instantiate().
|
||||
/// For an example, please see 3D WebView's CanvasWorldSpaceDemo scene.
|
||||
/// </summary>
|
||||
public class CanvasKeyboard : BaseKeyboard {
|
||||
|
||||
/// <summary>
|
||||
/// Sets the keyboard's initial resolution in pixels per Unity unit.
|
||||
/// You can change the resolution to make the keyboard's content appear larger or smaller.
|
||||
/// For more information on scaling web content, see
|
||||
/// [this support article](https://support.vuplex.com/articles/how-to-scale-web-content).
|
||||
/// </summary>
|
||||
[Label("Resolution (px / Unity unit)")]
|
||||
[Tooltip("You can change this to make web content appear larger or smaller.")]
|
||||
[FormerlySerializedAs("InitialResolution")]
|
||||
public float Resolution = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the WebViewPrefab used for the keyboard UI, or `null` if
|
||||
/// the keyboard hasn't finished initializing yet.
|
||||
/// You can use WaitUntilInitialized() to detect when the WebViewPrefab property is ready to use.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await keyboard.WaitUntilInitialized();
|
||||
/// keyboard.WebViewPrefab.Clicked += (sender, eventArgs) => {
|
||||
/// Debug.Log("Keyboard was clicked");
|
||||
/// };
|
||||
/// </code>
|
||||
/// </example>
|
||||
public CanvasWebViewPrefab WebViewPrefab { get { return (CanvasWebViewPrefab)_webViewPrefab; }}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Create a CanvasKeyboard.
|
||||
/// var keyboard = CanvasKeyboard.Instantiate();
|
||||
/// keyboard.transform.SetParent(canvas.transform, false);
|
||||
/// var rectTransform = keyboard.transform as RectTransform;
|
||||
/// rectTransform.anchoredPosition3D = Vector3.zero;
|
||||
/// rectTransform.offsetMin = Vector2.zero;
|
||||
/// rectTransform.offsetMax = Vector2.zero;
|
||||
/// rectTransform.sizeDelta = new Vector2(650, 162);
|
||||
/// </code>
|
||||
/// </example>
|
||||
public static CanvasKeyboard Instantiate() {
|
||||
|
||||
var prefabPrototype = (GameObject)Resources.Load("CanvasKeyboard");
|
||||
var gameObject = (GameObject)Instantiate(prefabPrototype);
|
||||
return gameObject.GetComponent<CanvasKeyboard>();
|
||||
}
|
||||
|
||||
void _initCanvasKeyboard() {
|
||||
|
||||
var canvasWebViewPrefab = CanvasWebViewPrefab.Instantiate(_webViewOptions);
|
||||
_webViewPrefab = canvasWebViewPrefab;
|
||||
_webViewPrefab.transform.SetParent(transform, false);
|
||||
_setLayerRecursively(_webViewPrefab.gameObject, gameObject.layer);
|
||||
var rectTransform = _webViewPrefab.transform as RectTransform;
|
||||
rectTransform.anchoredPosition3D = Vector3.zero;
|
||||
rectTransform.offsetMin = Vector2.zero;
|
||||
rectTransform.offsetMax = Vector2.zero;
|
||||
_webViewPrefab.transform.localScale = Vector3.one;
|
||||
canvasWebViewPrefab.Resolution = Resolution;
|
||||
_init();
|
||||
// Disable the image, which is just used as a placeholder in the editor.
|
||||
var image = GetComponent<Image>();
|
||||
if (image != null) {
|
||||
image.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Start() => _initCanvasKeyboard();
|
||||
|
||||
// Added in v3.12, deprecated in v4.0.
|
||||
[Obsolete("CanvasKeyboard.InitialResolution is now deprecated. Please use CanvasKeyboard.Resolution instead.")]
|
||||
public float InitialResolution {
|
||||
get { return Resolution; }
|
||||
set { Resolution = value; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bf3530b75f6314cc9a2e4796f3195ca2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,93 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using Vuplex.WebView.Internal;
|
||||
#if VUPLEX_MRTK
|
||||
using Microsoft.MixedReality.Toolkit.Input;
|
||||
#endif
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
[HelpURL("https://developer.vuplex.com/webview/IPointerInputDetector")]
|
||||
public class CanvasPointerInputDetector : DefaultPointerInputDetector {
|
||||
|
||||
RectTransform _cachedRectTransform;
|
||||
CachingGetter<Canvas> _canvasGetter;
|
||||
|
||||
protected override Vector2 _convertToNormalizedPoint(PointerEventData pointerEventData) {
|
||||
|
||||
if (_canvasGetter == null) {
|
||||
_canvasGetter = new CachingGetter<Canvas>(GetComponentInParent<Canvas>, 1, this);
|
||||
}
|
||||
var canvas = _canvasGetter.GetValue();
|
||||
var camera = canvas == null || canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera;
|
||||
Vector2 localPoint;
|
||||
var mousePosition = pointerEventData.position;
|
||||
#if (UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
|
||||
// To handle multiple displays on Windows and macOS, Display.RelativeMouseAt() must be used
|
||||
// to translate the mouse position. However, Unity's UI system still has a limitation where
|
||||
// this may not work when the monitors have different sizes / resolutions.
|
||||
// - https://issuetracker.unity3d.com/issues/buttons-hitbox-is-offset-when-building-standalone-project-for-two-screens
|
||||
var positionForDisplay = Display.RelativeMouseAt(new Vector3(mousePosition.x, mousePosition.y));
|
||||
// RelativeMouseAt() returns Vector3.zero when multiple displays aren't supported.
|
||||
if (positionForDisplay != Vector3.zero) {
|
||||
mousePosition = new Vector2(positionForDisplay.x, positionForDisplay.y);
|
||||
}
|
||||
#endif
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle(_getRectTransform(), mousePosition, camera, out localPoint);
|
||||
return _convertVector2ToNormalizedPoint(localPoint);
|
||||
}
|
||||
|
||||
protected override Vector2 _convertToNormalizedPoint(Vector3 worldPosition) {
|
||||
|
||||
var localPoint = _getRectTransform().InverseTransformPoint(worldPosition);
|
||||
var normalizedPoint = _convertVector2ToNormalizedPoint(localPoint);
|
||||
return normalizedPoint;
|
||||
}
|
||||
|
||||
// Note: This method was originally named _convertToNormalizedPoint(Vector2), but since a Vector3 can be implicitly
|
||||
// converted to a Vector2, it caused this method to incorrectly be called instead of _convertToNormalizedPoint(Vector3)
|
||||
// in some cases.
|
||||
Vector2 _convertVector2ToNormalizedPoint(Vector2 localPoint) {
|
||||
|
||||
var normalizedPoint = Rect.PointToNormalized(_getRectTransform().rect, localPoint);
|
||||
normalizedPoint.y = 1 - normalizedPoint.y;
|
||||
return normalizedPoint;
|
||||
}
|
||||
|
||||
RectTransform _getRectTransform() {
|
||||
|
||||
if (_cachedRectTransform == null) {
|
||||
_cachedRectTransform = GetComponent<RectTransform>();
|
||||
}
|
||||
return _cachedRectTransform;
|
||||
}
|
||||
|
||||
protected override bool _positionIsZero(PointerEventData eventData) => eventData.position == Vector2.zero;
|
||||
|
||||
void Start() {
|
||||
|
||||
#if VUPLEX_MRTK
|
||||
// Add a NearInteractionTouchable script to allow touch interactions
|
||||
// to trigger the IMixedRealityPointerHandler methods.
|
||||
var touchable = gameObject.AddComponent<NearInteractionTouchableUnityUI>();
|
||||
touchable.EventsToReceive = TouchableEventType.Pointer;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 70d2e4700f40744fe8b999f209d0253b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,531 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Serialization;
|
||||
using Vuplex.WebView.Internal;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// CanvasWebViewPrefab is a prefab that makes it easy to view and interact with an IWebView in a 2D Canvas.
|
||||
/// It takes care of creating an IWebView, displaying its texture, and handling pointer interactions
|
||||
/// from the user, like clicking, dragging, and scrolling. So, all you need to do is specify a URL or HTML to load,
|
||||
/// and then the user can view and interact with it. For use outside of a Canvas, see WebViewPrefab instead.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// There are two ways to create a CanvasWebViewPrefab:
|
||||
/// <list type="number">
|
||||
/// <item>
|
||||
/// By dragging the CanvasWebViewPrefab.prefab file into your scene via the editor and setting its "Initial URL" property.</item>
|
||||
/// <item>
|
||||
/// Or by creating an instance programmatically with CanvasWebViewPrefab.Instantiate(), waiting for
|
||||
/// it to initialize, and then calling methods on its WebView property, like LoadUrl().
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// <para>
|
||||
/// If your use case requires a high degree of customization, you can instead create an IWebView
|
||||
/// outside of the prefab with Web.CreateWebView().
|
||||
/// </para>
|
||||
/// See also:
|
||||
/// <list type="bullet">
|
||||
/// <item>WebViewPrefab: https://developer.vuplex.com/webview/WebViewPrefab</item>
|
||||
/// <item>How clicking and scrolling works: https://support.vuplex.com/articles/clicking</item>
|
||||
/// <item>IWebView: https://developer.vuplex.com/webview/IWebView</item>
|
||||
/// <item>Web (static methods): https://developer.vuplex.com/webview/Web</item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
[HelpURL("https://developer.vuplex.com/webview/CanvasWebViewPrefab")]
|
||||
public partial class CanvasWebViewPrefab : BaseWebViewPrefab {
|
||||
|
||||
public override event EventHandler<ClickedEventArgs> Clicked {
|
||||
add {
|
||||
if (_native2DModeActive) {
|
||||
_logNative2DModeWarning("The CanvasWebViewPrefab.Clicked event is not supported in Native 2D Mode.");
|
||||
}
|
||||
base.Clicked += value;
|
||||
}
|
||||
remove {
|
||||
base.Clicked -= value;
|
||||
}
|
||||
}
|
||||
|
||||
public override event EventHandler<ScrolledEventArgs> Scrolled {
|
||||
add {
|
||||
if (_native2DModeActive) {
|
||||
_logNative2DModeWarning("The CanvasWebViewPrefab.Scrolled event is not supported in Native 2D Mode.");
|
||||
}
|
||||
base.Scrolled += value;
|
||||
}
|
||||
remove {
|
||||
base.Scrolled -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables [Native 2D Mode](https://support.vuplex.com/articles/native-2d-mode/),
|
||||
/// which makes it so that 3D WebView positions a native 2D webview in front of the Unity game view
|
||||
/// instead of displaying web content as a texture in the Unity scene. The default is `false`. If set to `true` and the 3D WebView package
|
||||
/// in use doesn't support Native 2D Mode, then the default rendering mode is used instead.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Important notes:
|
||||
/// <list type="bullet">
|
||||
/// <item>
|
||||
/// Native 2D Mode is only supported for 3D WebView for Android (non-Gecko) and 3D WebView for iOS.
|
||||
/// For other packages, the default render mode is used instead.
|
||||
/// </item>
|
||||
/// <item>Native 2D Mode requires that the canvas's render mode be set to "Screen Space - Overlay".</item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
[Label("Native 2D Mode (Android, iOS, WebGL, and UWP only)")]
|
||||
[Tooltip("Native 2D Mode positions a native 2D webview in front of the Unity game view instead of rendering web content as a texture in the Unity scene. Native 2D Mode provides better performance on iOS and UWP, because the default mode of rendering web content to a texture is slower. \n\nImportant notes:\n• Native 2D Mode is only supported for Android (non-Gecko), iOS, WebGL, and UWP. For the other 3D WebView packages, the default render mode is used instead.\n• Native 2D Mode requires that the canvas's render mode be set to \"Screen Space - Overlay\".")]
|
||||
[HideInInspector]
|
||||
[Header("Platform-specific")]
|
||||
public bool Native2DModeEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the operating system's native on-screen keyboard is
|
||||
/// automatically shown when a text input in the webview is focused. The default for
|
||||
/// CanvasWebViewPrefab is `true`.
|
||||
/// </summary>
|
||||
/// <seealso cref="IWithNativeOnScreenKeyboard"/>
|
||||
/// <remarks>
|
||||
/// The native on-screen keyboard is only supported for the following packages:
|
||||
/// <list type="bullet">
|
||||
/// <item>3D WebView for Android (non-Gecko)</item>
|
||||
/// <item>3D WebView for iOS</item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
/// <remarks>
|
||||
/// 3D WebView for Android with Gecko Engine doesn't support automatically showing the native on-screen keyboard,
|
||||
/// but you can use Unity's [TouchScreenKeyboard](https://docs.unity3d.com/ScriptReference/TouchScreenKeyboard.html)
|
||||
/// API to show the keyboard and then send typed characters to the webview like described in [this article](https://support.vuplex.com/articles/how-to-use-a-third-party-keyboard).
|
||||
/// </remarks>
|
||||
/// <remarks>
|
||||
/// On iOS, disabling the keyboard for one webview disables it for all webviews.
|
||||
/// </remarks>
|
||||
/// <seealso cref="IWithNativeOnScreenKeyboard"/>
|
||||
/// <seealso cref="KeyboardEnabled"/>
|
||||
[Label("Native On-Screen Keyboard (Android and iOS only)")]
|
||||
[Tooltip("Determines whether the operating system's native on-screen keyboard is automatically shown when a text input in the webview is focused. The native on-screen keyboard is only supported for the following packages:\n• 3D WebView for Android (non-Gecko)\n• 3D WebView for iOS")]
|
||||
public bool NativeOnScreenKeyboardEnabled = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the prefab's resolution in pixels per Unity unit.
|
||||
/// You can change the resolution to make web content appear larger or smaller.
|
||||
/// The default resolution for CanvasWebViewPrefab is `1`.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Setting a lower resolution decreases the pixel density, but has the effect
|
||||
/// of making web content appear larger. Setting a higher resolution increases
|
||||
/// the pixel density, but has the effect of making content appear smaller.
|
||||
/// For more information on scaling web content, see
|
||||
/// [this support article](https://support.vuplex.com/articles/how-to-scale-web-content).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// When running in [Native 2D Mode](https://support.vuplex.com/articles/native-2d-mode), the Resolution field
|
||||
/// isn't used because the device's native resolution is used instead. So, the Resolution field's value is inaccurate and changes to it are ignored.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Set the resolution to 2.5px per Unity unit.
|
||||
/// webViewPrefab.Resolution = 2.5f;
|
||||
/// </code>
|
||||
/// </example>
|
||||
[Label("Resolution (px / Unity unit)")]
|
||||
[Tooltip("You can change this to make web content appear larger or smaller. Note that This property is ignored when running in Native 2D Mode.")]
|
||||
[HideInInspector]
|
||||
[FormerlySerializedAs("InitialResolution")]
|
||||
public float Resolution = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Determines the scroll sensitivity. The default sensitivity for CanvasWebViewPrefab is `15`.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This property is ignored when running in [Native 2D Mode](https://support.vuplex.com/articles/native-2d-mode).
|
||||
/// </remarks>
|
||||
[HideInInspector]
|
||||
[Tooltip("Determines the scroll sensitivity. Note that This property is ignored when running in Native 2D Mode.")]
|
||||
public float ScrollingSensitivity = 15;
|
||||
|
||||
public override bool Visible {
|
||||
get {
|
||||
var native2DWebView = _getNative2DWebViewIfActive();
|
||||
if (native2DWebView != null) {
|
||||
return native2DWebView.Visible;
|
||||
}
|
||||
return base.Visible;
|
||||
}
|
||||
set {
|
||||
var native2DWebView = _getNative2DWebViewIfActive();
|
||||
if (native2DWebView != null) {
|
||||
native2DWebView.SetVisible(value);
|
||||
return;
|
||||
}
|
||||
base.Visible = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The WebView property is available after initialization completes,
|
||||
/// which is indicated by WaitUntilInitialized().
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Create a CanvasWebViewPrefab
|
||||
/// var canvasWebViewPrefab = CanvasWebViewPrefab.Instantiate();
|
||||
/// // Position the prefab how we want it
|
||||
/// var canvas = GameObject.Find("Canvas");
|
||||
/// canvasWebViewPrefab.transform.parent = canvas.transform;
|
||||
/// var rectTransform = canvasWebViewPrefab.transform as RectTransform;
|
||||
/// rectTransform.anchoredPosition3D = Vector3.zero;
|
||||
/// rectTransform.offsetMin = Vector2.zero;
|
||||
/// rectTransform.offsetMax = Vector2.zero;
|
||||
/// canvasWebViewPrefab.transform.localScale = Vector3.one;
|
||||
/// // Load a URL once the prefab finishes initializing
|
||||
/// await canvasWebViewPrefab.WaitUntilInitialized();
|
||||
/// canvasWebViewPrefab.WebView.LoadUrl("https://vuplex.com");
|
||||
/// </code>
|
||||
/// </example>
|
||||
public static CanvasWebViewPrefab Instantiate() {
|
||||
|
||||
return Instantiate(new WebViewOptions());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Like Instantiate(), except it also accepts an object
|
||||
/// of options flags that can be used to alter the generated webview's behavior.
|
||||
/// </summary>
|
||||
public static CanvasWebViewPrefab Instantiate(WebViewOptions options) {
|
||||
|
||||
var prefabPrototype = (GameObject)Resources.Load("CanvasWebViewPrefab");
|
||||
var gameObject = (GameObject)Instantiate(prefabPrototype);
|
||||
var canvasWebViewPrefab = gameObject.GetComponent<CanvasWebViewPrefab>();
|
||||
canvasWebViewPrefab._options = options;
|
||||
return canvasWebViewPrefab;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Like Instantiate(float, float), except it initializes the instance with an existing, initialized
|
||||
/// IWebView instance. This causes the CanvasWebViewPrefab to use the existing
|
||||
/// IWebView instance instead of creating a new one. This can be used, for example, to create multiple
|
||||
/// WebViewPrefabs that are connected to the same IWebView, or to create a prefab for an IWebView
|
||||
/// created by IWithPopups.PopupRequested.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await firstWebViewPrefab.WaitUntilInitialized();
|
||||
/// var secondWebViewPrefab = CanvasWebViewPrefab.Instantiate(firstWebViewPrefab.WebView);
|
||||
/// // TODO: Position secondWebViewPrefab to the location where you want to display it.
|
||||
/// </code>
|
||||
/// </example>
|
||||
public static CanvasWebViewPrefab Instantiate(IWebView webView) {
|
||||
|
||||
var prefabPrototype = (GameObject)Resources.Load("CanvasWebViewPrefab");
|
||||
var gameObject = (GameObject)Instantiate(prefabPrototype);
|
||||
var canvasWebViewPrefab = gameObject.GetComponent<CanvasWebViewPrefab>();
|
||||
canvasWebViewPrefab.SetWebViewForInitialization(webView);
|
||||
return canvasWebViewPrefab;
|
||||
}
|
||||
|
||||
#region Non-public members
|
||||
RectTransform _cachedRectTransform;
|
||||
Canvas _canvas {
|
||||
get {
|
||||
if (_canvasGetter == null) {
|
||||
_canvasGetter = new CachingGetter<Canvas>(GetComponentInParent<Canvas>, 1, this);
|
||||
}
|
||||
return _canvasGetter.GetValue();
|
||||
}
|
||||
}
|
||||
CachingGetter<Canvas> _canvasGetter;
|
||||
bool _native2DModeActive {
|
||||
get {
|
||||
var webViewWith2DMode = WebView as IWithNative2DMode;
|
||||
return webViewWith2DMode != null && webViewWith2DMode.Native2DModeEnabled;
|
||||
}
|
||||
}
|
||||
RectTransform _rectTransform {
|
||||
get {
|
||||
if (_cachedRectTransform == null) {
|
||||
_cachedRectTransform = GetComponent<RectTransform>();
|
||||
}
|
||||
return _cachedRectTransform;
|
||||
}
|
||||
}
|
||||
|
||||
// Partial method implemented by various 3D WebView packages
|
||||
// to provide platform-specific warnings.
|
||||
partial void OnInit();
|
||||
|
||||
bool _canNative2DModeBeEnabled(bool logWarnings = false) {
|
||||
|
||||
if (_canvas != null && _canvas.renderMode == RenderMode.WorldSpace) {
|
||||
if (logWarnings) {
|
||||
_logNative2DModeWarning("CanvasWebViewPrefab.Native2DModeEnabled is enabled but the canvas's render mode is set to World Space, so Native 2D Mode will not be enabled. In order to use Native 2D Mode, please switch the canvas's render mode to \"Screen Space - Overlay\" or \"Screen Space - Camera\".");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (VXUtils.XRSettings.enabled) {
|
||||
if (logWarnings) {
|
||||
_logNative2DModeWarning("CanvasWebViewPrefab.Native2DModeEnabled is enabled but XR is enabled, so Native 2D Mode will not be enabled.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Rect _getRectForInitialization(bool preferNative2DMode) => preferNative2DMode ? _getScreenSpaceRect() : _rectTransform.rect;
|
||||
|
||||
protected override float _getResolution() {
|
||||
|
||||
if (Resolution > 0f) {
|
||||
return Resolution;
|
||||
}
|
||||
WebViewLogger.LogError("Invalid value set for CanvasWebViewPrefab.Resolution: " + Resolution);
|
||||
return 1;
|
||||
}
|
||||
|
||||
IWithNative2DMode _getNative2DWebViewIfActive() {
|
||||
|
||||
var webViewWith2DMode = WebView as IWithNative2DMode;
|
||||
if (webViewWith2DMode != null && webViewWith2DMode.Native2DModeEnabled) {
|
||||
return webViewWith2DMode;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override bool _getNativeOnScreenKeyboardEnabled() => NativeOnScreenKeyboardEnabled;
|
||||
|
||||
protected override float _getScrollingSensitivity() => ScrollingSensitivity;
|
||||
|
||||
Rect _getScreenSpaceRect() {
|
||||
|
||||
var canvas = _canvas;
|
||||
if (canvas == null) {
|
||||
WebViewLogger.LogError("Unable to determine the screen space rect for Native 2D Mode because the CanvasWebViewPrefab is not placed in a Canvas. Please place the CanvasWebViewPrefab as the child of a Unity UI Canvas.");
|
||||
return Rect.zero;
|
||||
}
|
||||
var worldCorners = new Vector3[4];
|
||||
_rectTransform.GetWorldCorners(worldCorners);
|
||||
var topLeftCorner = worldCorners[1];
|
||||
var bottomRightCorner = worldCorners[3];
|
||||
|
||||
if (canvas.renderMode != RenderMode.ScreenSpaceOverlay) {
|
||||
var camera = canvas.worldCamera;
|
||||
if (camera == null) {
|
||||
WebViewLogger.LogError("Unable to determine the screen space rect for Native 2D Mode because the Canvas's render camera is not set. Please set the Canvas's \"Render Camera\" setting or change its render mode to \"Screen Space - Overlay\".");
|
||||
} else {
|
||||
topLeftCorner = camera.WorldToScreenPoint(topLeftCorner);
|
||||
bottomRightCorner = camera.WorldToScreenPoint(bottomRightCorner);
|
||||
}
|
||||
}
|
||||
var x = topLeftCorner.x;
|
||||
var y = Screen.height - topLeftCorner.y;
|
||||
var width = bottomRightCorner.x - topLeftCorner.x;
|
||||
var height = topLeftCorner.y - bottomRightCorner.y;
|
||||
var scaleFactor = _getScreenSpaceScaleFactor();
|
||||
if (scaleFactor != 1f) {
|
||||
x *= scaleFactor;
|
||||
y *= scaleFactor;
|
||||
width *= scaleFactor;
|
||||
height *= scaleFactor;
|
||||
}
|
||||
return new Rect(x, y, width, height);
|
||||
}
|
||||
|
||||
// Provides a scale factor to account for an issue where GetWorldCorners() is incorrect in the following scenarios:
|
||||
// - If the screen resolution is changed at runtime using Screen.SetResolution().
|
||||
// - If the "Resolution Scaling Mode" is set to "Fixed DPI" in Player Settings -> Resolution and Presentation (on Android).
|
||||
float _getScreenSpaceScaleFactor() {
|
||||
|
||||
var display = Display.main;
|
||||
if (display.renderingWidth == display.systemHeight && display.renderingHeight == display.systemWidth) {
|
||||
// Some old versions of Unity (like 2019.4.33) have a bug in the Android player where after the device
|
||||
// is rotated, the Display's rendering width and height are swapped but the system width and height aren't.
|
||||
// Return 1 in that scenario to prevent computing an incorrect scale factor.
|
||||
return 1f;
|
||||
}
|
||||
// Notes:
|
||||
// - This approach doesn't work for detecting when "Resolution Scaling Mode" is set to "Fixed DPI" on iOS because
|
||||
// display.systemWidth is equal to display.renderingWidth on iOS in that scenario. However, the native iOS plugin
|
||||
// applies its own scale factor that works correctly for "Fixed DPI".
|
||||
// - If an Android device has a notch and the "Render outside safe area" option is disabled, then the renderingWidth will be
|
||||
// equal to the Screen.safeArea.width, which is less than the systemWidth. Unfortunately, it doesn't appear to
|
||||
// be possible to detect if the "Resolution Scaling Mode" is set to "Fixed DPI" in that scenario because it doesn't
|
||||
// appear to be possible to detect the "Fixed DPI" setting in native code like it is on iOS.
|
||||
// - It's important to also check that display.systemWidth != Screen.currentResolution.width because on UWP,
|
||||
// display.renderingWidth != display.systemWidth is true whenever the app's window isn't full screen, but
|
||||
// display.systemWidth and Screen.currentResolution.width are still equal in that scenario.
|
||||
// - This method used to work by comparing the current Screen.currentResolution to the original value of
|
||||
// Screen.currentResolution from when the app started, but that approach caused an issue on iPads because
|
||||
// Screen.currentResolution changes when multiple apps are shown side-by-side with the iPad's Split View.
|
||||
var screenHasNotchAndRenderOutsideSafeAreaIsDisabled = false;
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
screenHasNotchAndRenderOutsideSafeAreaIsDisabled = AndroidUtils.ScreenHasNotchAndRenderOutsideSafeAreaIsDisabled();
|
||||
#endif
|
||||
var screenResolutionChanged = display.renderingWidth != display.systemWidth &&
|
||||
!screenHasNotchAndRenderOutsideSafeAreaIsDisabled &&
|
||||
display.systemWidth != Screen.currentResolution.width;
|
||||
if (screenResolutionChanged) {
|
||||
float scaleFactor = (float)display.systemWidth / (float)display.renderingWidth;
|
||||
return scaleFactor;
|
||||
}
|
||||
return 1f;
|
||||
}
|
||||
|
||||
protected override ViewportMaterialView _getVideoLayer() {
|
||||
|
||||
var obj = transform.Find("VideoLayer");
|
||||
return obj == null ? null : obj.GetComponent<ViewportMaterialView>();
|
||||
}
|
||||
|
||||
protected override ViewportMaterialView _getView() {
|
||||
|
||||
var obj = transform.Find("CanvasWebViewPrefabView");
|
||||
return obj == null ? null : obj.GetComponent<ViewportMaterialView>();
|
||||
}
|
||||
|
||||
async void _initCanvasPrefab() {
|
||||
try {
|
||||
OnInit();
|
||||
Initialized += _logNative2DRecommendationIfNeeded;
|
||||
var preferNative2DMode = Native2DModeEnabled && _canNative2DModeBeEnabled(true);
|
||||
var rect = _getRectForInitialization(preferNative2DMode);
|
||||
if (_sizeIsInvalid(rect.size)) {
|
||||
// If the prefab is nested in a LayoutGroup, its width and height will be zero on the first frame,
|
||||
// so it's necessary to pass the LayoutGroup's RectTransform LayoutRebuilder.ForceRebuildLayoutImmediate().
|
||||
// https://forum.unity.com/threads/force-immediate-layout-update.372630
|
||||
var layoutGroup = GetComponentInParent<LayoutGroup>();
|
||||
if (layoutGroup != null) {
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)layoutGroup.transform);
|
||||
rect = _getRectForInitialization(preferNative2DMode);
|
||||
}
|
||||
}
|
||||
if (_logErrorIfSizeIsInvalid(rect.size)) {
|
||||
return;
|
||||
}
|
||||
await _initBase(rect, preferNative2DMode);
|
||||
} catch (Exception exception) {
|
||||
// Catch any exceptions that occur during initialization because
|
||||
// some applications terminate the application on uncaught exceptions.
|
||||
Debug.LogException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
bool _logErrorIfSizeIsInvalid(Vector2 size) {
|
||||
|
||||
if (_sizeIsInvalid(size)) {
|
||||
WebViewLogger.LogError($"CanvasWebViewPrefab dimensions are invalid! Width: {size.x.ToString("f4")}, Height: {size.y.ToString("f4")}. To correct this, please adjust the CanvasWebViewPrefab's RectTransform to make it so that its width and height are both greater than zero. https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/class-RectTransform.html");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void _logNative2DModeWarning(string message) {
|
||||
|
||||
WebViewLogger.LogWarning(message + " For more info, please see this article: <em>https://support.vuplex.com/articles/native-2d-mode</em>");
|
||||
}
|
||||
|
||||
void _logNative2DRecommendationIfNeeded(object sender, EventArgs eventArgs) {
|
||||
|
||||
var webViewWith2DMode = WebView as IWithNative2DMode;
|
||||
if (_canNative2DModeBeEnabled() && webViewWith2DMode != null && !webViewWith2DMode.Native2DModeEnabled) {
|
||||
WebViewLogger.LogTip("This platform supports Native 2D Mode, so consider enabling CanvasWebViewPrefab.Native2DModeEnabled for best results. For more info, see https://support.vuplex.com/articles/native-2d-mode .");
|
||||
}
|
||||
}
|
||||
|
||||
void OnDisable() {
|
||||
|
||||
// When in Native 2D Mode, hide the webview when the CanvasWebViewPrefab is deactivated.
|
||||
var webView = _getNative2DWebViewIfActive();
|
||||
if (webView != null) {
|
||||
webView.SetVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void OnEnable() {
|
||||
|
||||
// When in Native 2D Mode, show the webview when the CanvasWebViewPrefab is activated.
|
||||
var webView = _getNative2DWebViewIfActive();
|
||||
if (webView != null) {
|
||||
webView.SetVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void _setVideoLayerPosition(Rect videoRect) {
|
||||
|
||||
var videoRectTransform = _videoLayer.transform as RectTransform;
|
||||
// Use Vector2.Scale() because Vector2 * Vector2 isn't supported in Unity 2017.
|
||||
videoRectTransform.anchoredPosition = Vector2.Scale(Vector2.Scale(videoRect.position, _rectTransform.rect.size), new Vector2(1, -1));
|
||||
videoRectTransform.sizeDelta = Vector2.Scale(videoRect.size, _rectTransform.rect.size);
|
||||
}
|
||||
|
||||
bool _sizeIsInvalid(Vector2 size) => !(size.x > 0f && size.y > 0f);
|
||||
|
||||
void Start() => _initCanvasPrefab();
|
||||
|
||||
protected override void Update() {
|
||||
|
||||
base.Update();
|
||||
if (WebView == null) {
|
||||
return;
|
||||
}
|
||||
_sizeInUnityUnits = _rectTransform.rect.size;
|
||||
if (_logErrorIfSizeIsInvalid(_sizeInUnityUnits)) {
|
||||
return;
|
||||
}
|
||||
// Handle updating the rect for a native 2D webview.
|
||||
var native2DWebView = _getNative2DWebViewIfActive();
|
||||
if (native2DWebView != null) {
|
||||
var screenSpaceRect = _getScreenSpaceRect();
|
||||
if (native2DWebView.Rect != screenSpaceRect) {
|
||||
native2DWebView.SetRect(screenSpaceRect);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Handle resizing a regular webview.
|
||||
_resizeWebViewIfNeeded();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Obsolete APIs
|
||||
// Added in v3.2, removed in v3.12.
|
||||
[Obsolete("CanvasWebViewPrefab.Init() has been removed. The CanvasWebViewPrefab script now initializes itself automatically, so Init() no longer needs to be called.", true)]
|
||||
public void Init() {}
|
||||
|
||||
// Added in v3.2, removed in v3.12.
|
||||
[Obsolete("CanvasWebViewPrefab.Init() has been removed. The CanvasWebViewPrefab script now initializes itself automatically, so Init() no longer needs to be called.", true)]
|
||||
public void Init(WebViewOptions options) {}
|
||||
|
||||
// Added in v3.10, removed in v3.12.
|
||||
[Obsolete("CanvasWebViewPrefab.Init() has been removed. The CanvasWebViewPrefab script now initializes itself automatically, so Init() no longer needs to be called. Please use CanvasWebViewPrefab.SetWebViewForInitialization(IWebView) instead.", true)]
|
||||
public void Init(IWebView webView) {}
|
||||
|
||||
// Deprecated in v4.0.
|
||||
[Obsolete("CanvasWebViewPrefab.InitialResolution is now deprecated. Please use CanvasWebViewPrefab.Resolution instead.")]
|
||||
public float InitialResolution {
|
||||
get { return Resolution; }
|
||||
set { Resolution = value; }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 879d31ebe92b040cbb3ef97e98278140
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,32 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// Event args for WebViewPrefab.Clicked.
|
||||
/// </summary>
|
||||
public class ClickedEventArgs : EventArgs {
|
||||
|
||||
public ClickedEventArgs(Vector2 point) => Point = point;
|
||||
|
||||
/// <summary>
|
||||
/// The normalized point that was passed to IWebView.Click().
|
||||
/// </summary>
|
||||
public readonly Vector2 Point;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 933218f5f10cb4e1eba142d6ef865e7c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,53 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// Event args for `ConsoleMessageLogged`.
|
||||
/// </summary>
|
||||
public class ConsoleMessageEventArgs : EventArgs {
|
||||
|
||||
public ConsoleMessageEventArgs(ConsoleMessageLevel level, string message, string source, int line) {
|
||||
|
||||
Level = level;
|
||||
Message = message;
|
||||
Source = source;
|
||||
Line = line;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The message's log level.
|
||||
/// </summary>
|
||||
public readonly ConsoleMessageLevel Level;
|
||||
|
||||
/// <summary>
|
||||
/// The message logged to the JavaScript console.
|
||||
/// </summary>
|
||||
public readonly string Message;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the file from which the message was logged,
|
||||
/// or `null` if the source is unknown.
|
||||
/// </summary>
|
||||
public readonly string Source;
|
||||
|
||||
/// <summary>
|
||||
/// The line number of the file from which the message was logged,
|
||||
/// or `0` if the source is unknown.
|
||||
/// </summary>
|
||||
public readonly int Line;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 409b384742d2744ed97f710a648314dd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// Levels for messages logged to the JavaScript console.
|
||||
/// </summary>
|
||||
public enum ConsoleMessageLevel {
|
||||
Debug,
|
||||
Error,
|
||||
Log,
|
||||
Warning
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 46d435c1d5797420b83db35ed40f7526
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,120 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Vuplex.WebView.Internal;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// An HTTP cookie.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class Cookie {
|
||||
|
||||
/// <summary>
|
||||
/// The name of the cookie.
|
||||
/// </summary>
|
||||
public string Name;
|
||||
|
||||
/// <summary>
|
||||
/// The value of the cookie.
|
||||
/// </summary>
|
||||
public string Value;
|
||||
|
||||
/// <summary>
|
||||
/// The domain to which the cookie belongs (e.g. "www.vuplex.com", "example.com").
|
||||
/// </summary>
|
||||
public string Domain;
|
||||
|
||||
/// <summary>
|
||||
/// The URL path of the cookie (e.g. "/", "/products/1234").
|
||||
/// The default is "/".
|
||||
/// </summary>
|
||||
public string Path = "/";
|
||||
|
||||
/// <summary>
|
||||
/// A number representing the expiration date of the cookie as the number of seconds since the UNIX epoch, or 0
|
||||
/// if there is no expiration date. An expiration date is not provided for session cookies.
|
||||
/// </summary>
|
||||
public int ExpirationDate;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the cookie is marked as HttpOnly (i.e. the cookie is inaccessible to client-side scripts).
|
||||
/// </summary>
|
||||
public bool HttpOnly;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether cookie is marked as secure (i.e. its scope is limited to secure channels, typically HTTPS).
|
||||
/// </summary>
|
||||
public bool Secure;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the cookie is valid.
|
||||
/// </summary>
|
||||
public bool IsValid {
|
||||
get {
|
||||
var isValid = true;
|
||||
if (Name == null) {
|
||||
WebViewLogger.LogWarning("Invalid value for Cookie.Name: " + Name);
|
||||
isValid = false;
|
||||
}
|
||||
if (Value == null) {
|
||||
WebViewLogger.LogWarning("Invalid value for Cookie.Value: " + Value);
|
||||
isValid = false;
|
||||
}
|
||||
if (Domain == null || !Domain.Contains(".") || Domain.Contains("/")) {
|
||||
WebViewLogger.LogWarning("Invalid value for Cookie.Domain: " + Domain);
|
||||
isValid = false;
|
||||
}
|
||||
if (Path == null) {
|
||||
WebViewLogger.LogWarning("Invalid value for Cookie.Path: " + Path);
|
||||
isValid = false;
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a Cookie array from JSON.
|
||||
/// </summary>
|
||||
public static Cookie[] ArrayFromJson(string serializedCookies) {
|
||||
|
||||
if (serializedCookies == "null") {
|
||||
return new Cookie[0];
|
||||
}
|
||||
var cookiesWrapper = JsonUtility.FromJson<JsonArrayWrapper<Cookie>>(serializedCookies);
|
||||
var cookies = cookiesWrapper.Items ?? new Cookie[0];
|
||||
return cookies;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a Cookie from JSON.
|
||||
/// </summary>
|
||||
public static Cookie FromJson(string serializedCookie) {
|
||||
|
||||
if (serializedCookie == "null") {
|
||||
return null;
|
||||
}
|
||||
return JsonUtility.FromJson<Cookie>(serializedCookie);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the instance to JSON.
|
||||
/// </summary>
|
||||
public string ToJson() => JsonUtility.ToJson(this);
|
||||
|
||||
public override string ToString() => ToJson();
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 210d3253f4a834f5c912b7547d42c28e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,308 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using Vuplex.WebView.Internal;
|
||||
#if VUPLEX_MRTK
|
||||
using Microsoft.MixedReality.Toolkit.Input;
|
||||
#endif
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
[HelpURL("https://developer.vuplex.com/webview/IPointerInputDetector")]
|
||||
public class DefaultPointerInputDetector : MonoBehaviour,
|
||||
IPointerInputDetector,
|
||||
IBeginDragHandler,
|
||||
IDragHandler,
|
||||
IPointerClickHandler,
|
||||
IPointerDownHandler,
|
||||
IPointerEnterHandler,
|
||||
IPointerExitHandler,
|
||||
IPointerUpHandler,
|
||||
#if VUPLEX_MRTK
|
||||
IMixedRealityPointerHandler,
|
||||
#endif
|
||||
IScrollHandler {
|
||||
|
||||
public event EventHandler<EventArgs<Vector2>> BeganDrag;
|
||||
|
||||
public event EventHandler<EventArgs<Vector2>> Dragged;
|
||||
|
||||
public event EventHandler<PointerEventArgs> PointerDown;
|
||||
|
||||
public event EventHandler PointerEntered;
|
||||
|
||||
public event EventHandler<EventArgs<Vector2>> PointerExited;
|
||||
|
||||
public event EventHandler<EventArgs<Vector2>> PointerMoved;
|
||||
|
||||
public event EventHandler<PointerEventArgs> PointerUp;
|
||||
|
||||
public event EventHandler<ScrolledEventArgs> Scrolled;
|
||||
|
||||
public bool PointerMovedEnabled { get; set; }
|
||||
|
||||
/// <see cref="IBeginDragHandler"/>
|
||||
public void OnBeginDrag(PointerEventData eventData) {
|
||||
|
||||
_raiseBeganDragEvent(_convertToEventArgs(eventData));
|
||||
}
|
||||
|
||||
/// <see cref="IDragHandler"/>
|
||||
public void OnDrag(PointerEventData eventData) {
|
||||
|
||||
// The point is Vector3.zero when the user drags off of the screen.
|
||||
if (!_positionIsZero(eventData)) {
|
||||
_raiseDraggedEvent(_convertToEventArgs(eventData));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// VRIF requires IPointerClickHandler to be implemented in order to detect the object
|
||||
/// and invoke its OnPointerDown() and OnPointerUp() methods.
|
||||
/// </summary>
|
||||
/// <see cref="IPointerClickHandler"/>
|
||||
public void OnPointerClick(PointerEventData eventData) {}
|
||||
|
||||
/// <see cref="IPointerDownHandler"/>
|
||||
public virtual void OnPointerDown(PointerEventData eventData) {
|
||||
|
||||
_raisePointerDownEvent(_convertToPointerEventArgs(eventData));
|
||||
}
|
||||
|
||||
/// <see cref="IPointerEnterHandler"/>
|
||||
public void OnPointerEnter(PointerEventData eventData) {
|
||||
|
||||
_isHovering = true;
|
||||
_raisePointerEnteredEvent(EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <see cref="IPointerExitHandler"/>
|
||||
public void OnPointerExit(PointerEventData eventData) {
|
||||
|
||||
_isHovering = false;
|
||||
// When StandaloneInputModule triggers OnPointerExit, eventData.pointerCurrentRaycast.worldPosition is usually Vector3.zero,
|
||||
// so for world space, just fallback to sending a normalized point of Vector2.zero.
|
||||
var point = _positionIsZero(eventData) ? Vector2.zero : _convertToNormalizedPoint(eventData);
|
||||
// Since this is an exit event, the coordinate can sometimes be just outside the bounds of [0, 1], so clamp it to [0, 1].
|
||||
for (var i = 0; i < 2; i++) {
|
||||
if (point[i] < 0f) {
|
||||
point[i] = 0f;
|
||||
} else if (point[i] > 1f) {
|
||||
point[i] = 1f;
|
||||
}
|
||||
}
|
||||
_raisePointerExitedEvent(new EventArgs<Vector2>(point));
|
||||
}
|
||||
|
||||
/// <see cref="IPointerUpHandler"/>
|
||||
public virtual void OnPointerUp(PointerEventData eventData) {
|
||||
|
||||
_raisePointerUpEvent(_convertToPointerEventArgs(eventData));
|
||||
}
|
||||
|
||||
/// <see cref="IScrollHandler"/>
|
||||
public void OnScroll(PointerEventData eventData) {
|
||||
|
||||
var scrollDelta = -1 * eventData.scrollDelta;
|
||||
_raiseScrolledEvent(new ScrolledEventArgs(scrollDelta, _convertToNormalizedPoint(eventData)));
|
||||
}
|
||||
|
||||
bool _isHovering;
|
||||
|
||||
EventArgs<Vector2> _convertToEventArgs(Vector3 worldPosition) {
|
||||
|
||||
var screenPoint = _convertToNormalizedPoint(worldPosition);
|
||||
return new EventArgs<Vector2>(screenPoint);
|
||||
}
|
||||
|
||||
EventArgs<Vector2> _convertToEventArgs(PointerEventData pointerEventData) {
|
||||
|
||||
var screenPoint = _convertToNormalizedPoint(pointerEventData);
|
||||
return new EventArgs<Vector2>(screenPoint);
|
||||
}
|
||||
|
||||
protected virtual Vector2 _convertToNormalizedPoint(PointerEventData pointerEventData) {
|
||||
|
||||
return _convertToNormalizedPoint(pointerEventData.pointerCurrentRaycast.worldPosition);
|
||||
}
|
||||
|
||||
protected virtual Vector2 _convertToNormalizedPoint(Vector3 worldPosition) {
|
||||
|
||||
// Note: transform.parent is WebViewPrefabResizer
|
||||
var localPosition = transform.parent.InverseTransformPoint(worldPosition);
|
||||
var point = new Vector2(1 - localPosition.x, -1 * localPosition.y);
|
||||
// In some cases, the point may be outside the range of [0, 1], so we need to clamp it to [0, 1]. Scenarios where that's the case:
|
||||
// - OnPointerExit()
|
||||
// - OnPointerUp(), if the mouse button is released after dragging outside of the webview.
|
||||
for (var i = 0; i < 2; i++) {
|
||||
if (point[i] < 0f) {
|
||||
point[i] = 0f;
|
||||
} else if (point[i] > 1f) {
|
||||
point[i] = 1f;
|
||||
}
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
PointerEventArgs _convertToPointerEventArgs(PointerEventData eventData) {
|
||||
|
||||
return new PointerEventArgs {
|
||||
Point = _convertToNormalizedPoint(eventData),
|
||||
Button = (MouseButton)eventData.button,
|
||||
// StandaloneInputModule incorrectly specifies a click count of 0
|
||||
// for PointerDown events, so set the minimum to 1 click.
|
||||
ClickCount = Math.Max(eventData.clickCount, 1)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unity's event system doesn't include a standard pointer event
|
||||
/// for hovering (i.e. there's no `IPointerHoverHandler` interface).
|
||||
/// So, this method implements the equivalent functionality for different input modules.
|
||||
/// </summary>
|
||||
PointerEventData _getLastPointerEventData() {
|
||||
|
||||
var currentInputModule = EventSystem.current == null ? null : EventSystem.current.currentInputModule;
|
||||
// Support for input modules that derive from PointerInputModule, like StandaloneInputModule.
|
||||
var pointerInputModule = currentInputModule as PointerInputModule;
|
||||
if (pointerInputModule != null) {
|
||||
// Use reflection to get access to the protected GetPointerData()
|
||||
// method. Unity isn't going to change this API because most input modules
|
||||
// extend PointerInputModule. Note that GetPointerData() is used instead
|
||||
// of GetLastPointerEventData() because the latter doesn't work with
|
||||
// the Oculus SDK's OVRInputModule.
|
||||
var args = new object[] { PointerInputModule.kMouseLeftId, null, false };
|
||||
pointerInputModule.GetType().InvokeMember(
|
||||
"GetPointerData",
|
||||
BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
|
||||
null,
|
||||
pointerInputModule,
|
||||
args
|
||||
);
|
||||
// The second argument is an out param.
|
||||
var pointerEventData = args[1] as PointerEventData;
|
||||
return pointerEventData;
|
||||
}
|
||||
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
// Support for the new InputSystem's InputSystemUIInputModule.
|
||||
var uiInputModule = currentInputModule as UnityEngine.InputSystem.UI.InputSystemUIInputModule;
|
||||
if (uiInputModule != null) {
|
||||
var pointerEventData = new PointerEventData(EventSystem.current);
|
||||
var raycastResult = uiInputModule.GetLastRaycastResult(0);
|
||||
pointerEventData.position = raycastResult.screenPosition;
|
||||
pointerEventData.pointerCurrentRaycast = uiInputModule.GetLastRaycastResult(0);
|
||||
return pointerEventData;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if VUPLEX_XR_INTERACTION_TOOLKIT
|
||||
// Support for XR Interaction Toolkit.
|
||||
return Internal.XritPointerEventHelper.Instance.LastPointerEventData;
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
|
||||
protected virtual bool _positionIsZero(PointerEventData eventData) => eventData.pointerCurrentRaycast.worldPosition == Vector3.zero;
|
||||
|
||||
protected void _raiseBeganDragEvent(EventArgs<Vector2> eventArgs) => BeganDrag?.Invoke(this, eventArgs);
|
||||
|
||||
protected void _raiseDraggedEvent(EventArgs<Vector2> eventArgs) => Dragged?.Invoke(this, eventArgs);
|
||||
|
||||
protected void _raisePointerDownEvent(PointerEventArgs eventArgs) => PointerDown?.Invoke(this, eventArgs);
|
||||
|
||||
protected void _raisePointerEnteredEvent(EventArgs eventArgs) => PointerEntered?.Invoke(this, eventArgs);
|
||||
|
||||
protected void _raisePointerExitedEvent(EventArgs<Vector2> eventArgs) => PointerExited?.Invoke(this, eventArgs);
|
||||
|
||||
void _raisePointerMovedIfNeeded() {
|
||||
|
||||
if (!(PointerMovedEnabled && _isHovering)) {
|
||||
return;
|
||||
}
|
||||
var pointerEventData = _getLastPointerEventData();
|
||||
if (pointerEventData == null) {
|
||||
return;
|
||||
}
|
||||
var point = _convertToNormalizedPoint(pointerEventData);
|
||||
if (!(point.x >= 0f && point.y >= 0f)) {
|
||||
// This can happen while the prefab is being resized.
|
||||
return;
|
||||
}
|
||||
_raisePointerMovedEvent(new EventArgs<Vector2>(point));
|
||||
}
|
||||
|
||||
protected void _raisePointerMovedEvent(EventArgs<Vector2> eventArgs) => PointerMoved?.Invoke(this, eventArgs);
|
||||
|
||||
protected void _raisePointerUpEvent(PointerEventArgs eventArgs) => PointerUp?.Invoke(this, eventArgs);
|
||||
|
||||
protected void _raiseScrolledEvent(ScrolledEventArgs eventArgs) => Scrolled?.Invoke(this, eventArgs);
|
||||
|
||||
protected virtual void Update() => _raisePointerMovedIfNeeded();
|
||||
|
||||
// Code specific to Microsoft's Mixed Reality Toolkit.
|
||||
#if VUPLEX_MRTK
|
||||
bool _beganDragEmitted;
|
||||
|
||||
/// <see cref="IMixedRealityPointerHandler"/>
|
||||
public void OnPointerClicked(MixedRealityPointerEventData eventData) {}
|
||||
|
||||
/// <see cref="IMixedRealityPointerHandler"/>
|
||||
public void OnPointerDragged(MixedRealityPointerEventData eventData) {
|
||||
|
||||
var eventArgs = _convertToEventArgs(eventData.Pointer.Result.Details.Point);
|
||||
if (_beganDragEmitted) {
|
||||
_raiseDraggedEvent(eventArgs);
|
||||
} else {
|
||||
_beganDragEmitted = true;
|
||||
_raiseBeganDragEvent(eventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
/// <see cref="IMixedRealityPointerHandler"/>
|
||||
public void OnPointerDown(MixedRealityPointerEventData eventData) {
|
||||
|
||||
// Set IsTargetPositionLockedOnFocusLock to false, or else the Point
|
||||
// coordinates will be locked and won't change in OnPointerDragged or OnPointerUp.
|
||||
eventData.Pointer.IsTargetPositionLockedOnFocusLock = false;
|
||||
_beganDragEmitted = false;
|
||||
var screenPoint = _convertToNormalizedPoint(eventData.Pointer.Result.Details.Point);
|
||||
_raisePointerDownEvent(new PointerEventArgs { Point = screenPoint });
|
||||
}
|
||||
|
||||
/// <see cref="IMixedRealityPointerHandler"/>
|
||||
public void OnPointerUp(MixedRealityPointerEventData eventData) {
|
||||
|
||||
var screenPoint = _convertToNormalizedPoint(eventData.Pointer.Result.Details.Point);
|
||||
_raisePointerUpEvent(new PointerEventArgs { Point = screenPoint });
|
||||
}
|
||||
|
||||
void Start() {
|
||||
|
||||
WebViewLogger.Log("Just a heads-up: please ignore the warning 'BoxCollider is null...' warning from MRTK. WebViewPrefab doesn't use a BoxCollider, so it sets the bounds of NearInteractionTouchable manually, but MRTK doesn't provide a way to disable the warning.");
|
||||
// Add a NearInteractionTouchable script to allow touch interactions
|
||||
// to trigger the IMixedRealityPointerHandler methods.
|
||||
var touchable = gameObject.AddComponent<NearInteractionTouchable>();
|
||||
touchable.EventsToReceive = TouchableEventType.Pointer;
|
||||
touchable.SetBounds(Vector2.one);
|
||||
touchable.SetLocalForward(new Vector3(0, 0, -1));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9b5d2e4670d86405386a27a4b18941bf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,69 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// Event args for IWithDownloads.DownloadProgressChanged.
|
||||
/// </summary>
|
||||
public class DownloadChangedEventArgs : EventArgs {
|
||||
|
||||
public DownloadChangedEventArgs(string contentType, string filePath, string id, float progress, ProgressChangeType type, string url) {
|
||||
ContentType = contentType;
|
||||
FilePath = filePath;
|
||||
Id = id;
|
||||
Progress = progress;
|
||||
Type = type;
|
||||
Url = url;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The mime type indicated by the Content-Type response header,
|
||||
/// or `null` if no content type was specified.
|
||||
/// </summary>
|
||||
public readonly string ContentType;
|
||||
|
||||
/// <summary>
|
||||
/// The full file path of the downloaded file. Files are downloaded to
|
||||
/// Application.temporaryCachePath, but you can move them to a different
|
||||
/// location after they finish downloading.
|
||||
/// </summary>
|
||||
public readonly string FilePath;
|
||||
|
||||
/// <summary>
|
||||
/// An identifier for the file, which can be used to track the
|
||||
/// file's download progress across multiple invocations of the DownloadProgressChanged event.
|
||||
/// </summary>
|
||||
public readonly string Id;
|
||||
|
||||
/// <summary>
|
||||
/// The estimated download progress, normalized to a float between 0 and 1.
|
||||
/// Note that not all platforms support intermediate progress updates.
|
||||
/// </summary>
|
||||
public readonly float Progress;
|
||||
|
||||
/// <summary>
|
||||
/// The download progress event type. Note that not all platforms
|
||||
/// support the Updated event type.
|
||||
/// </summary>
|
||||
public readonly ProgressChangeType Type;
|
||||
|
||||
/// <summary>
|
||||
/// The URL from which the file was downloaded.
|
||||
/// </summary>
|
||||
public readonly string Url;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f0e00d0f766c742a9976e3b2d7382468
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,47 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// Options for how drag interactions affect
|
||||
/// WebViewPrefab and CanvasWebViewPrefab.
|
||||
/// </summary>
|
||||
/// <seealso cref="WebViewPrefab.DragMode"/>
|
||||
/// <seealso cref="CanvasWebViewPrefab.DragMode"/>
|
||||
public enum DragMode {
|
||||
|
||||
/// <summary>
|
||||
/// Drag interactions trigger scrolling (default). On platforms that support
|
||||
/// IWithTouch, touch events are used instead of mouse events. On platforms
|
||||
/// that don't support IWithTouch, mouse events are used, but dragging
|
||||
/// causes the page to be scrolled with IWebView.Scroll().
|
||||
/// </summary>
|
||||
DragToScroll,
|
||||
|
||||
/// <summary>
|
||||
/// Drag interactions trigger dragging within the web page
|
||||
/// via mouse events (e.g. dragging to select text, drag-and-drop).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For information on the limitations of drag interactions on iOS and UWP, please see
|
||||
/// https://support.vuplex.com/articles/hover-and-drag-limitations.
|
||||
/// </remarks>
|
||||
DragWithinPage,
|
||||
|
||||
/// <summary>
|
||||
/// Drag interactions have no effect.
|
||||
/// </summary>
|
||||
Disabled
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 43e0cfa25fe0e4b95bfd9835c371ea65
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,28 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// A generic version of System.EventArgs.
|
||||
/// </summary>
|
||||
public class EventArgs<T> : EventArgs {
|
||||
|
||||
public T Value { get; private set; }
|
||||
|
||||
public EventArgs(T val) => Value = val;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4e7ac5abaf9484dd98eeb848895e34b7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// Event args for FileSelectionRequested. To handle file selection, the application
|
||||
/// must either call Continue() to select files or call Cancel() to cancel file selection.
|
||||
/// </summary>
|
||||
public class FileSelectionEventArgs : EventArgs {
|
||||
|
||||
public FileSelectionEventArgs(string[] acceptFilters, bool multipleAllowed, Action<string[]> continueCallback, Action cancelCallback) {
|
||||
|
||||
AcceptFilters = acceptFilters;
|
||||
MultipleAllowed = multipleAllowed;
|
||||
Continue = continueCallback;
|
||||
Cancel = cancelCallback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters provided by the page to specify the allowed file types. If the page didn't specify
|
||||
/// any file types, then this array is empty.
|
||||
/// </summary>
|
||||
/// <seealso href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept">
|
||||
/// MDN's documentation for the file input `accept` attribute
|
||||
/// </seealso>
|
||||
public readonly string[] AcceptFilters;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether multiple files are permitted.
|
||||
/// </summary>
|
||||
/// <seealso href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#multiple">
|
||||
/// MDN's documentation for the file input `multiple` attribute
|
||||
/// </seealso>
|
||||
public readonly bool MultipleAllowed;
|
||||
|
||||
/// <summary>
|
||||
/// To select files, call this callback with an array of one or more absolute file paths.
|
||||
/// </summary>
|
||||
public readonly Action<string[]> Continue;
|
||||
|
||||
/// <summary>
|
||||
/// Call this callback to cancel file selection.
|
||||
/// </summary>
|
||||
public readonly Action Cancel;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9c5eee343014c4c80afed57a988e957c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
using Vuplex.WebView.Internal;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// Event args for FocusedInputFieldChanged.
|
||||
/// </summary>
|
||||
public class FocusedInputFieldChangedEventArgs : EventArgs {
|
||||
|
||||
public FocusedInputFieldChangedEventArgs(FocusedInputFieldType type) => Type = type;
|
||||
|
||||
/// <summary>
|
||||
/// The type of input field focused.
|
||||
/// </summary>
|
||||
public readonly FocusedInputFieldType Type;
|
||||
|
||||
public static FocusedInputFieldType ParseType(string typeString) {
|
||||
|
||||
switch (typeString) {
|
||||
case "TEXT":
|
||||
return FocusedInputFieldType.Text;
|
||||
case "NONE":
|
||||
return FocusedInputFieldType.None;
|
||||
default:
|
||||
WebViewLogger.LogWarning("Unrecognized FocusedInputFieldType string: " + typeString);
|
||||
return FocusedInputFieldType.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3b441f81b66cd453b9ce9d4b51bcd4fc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,33 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the type of input field focused.
|
||||
/// </summary>
|
||||
public enum FocusedInputFieldType {
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that a text input field is focused. Examples of a text input field include
|
||||
/// an `input` element, a `textarea` element, and an element with a `contentEditable`
|
||||
/// attribute.
|
||||
/// </summary>
|
||||
Text,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that no input field is focused.
|
||||
/// </summary>
|
||||
None
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2b121a7f539b6486e943b21290c60197
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,111 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// Provides methods for getting, setting, and deleting HTTP cookies.
|
||||
/// You can access the ICookieManager via Web.CookieManager.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When developing code that interacts with
|
||||
/// cookies, it may also be helpful to view a webview's cookies using
|
||||
/// [remote debugging](https://support.vuplex.com/articles/how-to-debug-web-content).
|
||||
/// </remarks>
|
||||
public interface ICookieManager {
|
||||
|
||||
/// <summary>
|
||||
/// Deletes all of the cookies that match the given URL and returns a
|
||||
/// Task<bool> indicating whether the deletion succeeded. A `cookieName`
|
||||
/// can be optionally passed as a second parameter to further filter
|
||||
/// to a specific cookie.
|
||||
/// If a deletion fails, it could be because the URL was invalid.
|
||||
/// For more details regarding a failure, check the Unity logs.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Important notes:
|
||||
/// <list type="bullet">
|
||||
/// <item>On Windows and macOS, if this method is called without a `cookieName` it only deletes cookies that were set without an explicit Domain attribute.</item>
|
||||
/// <item>On versions of iOS older than iOS 11, session cookies are excluded because WKHTTPCookieStore is only supported in iOS 11 and newer.</item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// if (Web.CookieManager == null) {
|
||||
/// Debug.Log("Web.CookieManager isn't supported on this platform.");
|
||||
/// return;
|
||||
/// }
|
||||
/// // Delete all the cookies for this cookie test page, which will reset the test.
|
||||
/// var succeeded = await Web.CookieManager.DeleteCookies("http://www.whatarecookies.com/cookietest.asp");
|
||||
/// Debug.Log("Cookie deletion succeeded: " + succeeded);
|
||||
/// </code>
|
||||
/// </example>
|
||||
Task<bool> DeleteCookies(string url, string cookieName = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all of the cookies that match the given URL. A `cookieName`
|
||||
/// can be optionally passed as a second parameter to further filter
|
||||
/// results to a specific cookie.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Important notes:
|
||||
/// <list type="bullet">
|
||||
/// <item>On Android, the cookies returned only have their Name and Value fields set. The other fields (e.g. Domain, Path) are set to their default values because Android doesn't provide a way to access those values.</item>
|
||||
/// <item>On versions of iOS older than iOS 11, session cookies are excluded because WKHTTPCookieStore is only supported in iOS 11 and newer.</item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// if (Web.CookieManager == null) {
|
||||
/// Debug.Log("Web.CookieManager isn't supported on this platform.");
|
||||
/// return;
|
||||
/// }
|
||||
/// // Get the cookie named "NID" set by google.com.
|
||||
/// var cookies = await Web.CookieManager.GetCookies("https://www.google.com", "NID");
|
||||
/// if (cookies.Length > 0) {
|
||||
/// Debug.Log("Cookie: " + cookies[0]);
|
||||
/// } else {
|
||||
/// Debug.Log("Cookie not found.");
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
Task<Cookie[]> GetCookies(string url, string cookieName = null);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the given cookie and returns a Task<bool> indicating
|
||||
/// whether the cookie was set successfully.
|
||||
/// If setting the cookie fails, it could be because the data in the provided Cookie
|
||||
/// was malformed. For more details regarding a failure, please check the Unity logs.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// if (Web.CookieManager == null) {
|
||||
/// Debug.Log("Web.CookieManager isn't supported on this platform.");
|
||||
/// return;
|
||||
/// }
|
||||
/// var success = await Web.CookieManager.SetCookie(new Cookie {
|
||||
/// Domain = "vuplex.com",
|
||||
/// Path = "/",
|
||||
/// Name = "example_name",
|
||||
/// Value = "example_value",
|
||||
/// Secure = true,
|
||||
/// // Expire one day from now
|
||||
/// ExpirationDate = (int)DateTimeOffset.Now.ToUnixTimeSeconds() + 60 * 60 * 24
|
||||
/// });
|
||||
/// </code>
|
||||
/// </example>
|
||||
Task<bool> SetCookie(Cookie cookie);
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4f02f1602fbb4443fa664b18925d2725
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,73 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// An interface that can be passed to WebViewPrefab.SetPointerInputDetector()
|
||||
/// CanvasWebViewPrefab.SetPointerInputDetector() to override how the prefab detects pointer input.
|
||||
/// For example implementations of this interface, please see 3D WebView's DefaultPointerInputDetector.cs
|
||||
/// and CanvasPointerInputDetector.cs scripts.
|
||||
/// </summary>
|
||||
public interface IPointerInputDetector {
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the normalized point for the beginning of a drag interaction.
|
||||
/// </summary>
|
||||
event EventHandler<EventArgs<Vector2>> BeganDrag;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the normalized point for the continuation of a drag interaction.
|
||||
/// </summary>
|
||||
event EventHandler<EventArgs<Vector2>> Dragged;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates a pointer down interaction occurred.
|
||||
/// </summary>
|
||||
event EventHandler<PointerEventArgs> PointerDown;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the pointer entered.
|
||||
/// </summary>
|
||||
event EventHandler PointerEntered;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the normalized point where the pointer exited.
|
||||
/// </summary>
|
||||
event EventHandler<EventArgs<Vector2>> PointerExited;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the normalized point where the pointer moved.
|
||||
/// </summary>
|
||||
event EventHandler<EventArgs<Vector2>> PointerMoved;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates a pointer up interaction occurred.
|
||||
/// </summary>
|
||||
event EventHandler<PointerEventArgs> PointerUp;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates a scroll interaction occurred.
|
||||
/// </summary>
|
||||
event EventHandler<ScrolledEventArgs> Scrolled;
|
||||
|
||||
/// <summary>
|
||||
/// The prefab sets this property to indicate whether
|
||||
/// the PointerMoved event should be enabled.
|
||||
/// </summary>
|
||||
bool PointerMovedEnabled { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d10c6c706509f46afa9a965d80cf0848
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,946 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// IWebView is the primary interface for loading and interacting with web content.
|
||||
/// It contains methods and properties for common browser-related functionality,
|
||||
/// like LoadUrl(), GoBack(), Reload(), and ExecuteJavaScript().
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// To create an IWebView, instantiate a WebViewPrefab or CanvasWebViewPrefab. After
|
||||
/// the prefab is initialized, you can access its IWebView via the WebViewPrefab.WebView property.
|
||||
/// If your use case requires a high degree of customization, you can instead create
|
||||
/// an IWebView outside of a prefab (to connect to your own custom GameObject) by
|
||||
/// using Web.CreateWebView().
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// For additional functionality, you can cast an IWebView to an interface for a specific
|
||||
/// feature, like IWithDownloads or IWithPopups. For a list of additional feature interfaces and
|
||||
/// information about how to use them, see this page: https://developer.vuplex.com/webview/additional-interfaces
|
||||
/// </para>
|
||||
/// See also:
|
||||
/// <list type="bullet">
|
||||
/// <item>WebViewPrefab: https://developer.vuplex.com/webview/WebViewPrefab</item>
|
||||
/// <item>CanvasWebViewPrefab: https://developer.vuplex.com/webview/CanvasWebViewPrefab</item>
|
||||
/// <item>Web (static methods): https://developer.vuplex.com/webview/Web</item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
public interface IWebView {
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that JavaScript in the page has called window.close(). Calling window.close()
|
||||
/// doesn't automatically close a webview, but the application can listen to this CloseRequested
|
||||
/// event to detect when window.close() is called and then choose whether to destroy the
|
||||
/// webview in response to it.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// webViewPrefab.WebView.CloseRequested += (sender, eventArgs) => {
|
||||
/// Debug.Log("Destroying the WebViewPrefab because window.close() was called.");
|
||||
/// webViewPrefab.Destroy();
|
||||
/// };
|
||||
/// </code>
|
||||
/// </example>
|
||||
event EventHandler CloseRequested;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that a message was logged to the JavaScript console.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The 3D WebView packages for Android with Gecko, iOS, and UWP have the following limitations:
|
||||
/// <list type="bullet">
|
||||
/// <item>
|
||||
/// Only messages explicitly passed to a console method like console.log() are included,
|
||||
/// and other messages like uncaught errors or network errors aren't automatically included.
|
||||
/// </item>
|
||||
/// <item>Messages from iframes aren't included.</item>
|
||||
/// <item>Messages logged early when the page starts loading may be missed.</item>
|
||||
/// </list>
|
||||
/// For Android Gecko, an alternative that avoids these limitations is to call
|
||||
/// AndroidGeckoWebView.SetConsoleOutputEnabled().
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// webViewPrefab.WebView.ConsoleMessageLogged += (sender, eventArgs) => {
|
||||
/// Debug.Log($"Console message logged: [{eventArgs.Level}] {eventArgs.Message}");
|
||||
/// };
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso cref="WebViewPrefab.LogConsoleMessages"/>
|
||||
/// <seealso href="https://support.vuplex.com/articles/how-to-debug-web-content">Remote debugging</seealso>
|
||||
event EventHandler<ConsoleMessageEventArgs> ConsoleMessageLogged;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates when an input field has been focused or unfocused. This can be used,
|
||||
/// for example, to determine when to show or hide an on-screen keyboard.
|
||||
/// This event is also raised when a focused input field is clicked subsequent times.
|
||||
/// Note that this event is currently only fired for input fields focused in the main frame
|
||||
/// and is not fired for input fields in iframes.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// webViewPrefab.WebView.FocusedInputFieldChanged += (sender, eventArgs) => {
|
||||
/// Debug.Log("Focused input field changed. Text input is focused: " + eventArgs.Type == FocusedInputFieldType.Text);
|
||||
/// };
|
||||
/// </code>
|
||||
/// </example>
|
||||
event EventHandler<FocusedInputFieldChangedEventArgs> FocusedInputFieldChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates changes in the loading status of a web page. This event can be used, for example,
|
||||
/// to detect when a page finishes loading or to implement a load progress bar. This event indicates
|
||||
/// the following types of load events:<br/>
|
||||
/// - `Started`: a new page started loading.<br/>
|
||||
/// - `Updated`: the load progress percentage was updated.<br/>
|
||||
/// - `Finished`: a page finished loading.<br/>
|
||||
/// - `Failed`: a page failed to load.<br/>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For 2D WebView for WebGL, LoadProgressChanged only indicates the ProgressChangeType.Started and Finished events,
|
||||
/// and it's unable to indicate the Failed or Updated events.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// webViewPrefab.WebView.LoadProgressChanged += (sender, eventArgs) => {
|
||||
/// Debug.Log($"Load progress changed: {eventArgs.Type}, {eventArgs.Progress}");
|
||||
/// if (eventArgs.Type == ProgressChangeType.Finished) {
|
||||
/// Debug.Log("The page finished loading");
|
||||
/// }
|
||||
/// };
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso cref="WaitForNextPageLoadToFinish"/>
|
||||
event EventHandler<ProgressChangedEventArgs> LoadProgressChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that JavaScript running in the page used the `window.vuplex.postMessage`
|
||||
/// JavaScript API to emit a message to the Unity application. For more details, please see
|
||||
/// [this support article](https://support.vuplex.com/articles/how-to-send-messages-from-javascript-to-c-sharp).
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// // Add JavaScript to the page that sends a message.
|
||||
/// webViewPrefab.WebView.PageLoadScripts.Add(@"
|
||||
/// window.vuplex.postMessage('Hello from JavaScript!');
|
||||
/// ");
|
||||
/// webViewPrefab.WebView.MessageEmitted += (sender, eventArgs) => {
|
||||
/// Debug.Log("Message received from JavaScript: " + eventArgs.Value);
|
||||
/// };
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso cref="ExecuteJavaScript"/>
|
||||
/// <seealso cref="PageLoadScripts"/>
|
||||
event EventHandler<EventArgs<string>> MessageEmitted;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the page failed to load. This can happen, for instance,
|
||||
/// if DNS is unable to resolve the hostname.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// webViewPrefab.WebView.PageLoadFailed += (sender, eventArgs) => {
|
||||
/// Debug.Log("Page load failed");
|
||||
/// };
|
||||
/// </code>
|
||||
/// </example>
|
||||
event EventHandler PageLoadFailed;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the browser engine reported that its process for the webview terminated unexpectedly,
|
||||
/// either because the web process crashed or because it was killed by the
|
||||
/// operating system. The webview cannot be used after it has been terminated, so if this event occurs, the webview must be
|
||||
/// destroyed, and then the appication can optionally create a new webview to replace it.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// webViewPrefab.WebView.Terminated += (sender, eventArgs) => {
|
||||
/// Debug.Log("The web content process was terminated. Reason: " + eventArgs.Type);
|
||||
/// // Destroy the webview because it can't be used any more.
|
||||
/// webViewPrefab.Destroy();
|
||||
/// // TODO: If the application still needs a webview, it can create a new one with WebViewPrefab.Instantiate().
|
||||
/// };
|
||||
/// </code>
|
||||
/// </example>
|
||||
event EventHandler<TerminatedEventArgs> Terminated;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the page's title changed.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// webViewPrefab.WebView.TitleChanged += (sender, eventArgs) => {
|
||||
/// Debug.Log("Page title changed: " + eventArgs.Value);
|
||||
/// };
|
||||
/// </code>
|
||||
/// </example>
|
||||
event EventHandler<EventArgs<string>> TitleChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the URL of the webview changed, either
|
||||
/// due to user interaction or JavaScript.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// webViewPrefab.WebView.UrlChanged += (sender, eventArgs) => {
|
||||
/// Debug.Log("URL changed: " + eventArgs.Url);
|
||||
/// };
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso cref="Url"/>
|
||||
event EventHandler<UrlChangedEventArgs> UrlChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the instance has been disposed via Dispose().
|
||||
/// </summary>
|
||||
bool IsDisposed { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the instance has been initialized via Init().
|
||||
/// </summary>
|
||||
bool IsInitialized { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of JavaScript scripts that are automatically executed in every new page that is loaded.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This list is empty by default, but the application can add scripts. When used in conjunction
|
||||
/// with 3D WebView's [message passing API](https://support.vuplex.com/articles/how-to-send-messages-from-javascript-to-c-sharp),
|
||||
/// it's possible to modify the browser's behavior in significant ways, similar to creating browser extensions.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Add a script that automatically hides all scrollbars.
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// webViewPrefab.WebView.PageLoadScripts.Add(@"
|
||||
/// var styleElement = document.createElement('style');
|
||||
/// styleElement.innerText = 'body::-webkit-scrollbar { display: none; }';
|
||||
/// document.head.appendChild(styleElement);
|
||||
/// ");
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso cref="ExecuteJavaScript"/>
|
||||
/// <seealso href="https://support.vuplex.com/articles/how-to-send-messages-from-javascript-to-c-sharp">JS-to-C# message passing</seealso>
|
||||
List<string> PageLoadScripts { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance's plugin type.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// Debug.Log("Plugin type: " + webViewPrefab.WebView.PluginType);
|
||||
/// </code>
|
||||
/// </example>
|
||||
WebPluginType PluginType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the webview's size in pixels.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// Debug.Log("Size: " + webViewPrefab.WebView.Size);
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso cref="Resize"/>
|
||||
/// <seealso cref="WebViewPrefab.Resolution"/>
|
||||
Vector2Int Size { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the texture for the webview's web content, or `null` if running in
|
||||
/// Native 2D Mode. In order to render the texture, the application must use
|
||||
/// a Material created with CreateMaterial().
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This texture is an "external texture" created with
|
||||
/// Texture2D.CreateExternalTexture(). An undocumented characteristic
|
||||
/// of external textures in Unity is that not all Texture2D methods work for them.
|
||||
/// For example, Texture2D.GetRawTextureData() and ImageConversion.EncodeToPNG()
|
||||
/// fail for external textures. To compensate, the IWebView interface includes
|
||||
/// its own GetRawTextureData() and CaptureScreenshot() methods to replace them.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Another quirk of this texture is that Unity always reports its size as
|
||||
/// 1300px × 1300px in the editor. In reality, 3D WebView resizes the
|
||||
/// texture in native code to match the dimensions of the webview, but
|
||||
/// Unity doesn't provide an API to notify the engine that an external texture's size
|
||||
/// has changed. So, Unity always reports its size as the initial size that was
|
||||
/// passed to Texture2D.CreateExternalTexture(), which in 3D WebView's case is
|
||||
/// 1300px × 1300px.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// var material = webViewPrefab.WebView.CreateMaterial();
|
||||
/// // Note: the material returned by CreateMaterial() already
|
||||
/// // has its mainTexture set to IWebView.Texture, so setting
|
||||
/// // it explicitly like this is really only needed if you are
|
||||
/// // switching a material from one webview's texture to another.
|
||||
/// material.mainTexture = webViewPrefab.WebView.Texture;
|
||||
/// </code>
|
||||
/// </example>
|
||||
Texture2D Texture { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current web page title.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Get the page's title after it finishes loading.
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// await webViewPrefab.WebView.WaitForNextPageLoadToFinish();
|
||||
/// Debug.Log("Page title: " + webViewPrefab.WebView.Title);
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso cref="TitleChanged"/>
|
||||
string Title { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current URL.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Get the page's URL after it finishes loading.
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// await webViewPrefab.WebView.WaitForNextPageLoadToFinish();
|
||||
/// Debug.Log("Page URL: " + webViewPrefab.WebView.Url);
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso cref="UrlChanged"/>
|
||||
string Url { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the webview can go back with a call to GoBack().
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <c>var canGoBack = await webViewPrefab.CanGoBack();</c>
|
||||
/// </example>
|
||||
/// <seealso cref="GoBack"/>
|
||||
Task<bool> CanGoBack();
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the webview can go forward with a call to GoForward().
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <c>var canGoForward = await webViewPrefab.CanGoForward();</c>
|
||||
/// </example>
|
||||
/// <seealso cref="GoForward"/>
|
||||
Task<bool> CanGoForward();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a PNG image of the content visible in the webview.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// On iOS, screenshots do not include video content, which appears black.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Get a screenshot and write it to a file.
|
||||
/// var screenshotBytes = await webViewPrefab.WebView.CaptureScreenshot();
|
||||
/// var filePath = Path.Combine(Application.peristentDataPath, "screenshot.png");
|
||||
/// File.WriteAllBytes(filePath, screenshotBytes);
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso href="https://docs.unity3d.com/ScriptReference/ImageConversion.LoadImage.html">ImageConversion.LoadImage()</seealso>
|
||||
/// <seealso cref="GetRawTextureData"/>
|
||||
Task<byte[]> CaptureScreenshot();
|
||||
|
||||
/// <summary>
|
||||
/// Clicks at the given coordinates in pixels in the web page, dispatching both a mouse
|
||||
/// down and a mouse up event.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Click at (250px, 100px).
|
||||
/// webViewPrefab.WebView.Click(250, 100);
|
||||
///
|
||||
/// // Click at (50px, 150px) and prevent stealing focus from another webview.
|
||||
/// webViewPrefab.WebView.Click(50, 150, true);
|
||||
/// </code>
|
||||
/// </example>
|
||||
void Click(int xInPixels, int yInPixels, bool preventStealingFocus = false);
|
||||
|
||||
/// <summary>
|
||||
/// Like Click(int, int, bool?), except it takes a normalized point instead of
|
||||
/// pixel coordinates.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Click in the exact center of the page.
|
||||
/// webViewPrefab.WebView.Click(new Vector2(0.5f, 0.5f));
|
||||
///
|
||||
/// // Click in the upper right quadrant of the page
|
||||
/// // and prevent stealing focus from another webview.
|
||||
/// webViewPrefab.WebView.Click(new Vector2(0.75f, 0.25f), true);
|
||||
/// </code>
|
||||
/// </example>
|
||||
void Click(Vector2 normalizedPoint, bool preventStealingFocus = false);
|
||||
|
||||
/// <summary>
|
||||
/// Copies the selected text to the clipboard.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <c>webViewPrefab.WebView.Copy();</c>
|
||||
/// </example>
|
||||
/// <seealso cref="Cut"/>
|
||||
/// <seealso cref="Paste"/>
|
||||
/// <seealso cref="SelectAll"/>
|
||||
void Copy();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Material that can be used to display the webview.
|
||||
/// The returned material already has the webview's Texture set as its mainTexture.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that WebViewPrefab and CanvasWebViewPrefab take care of material creation for you, so you only need
|
||||
/// to call this method directly if you need to create an IWebView instance outside of a prefab with
|
||||
/// Web.CreateWebView().
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// GetComponent<Renderer>().material = webView.CreateMaterial();
|
||||
/// </code>
|
||||
/// </example>
|
||||
Material CreateMaterial();
|
||||
|
||||
/// <summary>
|
||||
/// Copies the selected text to the clipboard and removes it.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <c>webViewPrefab.WebView.Cut();</c>
|
||||
/// </example>
|
||||
/// <seealso cref="Copy"/>
|
||||
/// <seealso cref="Paste"/>
|
||||
/// <seealso cref="SelectAll"/>
|
||||
void Cut();
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the webview, releasing all of its resources.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If you're using a WebViewPrefab or CanvasWebViewPrefab, please call Destroy() on the prefab instead
|
||||
/// of calling IWebView.Dispose(). Calling IWebView.Dispose() while the prefab is still using the webview
|
||||
/// can cause issues.
|
||||
/// </remarks>
|
||||
void Dispose();
|
||||
|
||||
/// <summary>
|
||||
/// Executes the given JavaScript in the context of the page and returns the result.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// In order to run JavaScript, a web page must first be loaded. You can use WaitForNextPageLoadToFinish() or the
|
||||
/// LoadProgressChanged event to run JavaScript after a page loads.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// await webViewPrefab.WebView.WaitForNextPageLoadToFinish();
|
||||
/// var headerText = await webViewPrefab.WebView.ExecuteJavaScript("document.getElementsByTagName('h1')[0].innerText");
|
||||
/// Debug.Log("H1 text: " + headerText);
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso cref="PageLoadScripts"/>
|
||||
/// <seealso href="https://support.vuplex.com/articles/javascript-promise-result">How to get ExecuteJavaScript() to return the result of a Promise?</seealso>
|
||||
/// <seealso href="https://support.vuplex.com/articles/how-to-send-messages-from-javascript-to-c-sharp">JS-to-C# message passing</seealso>
|
||||
/// <seealso href="https://support.vuplex.com/articles/how-to-get-html">How to get HTML, text, images, or other info from a web page?</seealso>
|
||||
Task<string> ExecuteJavaScript(string javaScript);
|
||||
|
||||
/// <summary>
|
||||
/// Like the other version of ExecuteJavaScript(), except it uses a callback instead
|
||||
/// of a Task to return the result. If you don't need the result from executing the JavaScript, you can
|
||||
/// improve the method's efficiency by passing `null` as the callback argument.
|
||||
/// </summary>
|
||||
void ExecuteJavaScript(string javaScript, Action<string> callback);
|
||||
|
||||
/// <summary>
|
||||
/// A replacement for [Texture2D.GetRawTextureData()](https://docs.unity3d.com/ScriptReference/Texture2D.GetRawTextureData.html)
|
||||
/// for IWebView.Texture.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Unity's Texture2D.GetRawTextureData() method currently does not work for textures created with
|
||||
/// Texture2D.CreateExternalTexture(). So, this method serves as a replacement by providing
|
||||
/// the equivalent functionality. You can load the bytes returned by this method into another
|
||||
/// texture using [Texture2D.LoadRawTextureData()](https://docs.unity3d.com/ScriptReference/Texture2D.LoadRawTextureData.html).
|
||||
/// Note that on iOS, the texture data excludes video content, which appears black.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// var webView = webViewPrefab.WebView;
|
||||
/// var textureData = await webView.GetRawTextureData();
|
||||
/// var texture = new Texture2D(
|
||||
/// webView.Size.x,
|
||||
/// webView.Size.y,
|
||||
/// TextureFormat.RGBA32,
|
||||
/// false,
|
||||
/// false
|
||||
/// );
|
||||
/// texture.LoadRawTextureData(textureData);
|
||||
/// texture.Apply();
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso href="https://docs.unity3d.com/ScriptReference/Texture2D.LoadRawTextureData.html">Texture2D.GetRawTextureData()</seealso>
|
||||
/// <seealso cref="CaptureScreenshot"/>
|
||||
Task<byte[]> GetRawTextureData();
|
||||
|
||||
/// <summary>
|
||||
/// Navigates back to the previous page in the webview's history.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <c>webViewPrefab.WebView.GoBack();</c>
|
||||
/// </example>
|
||||
/// <seealso cref="CanGoBack"/>
|
||||
void GoBack();
|
||||
|
||||
/// <summary>
|
||||
/// Navigates forward to the next page in the webview's history.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <c>webViewPrefab.WebView.GoForward();</c>
|
||||
/// </example>
|
||||
/// <seealso cref="CanGoForward"/>
|
||||
void GoForward();
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously initializes the webview with the given the dimensions in pixels.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that you don't need to call this method if you're using one of the prefabs, like WebViewPrefab.
|
||||
/// You only need to call Init() if you create an IWebView directly with Web.CreateWebView()].
|
||||
/// Also, this method's signature was [updated in 3D WebView v4](https://support.vuplex.com/articles/v4-changes#init).
|
||||
/// </remarks>
|
||||
Task Init(int width, int height);
|
||||
|
||||
/// <summary>
|
||||
/// Loads the web page contained in the given HTML string. Note that HTML loaded via this method
|
||||
/// cannot load subresources (e.g. images, CSS, JavaScript) from the local file system (i.e. via file:// URLs).
|
||||
/// If you need to load subresources from the local file system, please use one of the approaches described
|
||||
/// in <see="https://support.vuplex.com/articles/how-to-load-local-files">this article</see> instead.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// <![CDATA[
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// webViewPrefab.WebView.LoadHtml(@"
|
||||
/// <!DOCTYPE html>
|
||||
/// <html>
|
||||
/// <head>
|
||||
/// <title>Test Page</title>
|
||||
/// <style>
|
||||
/// h1 {
|
||||
/// font-family: Helvetica, Arial, Sans-Serif;
|
||||
/// }
|
||||
/// </style>
|
||||
/// </head>
|
||||
/// <body>
|
||||
/// <h1>LoadHtml Example</h1>
|
||||
/// <script>
|
||||
/// console.log('This page was loaded!');
|
||||
/// </script>
|
||||
/// </body>
|
||||
/// </html>"
|
||||
/// );
|
||||
/// ]]>
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso cref="LoadUrl"/>
|
||||
void LoadHtml(string html);
|
||||
|
||||
/// <summary>
|
||||
/// Loads the given URL. Supported URL schemes:
|
||||
/// - `http://`, `https://` - loads a remote page over HTTP
|
||||
/// - `streaming-assets://` - loads a local page from StreamingAssets
|
||||
/// (equivalent to `"file://" + Application.streamingAssetsPath + path`)
|
||||
/// - `file://` - some platforms support loading arbitrary file URLs
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// webViewPrefab.WebView.LoadUrl("https://vuplex.com");
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso href="https://support.vuplex.com/articles/how-to-load-local-files">How to load local files</seealso>
|
||||
/// <seealso cref="LoadHtml"/>
|
||||
/// <seealso cref="WebViewPrefab.InitialUrl"/>
|
||||
void LoadUrl(string url);
|
||||
|
||||
/// <summary>
|
||||
/// Like LoadUrl(string url), but also sends the given additional HTTP request headers
|
||||
/// when loading the URL. The headers are sent for the initial page load request but are not sent
|
||||
/// for requests for subsequent resources, like linked JavaScript or CSS files.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// On Windows and macOS, this method cannot be used to set the Accept-Language header.
|
||||
/// For more info, please see [this article](https://support.vuplex.com/articles/how-to-change-accept-language-header).
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// webViewPrefab.WebView.LoadUrl("https://vuplex.com", new Dictionary<string, string> {
|
||||
/// ["Authorization"] = "Basic YWxhZGRpbjpvcGVuc2VzYW1l",
|
||||
/// ["Cookie"] = "foo=bar"
|
||||
/// });
|
||||
/// </code>
|
||||
/// </example>
|
||||
void LoadUrl(string url, Dictionary<string, string> additionalHttpHeaders);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a point in pixels for the given normalized point.
|
||||
/// </summary>
|
||||
/// <seealso cref="PointToNormalized"/>
|
||||
Vector2Int NormalizedToPoint(Vector2 normalizedPoint);
|
||||
|
||||
/// <summary>
|
||||
/// Pastes text from the clipboard.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <c>webViewPrefab.WebView.Paste();</c>
|
||||
/// </example>
|
||||
/// <seealso cref="Copy"/>
|
||||
/// <seealso cref="Cut"/>
|
||||
void Paste();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a normalized point for the given x and y coordinates in pixels.
|
||||
/// This can be used to create normalized points for APIs that accept them, like MovePointer().
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// var webView = webViewPrefab.WebView;
|
||||
/// // Scroll to the right by 50 pixels at (100px, 1300px).
|
||||
/// webView.Scroll(
|
||||
/// webView.PointToNormalized(50, 0),
|
||||
/// webView.PointToNormalized(100, 1300)
|
||||
/// );
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso cref="NormalizedToPoint"/>
|
||||
Vector2 PointToNormalized(int xInPixels, int yInPixels);
|
||||
|
||||
/// <summary>
|
||||
/// Posts a message that JavaScript within the webview can listen for
|
||||
/// using `window.vuplex.addEventListener('message', function(message) {})`.
|
||||
/// The provided data string is passed as the data property of the message object.
|
||||
/// For more details, please see [this support article](https://support.vuplex.com/articles/how-to-send-messages-from-javascript-to-c-sharp).
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WebView.WaitUntilInitialized();
|
||||
/// // Add some JavaScript to the page to receive the message.
|
||||
/// webViewPrefab.WebView.PageLoadScripts(@"
|
||||
/// window.vuplex.addEventListener('message', function(event) {
|
||||
/// console.log('Message received from C#: ' + event.data);
|
||||
/// });
|
||||
/// ");
|
||||
/// // When the page finishes loading, send a message from C# to JavaScript.
|
||||
/// await webViewPrefab.WebView.WaitForNextPageLoadToFinish();
|
||||
/// webViewPrefab.WebView.PostMessage("Hello from C#");
|
||||
/// </code>
|
||||
/// </example>
|
||||
void PostMessage(string data);
|
||||
|
||||
/// <summary>
|
||||
/// Reloads the current page.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <c>webViewPrefab.WebView.Reload();</c>
|
||||
/// </example>
|
||||
void Reload();
|
||||
|
||||
/// <summary>
|
||||
/// Resizes the webview to the given dimensions in pixels.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If you're using WebViewPrefab, you should call WebViewPrefab.Resize() instead.
|
||||
/// </remarks>
|
||||
/// <seealso cref="Size"/>
|
||||
/// <seealso cref="WebViewPrefab.Resolution"/>
|
||||
void Resize(int width, int height);
|
||||
|
||||
/// <summary>
|
||||
/// Scrolls the top-level document by the given delta in pixels.
|
||||
/// This method works by calling window.scrollBy(), which works for simple web
|
||||
/// pages but not for all pages. An alternative is to instead use Scroll(Vector2, Vector2)
|
||||
/// to scroll at a specific location in the page.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Scroll down by 50 pixels.
|
||||
/// webViewPrefab.WebView.Scroll(0, 50);
|
||||
///
|
||||
/// // Scroll to the left by 20 pixels.
|
||||
/// webViewPrefab.WebView.Scroll(-20, 0);
|
||||
/// </code>
|
||||
/// </example>
|
||||
void Scroll(int scrollDeltaXInPixels, int scrollDeltaYInPixels);
|
||||
|
||||
/// <summary>
|
||||
/// Like Scroll(int, int), but accepts a normalized scroll delta instead of
|
||||
/// values in pixels.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Scroll down one quarter of the page.
|
||||
/// webViewPrefab.WebView.Scroll(new Vector2(0, 0.25f));
|
||||
/// </code>
|
||||
/// </example>
|
||||
void Scroll(Vector2 normalizedScrollDelta);
|
||||
|
||||
/// <summary>
|
||||
/// Scrolls by the given normalized scroll delta at the given normalized pointer position.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// var webView = webViewPrefab.WebView;
|
||||
/// // Scroll down by a quarter of the page in the center of the page
|
||||
/// webView.Scroll(new Vector2(0, 0.25f), new Vector2(0.5f, 0.5f));
|
||||
///
|
||||
/// // Scroll to the right by 50 pixels at (100px, 1300px).
|
||||
/// webView.Scroll(
|
||||
/// webView.PointToNormalized(50, 0),
|
||||
/// webView.PointToNormalized(100, 1300)
|
||||
/// );
|
||||
/// </code>
|
||||
/// </example>
|
||||
void Scroll(Vector2 normalizedScrollDelta, Vector2 normalizedPoint);
|
||||
|
||||
/// <summary>
|
||||
/// Selects all text, depending on the page's focused element.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <c>webViewPrefab.WebView.SelectAll();</c>
|
||||
/// </example>
|
||||
/// <seealso cref="Copy"/>
|
||||
void SelectAll();
|
||||
|
||||
/// <summary>
|
||||
/// Dispatches the given keyboard key to the webview.
|
||||
/// </summary>
|
||||
/// <param name="key">
|
||||
/// A key can either be a single character representing
|
||||
/// a unicode character (e.g. "A", "b", "?") or a [JavaScript key value](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values)
|
||||
/// (e.g. "ArrowUp", "Enter", "Backspace", "Delete").
|
||||
/// </param>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Type "Hi!" and then submit the Enter key.
|
||||
/// webViewPrefab.WebView.SendKey("H");
|
||||
/// webViewPrefab.WebView.SendKey("i");
|
||||
/// webViewPrefab.WebView.SendKey("!");
|
||||
/// webViewPrefab.WebView.SendKey("Enter");
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso cref="IWithKeyDownAndUp"/>
|
||||
void SendKey(string key);
|
||||
|
||||
/// <summary>
|
||||
/// By default, if a web page doesn't specify a background, 3D WebView sets the page's
|
||||
/// background to white because that's what web browsers typically do. However, an
|
||||
/// application can use this method to disable the default white background so that pages
|
||||
/// that don't set a background will instead have a transparent background. Note that this method
|
||||
/// must be called before a web page is loaded in order for it to take effect for that page.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Nearly all of the 3D WebView packages support transparent webviews, but there are two exceptions: <br/>
|
||||
/// - 3D WebView for Android with Gecko Engine doesn't support transparency because the mobile Gecko browser engine doesn't currently support it. <br/>
|
||||
/// - 3D WebView for UWP doesn't support transparency on mixed reality headsets like Hololens.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// // Disable the default white background so the page can be transparent.
|
||||
/// webViewPrefab.WebView.SetDefaultBackgroundEnabled(false);
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso href="https://support.vuplex.com/articles/how-to-make-a-webview-transparent">How to make a webview transparent?</seealso>
|
||||
void SetDefaultBackgroundEnabled(bool enabled);
|
||||
|
||||
/// <summary>
|
||||
/// Makes the webview take or relinquish focus.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <c>webViewPrefab.WebView.SetFocused(true);</c>
|
||||
/// </example>
|
||||
void SetFocused(bool focused);
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the webview's ability to render to its texture.
|
||||
/// By default, a webview renders web content to its texture, but you can
|
||||
/// use this method to disable or re-enable rendering.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method is ignored when running in [Native 2D Mode](https://support.vuplex.com/articles/native-2d-mode).
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <c>webViewPrefab.WebView.SetRenderingEnabled(false);</c>
|
||||
/// </example>
|
||||
void SetRenderingEnabled(bool enabled);
|
||||
|
||||
/// <summary>
|
||||
/// Stops the current page load if one is in progress.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <c>webViewPrefab.WebView.StopLoad();</c>
|
||||
/// </example>
|
||||
void StopLoad();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a task that completes when the next page load finishes loading, or
|
||||
/// throws a PageLoadFailedException if the page load fails.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// await webViewPrefab.WebView.WaitForNextPageLoadToFinish();
|
||||
/// Debug.Log("The web page finished loading.");
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <seealso cref="LoadProgressChanged"/>
|
||||
Task WaitForNextPageLoadToFinish();
|
||||
|
||||
/// <summary>
|
||||
/// Zooms into the currently loaded web content. Note that the zoom level gets reset when a new page is loaded.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// On Windows and macOS, adjusting the zoom also affects other webviews viewing the same site,
|
||||
/// similar to how tabs behave in a desktop browser.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Zoom in after the page finishes loading.
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// await webViewPrefab.WebView.WaitForNextPageLoadToFinish();
|
||||
/// webViewPrefab.WebView.ZoomIn();
|
||||
/// </code>
|
||||
/// </example>
|
||||
void ZoomIn();
|
||||
|
||||
/// <summary>
|
||||
/// Zooms back out after a previous call to ZoomIn(). Note that the zoom level gets reset when a new page is loaded.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// On Windows and macOS, adjusting the zoom also affects other webviews viewing the same site,
|
||||
/// similar to how tabs behave in a desktop browser.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Zoom out after the page finishes loading.
|
||||
/// await webViewPrefab.WaitUntilInitialized();
|
||||
/// await webViewPrefab.WebView.WaitForNextPageLoadToFinish();
|
||||
/// webViewPrefab.WebView.ZoomOut();
|
||||
/// </code>
|
||||
/// </example>
|
||||
void ZoomOut();
|
||||
|
||||
#region Obsolete APIs
|
||||
// Added in v1.0, deprecated in v3.13, removed in v4.0.
|
||||
[Obsolete(ObsoletionMessages.Blur, true)]
|
||||
void Blur();
|
||||
|
||||
// Added in v1.0, deprecated in v3.16, removed in v4.0.
|
||||
[Obsolete(ObsoletionMessages.CanGoBack, true)]
|
||||
void CanGoBack(Action<bool> callback);
|
||||
|
||||
// Added in v1.0, deprecated in v3.16, removed in v4.0.
|
||||
[Obsolete(ObsoletionMessages.CanGoForward, true)]
|
||||
void CanGoForward(Action<bool> callback);
|
||||
|
||||
// Added in v2.4, deprecated in v3.16, removed in v4.0.
|
||||
[Obsolete(ObsoletionMessages.CaptureScreenshot, true)]
|
||||
void CaptureScreenshot(Action<byte[]> callback);
|
||||
|
||||
[Obsolete(ObsoletionMessages.DisableViewUpdates, true)]
|
||||
void DisableViewUpdates();
|
||||
|
||||
[Obsolete(ObsoletionMessages.EnableViewUpdates, true)]
|
||||
void EnableViewUpdates();
|
||||
|
||||
// Added in v1.0, deprecated in v3.13, removed in v4.0.
|
||||
[Obsolete(ObsoletionMessages.Focus, true)]
|
||||
void Focus();
|
||||
|
||||
// Added in v2.6, deprecated in v3.16, removed in v4.0.
|
||||
[Obsolete(ObsoletionMessages.GetRawTextureData, true)]
|
||||
void GetRawTextureData(Action<byte[]> callback);
|
||||
|
||||
// Added in v1.0, deprecated in v4.0.
|
||||
[Obsolete(ObsoletionMessages.HandleKeyboardInput)]
|
||||
void HandleKeyboardInput(string key);
|
||||
|
||||
// Added in v1.0, removed in v4.0.
|
||||
[Obsolete(ObsoletionMessages.Init, true)]
|
||||
void Init(Texture2D texture, float width, float height);
|
||||
|
||||
// Added in v1.0, removed in v4.0.
|
||||
[Obsolete(ObsoletionMessages.Init2, true)]
|
||||
void Init(Texture2D texture, float width, float height, Texture2D videoTexture);
|
||||
|
||||
// Added in v1.0, removed in v4.0.
|
||||
[Obsolete(ObsoletionMessages.Resolution, true)]
|
||||
float Resolution { get; }
|
||||
|
||||
// Added in v1.0, removed in v4.0.
|
||||
[Obsolete(ObsoletionMessages.SetResolution, true)]
|
||||
void SetResolution(float pixelsPerUnityUnit);
|
||||
|
||||
// Deprecated in v4.0
|
||||
[Obsolete(ObsoletionMessages.SizeInPixels)]
|
||||
Vector2 SizeInPixels { get; }
|
||||
|
||||
// Added in v1.0, removed in v4.0.
|
||||
[Obsolete(ObsoletionMessages.VideoRectChanged, true)]
|
||||
event EventHandler<EventArgs<Rect>> VideoRectChanged;
|
||||
|
||||
// Added in v1.0, removed in v4.0.
|
||||
[Obsolete(ObsoletionMessages.VideoTexture, true)]
|
||||
Texture2D VideoTexture { get; }
|
||||
#endregion
|
||||
}
|
||||
|
||||
static class ObsoletionMessages {
|
||||
public const string Blur = "IWebView.Blur() has been removed. Please use SetFocused(false) instead: https://developer.vuplex.com/webview/IWebView#SetFocused";
|
||||
public const string CanGoBack = "The callback-based CanGoBack(Action) version of this method has been removed. Please switch to the Task-based CanGoBack() version instead. If you prefer using a callback instead of awaiting the Task, you can still use a callback like this: CanGoBack().ContinueWith(result => {...})";
|
||||
public const string CanGoForward = "The callback-based CanGoForward(Action) version of this method has been removed. Please switch to the Task-based CanGoForward() version instead. If you prefer using a callback instead of awaiting the Task, you can still use a callback like this: CanGoForward().ContinueWith(result => {...})";
|
||||
public const string CaptureScreenshot = "The callback-based CaptureScreenshot(Action) version of this method has been removed. Please switch to the Task-based CaptureScreenshot() version instead. If you prefer using a callback instead of awaiting the Task, you can still use a callback like this: CaptureScreenshot().ContinueWith(result => {...})";
|
||||
public const string DisableViewUpdates = "DisableViewUpdates() has been removed. Please use SetRenderingEnabled(false) instead: https://developer.vuplex.com/webview/IWebView#SetRenderingEnabled";
|
||||
public const string EnableViewUpdates = "EnableViewUpdates() has been removed. Please use SetRenderingEnabled(true) instead: https://developer.vuplex.com/webview/IWebView#SetRenderingEnabled";
|
||||
public const string Focus = "IWebView.Focus() has been removed. Please use SetFocused(false) instead: https://developer.vuplex.com/webview/IWebView#SetFocused";
|
||||
public const string GetRawTextureData = "The callback-based GetRawTextureData(Action) version of this method has been removed. Please switch to the Task-based GetRawTextureData() version instead. If you prefer using a callback instead of awaiting the Task, you can still use a callback like this: GetRawTextureData().ContinueWith(result => {...})";
|
||||
public const string HandleKeyboardInput = "IWebView.HandleKeyboardInput() has been renamed to IWebView.SendKey(). Please switch to SendKey().";
|
||||
public const string Init = "IWebView.Init(Texture2D, float, float) has been removed in v4. Please switch to IWebView.Init(int, int) and await the Task it returns. For more details, please see this article: https://support.vuplex.com/articles/v4-changes#init";
|
||||
public const string Init2 = "IWebView.Init(Texture2D, float, float, Texture2D) has been removed in v4. Please switch to IWebView.Init(int, int) and await the Task it returns. For more details, please see this article: https://support.vuplex.com/articles/v4-changes#init";
|
||||
public const string Resolution = "IWebView.Resolution has been removed in v4. Please use WebViewPrefab.Resolution or CanvasWebViewPrefab.Resolution instead. For more details, please see this article: https://support.vuplex.com/articles/v4-changes#resolution";
|
||||
public const string SetResolution = "IWebView.SetResolution() has been removed in v4. Please set the WebViewPrefab.Resolution or CanvasWebViewPrefab.Resolution property instead. For more details, please see this article: https://support.vuplex.com/articles/v4-changes#resolution";
|
||||
public const string SizeInPixels = "IWebView.SizeInPixels is now deprecated. Please use IWebView.Size instead: https://developer.vuplex.com/webview/IWebView#Size";
|
||||
public const string VideoRectChanged = "IWebView.VideoRectChanged has been removed. Please use IWithFallbackVideo.VideoRectChanged instead: https://developer.vuplex.com/webview/IWithFallbackVideo#VideoRectChanged";
|
||||
public const string VideoTexture = "IWebView.VideoTexture has been removed. Please use IWithFallbackVideo.VideoTexture instead: https://developer.vuplex.com/webview/IWithFallbackVideo#VideoTexture";
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 50fd149ca81084699834f1aab50202f2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) 2023 Vuplex Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Vuplex Commercial Software Library License, you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// https://vuplex.com/commercial-library-license
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Vuplex.WebView {
|
||||
|
||||
/// <summary>
|
||||
/// Unity added support for using Texture2D.CreateExternalTexture() with Vulkan in 2020.2,
|
||||
/// but support for Texture2D.UpdateExternalTexture() wasn't added until 2022.1.
|
||||
/// So, this interface is used by 3D WebView on Android to update the texture
|
||||
/// when Vulkan is used with versions of Unity prior to 2022.1.
|
||||
/// https://issuetracker.unity3d.com/issues/android-vulkan-texture2d-dot-updateexternaltexture-does-not-respond-when-a-project-is-built-on-android-with-vulkan-graphics-api
|
||||
/// </summary>
|
||||
public interface IWithChangingTexture {
|
||||
|
||||
event EventHandler<EventArgs<Texture2D>> TextureChanged;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 749ba8541c9624896bf3788189c9477e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue