├── Editor.meta
├── Editor
├── MediationAdapterDependencies.xml
├── MediationAdapterDependencies.xml.meta
├── Scripts.meta
├── Scripts
│ ├── UnityWebViewPostprocessBuild.cs
│ └── UnityWebViewPostprocessBuild.cs.meta
├── TLab.WebView.Editor.asmdef
└── TLab.WebView.Editor.asmdef.meta
├── LICENSE.md
├── LICENSE.md.meta
├── Media.meta
├── Media
├── header.png
├── header.png.meta
├── image.0.png
├── image.0.png.meta
├── tlab-webview-settings.png
├── tlab-webview-settings.png.meta
├── tlab-webview-vr.gif
├── tlab-webview-vr.gif.meta
├── tlab-webview.png
└── tlab-webview.png.meta
├── Plugins.meta
├── Plugins
├── Android.meta
└── Android
│ ├── copy.bat
│ ├── copy.bat.meta
│ ├── libTLabWebView-release.aar
│ └── libTLabWebView-release.aar.meta
├── README-ja.md
├── README-ja.md.meta
├── README.md
├── README.md.meta
├── Resources.meta
├── Resources
├── TLab.meta
└── TLab
│ ├── WebView.meta
│ └── WebView
│ ├── Browser.prefab
│ ├── Browser.prefab.meta
│ ├── Samples.meta
│ └── Samples
│ ├── Browser Sample.prefab
│ ├── Browser Sample.prefab.meta
│ ├── Scripts.meta
│ ├── Scripts
│ ├── JS.meta
│ └── JS
│ │ ├── disable-beforunload.txt
│ │ ├── disable-beforunload.txt.meta
│ │ ├── fetch-blob.txt
│ │ ├── fetch-blob.txt.meta
│ │ ├── focus-in-out-interaction.txt
│ │ └── focus-in-out-interaction.txt.meta
│ ├── Widget.meta
│ └── Widget
│ ├── Dialog.prefab
│ ├── Dialog.prefab.meta
│ ├── Number Picker.prefab
│ ├── Number Picker.prefab.meta
│ ├── Select.meta
│ └── Select
│ ├── Group.prefab
│ ├── Group.prefab.meta
│ ├── Selectable.prefab
│ ├── Selectable.prefab.meta
│ ├── Separator.prefab
│ └── Separator.prefab.meta
├── Runtime.meta
├── Runtime
├── BaseInputListener.cs
├── BaseInputListener.cs.meta
├── Browser.cs
├── Browser.cs.meta
├── BrowserContainer.cs
├── BrowserContainer.cs.meta
├── BrowserInputField.cs
├── BrowserInputField.cs.meta
├── BrowserInputListener.cs
├── BrowserInputListener.cs.meta
├── BrowserManager.cs
├── BrowserManager.cs.meta
├── Common.cs
├── Common.cs.meta
├── FragmentCapture.cs
├── FragmentCapture.cs.meta
├── GeckoView.cs
├── GeckoView.cs.meta
├── IBrowser.cs
├── IBrowser.cs.meta
├── IOffscreen.cs
├── IOffscreen.cs.meta
├── NativePlugin.cs
├── NativePlugin.cs.meta
├── Sample.meta
├── Sample
│ ├── BrowserBGSample.cs
│ ├── BrowserBGSample.cs.meta
│ ├── BrowserSample.cs
│ ├── BrowserSample.cs.meta
│ ├── CreateNewInRuntime.cs
│ ├── CreateNewInRuntime.cs.meta
│ ├── DownloadHandlerSample.cs
│ ├── DownloadHandlerSample.cs.meta
│ ├── FocusInOutInteractionSample.cs
│ ├── FocusInOutInteractionSample.cs.meta
│ ├── JSSnippets.cs
│ ├── JSSnippets.cs.meta
│ ├── LoadLocalFileSample.cs
│ ├── LoadLocalFileSample.cs.meta
│ ├── Util.meta
│ ├── Util
│ │ ├── FPSCounter.cs
│ │ └── FPSCounter.cs.meta
│ ├── Widget.meta
│ └── Widget
│ │ ├── AlertDialogSample.cs
│ │ ├── AlertDialogSample.cs.meta
│ │ ├── AuthWidgetSample.cs
│ │ ├── AuthWidgetSample.cs.meta
│ │ ├── ColorWidgetSample.cs
│ │ ├── ColorWidgetSample.cs.meta
│ │ ├── DateTimeWidgetSample.cs
│ │ ├── DateTimeWidgetSample.cs.meta
│ │ ├── SelectWidgetSample.cs
│ │ └── SelectWidgetSample.cs.meta
├── SearchBar.cs
├── SearchBar.cs.meta
├── TLab.WebView.Runtime.asmdef
├── TLab.WebView.Runtime.asmdef.meta
├── Test.meta
├── Test
│ ├── BrowserAPITest.cs
│ ├── BrowserAPITest.cs.meta
│ ├── LoadUnloadTest.cs
│ └── LoadUnloadTest.cs.meta
├── WebView.cs
├── WebView.cs.meta
├── Widget.meta
└── Widget
│ ├── AlertDialog.cs
│ ├── AlertDialog.cs.meta
│ ├── AuthWidget.cs
│ ├── AuthWidget.cs.meta
│ ├── ColorWidget.cs
│ ├── ColorWidget.cs.meta
│ ├── Common.cs
│ ├── Common.cs.meta
│ ├── DateTimeWidget.cs
│ ├── DateTimeWidget.cs.meta
│ ├── NumberPicker.cs
│ ├── NumberPicker.cs.meta
│ ├── SelectWidget.cs
│ ├── SelectWidget.cs.meta
│ ├── TextWidget.cs
│ ├── TextWidget.cs.meta
│ ├── Widget.cs
│ └── Widget.cs.meta
├── Samples.meta
├── Samples
├── Scenes.meta
└── Scenes
│ ├── Load Unload Sample.unity
│ ├── Load Unload Sample.unity.meta
│ ├── Mobile Sample.unity
│ └── Mobile Sample.unity.meta
├── merge.bat
├── merge.bat.meta
├── package.json
└── package.json.meta
/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2929ddabb58e75f408b2839325c240b7
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Editor/MediationAdapterDependencies.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | https://unity3ddist.jfrog.io/artifactory/unity-mediation-mvn-prod-local/
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Editor/MediationAdapterDependencies.xml.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d46ce131972a0564f923f45bb8f3217f
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Editor/Scripts.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e06d850e31bed0242a6f287cefcc0293
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Editor/Scripts/UnityWebViewPostprocessBuild.cs:
--------------------------------------------------------------------------------
1 | /***
2 | * This code is adapted from
3 | * https://github.com/gree/unity-webview/blob/master/dist/package/Assets/Plugins/Editor/UnityWebViewPostprocessBuild.cs
4 | **/
5 |
6 | #if UNITY_EDITOR
7 | using System.IO;
8 | using System.Text;
9 | using System.Xml;
10 | using UnityEngine;
11 | using UnityEditor.Android;
12 |
13 | namespace TLab.WebView.Editor
14 | {
15 | #if UNITY_2018_1_OR_NEWER
16 | public class UnityWebViewPostprocessBuild : IPostGenerateGradleAndroidProject
17 | {
18 | //// for android/unity 2018.1 or newer
19 | //// cf. https://forum.unity.com/threads/android-hardwareaccelerated-is-forced-false-in-all-activities.532786/
20 | //// cf. https://github.com/Over17/UnityAndroidManifestCallback
21 |
22 | // This function called from unity when Android Gradle project is generated and before building begins.
23 | public void OnPostGenerateGradleAndroidProject(string basePath)
24 | {
25 | // ----------------------------------------------------------------------------------
26 | // Rewrite AndroidManifest.xml
27 | //
28 |
29 | var changed = false;
30 | var androidManifest = new AndroidManifest(GetManifestPath(basePath));
31 |
32 | changed = androidManifest.AddApplicationElement("supportsRtl", true) || changed;
33 |
34 | changed = androidManifest.AddApplicationElement("allowBackup", true) || changed;
35 |
36 | changed = androidManifest.SetExported(true) || changed;
37 |
38 | changed = androidManifest.SetHardwareAccelerated(true) || changed;
39 |
40 | #if UNITYWEBVIEW_ANDROID_USES_CLEARTEXT_TRAFFIC
41 | changed = androidManifest.SetUsesCleartextTraffic(true) || changed;
42 | #endif
43 |
44 | #if UNITYWEBVIEW_ANDROID_ENABLE_CAMERA
45 | changed = androidManifest.AddCamera() || changed;
46 | changed = androidManifest.AddGallery() || changed;
47 | #endif
48 |
49 | #if UNITYWEBVIEW_ANDROID_ENABLE_MICROPHONE
50 | changed = androidManifest.AddMicrophone() || changed;
51 | #endif
52 |
53 | if (changed)
54 | {
55 | var result = androidManifest.Save();
56 | Debug.Log("AndroidManifest.xml overwrite complete: " + result);
57 | }
58 | }
59 |
60 |
61 | public int callbackOrder
62 | {
63 | get
64 | {
65 | return 1;
66 | }
67 | }
68 |
69 | // ----------------------------------------------------------------------------------
70 | // Get each file
71 | //
72 |
73 | private string GetManifestPath(string basePath)
74 | {
75 | var pathBuilder = new StringBuilder(basePath);
76 | pathBuilder.Append(Path.DirectorySeparatorChar).Append("src");
77 | pathBuilder.Append(Path.DirectorySeparatorChar).Append("main");
78 | pathBuilder.Append(Path.DirectorySeparatorChar).Append("AndroidManifest.xml");
79 | var pathString = pathBuilder.ToString();
80 | Debug.Log("android custom manifest path: " + pathString);
81 | return pathString;
82 | }
83 | }
84 |
85 | internal class AndroidXmlDocument : XmlDocument
86 | {
87 | private string m_Path;
88 | protected XmlNamespaceManager nsMgr;
89 | public readonly string AndroidXmlNamespace = "http://schemas.android.com/apk/res/android";
90 |
91 | public AndroidXmlDocument(string path)
92 | {
93 | m_Path = path;
94 | using (var reader = new XmlTextReader(m_Path))
95 | {
96 | reader.Read();
97 | Load(reader);
98 | }
99 | nsMgr = new XmlNamespaceManager(NameTable);
100 | nsMgr.AddNamespace("android", AndroidXmlNamespace);
101 | }
102 |
103 | public string Save()
104 | {
105 | return SaveAs(m_Path);
106 | }
107 |
108 | public string SaveAs(string path)
109 | {
110 | using (var writer = new XmlTextWriter(path, new UTF8Encoding(false)))
111 | {
112 | writer.Formatting = Formatting.Indented;
113 | Save(writer);
114 | }
115 | return path;
116 | }
117 | }
118 |
119 | internal class AndroidManifest : AndroidXmlDocument
120 | {
121 | private readonly XmlElement ManifestElement;
122 | private readonly XmlElement ApplicationElement;
123 |
124 | public AndroidManifest(string path) : base(path)
125 | {
126 | ManifestElement = SelectSingleNode("/manifest") as XmlElement;
127 | ApplicationElement = SelectSingleNode("/manifest/application") as XmlElement;
128 | }
129 |
130 | private XmlAttribute CreateAndroidAttribute(string key, string value)
131 | {
132 | XmlAttribute attr = CreateAttribute("android", key, AndroidXmlNamespace);
133 | attr.Value = value;
134 | return attr;
135 | }
136 |
137 | internal XmlNode GetActivityWithLaunchIntent()
138 | {
139 | return
140 | SelectSingleNode(
141 | "/manifest/application/activity[intent-filter/action/@android:name='android.intent.action.MAIN' and "
142 | + "intent-filter/category/@android:name='android.intent.category.LAUNCHER']",
143 | nsMgr);
144 | }
145 |
146 | internal bool AddApplicationElement(string attribute, bool enabled)
147 | {
148 | var changed = false;
149 | var value = enabled ? "true" : "false";
150 |
151 | var attributeResult = ApplicationElement.GetAttribute(attribute, AndroidXmlNamespace);
152 |
153 | if (attributeResult == null || attributeResult == "" || attributeResult != value)
154 | {
155 | ApplicationElement.SetAttribute(attribute, AndroidXmlNamespace, value);
156 | changed = true;
157 | }
158 |
159 | Debug.Log($"Succeed in {nameof(ApplicationElement.SetAttribute)}: " + attribute);
160 | return changed;
161 | }
162 |
163 | internal bool SetUsesCleartextTraffic(bool enabled)
164 | {
165 | var changed = false;
166 | var value = enabled ? "true" : "false";
167 |
168 | #if UNITY_2022_1_OR_NEWER
169 | changed = changed || AddApplicationElement("usesCleartextTraffic", true);
170 | #elif UNITY_2018_1_OR_NEWER
171 | var attributeResult = ApplicationElement.GetAttribute("usesCleartextTraffic", AndroidXmlNamespace);
172 | if (attributeResult != value)
173 | {
174 | ApplicationElement.SetAttribute("usesCleartextTraffic", AndroidXmlNamespace, value);
175 | changed = true;
176 | }
177 | #endif
178 | return changed;
179 | }
180 |
181 | internal bool SetAttributeInLaunchIntent(bool enabled, string key)
182 | {
183 | bool changed = false;
184 | var value = enabled ? "true" : "false";
185 |
186 | var activity = GetActivityWithLaunchIntent() as XmlElement;
187 | if (activity != null)
188 | {
189 | var attributeResult = activity.HasAttribute(key) ? activity.GetAttribute(key, AndroidXmlNamespace) : null;
190 | if (attributeResult != value)
191 | {
192 | activity.SetAttribute(key, AndroidXmlNamespace, value);
193 | changed = true;
194 | }
195 | }
196 | else
197 | {
198 | Debug.LogWarning("Activity not found");
199 | }
200 | return changed;
201 | }
202 |
203 | // For API level 33
204 | internal bool SetExported(bool enabled) =>
205 | SetAttributeInLaunchIntent(enabled, "exported");
206 |
207 | internal bool SetHardwareAccelerated(bool enabled) =>
208 | SetAttributeInLaunchIntent(enabled, "hardwareAccelerated");
209 |
210 | internal bool AddCamera()
211 | {
212 | bool changed = false;
213 | if (SelectNodes("/manifest/uses-permission[@android:name='android.permission.CAMERA']", nsMgr).Count == 0)
214 | {
215 | var elem = CreateElement("uses-permission");
216 | elem.Attributes.Append(CreateAndroidAttribute("name", "android.permission.CAMERA"));
217 | ManifestElement.AppendChild(elem);
218 | changed = true;
219 | }
220 | if (SelectNodes("/manifest/uses-feature[@android:name='android.hardware.camera']", nsMgr).Count == 0)
221 | {
222 | var elem = CreateElement("uses-feature");
223 | elem.Attributes.Append(CreateAndroidAttribute("name", "android.hardware.camera"));
224 | ManifestElement.AppendChild(elem);
225 | changed = true;
226 | }
227 | // cf. https://developer.android.com/training/data-storage/shared/media#media-location-permission
228 | if (SelectNodes("/manifest/uses-permission[@android:name='android.permission.ACCESS_MEDIA_LOCATION']", nsMgr).Count == 0)
229 | {
230 | var elem = CreateElement("uses-permission");
231 | elem.Attributes.Append(CreateAndroidAttribute("name", "android.permission.ACCESS_MEDIA_LOCATION"));
232 | ManifestElement.AppendChild(elem);
233 | changed = true;
234 | }
235 | // cf. https://developer.android.com/training/package-visibility/declaring
236 | if (SelectNodes("/manifest/queries", nsMgr).Count == 0)
237 | {
238 | var elem = CreateElement("queries");
239 | ManifestElement.AppendChild(elem);
240 | changed = true;
241 | }
242 | if (SelectNodes("/manifest/queries/intent/action[@android:name='android.media.action.IMAGE_CAPTURE']", nsMgr).Count == 0)
243 | {
244 | var action = CreateElement("action");
245 | action.Attributes.Append(CreateAndroidAttribute("name", "android.media.action.IMAGE_CAPTURE"));
246 | var intent = CreateElement("intent");
247 | intent.AppendChild(action);
248 | var queries = SelectSingleNode("/manifest/queries") as XmlElement;
249 | queries.AppendChild(intent);
250 | changed = true;
251 | }
252 | return changed;
253 | }
254 |
255 | internal bool AddGallery()
256 | {
257 | bool changed = false;
258 | // for api level 33
259 | if (SelectNodes("/manifest/uses-permission[@android:name='android.permission.READ_MEDIA_IMAGES']", nsMgr).Count == 0)
260 | {
261 | var elem = CreateElement("uses-permission");
262 | elem.Attributes.Append(CreateAndroidAttribute("name", "android.permission.READ_MEDIA_IMAGES"));
263 | ManifestElement.AppendChild(elem);
264 | changed = true;
265 | }
266 | if (SelectNodes("/manifest/uses-permission[@android:name='android.permission.READ_MEDIA_VIDEO']", nsMgr).Count == 0)
267 | {
268 | var elem = CreateElement("uses-permission");
269 | elem.Attributes.Append(CreateAndroidAttribute("name", "android.permission.READ_MEDIA_VIDEO"));
270 | ManifestElement.AppendChild(elem);
271 | changed = true;
272 | }
273 | if (SelectNodes("/manifest/uses-permission[@android:name='android.permission.READ_MEDIA_AUDIO']", nsMgr).Count == 0)
274 | {
275 | var elem = CreateElement("uses-permission");
276 | elem.Attributes.Append(CreateAndroidAttribute("name", "android.permission.READ_MEDIA_AUDIO"));
277 | ManifestElement.AppendChild(elem);
278 | changed = true;
279 | }
280 | // cf. https://developer.android.com/training/package-visibility/declaring
281 | if (SelectNodes("/manifest/queries", nsMgr).Count == 0)
282 | {
283 | var elem = CreateElement("queries");
284 | ManifestElement.AppendChild(elem);
285 | changed = true;
286 | }
287 | if (SelectNodes("/manifest/queries/intent/action[@android:name='android.media.action.GET_CONTENT']", nsMgr).Count == 0)
288 | {
289 | var action = CreateElement("action");
290 | action.Attributes.Append(CreateAndroidAttribute("name", "android.media.action.GET_CONTENT"));
291 | var intent = CreateElement("intent");
292 | intent.AppendChild(action);
293 | var queries = SelectSingleNode("/manifest/queries") as XmlElement;
294 | queries.AppendChild(intent);
295 | changed = true;
296 | }
297 | return changed;
298 | }
299 |
300 | internal bool AddMicrophone()
301 | {
302 | bool changed = false;
303 | if (SelectNodes("/manifest/uses-permission[@android:name='android.permission.MICROPHONE']", nsMgr).Count == 0)
304 | {
305 | var elem = CreateElement("uses-permission");
306 | elem.Attributes.Append(CreateAndroidAttribute("name", "android.permission.MICROPHONE"));
307 | ManifestElement.AppendChild(elem);
308 | changed = true;
309 | }
310 | if (SelectNodes("/manifest/uses-feature[@android:name='android.hardware.microphone']", nsMgr).Count == 0)
311 | {
312 | var elem = CreateElement("uses-feature");
313 | elem.Attributes.Append(CreateAndroidAttribute("name", "android.hardware.microphone"));
314 | ManifestElement.AppendChild(elem);
315 | changed = true;
316 | }
317 | // cf. https://github.com/gree/unity-webview/issues/679
318 | // cf. https://github.com/fluttercommunity/flutter_webview_plugin/issues/138#issuecomment-559307558
319 | // cf. https://stackoverflow.com/questions/38917751/webview-webrtc-not-working/68024032#68024032
320 | // cf. https://stackoverflow.com/questions/40236925/allowing-microphone-accesspermission-in-webview-android-studio-java/47410311#47410311
321 | if (SelectNodes("/manifest/uses-permission[@android:name='android.permission.MODIFY_AUDIO_SETTINGS']", nsMgr).Count == 0)
322 | {
323 | var elem = CreateElement("uses-permission");
324 | elem.Attributes.Append(CreateAndroidAttribute("name", "android.permission.MODIFY_AUDIO_SETTINGS"));
325 | ManifestElement.AppendChild(elem);
326 | changed = true;
327 | }
328 | if (SelectNodes("/manifest/uses-permission[@android:name='android.permission.RECORD_AUDIO']", nsMgr).Count == 0)
329 | {
330 | var elem = CreateElement("uses-permission");
331 | elem.Attributes.Append(CreateAndroidAttribute("name", "android.permission.RECORD_AUDIO"));
332 | ManifestElement.AppendChild(elem);
333 | changed = true;
334 | }
335 | return changed;
336 | }
337 | }
338 | #endif
339 | }
340 | #endif
--------------------------------------------------------------------------------
/Editor/Scripts/UnityWebViewPostprocessBuild.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c1f38ba5c49717146a8b45aa13753678
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Editor/TLab.WebView.Editor.asmdef:
--------------------------------------------------------------------------------
1 | {
2 | "name": "TLab.WebView.Editor",
3 | "rootNamespace": "",
4 | "references": [
5 | "GUID:643142c4527239447a4feb8d9fba651e"
6 | ],
7 | "includePlatforms": [
8 | "Editor"
9 | ],
10 | "excludePlatforms": [],
11 | "allowUnsafeCode": false,
12 | "overrideReferences": false,
13 | "precompiledReferences": [],
14 | "autoReferenced": true,
15 | "defineConstraints": [],
16 | "versionDefines": [],
17 | "noEngineReferences": false
18 | }
--------------------------------------------------------------------------------
/Editor/TLab.WebView.Editor.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c70208384e755dc47bf7357c1918d1be
3 | AssemblyDefinitionImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 tlabaltoh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LICENSE.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9ec5c2a3889e691439f3950d0e26d6ff
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Media.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 86f9a35fea2d5e34186fb1d8e032be3b
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Media/header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLabAltoh/TLabWebView/0323d5f672b79ce14676e321757f09328be1c343/Media/header.png
--------------------------------------------------------------------------------
/Media/header.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 589eba7235633cc47af2a18bf1db88d2
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 12
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 1
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | vTOnly: 0
27 | ignoreMasterTextureLimit: 0
28 | grayScaleToAlpha: 0
29 | generateCubemap: 6
30 | cubemapConvolution: 0
31 | seamlessCubemap: 0
32 | textureFormat: 1
33 | maxTextureSize: 2048
34 | textureSettings:
35 | serializedVersion: 2
36 | filterMode: 1
37 | aniso: 1
38 | mipBias: 0
39 | wrapU: 0
40 | wrapV: 0
41 | wrapW: 0
42 | nPOTScale: 1
43 | lightmap: 0
44 | compressionQuality: 50
45 | spriteMode: 0
46 | spriteExtrude: 1
47 | spriteMeshType: 1
48 | alignment: 0
49 | spritePivot: {x: 0.5, y: 0.5}
50 | spritePixelsToUnits: 100
51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
52 | spriteGenerateFallbackPhysicsShape: 1
53 | alphaUsage: 1
54 | alphaIsTransparency: 0
55 | spriteTessellationDetail: -1
56 | textureType: 0
57 | textureShape: 1
58 | singleChannelComponent: 0
59 | flipbookRows: 1
60 | flipbookColumns: 1
61 | maxTextureSizeSet: 0
62 | compressionQualitySet: 0
63 | textureFormatSet: 0
64 | ignorePngGamma: 0
65 | applyGammaDecoding: 0
66 | cookieLightType: 0
67 | platformSettings:
68 | - serializedVersion: 3
69 | buildTarget: DefaultTexturePlatform
70 | maxTextureSize: 2048
71 | resizeAlgorithm: 0
72 | textureFormat: -1
73 | textureCompression: 1
74 | compressionQuality: 50
75 | crunchedCompression: 0
76 | allowsAlphaSplitting: 0
77 | overridden: 0
78 | androidETC2FallbackOverride: 0
79 | forceMaximumCompressionQuality_BC6H_BC7: 0
80 | - serializedVersion: 3
81 | buildTarget: Standalone
82 | maxTextureSize: 2048
83 | resizeAlgorithm: 0
84 | textureFormat: -1
85 | textureCompression: 1
86 | compressionQuality: 50
87 | crunchedCompression: 0
88 | allowsAlphaSplitting: 0
89 | overridden: 0
90 | androidETC2FallbackOverride: 0
91 | forceMaximumCompressionQuality_BC6H_BC7: 0
92 | - serializedVersion: 3
93 | buildTarget: WebGL
94 | maxTextureSize: 2048
95 | resizeAlgorithm: 0
96 | textureFormat: -1
97 | textureCompression: 1
98 | compressionQuality: 50
99 | crunchedCompression: 0
100 | allowsAlphaSplitting: 0
101 | overridden: 0
102 | androidETC2FallbackOverride: 0
103 | forceMaximumCompressionQuality_BC6H_BC7: 0
104 | - serializedVersion: 3
105 | buildTarget: Android
106 | maxTextureSize: 2048
107 | resizeAlgorithm: 0
108 | textureFormat: -1
109 | textureCompression: 1
110 | compressionQuality: 50
111 | crunchedCompression: 0
112 | allowsAlphaSplitting: 0
113 | overridden: 0
114 | androidETC2FallbackOverride: 0
115 | forceMaximumCompressionQuality_BC6H_BC7: 0
116 | spriteSheet:
117 | serializedVersion: 2
118 | sprites: []
119 | outline: []
120 | physicsShape: []
121 | bones: []
122 | spriteID:
123 | internalID: 0
124 | vertices: []
125 | indices:
126 | edges: []
127 | weights: []
128 | secondaryTextures: []
129 | nameFileIdTable: {}
130 | spritePackingTag:
131 | pSDRemoveMatte: 0
132 | pSDShowRemoveMatteOption: 0
133 | userData:
134 | assetBundleName:
135 | assetBundleVariant:
136 |
--------------------------------------------------------------------------------
/Media/image.0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLabAltoh/TLabWebView/0323d5f672b79ce14676e321757f09328be1c343/Media/image.0.png
--------------------------------------------------------------------------------
/Media/image.0.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0afdd9fb8c8054c47898b73ab22c5ff5
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 12
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 1
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | vTOnly: 0
27 | ignoreMasterTextureLimit: 0
28 | grayScaleToAlpha: 0
29 | generateCubemap: 6
30 | cubemapConvolution: 0
31 | seamlessCubemap: 0
32 | textureFormat: 1
33 | maxTextureSize: 2048
34 | textureSettings:
35 | serializedVersion: 2
36 | filterMode: 1
37 | aniso: 1
38 | mipBias: 0
39 | wrapU: 0
40 | wrapV: 0
41 | wrapW: 0
42 | nPOTScale: 1
43 | lightmap: 0
44 | compressionQuality: 50
45 | spriteMode: 0
46 | spriteExtrude: 1
47 | spriteMeshType: 1
48 | alignment: 0
49 | spritePivot: {x: 0.5, y: 0.5}
50 | spritePixelsToUnits: 100
51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
52 | spriteGenerateFallbackPhysicsShape: 1
53 | alphaUsage: 1
54 | alphaIsTransparency: 0
55 | spriteTessellationDetail: -1
56 | textureType: 0
57 | textureShape: 1
58 | singleChannelComponent: 0
59 | flipbookRows: 1
60 | flipbookColumns: 1
61 | maxTextureSizeSet: 0
62 | compressionQualitySet: 0
63 | textureFormatSet: 0
64 | ignorePngGamma: 0
65 | applyGammaDecoding: 0
66 | cookieLightType: 0
67 | platformSettings:
68 | - serializedVersion: 3
69 | buildTarget: DefaultTexturePlatform
70 | maxTextureSize: 2048
71 | resizeAlgorithm: 0
72 | textureFormat: -1
73 | textureCompression: 1
74 | compressionQuality: 50
75 | crunchedCompression: 0
76 | allowsAlphaSplitting: 0
77 | overridden: 0
78 | androidETC2FallbackOverride: 0
79 | forceMaximumCompressionQuality_BC6H_BC7: 0
80 | - serializedVersion: 3
81 | buildTarget: Standalone
82 | maxTextureSize: 2048
83 | resizeAlgorithm: 0
84 | textureFormat: -1
85 | textureCompression: 1
86 | compressionQuality: 50
87 | crunchedCompression: 0
88 | allowsAlphaSplitting: 0
89 | overridden: 0
90 | androidETC2FallbackOverride: 0
91 | forceMaximumCompressionQuality_BC6H_BC7: 0
92 | - serializedVersion: 3
93 | buildTarget: WebGL
94 | maxTextureSize: 2048
95 | resizeAlgorithm: 0
96 | textureFormat: -1
97 | textureCompression: 1
98 | compressionQuality: 50
99 | crunchedCompression: 0
100 | allowsAlphaSplitting: 0
101 | overridden: 0
102 | androidETC2FallbackOverride: 0
103 | forceMaximumCompressionQuality_BC6H_BC7: 0
104 | - serializedVersion: 3
105 | buildTarget: Android
106 | maxTextureSize: 2048
107 | resizeAlgorithm: 0
108 | textureFormat: -1
109 | textureCompression: 1
110 | compressionQuality: 50
111 | crunchedCompression: 0
112 | allowsAlphaSplitting: 0
113 | overridden: 0
114 | androidETC2FallbackOverride: 0
115 | forceMaximumCompressionQuality_BC6H_BC7: 0
116 | spriteSheet:
117 | serializedVersion: 2
118 | sprites: []
119 | outline: []
120 | physicsShape: []
121 | bones: []
122 | spriteID:
123 | internalID: 0
124 | vertices: []
125 | indices:
126 | edges: []
127 | weights: []
128 | secondaryTextures: []
129 | nameFileIdTable: {}
130 | spritePackingTag:
131 | pSDRemoveMatte: 0
132 | pSDShowRemoveMatteOption: 0
133 | userData:
134 | assetBundleName:
135 | assetBundleVariant:
136 |
--------------------------------------------------------------------------------
/Media/tlab-webview-settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLabAltoh/TLabWebView/0323d5f672b79ce14676e321757f09328be1c343/Media/tlab-webview-settings.png
--------------------------------------------------------------------------------
/Media/tlab-webview-settings.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 43a59d8dd443d2740a8d5acd0370294c
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 12
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 1
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | vTOnly: 0
27 | ignoreMasterTextureLimit: 0
28 | grayScaleToAlpha: 0
29 | generateCubemap: 6
30 | cubemapConvolution: 0
31 | seamlessCubemap: 0
32 | textureFormat: 1
33 | maxTextureSize: 2048
34 | textureSettings:
35 | serializedVersion: 2
36 | filterMode: 1
37 | aniso: 1
38 | mipBias: 0
39 | wrapU: 0
40 | wrapV: 0
41 | wrapW: 0
42 | nPOTScale: 1
43 | lightmap: 0
44 | compressionQuality: 50
45 | spriteMode: 0
46 | spriteExtrude: 1
47 | spriteMeshType: 1
48 | alignment: 0
49 | spritePivot: {x: 0.5, y: 0.5}
50 | spritePixelsToUnits: 100
51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
52 | spriteGenerateFallbackPhysicsShape: 1
53 | alphaUsage: 1
54 | alphaIsTransparency: 0
55 | spriteTessellationDetail: -1
56 | textureType: 0
57 | textureShape: 1
58 | singleChannelComponent: 0
59 | flipbookRows: 1
60 | flipbookColumns: 1
61 | maxTextureSizeSet: 0
62 | compressionQualitySet: 0
63 | textureFormatSet: 0
64 | ignorePngGamma: 0
65 | applyGammaDecoding: 0
66 | cookieLightType: 0
67 | platformSettings:
68 | - serializedVersion: 3
69 | buildTarget: DefaultTexturePlatform
70 | maxTextureSize: 2048
71 | resizeAlgorithm: 0
72 | textureFormat: -1
73 | textureCompression: 1
74 | compressionQuality: 50
75 | crunchedCompression: 0
76 | allowsAlphaSplitting: 0
77 | overridden: 0
78 | androidETC2FallbackOverride: 0
79 | forceMaximumCompressionQuality_BC6H_BC7: 0
80 | - serializedVersion: 3
81 | buildTarget: Standalone
82 | maxTextureSize: 2048
83 | resizeAlgorithm: 0
84 | textureFormat: -1
85 | textureCompression: 1
86 | compressionQuality: 50
87 | crunchedCompression: 0
88 | allowsAlphaSplitting: 0
89 | overridden: 0
90 | androidETC2FallbackOverride: 0
91 | forceMaximumCompressionQuality_BC6H_BC7: 0
92 | - serializedVersion: 3
93 | buildTarget: Server
94 | maxTextureSize: 2048
95 | resizeAlgorithm: 0
96 | textureFormat: -1
97 | textureCompression: 1
98 | compressionQuality: 50
99 | crunchedCompression: 0
100 | allowsAlphaSplitting: 0
101 | overridden: 0
102 | androidETC2FallbackOverride: 0
103 | forceMaximumCompressionQuality_BC6H_BC7: 0
104 | - serializedVersion: 3
105 | buildTarget: Android
106 | maxTextureSize: 2048
107 | resizeAlgorithm: 0
108 | textureFormat: -1
109 | textureCompression: 1
110 | compressionQuality: 50
111 | crunchedCompression: 0
112 | allowsAlphaSplitting: 0
113 | overridden: 0
114 | androidETC2FallbackOverride: 0
115 | forceMaximumCompressionQuality_BC6H_BC7: 0
116 | - serializedVersion: 3
117 | buildTarget: WebGL
118 | maxTextureSize: 2048
119 | resizeAlgorithm: 0
120 | textureFormat: -1
121 | textureCompression: 1
122 | compressionQuality: 50
123 | crunchedCompression: 0
124 | allowsAlphaSplitting: 0
125 | overridden: 0
126 | androidETC2FallbackOverride: 0
127 | forceMaximumCompressionQuality_BC6H_BC7: 0
128 | - serializedVersion: 3
129 | buildTarget: Windows Store Apps
130 | maxTextureSize: 2048
131 | resizeAlgorithm: 0
132 | textureFormat: -1
133 | textureCompression: 1
134 | compressionQuality: 50
135 | crunchedCompression: 0
136 | allowsAlphaSplitting: 0
137 | overridden: 0
138 | androidETC2FallbackOverride: 0
139 | forceMaximumCompressionQuality_BC6H_BC7: 0
140 | spriteSheet:
141 | serializedVersion: 2
142 | sprites: []
143 | outline: []
144 | physicsShape: []
145 | bones: []
146 | spriteID:
147 | internalID: 0
148 | vertices: []
149 | indices:
150 | edges: []
151 | weights: []
152 | secondaryTextures: []
153 | nameFileIdTable: {}
154 | spritePackingTag:
155 | pSDRemoveMatte: 0
156 | pSDShowRemoveMatteOption: 0
157 | userData:
158 | assetBundleName:
159 | assetBundleVariant:
160 |
--------------------------------------------------------------------------------
/Media/tlab-webview-vr.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLabAltoh/TLabWebView/0323d5f672b79ce14676e321757f09328be1c343/Media/tlab-webview-vr.gif
--------------------------------------------------------------------------------
/Media/tlab-webview-vr.gif.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: df176f80dbdf58940b966a8978e143af
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 12
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 1
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | vTOnly: 0
27 | ignoreMasterTextureLimit: 0
28 | grayScaleToAlpha: 0
29 | generateCubemap: 6
30 | cubemapConvolution: 0
31 | seamlessCubemap: 0
32 | textureFormat: 1
33 | maxTextureSize: 2048
34 | textureSettings:
35 | serializedVersion: 2
36 | filterMode: 1
37 | aniso: 1
38 | mipBias: 0
39 | wrapU: 0
40 | wrapV: 0
41 | wrapW: 0
42 | nPOTScale: 1
43 | lightmap: 0
44 | compressionQuality: 50
45 | spriteMode: 0
46 | spriteExtrude: 1
47 | spriteMeshType: 1
48 | alignment: 0
49 | spritePivot: {x: 0.5, y: 0.5}
50 | spritePixelsToUnits: 100
51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
52 | spriteGenerateFallbackPhysicsShape: 1
53 | alphaUsage: 1
54 | alphaIsTransparency: 0
55 | spriteTessellationDetail: -1
56 | textureType: 0
57 | textureShape: 1
58 | singleChannelComponent: 0
59 | flipbookRows: 1
60 | flipbookColumns: 1
61 | maxTextureSizeSet: 0
62 | compressionQualitySet: 0
63 | textureFormatSet: 0
64 | ignorePngGamma: 0
65 | applyGammaDecoding: 0
66 | cookieLightType: 0
67 | platformSettings:
68 | - serializedVersion: 3
69 | buildTarget: DefaultTexturePlatform
70 | maxTextureSize: 2048
71 | resizeAlgorithm: 0
72 | textureFormat: -1
73 | textureCompression: 1
74 | compressionQuality: 50
75 | crunchedCompression: 0
76 | allowsAlphaSplitting: 0
77 | overridden: 0
78 | androidETC2FallbackOverride: 0
79 | forceMaximumCompressionQuality_BC6H_BC7: 0
80 | - serializedVersion: 3
81 | buildTarget: Standalone
82 | maxTextureSize: 2048
83 | resizeAlgorithm: 0
84 | textureFormat: -1
85 | textureCompression: 1
86 | compressionQuality: 50
87 | crunchedCompression: 0
88 | allowsAlphaSplitting: 0
89 | overridden: 0
90 | androidETC2FallbackOverride: 0
91 | forceMaximumCompressionQuality_BC6H_BC7: 0
92 | - serializedVersion: 3
93 | buildTarget: WebGL
94 | maxTextureSize: 2048
95 | resizeAlgorithm: 0
96 | textureFormat: -1
97 | textureCompression: 1
98 | compressionQuality: 50
99 | crunchedCompression: 0
100 | allowsAlphaSplitting: 0
101 | overridden: 0
102 | androidETC2FallbackOverride: 0
103 | forceMaximumCompressionQuality_BC6H_BC7: 0
104 | - serializedVersion: 3
105 | buildTarget: Android
106 | maxTextureSize: 2048
107 | resizeAlgorithm: 0
108 | textureFormat: -1
109 | textureCompression: 1
110 | compressionQuality: 50
111 | crunchedCompression: 0
112 | allowsAlphaSplitting: 0
113 | overridden: 0
114 | androidETC2FallbackOverride: 0
115 | forceMaximumCompressionQuality_BC6H_BC7: 0
116 | spriteSheet:
117 | serializedVersion: 2
118 | sprites: []
119 | outline: []
120 | physicsShape: []
121 | bones: []
122 | spriteID:
123 | internalID: 0
124 | vertices: []
125 | indices:
126 | edges: []
127 | weights: []
128 | secondaryTextures: []
129 | nameFileIdTable: {}
130 | spritePackingTag:
131 | pSDRemoveMatte: 0
132 | pSDShowRemoveMatteOption: 0
133 | userData:
134 | assetBundleName:
135 | assetBundleVariant:
136 |
--------------------------------------------------------------------------------
/Media/tlab-webview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLabAltoh/TLabWebView/0323d5f672b79ce14676e321757f09328be1c343/Media/tlab-webview.png
--------------------------------------------------------------------------------
/Media/tlab-webview.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bfcb64e86b0f42b4193a92fefbf781de
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 12
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 1
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | vTOnly: 0
27 | ignoreMasterTextureLimit: 0
28 | grayScaleToAlpha: 0
29 | generateCubemap: 6
30 | cubemapConvolution: 0
31 | seamlessCubemap: 0
32 | textureFormat: 1
33 | maxTextureSize: 2048
34 | textureSettings:
35 | serializedVersion: 2
36 | filterMode: 1
37 | aniso: 1
38 | mipBias: 0
39 | wrapU: 0
40 | wrapV: 0
41 | wrapW: 0
42 | nPOTScale: 1
43 | lightmap: 0
44 | compressionQuality: 50
45 | spriteMode: 0
46 | spriteExtrude: 1
47 | spriteMeshType: 1
48 | alignment: 0
49 | spritePivot: {x: 0.5, y: 0.5}
50 | spritePixelsToUnits: 100
51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
52 | spriteGenerateFallbackPhysicsShape: 1
53 | alphaUsage: 1
54 | alphaIsTransparency: 0
55 | spriteTessellationDetail: -1
56 | textureType: 0
57 | textureShape: 1
58 | singleChannelComponent: 0
59 | flipbookRows: 1
60 | flipbookColumns: 1
61 | maxTextureSizeSet: 0
62 | compressionQualitySet: 0
63 | textureFormatSet: 0
64 | ignorePngGamma: 0
65 | applyGammaDecoding: 0
66 | cookieLightType: 0
67 | platformSettings:
68 | - serializedVersion: 3
69 | buildTarget: DefaultTexturePlatform
70 | maxTextureSize: 2048
71 | resizeAlgorithm: 0
72 | textureFormat: -1
73 | textureCompression: 1
74 | compressionQuality: 50
75 | crunchedCompression: 0
76 | allowsAlphaSplitting: 0
77 | overridden: 0
78 | androidETC2FallbackOverride: 0
79 | forceMaximumCompressionQuality_BC6H_BC7: 0
80 | - serializedVersion: 3
81 | buildTarget: Standalone
82 | maxTextureSize: 2048
83 | resizeAlgorithm: 0
84 | textureFormat: -1
85 | textureCompression: 1
86 | compressionQuality: 50
87 | crunchedCompression: 0
88 | allowsAlphaSplitting: 0
89 | overridden: 0
90 | androidETC2FallbackOverride: 0
91 | forceMaximumCompressionQuality_BC6H_BC7: 0
92 | - serializedVersion: 3
93 | buildTarget: Server
94 | maxTextureSize: 2048
95 | resizeAlgorithm: 0
96 | textureFormat: -1
97 | textureCompression: 1
98 | compressionQuality: 50
99 | crunchedCompression: 0
100 | allowsAlphaSplitting: 0
101 | overridden: 0
102 | androidETC2FallbackOverride: 0
103 | forceMaximumCompressionQuality_BC6H_BC7: 0
104 | - serializedVersion: 3
105 | buildTarget: Android
106 | maxTextureSize: 2048
107 | resizeAlgorithm: 0
108 | textureFormat: -1
109 | textureCompression: 1
110 | compressionQuality: 50
111 | crunchedCompression: 0
112 | allowsAlphaSplitting: 0
113 | overridden: 0
114 | androidETC2FallbackOverride: 0
115 | forceMaximumCompressionQuality_BC6H_BC7: 0
116 | - serializedVersion: 3
117 | buildTarget: WebGL
118 | maxTextureSize: 2048
119 | resizeAlgorithm: 0
120 | textureFormat: -1
121 | textureCompression: 1
122 | compressionQuality: 50
123 | crunchedCompression: 0
124 | allowsAlphaSplitting: 0
125 | overridden: 0
126 | androidETC2FallbackOverride: 0
127 | forceMaximumCompressionQuality_BC6H_BC7: 0
128 | - serializedVersion: 3
129 | buildTarget: Windows Store Apps
130 | maxTextureSize: 2048
131 | resizeAlgorithm: 0
132 | textureFormat: -1
133 | textureCompression: 1
134 | compressionQuality: 50
135 | crunchedCompression: 0
136 | allowsAlphaSplitting: 0
137 | overridden: 0
138 | androidETC2FallbackOverride: 0
139 | forceMaximumCompressionQuality_BC6H_BC7: 0
140 | spriteSheet:
141 | serializedVersion: 2
142 | sprites: []
143 | outline: []
144 | physicsShape: []
145 | bones: []
146 | spriteID:
147 | internalID: 0
148 | vertices: []
149 | indices:
150 | edges: []
151 | weights: []
152 | secondaryTextures: []
153 | nameFileIdTable: {}
154 | spritePackingTag:
155 | pSDRemoveMatte: 0
156 | pSDShowRemoveMatteOption: 0
157 | userData:
158 | assetBundleName:
159 | assetBundleVariant:
160 |
--------------------------------------------------------------------------------
/Plugins.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4a6dd89a1b1090f4281bdd3b7fabecd2
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Plugins/Android.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: fbc52ad3b7e859b43a70296fa0135f3e
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Plugins/Android/copy.bat:
--------------------------------------------------------------------------------
1 | copy "%USERPROFILE%\source\tmp\TLabWebViewPlugin\libTLabWebView\build\outputs\aar\libTLabWebView-release.aar" .
2 | clear
3 | ls -lia
4 |
--------------------------------------------------------------------------------
/Plugins/Android/copy.bat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 32f7b1757940a77489f8347723c2b9e3
3 | DefaultImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Plugins/Android/libTLabWebView-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLabAltoh/TLabWebView/0323d5f672b79ce14676e321757f09328be1c343/Plugins/Android/libTLabWebView-release.aar
--------------------------------------------------------------------------------
/Plugins/Android/libTLabWebView-release.aar.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8927d9548af8466459a6c2ff0eed6662
3 | PluginImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | iconMap: {}
7 | executionOrder: {}
8 | defineConstraints: []
9 | isPreloaded: 1
10 | isOverridable: 0
11 | isExplicitlyReferenced: 0
12 | validateReferences: 1
13 | platformData:
14 | - first:
15 | : Any
16 | second:
17 | enabled: 0
18 | settings:
19 | Exclude Android: 0
20 | Exclude Editor: 1
21 | Exclude Linux64: 1
22 | Exclude OSXUniversal: 1
23 | Exclude WebGL: 1
24 | Exclude Win: 1
25 | Exclude Win64: 1
26 | - first:
27 | Android: Android
28 | second:
29 | enabled: 1
30 | settings:
31 | CPU: ARMv7
32 | - first:
33 | Any:
34 | second:
35 | enabled: 0
36 | settings: {}
37 | - first:
38 | Editor: Editor
39 | second:
40 | enabled: 0
41 | settings:
42 | CPU: AnyCPU
43 | DefaultValueInitialized: true
44 | OS: AnyOS
45 | - first:
46 | Standalone: Linux64
47 | second:
48 | enabled: 0
49 | settings:
50 | CPU: AnyCPU
51 | - first:
52 | Standalone: OSXUniversal
53 | second:
54 | enabled: 0
55 | settings:
56 | CPU: AnyCPU
57 | - first:
58 | Standalone: Win
59 | second:
60 | enabled: 0
61 | settings:
62 | CPU: AnyCPU
63 | - first:
64 | Standalone: Win64
65 | second:
66 | enabled: 0
67 | settings:
68 | CPU: AnyCPU
69 | userData:
70 | assetBundleName:
71 | assetBundleVariant:
72 |
--------------------------------------------------------------------------------
/README-ja.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # TLabWebView
4 |
5 | Android で使用可能なブラウザコンポーネント ([```WebView```](https://developer.android.com/reference/android/webkit/WebView) / [```GeckoView```](https://mozilla.github.io/geckoview/)) を uGUI (Texture2D) として利用するためのプラグイン.3Dウェブブラウザ (3D WebView) の実装が可能になります.
6 |
7 | - [x] キーボード入力
8 | - [x] タッチ操作
9 | - [x] ファイルダウンロード (blob, data urlを含む)
10 | - [x] リサイズ
11 | - [x] Javascriptの実行
12 | - [x] 複数インスタンスの同時実行をサポート
13 | - [x] 複数のブラウザエンジンをサポート
14 | - [x] [```WebView```](https://developer.android.com/reference/android/webkit/WebView): 安定していて,javascriptインターフェースが充実
15 | - [x] [```GeckoView```](https://mozilla.github.io/geckoview/): WebViewと比べて,拡張性が高い(ポップアップ等)
16 | - [x] 複数のレンダリング方法をサポート
17 | - [x] ```HardwareBudder```: Androidの低レイヤー機能を使用した実装.パフォーマンス⭕️
18 | - [x] ```ByteBuffer```: C#側でbyte配列として結果を取得するためフレームへのアクセスが容易.安定性⭕️.**デフォルトではこのオプションが使用されています.**
19 | - [x] ```Surface```: Androidの ```Surface``` クラスに直接レンダリングを行う.[```CompositionLayers```](https://docs.unity3d.com/Packages/com.unity.xr.compositionlayers@0.5/manual/usage-guide.html)などを活用する際に利用することを想定
20 |
21 | [ドキュメントはこちら](https://tlabgames.gitbook.io/tlabwebview)
22 | [スニペットはこちら](https://gist.github.com/TLabAltoh/e0512b3367c25d3e1ec28ddbe95da497#file-tlabwebview-snippets-md)
23 | [Javaプラグインのソースコードはこちら](https://github.com/TLabAltoh/TLabWebViewPlugin)
24 |
25 | [](https://www.buymeacoffee.com/tlabaltoh)
26 |
27 | ## 対応しているUnityのバージョン
28 | - [x] Unity 2021
29 | - [x] Unity 2022
30 | - [x] Unity 6000 (`WebView`のみテスト済みです.`GeckoView`はまだテストしていません.)
31 |
32 | ## 対応するグラフィックスAPI
33 | - [x] OpenGLES
34 | - [x] Vulkan
35 |
36 | ## スクリーンショット
37 | Android13, Adreno 619で実行した画面
38 |
39 |
40 |
41 | VR サンプル
42 |
43 |
44 | ## 動作環境
45 |
46 | | | |
47 | | ----- | ------------------------ |
48 | | OS | Android 10 ~ 14 |
49 | | GPU | Qualcomm Adreno 505, 619 |
50 | | Unity | 2021.3 |
51 |
52 | ## スタートガイド
53 |
54 | ### 依存するライブラリ
55 |
56 | - [TLabVKeyborad](https://github.com/TLabAltoh/TLabVKeyborad) ```v1.0.1```
57 |
58 | ### インストール
59 | こちらをご覧ください
60 |
61 | #### Submodule
62 | 以下のコマンドでリポジトリをクローンしてください
63 | ```
64 | git clone https://github.com/TLabAltoh/TLabWebView.git
65 | ```
66 | or
67 | ```
68 | git submodule add https://github.com/TLabAltoh/TLabWebView.git
69 | ```
70 |
71 | #### UPM
72 | Unity Package Managerで```add package from git ...```から以下のurlでパッケージをダウンロードしてください
73 | ```
74 | https://github.com/TLabAltoh/TLabWebView.git#upm
75 | ```
76 |
77 | #### アプリストア互換性
78 | このプラグインを使用したアプリをアプリストアに出した場合,以下のような警告を受ける場合があります.
79 |
80 | > ### Unsafe SSL override in WebViews
81 | > Your application may contain an unsafe implementation of the WebView's [onReceivedSslError() method](https://www.oculus.com/lynx/?u=https%3A%2F%2Fdeveloper.android.com%2Freference%2Fandroid%2Fwebkit%2FWebViewClient.html%23onReceivedSslError(android.webkit.WebView%2C%2520android.webkit.SslErrorHandler%2C%2520android.net.http.SslError)&e=AT0HN6RWgLynCRtwcCSOzSVvlpMDUhi7C5saZwaY5p4unt4S4-GxIACJX_OPzTQp1Fn4oADk7Q_rwvZvRiF5XstftUzyuAWAolfkkk_WAtDpvOgW0Llcn_BXIEpgYobFNELMZ31ntKzTQXflaLkeRA) with a call to `handler.proceed() with insufficient validations. This may cause the WebView to ignore SSL certificate validation errors, making the application vulnerable to man-in-the-middle attacks.
82 | >
83 | > https://www.meta.com/experiences/
84 |
85 |
86 | > ### Security and trust
87 | > #### onReceivedSslError
88 | > your app is using an unsafe implementation of [```WebviewClient.onReceivedSslError```](https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedSslError(android.webkit.WebView,%20android.webkit.SslErrorHandler,%20android.net.http.SslError)) handler
89 | >
90 | > https://developer.android.com/distribute/console
91 |
92 | その場合は,アプリストアに対応したバージョンのパッケージに切り替えてください.
93 |
94 | ```add package from git URL ...```
95 | ```
96 | https://github.com/TLabAltoh/TLabWebView.git#appstore-compatible-upm
97 | ```
98 |
99 | アプリストア対応バージョンはセキュアではないウェブサイトを読み込むことができない点をあらかじめご了承ください.
100 |
101 |
102 |
103 | ### セットアップ
104 |
105 | こちらをご覧ください
106 |
107 | - Build Settings
108 |
109 | | Property | Value |
110 | | -------- | ------- |
111 | | Platform | Android |
112 |
113 | - Project Settings
114 |
115 | | Property | Value |
116 | | ----------------- | ------------------------------------- |
117 | | Color Space | Linear |
118 | | Minimum API Level | 26 |
119 | | Target API Level | 30 (Unity 2021), 31 ~ 32 (Unity 2022) |
120 |
121 |
122 | - Project Settings --> Player --> Other Settings に以下のシンボルを追加(ビルド時に使用)
123 |
124 | ```
125 | UNITYWEBVIEW_ANDROID_USES_CLEARTEXT_TRAFFIC
126 | ```
127 | ```
128 | UNITYWEBVIEW_ANDROID_ENABLE_CAMERA
129 | ```
130 | ```
131 | UNITYWEBVIEW_ANDROID_ENABLE_MICROPHONE
132 | ```
133 |
134 | - Scene
135 |
136 | ```BrowserManager```をシーン内のいずれかのGameObjectにアタッチしてください.(EventSystemにアタッチするのが一番望ましいかも ...).
137 |
138 | #### ```GeckoView``` をブラウザエンジンとして使用したい場合
139 |
140 | PluginsフォルダーをAssets以下に作成し,以下のファイルを置いてください.また,```BrowserContainer.browser```に```WebView```の代わりに```GeckoView```をアタッチしてください.また,```GeckoView```の使用には API level ```33``` ~ が求められます.```Project Settings```からターゲットAPIレベルを33以上に設定してください.
141 |
142 | 1. gradleTemplate.properties
143 |
144 | ```properties
145 | org.gradle.jvmargs=-Xmx**JVM_HEAP_SIZE**M
146 | org.gradle.parallel=true
147 | # android.enableR8=**MINIFY_WITH_R_EIGHT**
148 | unityStreamingAssets=**STREAMING_ASSETS**
149 | **ADDITIONAL_PROPERTIES**
150 | android.useAndroidX=true
151 | # android.enableJetifier=true
152 | ```
153 |
154 | 2. mainTemplate.gradle
155 |
156 | ```gradle
157 | ...
158 |
159 | dependencies {
160 | implementation "androidx.annotation:annotation-jvm:1.9.1"
161 |
162 | def collection_version = "1.4.3"
163 | implementation "androidx.collection:collection:$collection_version"
164 |
165 | def lifecycle_version = "2.6.1"
166 | implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
167 | implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
168 | implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
169 | implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
170 | implementation "androidx.lifecycle:lifecycle-runtime-compose:$lifecycle_version"
171 | implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
172 | implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
173 | implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
174 | implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
175 | implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
176 | }
177 |
178 | ...
179 | ```
180 |
181 | 3. GeckoView plugin (```.aar```) (現在 [125.0.20240425211020 version](https://mvnrepository.com/artifact/org.mozilla.geckoview/geckoview/125.0.20240425211020) のみで開発・テストを行っているので,同じバージョンのものをダウンロードしてください.)
182 |
183 |
184 |
185 | ### Prefab
186 | 以下に置いてあるプレハブをCanvasに追加することでWebViewを実装できます
187 | ```
188 | /Resources/TLab/WebView/Browser.prefab
189 | ```
190 |
191 | ### Keyborad
192 | このパッケージでは,デフォルトでuGUIをベースに実装されたバーチャルキーボードが利用できます.しかし,uGUIをベースにしたバーチャルキーボードはデザインなどの拡張性の点で利点がありますが,場合によってはOS標準のシステムキーボードを利用したい場面もあるかもしれません.その場合は,各プラットフォームの設定に従って,アプリ側でパーミッション等を使用してシステムキーボードを有効にしてください (例: Meta Quest での設定は[こちら](https://developers.meta.com/horizon/documentation/unity/unity-keyboard-overlay/)).アプリ側での設定が完了すると,WebViewでのシステムキーボードの利用が可能になります.
193 |
194 | ##
195 | > [!NOTE]
196 | > 外部ストレージ(```/Download```や```/Picture```など)にファイルをダウンロードしたい場合,以下のパーミッションを```AndroidManifest.xml```に追加してください.これは,Android 11以降のデバイスで必要になります (詳細は[こちら](https://developer.android.com/training/data-storage/manage-all-files?hl=ja)).
197 | > ```.xml
198 | >
199 | > ```
200 |
201 | > [!WARNING]
202 | > このプラグインはAndroidデバイス上でのみ動作します.Unity Editor上で実行してもWebページは表示されないことに注意してください.
203 |
204 | > [!WARNING]
205 | > `HardwareBuffer` モードは,プラグインを実行するデバイスによっては正常に動作しない場合があるかもしれません. その場合は,プロジェクトの`Graphics API`を`Vulkan`から`OpenGLES`に変更する (`HardwareBuffer`モードにおける問題は,ほとんどが,プロジェクトで`Vulkan` APIを使用している場合に報告されています).もしくは,`HardwareBuffer` から `ByteBuffer` へ `CaptureMode` を切り替えてください (安定したレンダリングオプションです).
206 | >
207 | >
208 |
209 | > [!WARNING]
210 | > Android WebViewは [WebXR API](https://developer.mozilla.org/ja/docs/Web/API/WebXR_Device_API/Fundamentals) をサポートしません.
211 |
212 | > [!WARNING]
213 | > OculusQuestはいくつかのHTML5 input タグをサポートしていません(下記参照).それらを使用したい場合,```GeckoView```を```WebView```の代わりに```Browser```として使用してください.uGUIで実装したウィジェットを表示します.以下は,このプラグインによる,HTML5 inpu タグの対応状況です.
214 | >
215 | > - [x] [datetime-local](https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/datetime-local)
216 | > - [x] [date](https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/date)
217 | > - [x] [time](https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/time)
218 | > - [x] [color](https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/color)
219 | > - [ ] [week](https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/week)
220 | > - [ ] [month](https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/month)
221 | > - [ ] [image](https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/image)
222 | > - [ ] [file](https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/file)
223 |
224 | > [!WARNING]
225 | > このプラグインは,```OpenGLES```と```Vulkan```の両方をサポートしていますが,```Vulkan API``` を使用する場合は,デバイスが```OpenGLES 3.1```以上をサポートしている必要があることに留意してください.
226 |
--------------------------------------------------------------------------------
/README-ja.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2a0ed03dbd353ec48b2b39d16f29ca96
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # TLabWebView
4 |
5 | [日本語版READMEはこちら](README-ja.md)
6 |
7 | A Unity plugin that enables the use of Android’s web browser component ([```WebView```](https://developer.android.com/reference/android/webkit/WebView) / [```GeckoView```](https://mozilla.github.io/geckoview/)) as a uGUI (Texture2D). This plugin makes it possible to implement a 3D web browser (3D WebView) within Unity.
8 |
9 | - [x] Keyboard Input
10 | - [x] Touch Interaction
11 | - [x] File download (include blob, data url)
12 | - [x] Resize
13 | - [x] Run Javascript
14 | - [x] Support for multiple instances running concurrently
15 | - [x] Support for multiple browser engines
16 | - [x] [```WebView```](https://developer.android.com/reference/android/webkit/WebView): Stable and powerful javascript interface
17 | - [x] [```GeckoView```](https://mozilla.github.io/geckoview/): Highly extensible to pop-ups and other areas that cannot be controlled by WebView
18 | - [x] Support for multiple rendering method
19 | - [x] ```HardwareBudder```: implemented using a low-level feature of Android. Best performance
20 | - [x] ```ByteBuffer```: Easy access to frames, since the results are obtained as byte arrays on the C# side. High stability. **This option is used by default**.
21 | - [x] ```Surface```: Direct rendering to Android's ```Surface``` class, used for active use of features such as [```CompositionLayers```](https://docs.unity3d.com/Packages/com.unity.xr.compositionlayers@0.5/manual/usage-guide.html)
22 |
23 | [Document is here](https://tlabgames.gitbook.io/tlabwebview)
24 | [Snippets is here](https://gist.github.com/TLabAltoh/e0512b3367c25d3e1ec28ddbe95da497#file-tlabwebview-snippets-md)
25 | [The Java plugin source code is here](https://github.com/TLabAltoh/TLabWebViewPlugin)
26 |
27 | [](https://www.buymeacoffee.com/tlabaltoh)
28 |
29 |
30 |
31 | ## Unity version this plugin supports
32 | - [x] Unity 2021
33 | - [x] Unity 2022
34 | - [x] Unity 6000 (Only `WebView` tested, Not yet tested in `GeckoView`.)
35 |
36 |
37 | ## Graphics api this plugin supports
38 | - [x] OpenGLES
39 | - [x] Vulkan
40 |
41 | ## Screenshot
42 | Screenshot run on Android 13, Adreno 619
43 |
44 |
45 |
46 | VR sample
47 |
48 |
49 | ## Operating Environment
50 |
51 | | | |
52 | | ----- | ------------------------ |
53 | | OS | Android 10 ~ 14 |
54 | | GPU | Qualcomm Adreno 505, 619 |
55 | | Unity | 2021.3 |
56 |
57 | ## Getting Started
58 |
59 | ### Requirements
60 | - [TLabVKeyborad](https://github.com/TLabAltoh/TLabVKeyborad) ```v1.0.1+```
61 |
62 | ### Installing
63 |
64 | Please see here
65 |
66 | #### Submodule
67 | Clone this repository with the following command
68 | ```
69 | git clone https://github.com/TLabAltoh/TLabWebView.git
70 | ```
71 | or
72 | ```
73 | git submodule add https://github.com/TLabAltoh/TLabWebView.git
74 | ```
75 |
76 | #### UPM
77 | ```add package from git URL ...```
78 | ```
79 | https://github.com/TLabAltoh/TLabWebView.git#upm
80 | ```
81 |
82 | #### For App-Store compatibility
83 | When you publishing your app that using this plugin. Sometimes you get bellow warning.
84 |
85 | > ### Unsafe SSL override in WebViews
86 | > Your application may contain an unsafe implementation of the WebView's [onReceivedSslError() method](https://www.oculus.com/lynx/?u=https%3A%2F%2Fdeveloper.android.com%2Freference%2Fandroid%2Fwebkit%2FWebViewClient.html%23onReceivedSslError(android.webkit.WebView%2C%2520android.webkit.SslErrorHandler%2C%2520android.net.http.SslError)&e=AT0HN6RWgLynCRtwcCSOzSVvlpMDUhi7C5saZwaY5p4unt4S4-GxIACJX_OPzTQp1Fn4oADk7Q_rwvZvRiF5XstftUzyuAWAolfkkk_WAtDpvOgW0Llcn_BXIEpgYobFNELMZ31ntKzTQXflaLkeRA) with a call to `handler.proceed() with insufficient validations. This may cause the WebView to ignore SSL certificate validation errors, making the application vulnerable to man-in-the-middle attacks.
87 | >
88 | > https://www.meta.com/experiences/
89 |
90 |
91 | > ### Security and trust
92 | > #### onReceivedSslError
93 | > your app is using an unsafe implementation of [```WebviewClient.onReceivedSslError```](https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedSslError(android.webkit.WebView,%20android.webkit.SslErrorHandler,%20android.net.http.SslError)) handler
94 | >
95 | > https://developer.android.com/distribute/console
96 |
97 | Than, please switch repository's branch to app store compatible version.
98 |
99 | ```add package from git URL ...```
100 | ```
101 | https://github.com/TLabAltoh/TLabWebView.git#appstore-compatible-upm
102 | ```
103 |
104 | Please note that this version will not be able to load insecure websites (URL starting with ```http://```).
105 |
106 |
107 |
108 | ### Set Up
109 |
110 | Please see here
111 |
112 | - Build Settings
113 |
114 | | Property | Value |
115 | | -------- | ------- |
116 | | Platform | Android |
117 |
118 | - Project Settings
119 |
120 | | Property | Value |
121 | | ----------------- | ------------------------------------- |
122 | | Color Space | Linear |
123 | | Minimum API Level | 26 |
124 | | Target API Level | 30 (Unity 2021), 31 ~ 32 (Unity 2022) |
125 |
126 | - Add the following symbols to Project Settings --> Player --> Other Settings (to be used at build time)
127 |
128 | ```
129 | UNITYWEBVIEW_ANDROID_USES_CLEARTEXT_TRAFFIC
130 | ```
131 | ```
132 | UNITYWEBVIEW_ANDROID_ENABLE_CAMERA
133 | ```
134 | ```
135 | UNITYWEBVIEW_ANDROID_ENABLE_MICROPHONE
136 | ```
137 |
138 | - Scene
139 |
140 | Please add the ```BrowserManager``` to any GameObject (maybe EventSystem is best).
141 |
142 | #### If you want to use ```GeckoView``` as a browser engine.
143 |
144 | Please create a Plugins folder in your Assets folder and create files in it. And please set the ```BrowserContainer.browser``` to ```GeckoView``` instead of ```WebView```. Also ```GeckoView``` needs Android ```13``` ~ (API level ```33``` ~). Please set tartget level to API level ```33``` in the ```Project Settings```.
145 |
146 | 1. gradleTemplate.properties
147 |
148 | ```properties
149 | org.gradle.jvmargs=-Xmx**JVM_HEAP_SIZE**M
150 | org.gradle.parallel=true
151 | # android.enableR8=**MINIFY_WITH_R_EIGHT**
152 | unityStreamingAssets=**STREAMING_ASSETS**
153 | **ADDITIONAL_PROPERTIES**
154 | android.useAndroidX=true
155 | # android.enableJetifier=true
156 | ```
157 |
158 | 2. mainTemplate.gradle
159 |
160 | ```gradle
161 | ...
162 |
163 | dependencies {
164 | implementation "androidx.annotation:annotation-jvm:1.9.1"
165 |
166 | def collection_version = "1.4.3"
167 | implementation "androidx.collection:collection:$collection_version"
168 |
169 | def lifecycle_version = "2.6.1"
170 | implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
171 | implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
172 | implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
173 | implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
174 | implementation "androidx.lifecycle:lifecycle-runtime-compose:$lifecycle_version"
175 | implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
176 | implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
177 | implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
178 | implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
179 | implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
180 | }
181 |
182 | ...
183 | ```
184 |
185 | 3. GeckoView plugin (```.aar```) (please install the [125.0.20240425211020 version](https://mvnrepository.com/artifact/org.mozilla.geckoview/geckoview/125.0.20240425211020), as this package is only developed and tested with it)
186 |
187 |
188 |
189 | ### Prefab
190 | Prefab is here. Just add prefab to the canvas to implement webview
191 | ```
192 | /Resources/TLab/WebView/Browser.prefab
193 | ```
194 |
195 | ### Keyborad
196 | By default, a virtual keyboard based on uGUI is available in this package. However, while the uGUI-based virtual keyboard has advantages in terms of extensibility of design, etc., there may be situations where you prefer to use the OS standard system keyboard. In such a case, please enable the system keyboard using permissions, etc. on the app side according to the settings of each platform (e.g., see [here](https://developers.meta.com/horizon/documentation/unity/unity-keyboard-overlay/) for settings on Meta Quest). Once the app has been configured, the system keyboard can be used in WebView.
197 |
198 | ##
199 | > [!NOTE]
200 | > If you want to download the file to external storage (like ```/Download```, ```/Picture```), please add the following permission to the manifest. This is required for Android 11+ (see [here](https://developer.android.com/training/data-storage/manage-all-files?hl=en) for more details).
201 | > ```.xml
202 | >
203 | > ```
204 |
205 | > [!WARNING]
206 | > Note that this plugin only works on Android devices; it will not display web pages when run on the Unity Editor.
207 |
208 | > [!WARNING]
209 | > `HardwareBuffer` mode may not work properly for some devices. In such cases, Please change the project's `Graphics API` from `Vulkan` to `OpenGLES` (Problems in `HardwareBuffer` mode are most often reported when using the `Vulkan` API in a project). Or switch `CaptureMode` from `HardwareBuffer` to `ByteBuffer` (This is a stable rendering option).
210 | >
211 | >
212 |
213 | > [!WARNING]
214 | > Android WebView doesn't support the [WebXR API](https://developer.mozilla.org/en-US/docs/Web/API/WebXR_Device_API/Fundamentals).
215 |
216 | > [!WARNING]
217 | > OculusQuest doesn't support some HTML5 input tags (see below). If you want to use them, please use ```GeckoView``` as ```Browser``` instead of ```WebView```. It will display a widget implemented by uGUI. Below is the status of HTML5 input tag support by this plugin's custom widget.
218 | >
219 | > - [x] [datetime-local](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local)
220 | > - [x] [date](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date)
221 | > - [x] [time](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/time)
222 | > - [x] [color](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/color)
223 | > - [ ] [week](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/week)
224 | > - [ ] [month](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/month)
225 | > - [ ] [image](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/image)
226 | > - [ ] [file](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file)
227 |
228 | > [!WARNING]
229 | > This plugin supports both ```Vulkan``` and ```OpenGLES```, but if you are building an application that uses a ```Vulkan``` graphics API, the Android device must support ```OpenGLES (3.1+)``` as well as ```Vulkan```.
230 |
231 |
--------------------------------------------------------------------------------
/README.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7f5779309827a6746bfb3c2cefbeb86c
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Resources.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5a7121755fc31864e860fc7593c48c8f
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Resources/TLab.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 82dacb2949de873498e00534e5bb060c
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8a7d4c8060ac1b746959cd465e0c79ca
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Browser.prefab.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: cf5767a7a6501d04fb202c6ed3ef427c
3 | PrefabImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 80c6abf5cb71ad74386217c65038910b
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Browser Sample.prefab.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4272bd6725bd64846b07be9b4d76ad90
3 | PrefabImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Scripts.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7932db4ef0752bb448b93699e3592c00
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Scripts/JS.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bb3df9691c09f0845a8fdcfb2ea54bcb
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Scripts/JS/disable-beforunload.txt:
--------------------------------------------------------------------------------
1 | const originalAddEventListener = window.addEventListener;
2 | window.addEventListener = function (type, listener, options) {
3 | if (type === 'beforeunload') {
4 | console.warn("Blocked a 'beforeunload' listener from being added.");
5 | return;
6 | }
7 | originalAddEventListener.call(this, type, listener, options);
8 | };
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Scripts/JS/disable-beforunload.txt.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 77170db0d6c43084ab19b7b12a55e1b2
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Scripts/JS/fetch-blob.txt:
--------------------------------------------------------------------------------
1 | function writeBuffer(buffer, bufferId, segmentSize, offset) {
2 | if (segmentSize === 0) return;
3 | var i = offset;
4 | while (i + segmentSize <= buffer.length) {
5 | window.tlab.write(bufferId, buffer.slice(i, i + segmentSize));
6 | i += segmentSize
7 | }
8 | writeBuffer(buffer, bufferId, parseInt(segmentSize / 2), i);
9 | }
10 | var xhr = new XMLHttpRequest();
11 | xhr.open("GET", url, true);
12 | xhr.setRequestHeader("Content-type", mimetype + ";charset=UTF-8");
13 | xhr.responseType = "blob";
14 | xhr.onload = function (e) {
15 | if (this.status == 200) {
16 | var blobFile = this.response;
17 | var reader = new FileReader();
18 | reader.readAsDataURL(blobFile);
19 | reader.onloadend = function () {
20 | base64data = reader.result;
21 | bufferId = url;
22 | buffer = new TextEncoder().encode(base64data);
23 | window.tlab.malloc(bufferId, buffer.length);
24 | writeBuffer(buffer, bufferId, 500000, 0);
25 | window.tlab.unitySendMessage(go, method, argments);
26 | }
27 | }
28 | };
29 | xhr.send();
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Scripts/JS/fetch-blob.txt.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b4964ae62ac4eb34ca2ad1e4b2801896
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Scripts/JS/focus-in-out-interaction.txt:
--------------------------------------------------------------------------------
1 | function searchShadowRoot(node, roots) {
2 | if (node == null) {
3 | return;
4 | }
5 | if (node.shadowRoot != undefined && node.shadowRoot != null) {
6 | roots.push(node.shadowRoot);
7 | searchShadowRoot(node.shadowRoot, roots);
8 | }
9 | for (var i = 0; i < node.childNodes.length; i++) {
10 | searchShadowRoot(node.childNodes[i], roots);
11 | }
12 | }
13 |
14 | function getAllRoot() {
15 | var roots = [document];
16 | searchShadowRoot(document, roots);
17 | return roots;
18 | }
19 |
20 | var roots = getAllRoot();
21 |
22 | function focusin (e) {
23 | const target = e.target;
24 | if (target.tagName == 'INPUT' || target.tagName == 'TEXTAREA') {
25 | window.tlab.unitySendMessage(go, method, 'Focusin');
26 | }
27 | }
28 |
29 | function focusout (e) {
30 | const target = e.target;
31 | if (target.tagName == 'INPUT' || target.tagName == 'TEXTAREA') {
32 | window.tlab.unitySendMessage(go, method, 'Focusout');
33 | }
34 | }
35 |
36 | for (var i = 0; i < roots.length; i++) {
37 | roots[i].removeEventListener('focusin', focusin);
38 | roots[i].removeEventListener('focusout', focusout);
39 |
40 | roots[i].addEventListener('focusin', focusin);
41 | roots[i].addEventListener('focusout', focusout);
42 | }
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Scripts/JS/focus-in-out-interaction.txt.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8c945e4fa883ec548a91eba33e462a5c
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Widget.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f37fc890ddb3fdb4b980c8d9512f5792
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Widget/Dialog.prefab.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 413d4daf4d477ed47b66a273dc2937b0
3 | PrefabImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Widget/Number Picker.prefab.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6940f93adaa13ac4192b8da573396f85
3 | PrefabImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Widget/Select.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 61db13b0f91a53f49993cc1e89bf636e
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Widget/Select/Group.prefab:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1 &1264867841882999603
4 | GameObject:
5 | m_ObjectHideFlags: 0
6 | m_CorrespondingSourceObject: {fileID: 0}
7 | m_PrefabInstance: {fileID: 0}
8 | m_PrefabAsset: {fileID: 0}
9 | serializedVersion: 6
10 | m_Component:
11 | - component: {fileID: 2526483044092763727}
12 | - component: {fileID: 5319220898759178625}
13 | - component: {fileID: 2800390673303244714}
14 | m_Layer: 0
15 | m_Name: Text (TMP)
16 | m_TagString: Untagged
17 | m_Icon: {fileID: 0}
18 | m_NavMeshLayer: 0
19 | m_StaticEditorFlags: 0
20 | m_IsActive: 1
21 | --- !u!224 &2526483044092763727
22 | RectTransform:
23 | m_ObjectHideFlags: 0
24 | m_CorrespondingSourceObject: {fileID: 0}
25 | m_PrefabInstance: {fileID: 0}
26 | m_PrefabAsset: {fileID: 0}
27 | m_GameObject: {fileID: 1264867841882999603}
28 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
29 | m_LocalPosition: {x: 0, y: 0, z: 0}
30 | m_LocalScale: {x: 1, y: 1, z: 1}
31 | m_ConstrainProportionsScale: 0
32 | m_Children: []
33 | m_Father: {fileID: 6541164512831261800}
34 | m_RootOrder: 0
35 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
36 | m_AnchorMin: {x: 0, y: 0}
37 | m_AnchorMax: {x: 1, y: 1}
38 | m_AnchoredPosition: {x: 0, y: 0}
39 | m_SizeDelta: {x: -6, y: -6}
40 | m_Pivot: {x: 0.5, y: 0.5}
41 | --- !u!222 &5319220898759178625
42 | CanvasRenderer:
43 | m_ObjectHideFlags: 0
44 | m_CorrespondingSourceObject: {fileID: 0}
45 | m_PrefabInstance: {fileID: 0}
46 | m_PrefabAsset: {fileID: 0}
47 | m_GameObject: {fileID: 1264867841882999603}
48 | m_CullTransparentMesh: 1
49 | --- !u!114 &2800390673303244714
50 | MonoBehaviour:
51 | m_ObjectHideFlags: 0
52 | m_CorrespondingSourceObject: {fileID: 0}
53 | m_PrefabInstance: {fileID: 0}
54 | m_PrefabAsset: {fileID: 0}
55 | m_GameObject: {fileID: 1264867841882999603}
56 | m_Enabled: 1
57 | m_EditorHideFlags: 0
58 | m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
59 | m_Name:
60 | m_EditorClassIdentifier:
61 | m_Material: {fileID: 0}
62 | m_Color: {r: 1, g: 1, b: 1, a: 1}
63 | m_RaycastTarget: 1
64 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
65 | m_Maskable: 1
66 | m_OnCullStateChanged:
67 | m_PersistentCalls:
68 | m_Calls: []
69 | m_text: Text ...
70 | m_isRightToLeft: 0
71 | m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
72 | m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
73 | m_fontSharedMaterials: []
74 | m_fontMaterial: {fileID: 0}
75 | m_fontMaterials: []
76 | m_fontColor32:
77 | serializedVersion: 2
78 | rgba: 4278190080
79 | m_fontColor: {r: 0, g: 0, b: 0, a: 1}
80 | m_enableVertexGradient: 0
81 | m_colorMode: 3
82 | m_fontColorGradient:
83 | topLeft: {r: 1, g: 1, b: 1, a: 1}
84 | topRight: {r: 1, g: 1, b: 1, a: 1}
85 | bottomLeft: {r: 1, g: 1, b: 1, a: 1}
86 | bottomRight: {r: 1, g: 1, b: 1, a: 1}
87 | m_fontColorGradientPreset: {fileID: 0}
88 | m_spriteAsset: {fileID: 0}
89 | m_tintAllSprites: 0
90 | m_StyleSheet: {fileID: 0}
91 | m_TextStyleHashCode: -1183493901
92 | m_overrideHtmlColors: 0
93 | m_faceColor:
94 | serializedVersion: 2
95 | rgba: 4294967295
96 | m_fontSize: 30
97 | m_fontSizeBase: 30
98 | m_fontWeight: 400
99 | m_enableAutoSizing: 0
100 | m_fontSizeMin: 18
101 | m_fontSizeMax: 72
102 | m_fontStyle: 0
103 | m_HorizontalAlignment: 1
104 | m_VerticalAlignment: 512
105 | m_textAlignment: 65535
106 | m_characterSpacing: 0
107 | m_wordSpacing: 0
108 | m_lineSpacing: 0
109 | m_lineSpacingMax: 0
110 | m_paragraphSpacing: 0
111 | m_charWidthMaxAdj: 0
112 | m_enableWordWrapping: 1
113 | m_wordWrappingRatios: 0.4
114 | m_overflowMode: 1
115 | m_linkedTextComponent: {fileID: 0}
116 | parentLinkedComponent: {fileID: 0}
117 | m_enableKerning: 1
118 | m_enableExtraPadding: 0
119 | checkPaddingRequired: 0
120 | m_isRichText: 1
121 | m_parseCtrlCharacters: 1
122 | m_isOrthographic: 1
123 | m_isCullingEnabled: 0
124 | m_horizontalMapping: 0
125 | m_verticalMapping: 0
126 | m_uvLineOffset: 0
127 | m_geometrySortingOrder: 0
128 | m_IsTextObjectScaleStatic: 0
129 | m_VertexBufferAutoSizeReduction: 0
130 | m_useMaxVisibleDescender: 1
131 | m_pageToDisplay: 1
132 | m_margin: {x: 0, y: 0, z: 0, w: 0}
133 | m_isUsingLegacyAnimationComponent: 0
134 | m_isVolumetricText: 0
135 | m_hasFontAssetChanged: 0
136 | m_baseMaterial: {fileID: 0}
137 | m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
138 | --- !u!1 &1651959583725008689
139 | GameObject:
140 | m_ObjectHideFlags: 0
141 | m_CorrespondingSourceObject: {fileID: 0}
142 | m_PrefabInstance: {fileID: 0}
143 | m_PrefabAsset: {fileID: 0}
144 | serializedVersion: 6
145 | m_Component:
146 | - component: {fileID: 6541164512831261800}
147 | - component: {fileID: 6235827200066371057}
148 | - component: {fileID: 4229614656884787150}
149 | m_Layer: 0
150 | m_Name: Group
151 | m_TagString: Untagged
152 | m_Icon: {fileID: 0}
153 | m_NavMeshLayer: 0
154 | m_StaticEditorFlags: 0
155 | m_IsActive: 1
156 | --- !u!224 &6541164512831261800
157 | RectTransform:
158 | m_ObjectHideFlags: 0
159 | m_CorrespondingSourceObject: {fileID: 0}
160 | m_PrefabInstance: {fileID: 0}
161 | m_PrefabAsset: {fileID: 0}
162 | m_GameObject: {fileID: 1651959583725008689}
163 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
164 | m_LocalPosition: {x: 0, y: 0, z: 0}
165 | m_LocalScale: {x: 1, y: 1, z: 1}
166 | m_ConstrainProportionsScale: 0
167 | m_Children:
168 | - {fileID: 2526483044092763727}
169 | m_Father: {fileID: 0}
170 | m_RootOrder: 0
171 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
172 | m_AnchorMin: {x: 0, y: 0}
173 | m_AnchorMax: {x: 0, y: 0}
174 | m_AnchoredPosition: {x: 0, y: 0}
175 | m_SizeDelta: {x: 500, y: 55}
176 | m_Pivot: {x: 0.5, y: 0.5}
177 | --- !u!222 &6235827200066371057
178 | CanvasRenderer:
179 | m_ObjectHideFlags: 0
180 | m_CorrespondingSourceObject: {fileID: 0}
181 | m_PrefabInstance: {fileID: 0}
182 | m_PrefabAsset: {fileID: 0}
183 | m_GameObject: {fileID: 1651959583725008689}
184 | m_CullTransparentMesh: 1
185 | --- !u!114 &4229614656884787150
186 | MonoBehaviour:
187 | m_ObjectHideFlags: 0
188 | m_CorrespondingSourceObject: {fileID: 0}
189 | m_PrefabInstance: {fileID: 0}
190 | m_PrefabAsset: {fileID: 0}
191 | m_GameObject: {fileID: 1651959583725008689}
192 | m_Enabled: 1
193 | m_EditorHideFlags: 0
194 | m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
195 | m_Name:
196 | m_EditorClassIdentifier:
197 | m_Material: {fileID: 0}
198 | m_Color: {r: 1, g: 1, b: 1, a: 0.392}
199 | m_RaycastTarget: 1
200 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
201 | m_Maskable: 1
202 | m_OnCullStateChanged:
203 | m_PersistentCalls:
204 | m_Calls: []
205 | m_Sprite: {fileID: 0}
206 | m_Type: 1
207 | m_PreserveAspect: 0
208 | m_FillCenter: 1
209 | m_FillMethod: 4
210 | m_FillAmount: 1
211 | m_FillClockwise: 1
212 | m_FillOrigin: 0
213 | m_UseSpriteMesh: 0
214 | m_PixelsPerUnitMultiplier: 1
215 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Widget/Select/Group.prefab.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 373e78f16f78cfc4fb6c44f30db601b0
3 | PrefabImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Widget/Select/Selectable.prefab:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1 &5213916560862622005
4 | GameObject:
5 | m_ObjectHideFlags: 0
6 | m_CorrespondingSourceObject: {fileID: 0}
7 | m_PrefabInstance: {fileID: 0}
8 | m_PrefabAsset: {fileID: 0}
9 | serializedVersion: 6
10 | m_Component:
11 | - component: {fileID: 8852358417840088137}
12 | - component: {fileID: 1155051106320089991}
13 | - component: {fileID: 9154348682113512876}
14 | m_Layer: 0
15 | m_Name: Text (TMP)
16 | m_TagString: Untagged
17 | m_Icon: {fileID: 0}
18 | m_NavMeshLayer: 0
19 | m_StaticEditorFlags: 0
20 | m_IsActive: 1
21 | --- !u!224 &8852358417840088137
22 | RectTransform:
23 | m_ObjectHideFlags: 0
24 | m_CorrespondingSourceObject: {fileID: 0}
25 | m_PrefabInstance: {fileID: 0}
26 | m_PrefabAsset: {fileID: 0}
27 | m_GameObject: {fileID: 5213916560862622005}
28 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
29 | m_LocalPosition: {x: 0, y: 0, z: 0}
30 | m_LocalScale: {x: 1, y: 1, z: 1}
31 | m_ConstrainProportionsScale: 0
32 | m_Children: []
33 | m_Father: {fileID: 220915606408181358}
34 | m_RootOrder: 0
35 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
36 | m_AnchorMin: {x: 0, y: 0}
37 | m_AnchorMax: {x: 1, y: 1}
38 | m_AnchoredPosition: {x: 0, y: 0}
39 | m_SizeDelta: {x: -6, y: -6}
40 | m_Pivot: {x: 0.5, y: 0.5}
41 | --- !u!222 &1155051106320089991
42 | CanvasRenderer:
43 | m_ObjectHideFlags: 0
44 | m_CorrespondingSourceObject: {fileID: 0}
45 | m_PrefabInstance: {fileID: 0}
46 | m_PrefabAsset: {fileID: 0}
47 | m_GameObject: {fileID: 5213916560862622005}
48 | m_CullTransparentMesh: 1
49 | --- !u!114 &9154348682113512876
50 | MonoBehaviour:
51 | m_ObjectHideFlags: 0
52 | m_CorrespondingSourceObject: {fileID: 0}
53 | m_PrefabInstance: {fileID: 0}
54 | m_PrefabAsset: {fileID: 0}
55 | m_GameObject: {fileID: 5213916560862622005}
56 | m_Enabled: 1
57 | m_EditorHideFlags: 0
58 | m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
59 | m_Name:
60 | m_EditorClassIdentifier:
61 | m_Material: {fileID: 0}
62 | m_Color: {r: 1, g: 1, b: 1, a: 1}
63 | m_RaycastTarget: 1
64 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
65 | m_Maskable: 1
66 | m_OnCullStateChanged:
67 | m_PersistentCalls:
68 | m_Calls: []
69 | m_text: Text ...
70 | m_isRightToLeft: 0
71 | m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
72 | m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
73 | m_fontSharedMaterials: []
74 | m_fontMaterial: {fileID: 0}
75 | m_fontMaterials: []
76 | m_fontColor32:
77 | serializedVersion: 2
78 | rgba: 4278190080
79 | m_fontColor: {r: 0, g: 0, b: 0, a: 1}
80 | m_enableVertexGradient: 0
81 | m_colorMode: 3
82 | m_fontColorGradient:
83 | topLeft: {r: 1, g: 1, b: 1, a: 1}
84 | topRight: {r: 1, g: 1, b: 1, a: 1}
85 | bottomLeft: {r: 1, g: 1, b: 1, a: 1}
86 | bottomRight: {r: 1, g: 1, b: 1, a: 1}
87 | m_fontColorGradientPreset: {fileID: 0}
88 | m_spriteAsset: {fileID: 0}
89 | m_tintAllSprites: 0
90 | m_StyleSheet: {fileID: 0}
91 | m_TextStyleHashCode: -1183493901
92 | m_overrideHtmlColors: 0
93 | m_faceColor:
94 | serializedVersion: 2
95 | rgba: 4294967295
96 | m_fontSize: 30
97 | m_fontSizeBase: 30
98 | m_fontWeight: 400
99 | m_enableAutoSizing: 0
100 | m_fontSizeMin: 18
101 | m_fontSizeMax: 72
102 | m_fontStyle: 0
103 | m_HorizontalAlignment: 1
104 | m_VerticalAlignment: 512
105 | m_textAlignment: 65535
106 | m_characterSpacing: 0
107 | m_wordSpacing: 0
108 | m_lineSpacing: 0
109 | m_lineSpacingMax: 0
110 | m_paragraphSpacing: 0
111 | m_charWidthMaxAdj: 0
112 | m_enableWordWrapping: 1
113 | m_wordWrappingRatios: 0.4
114 | m_overflowMode: 1
115 | m_linkedTextComponent: {fileID: 0}
116 | parentLinkedComponent: {fileID: 0}
117 | m_enableKerning: 1
118 | m_enableExtraPadding: 0
119 | checkPaddingRequired: 0
120 | m_isRichText: 1
121 | m_parseCtrlCharacters: 1
122 | m_isOrthographic: 1
123 | m_isCullingEnabled: 0
124 | m_horizontalMapping: 0
125 | m_verticalMapping: 0
126 | m_uvLineOffset: 0
127 | m_geometrySortingOrder: 0
128 | m_IsTextObjectScaleStatic: 0
129 | m_VertexBufferAutoSizeReduction: 0
130 | m_useMaxVisibleDescender: 1
131 | m_pageToDisplay: 1
132 | m_margin: {x: 0, y: 0, z: 0, w: 0}
133 | m_isUsingLegacyAnimationComponent: 0
134 | m_isVolumetricText: 0
135 | m_hasFontAssetChanged: 0
136 | m_baseMaterial: {fileID: 0}
137 | m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
138 | --- !u!1 &5709099332327001399
139 | GameObject:
140 | m_ObjectHideFlags: 0
141 | m_CorrespondingSourceObject: {fileID: 0}
142 | m_PrefabInstance: {fileID: 0}
143 | m_PrefabAsset: {fileID: 0}
144 | serializedVersion: 6
145 | m_Component:
146 | - component: {fileID: 220915606408181358}
147 | - component: {fileID: 1106794971665713143}
148 | - component: {fileID: 7162034007823695304}
149 | - component: {fileID: 4919607304810742064}
150 | m_Layer: 0
151 | m_Name: Selectable
152 | m_TagString: Untagged
153 | m_Icon: {fileID: 0}
154 | m_NavMeshLayer: 0
155 | m_StaticEditorFlags: 0
156 | m_IsActive: 1
157 | --- !u!224 &220915606408181358
158 | RectTransform:
159 | m_ObjectHideFlags: 0
160 | m_CorrespondingSourceObject: {fileID: 0}
161 | m_PrefabInstance: {fileID: 0}
162 | m_PrefabAsset: {fileID: 0}
163 | m_GameObject: {fileID: 5709099332327001399}
164 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
165 | m_LocalPosition: {x: 0, y: 0, z: 0}
166 | m_LocalScale: {x: 1, y: 1, z: 1}
167 | m_ConstrainProportionsScale: 0
168 | m_Children:
169 | - {fileID: 8852358417840088137}
170 | m_Father: {fileID: 0}
171 | m_RootOrder: 0
172 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
173 | m_AnchorMin: {x: 0, y: 0}
174 | m_AnchorMax: {x: 0, y: 0}
175 | m_AnchoredPosition: {x: 0, y: 0}
176 | m_SizeDelta: {x: 500, y: 55}
177 | m_Pivot: {x: 0.5, y: 0.5}
178 | --- !u!222 &1106794971665713143
179 | CanvasRenderer:
180 | m_ObjectHideFlags: 0
181 | m_CorrespondingSourceObject: {fileID: 0}
182 | m_PrefabInstance: {fileID: 0}
183 | m_PrefabAsset: {fileID: 0}
184 | m_GameObject: {fileID: 5709099332327001399}
185 | m_CullTransparentMesh: 1
186 | --- !u!114 &7162034007823695304
187 | MonoBehaviour:
188 | m_ObjectHideFlags: 0
189 | m_CorrespondingSourceObject: {fileID: 0}
190 | m_PrefabInstance: {fileID: 0}
191 | m_PrefabAsset: {fileID: 0}
192 | m_GameObject: {fileID: 5709099332327001399}
193 | m_Enabled: 1
194 | m_EditorHideFlags: 0
195 | m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
196 | m_Name:
197 | m_EditorClassIdentifier:
198 | m_Material: {fileID: 0}
199 | m_Color: {r: 1, g: 1, b: 1, a: 0.392}
200 | m_RaycastTarget: 1
201 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
202 | m_Maskable: 1
203 | m_OnCullStateChanged:
204 | m_PersistentCalls:
205 | m_Calls: []
206 | m_Sprite: {fileID: 0}
207 | m_Type: 1
208 | m_PreserveAspect: 0
209 | m_FillCenter: 1
210 | m_FillMethod: 4
211 | m_FillAmount: 1
212 | m_FillClockwise: 1
213 | m_FillOrigin: 0
214 | m_UseSpriteMesh: 0
215 | m_PixelsPerUnitMultiplier: 1
216 | --- !u!114 &4919607304810742064
217 | MonoBehaviour:
218 | m_ObjectHideFlags: 0
219 | m_CorrespondingSourceObject: {fileID: 0}
220 | m_PrefabInstance: {fileID: 0}
221 | m_PrefabAsset: {fileID: 0}
222 | m_GameObject: {fileID: 5709099332327001399}
223 | m_Enabled: 1
224 | m_EditorHideFlags: 0
225 | m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
226 | m_Name:
227 | m_EditorClassIdentifier:
228 | m_Navigation:
229 | m_Mode: 3
230 | m_WrapAround: 0
231 | m_SelectOnUp: {fileID: 0}
232 | m_SelectOnDown: {fileID: 0}
233 | m_SelectOnLeft: {fileID: 0}
234 | m_SelectOnRight: {fileID: 0}
235 | m_Transition: 1
236 | m_Colors:
237 | m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
238 | m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
239 | m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
240 | m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
241 | m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
242 | m_ColorMultiplier: 1
243 | m_FadeDuration: 0.1
244 | m_SpriteState:
245 | m_HighlightedSprite: {fileID: 0}
246 | m_PressedSprite: {fileID: 0}
247 | m_SelectedSprite: {fileID: 0}
248 | m_DisabledSprite: {fileID: 0}
249 | m_AnimationTriggers:
250 | m_NormalTrigger: Normal
251 | m_HighlightedTrigger: Highlighted
252 | m_PressedTrigger: Pressed
253 | m_SelectedTrigger: Selected
254 | m_DisabledTrigger: Disabled
255 | m_Interactable: 1
256 | m_TargetGraphic: {fileID: 7162034007823695304}
257 | m_OnClick:
258 | m_PersistentCalls:
259 | m_Calls: []
260 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Widget/Select/Selectable.prefab.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 49e4bf32b87812e4aa4a235ce4caa5f8
3 | PrefabImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Widget/Select/Separator.prefab:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1 &314910016294810781
4 | GameObject:
5 | m_ObjectHideFlags: 0
6 | m_CorrespondingSourceObject: {fileID: 0}
7 | m_PrefabInstance: {fileID: 0}
8 | m_PrefabAsset: {fileID: 0}
9 | serializedVersion: 6
10 | m_Component:
11 | - component: {fileID: 2082981106636589263}
12 | - component: {fileID: 7498795620532289602}
13 | - component: {fileID: 8418542230732811784}
14 | - component: {fileID: 649669995515007034}
15 | m_Layer: 0
16 | m_Name: Separator
17 | m_TagString: Untagged
18 | m_Icon: {fileID: 0}
19 | m_NavMeshLayer: 0
20 | m_StaticEditorFlags: 0
21 | m_IsActive: 1
22 | --- !u!224 &2082981106636589263
23 | RectTransform:
24 | m_ObjectHideFlags: 0
25 | m_CorrespondingSourceObject: {fileID: 0}
26 | m_PrefabInstance: {fileID: 0}
27 | m_PrefabAsset: {fileID: 0}
28 | m_GameObject: {fileID: 314910016294810781}
29 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
30 | m_LocalPosition: {x: 0, y: 0, z: 0}
31 | m_LocalScale: {x: 1, y: 1, z: 1}
32 | m_ConstrainProportionsScale: 0
33 | m_Children: []
34 | m_Father: {fileID: 0}
35 | m_RootOrder: 0
36 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
37 | m_AnchorMin: {x: 0, y: 0}
38 | m_AnchorMax: {x: 0, y: 0}
39 | m_AnchoredPosition: {x: 0, y: 0}
40 | m_SizeDelta: {x: 500, y: 9.484}
41 | m_Pivot: {x: 0.5, y: 0.5}
42 | --- !u!222 &7498795620532289602
43 | CanvasRenderer:
44 | m_ObjectHideFlags: 0
45 | m_CorrespondingSourceObject: {fileID: 0}
46 | m_PrefabInstance: {fileID: 0}
47 | m_PrefabAsset: {fileID: 0}
48 | m_GameObject: {fileID: 314910016294810781}
49 | m_CullTransparentMesh: 1
50 | --- !u!114 &8418542230732811784
51 | MonoBehaviour:
52 | m_ObjectHideFlags: 0
53 | m_CorrespondingSourceObject: {fileID: 0}
54 | m_PrefabInstance: {fileID: 0}
55 | m_PrefabAsset: {fileID: 0}
56 | m_GameObject: {fileID: 314910016294810781}
57 | m_Enabled: 1
58 | m_EditorHideFlags: 0
59 | m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
60 | m_Name:
61 | m_EditorClassIdentifier:
62 | m_Material: {fileID: 0}
63 | m_Color: {r: 0, g: 0, b: 0, a: 0.392}
64 | m_RaycastTarget: 1
65 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
66 | m_Maskable: 1
67 | m_OnCullStateChanged:
68 | m_PersistentCalls:
69 | m_Calls: []
70 | m_Sprite: {fileID: 0}
71 | m_Type: 1
72 | m_PreserveAspect: 0
73 | m_FillCenter: 1
74 | m_FillMethod: 4
75 | m_FillAmount: 1
76 | m_FillClockwise: 1
77 | m_FillOrigin: 0
78 | m_UseSpriteMesh: 0
79 | m_PixelsPerUnitMultiplier: 1
80 | --- !u!114 &649669995515007034
81 | MonoBehaviour:
82 | m_ObjectHideFlags: 0
83 | m_CorrespondingSourceObject: {fileID: 0}
84 | m_PrefabInstance: {fileID: 0}
85 | m_PrefabAsset: {fileID: 0}
86 | m_GameObject: {fileID: 314910016294810781}
87 | m_Enabled: 1
88 | m_EditorHideFlags: 0
89 | m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
90 | m_Name:
91 | m_EditorClassIdentifier:
92 | m_Navigation:
93 | m_Mode: 3
94 | m_WrapAround: 0
95 | m_SelectOnUp: {fileID: 0}
96 | m_SelectOnDown: {fileID: 0}
97 | m_SelectOnLeft: {fileID: 0}
98 | m_SelectOnRight: {fileID: 0}
99 | m_Transition: 1
100 | m_Colors:
101 | m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
102 | m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
103 | m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
104 | m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
105 | m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
106 | m_ColorMultiplier: 1
107 | m_FadeDuration: 0.1
108 | m_SpriteState:
109 | m_HighlightedSprite: {fileID: 0}
110 | m_PressedSprite: {fileID: 0}
111 | m_SelectedSprite: {fileID: 0}
112 | m_DisabledSprite: {fileID: 0}
113 | m_AnimationTriggers:
114 | m_NormalTrigger: Normal
115 | m_HighlightedTrigger: Highlighted
116 | m_PressedTrigger: Pressed
117 | m_SelectedTrigger: Selected
118 | m_DisabledTrigger: Disabled
119 | m_Interactable: 1
120 | m_TargetGraphic: {fileID: 8418542230732811784}
121 | m_OnClick:
122 | m_PersistentCalls:
123 | m_Calls: []
124 |
--------------------------------------------------------------------------------
/Resources/TLab/WebView/Samples/Widget/Select/Separator.prefab.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 046a49799505c2545a7e739e63a2f896
3 | PrefabImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Runtime.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0d1f0038cc22a3a46837eb43a8f33999
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime/BaseInputListener.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using UnityEngine.EventSystems;
3 |
4 | namespace TLab.WebView
5 | {
6 | public abstract class BaseInputListener : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler, IPointerExitHandler
7 | {
8 | private bool m_pointerDown = false;
9 | private int? m_pointerId = null;
10 | private RenderMode m_renderMode;
11 | private Vector2 m_current;
12 | private Vector2 m_prev;
13 |
14 | private InputEventData m_inputEventData = new InputEventData();
15 |
16 | private string THIS_NAME => "[" + this.GetType() + "] ";
17 |
18 | public class InputEventData
19 | {
20 | public Vector2 position;
21 | public Vector2 delta;
22 |
23 | public InputEventData(Vector2 position, Vector2 delta) => Update(position, delta);
24 |
25 | public InputEventData() { }
26 |
27 | public void Update(Vector2 position, Vector2 delta)
28 | {
29 | this.position = position;
30 | this.delta = delta;
31 | }
32 | }
33 |
34 | protected bool GetInputPosition(PointerEventData eventData)
35 | {
36 | m_prev = m_current;
37 |
38 | var localPosition = Vector2.zero;
39 |
40 | var rectTransform = (RectTransform)transform;
41 |
42 | switch (m_renderMode)
43 | {
44 | case RenderMode.ScreenSpaceOverlay:
45 | localPosition = transform.InverseTransformPoint(eventData.position);
46 | break;
47 | case RenderMode.ScreenSpaceCamera:
48 | case RenderMode.WorldSpace:
49 | RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out localPosition);
50 | break;
51 | }
52 |
53 | var x = localPosition.x / rectTransform.rect.width + rectTransform.pivot.x;
54 | var y = 1f - (localPosition.y / rectTransform.rect.height + rectTransform.pivot.y);
55 |
56 | if (Range(x, 0, 1) && Range(y, 0, 1))
57 | {
58 | m_current = new Vector2(x, y);
59 |
60 | return true;
61 | }
62 |
63 | m_current = Vector2.zero;
64 |
65 | return false;
66 | }
67 |
68 | protected abstract void OnPointerDown(PointerEventData pointerEventData, InputEventData inputEventData);
69 |
70 | public void OnPointerDown(PointerEventData eventData)
71 | {
72 | if (m_pointerId == null && !m_pointerDown && GetInputPosition(eventData))
73 | {
74 | m_pointerId = eventData.pointerId;
75 |
76 | m_inputEventData.Update(m_current, Vector2.zero);
77 | OnPointerDown(eventData, m_inputEventData);
78 |
79 | m_pointerDown = true;
80 | }
81 | }
82 |
83 | protected abstract void OnDrag(PointerEventData pointerEventData, InputEventData inputEventData);
84 |
85 | public void OnDrag(PointerEventData eventData)
86 | {
87 | if ((m_pointerId == eventData.pointerId) && m_pointerDown && GetInputPosition(eventData))
88 | {
89 | m_inputEventData.Update(m_current, m_current - m_prev);
90 | OnDrag(eventData, m_inputEventData);
91 | }
92 | }
93 |
94 | protected abstract void OnPointerUp(PointerEventData pointerEventData, InputEventData inputEventData);
95 |
96 | public void OnPointerUp(PointerEventData eventData)
97 | {
98 | if ((m_pointerId == eventData.pointerId) && m_pointerDown && GetInputPosition(eventData))
99 | {
100 | m_inputEventData.Update(m_current, m_current - m_prev);
101 | OnPointerUp(eventData, m_inputEventData);
102 |
103 | m_pointerId = null;
104 |
105 | m_pointerDown = false;
106 | }
107 | }
108 |
109 | protected abstract void OnPointerExit(PointerEventData pointerEventData, InputEventData inputEventData);
110 |
111 | public void OnPointerExit(PointerEventData eventData)
112 | {
113 | if ((m_pointerId == eventData.pointerId) && m_pointerDown)
114 | {
115 | m_inputEventData.Update(m_current, m_current - m_prev);
116 | OnPointerExit(eventData, m_inputEventData);
117 |
118 | m_pointerId = null;
119 |
120 | m_pointerDown = false;
121 | }
122 | }
123 |
124 | protected virtual void OnEnable()
125 | {
126 | var canvas = GetComponentInParent