最近项目需求,要用Unity打包成WebGL网页版,我在此简单说下遇到的坑!!!,本人用的是2018.3.0f2版本 1.字体问题 引擎自带的字体,打包之后,在网页上是显示不出来的,此时需要我们导入一个新字体样式即可解决 2.材质问题 如果在场景中或者脚本中使用了自定义的Shader,这时我们在打包之前,把这个Shader添加到Graphics设置中,如下图所示: 3.UI布局问题 个人建议:我们在做UI锚点选择时,尽量选择统一,不要出现一套UI界面上多个锚点定位的问题,要不然我们在自适应窗口化时,有的UI会重叠到一起,影响视觉效果 4.输入不了中文问题 打包后,我们会发现输入不了中文,What?,是不是很奔溃?不过在我的执着的小心脏面前,它屈服了. 下面是我的解决办法: 4.1第一步
var WebGLInputField = {
ShowInputFieldDialog:function(defaultValue){
try {
defaultValue = Pointer_stringify(defaultValue);
} catch (e) {
alert(e);
return;
}
if(!document.getElementById("nativeInputDialog")) {
var element = document.createElement('div');
var html = '<div id="nativeInputDialog" style="background:transparent; width:0%; height:0%; margin: 0; padding: 0; position: absolute; z-index:888;">' +
'<input id="nativeInputDialogInput" type="text" style="border: none; background: none; width:0; height:0;left: 0; top:0;color: white; outline: none; display: block; position: relative; font-size: 10px; ">' +
'</div>';
element.innerHTML = html;
document.body.appendChild(element);
var m_nativeInputDialogInput = document.getElementById("nativeInputDialogInput");
m_nativeInputDialogInput.onkeypress = function (event) {
if (event.keyCode == 13) {
document.getElementById("nativeInputDialog").style.display="none";
}
};
document.onmousemove=function(event){
event = event||window.event;
document.getElementById("nativeInputDialog").style.left = event.clientX + 'px';
document.getElementById("nativeInputDialog").style.top = event.clientY + 20 + 'px';
}
}
var m_nativeInputDialog = document.getElementById("nativeInputDialogInput");
m_nativeInputDialog.value = defaultValue;
document.getElementById("nativeInputDialog").style.display="";
document.getElementById("nativeInputDialogInput").focus();
},
HideInputFieldDialog :function(){
document.getElementById("nativeInputDialog").style.display="none";
},
IsInputFieldDialogActive:function(){
var nativeDialog = document.getElementById("nativeInputDialog" );
if(!nativeDialog ){
return false;
}
return ( nativeDialog.style.display != 'none' );
},
GetInputFieldValue:function(){
var elem = document.getElementById("nativeInputDialogInput");
var returnStr = elem.value;
var bufferSize = lengthBytesUTF8(returnStr) + 1;
var buffer = _malloc(bufferSize);
stringToUTF8(returnStr, buffer, bufferSize);
return buffer;
},
GetInputFieldCursortPosition:function () {
var dialog = document.getElementById("nativeInputDialogInput");
var index = dialog.selectionStart;
return index;
},
GetInputFieldCursortFocusPosition:function () {
var dialog = document.getElementById("nativeInputDialogInput");
var index = dialog.selectionEnd;
return index;
},
SetInputFieldCursortPosition:function (selectionStart,selectionEnd) {
var elem = document.getElementById("nativeInputDialogInput");
var val = elem.value
var len = val.length
if (len < selectionStart || len < selectionEnd) return;
setTimeout(function() {
elem.focus()
if (elem.setSelectionRange) {
elem.setSelectionRange(selectionStart, selectionEnd);
}
}, 10)
}
};
mergeInto(LibraryManager.library , WebGLInputField );
以上代码以 .jslib 结尾保存,放到Plugins文件夹下 4.2 第二步
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Runtime.InteropServices;
using System;
public class WebGLInputField : InputField
{
#if UNITY_WEBGL && !UNITY_EDITOR
[DllImport("__Internal")]
private static extern void ShowInputFieldDialog(string text);
[DllImport("__Internal")]
private static extern void HideInputFieldDialog();
[DllImport("__Internal")]
private static extern bool IsInputFieldDialogActive();
[DllImport("__Internal")]
private static extern string GetInputFieldValue();
[DllImport("__Internal")]
private static extern int GetInputFieldCursortPosition();
[DllImport("__Internal")]
private static extern int GetInputFieldCursortFocusPosition();
[DllImport("__Internal")]
private static extern void SetInputFieldCursortPosition(int selectionStart, int selectionEnd);
private bool captureAllKeyboardInput
{
get
{
return WebGLInput.captureAllKeyboardInput;
}
set
{
WebGLInput.captureAllKeyboardInput = value;
}
}
private float timer;
private Coroutine overlayhtml;
private Coroutine setposCoroutine;
public override void OnPointerClick(PointerEventData eventData)
{
base.OnPointerClick(eventData);
captureAllKeyboardInput = false;
ShowInputFieldDialog(text);
if (IsInputFieldDialogActive() && overlayhtml != null)
{
if(setposCoroutine != null)
{
SetSelection();
}
else
{
setposCoroutine = StartCoroutine(DelySetPostion());
}
}
else
{
overlayhtml = StartCoroutine(this.OverlayHtmlCoroutine());
}
}
private IEnumerator DelySetPostion()
{
captureAllKeyboardInput = true;
yield return null;
SetSelection();
captureAllKeyboardInput = false;
setposCoroutine = null;
System.GC.Collect();
}
private IEnumerator OverlayHtmlCoroutine()
{
yield return DelySetPostion();
while (IsInputFieldDialogActive() && isFocused)
{
yield return null;
var textFromHtml = GetInputFieldValue();
if (textFromHtml != this.text)
{
this.text = textFromHtml;
ForceLabelUpdate();
yield return null;
}
if (!captureAllKeyboardInput && setposCoroutine == null && !Input.GetMouseButton(0))
{
UpdateCaretPositions();
yield return null;
}
}
HideInputFieldDialog();
EventSystem.current.SetSelectedGameObject(null);
captureAllKeyboardInput = true;
overlayhtml = null;
System.GC.Collect();
}
private void SetSelection()
{
var selectionStart = selectionAnchorPosition < selectionFocusPosition ? selectionAnchorPosition : selectionFocusPosition;
var selectionEnd = selectionAnchorPosition > selectionFocusPosition ? selectionAnchorPosition : selectionFocusPosition;
SetInputFieldCursortPosition(selectionStart, selectionEnd);
}
private void UpdateCaretPositions()
{
var cpos = GetInputFieldCursortPosition();
var fpos = GetInputFieldCursortFocusPosition();
var changed = false;
if (cpos != caretPosition)
{
caretPosition = cpos;
changed = true;
}
if (fpos != selectionFocusPosition)
{
selectionFocusPosition = fpos;
changed = true;
}
if (changed)
{
ForceLabelUpdate();
}
}
#endif
}
用这个脚本替换系统自带的 InputField 组件 即可 经过这两步以后,就可以实现输入中文了
5.AB包问题 相信我们在做资源更新时,会用到AB包,不过在打包成WebGL时,我们要注意了,就是我们在设置PlayerSettings时,Other Settings–>Strip Engine Code 这个选项一定不要勾选,否则加载不出来资源.
6.播放音频问题 个人建议:使用系统自带的播放音频的组件去播放音频,不要使用一些文字转语音的插件,很多这类插件是不支持网页版的. 7.模板 个人建议:在我们发布webgl时,我们可以自定义自己喜欢的模板,发布的时候选择它,这样的话我们就不用每次发布完后,还要再去调整一遍样式,如下图所示 至于具体的怎样去创建模板,我就不再一一讲解了,官网上有教程,需要的小伙伴可以出查看
至此 我把我这个项目中遇到的一些问题写出来,供大家参考,我们相互学习,共同进步.
|