Unity打包Webgl中遇到的问题
2026/9/4 13:54:23 网站建设 项目流程

最近项目需求,要用Unity打包成WebGL网页版,我在此简单说下遇到的坑!!!,本人用的是2018.3.0f2版本
1.字体问题
引擎自带的字体,打包之后,在网页上是显示不出来的,此时需要我们导入一个新字体样式即可解决
2.材质问题
如果在场景中或者脚本中使用了自定义的Shader,这时我们在打包之前,把这个Shader添加到Graphics设置中,如下图所示:

3.UI布局问题
个人建议:我们在做UI锚点选择时,尽量选择统一,不要出现一套UI界面上多个锚点定位的问题,要不然我们在自适应窗口化时,有的UI会重叠到一起,影响视觉效果
4.输入不了中文问题
打包后,我们会发现输入不了中文,What?,是不是很奔溃?不过在我的执着的小心脏面前,它屈服了.
下面是我的解决办法:
4.1第一步

varWebGLInputField={//打开输入框ShowInputFieldDialog:function(defaultValue){try{defaultValue=Pointer_stringify(defaultValue);}catch(e){alert(e);return;}if(!document.getElementById("nativeInputDialog")){varelement=document.createElement('div');// setup htmlvarhtml='<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);varm_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';}}varm_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(){varnativeDialog=document.getElementById("nativeInputDialog");if(!nativeDialog){returnfalse;}return(nativeDialog.style.display!='none');},GetInputFieldValue:function(){varelem=document.getElementById("nativeInputDialogInput");varreturnStr=elem.value;varbufferSize=lengthBytesUTF8(returnStr)+1;varbuffer=_malloc(bufferSize);stringToUTF8(returnStr,buffer,bufferSize);returnbuffer;},GetInputFieldCursortPosition:function(){vardialog=document.getElementById("nativeInputDialogInput");varindex=dialog.selectionStart;returnindex;},GetInputFieldCursortFocusPosition:function(){vardialog=document.getElementById("nativeInputDialogInput");varindex=dialog.selectionEnd;returnindex;},SetInputFieldCursortPosition:function(selectionStart,selectionEnd){varelem=document.getElementById("nativeInputDialogInput");varval=elem.valuevarlen=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 第二步

usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;usingUnityEngine.UI;usingUnityEngine.EventSystems;usingSystem.Runtime.InteropServices;usingSystem;publicclassWebGLInputField:InputField{#ifUNITY_WEBGL && !UNITY_EDITOR[DllImport("__Internal")]//显示对话框privatestaticexternvoidShowInputFieldDialog(stringtext);[DllImport("__Internal")]//隐藏对话框privatestaticexternvoidHideInputFieldDialog();[DllImport("__Internal")]//对话框是否显示中privatestaticexternboolIsInputFieldDialogActive();[DllImport("__Internal")]//获取对话框的数据privatestaticexternstringGetInputFieldValue();[DllImport("__Internal")]//获取光标选中坐标(起点点)privatestaticexternintGetInputFieldCursortPosition();[DllImport("__Internal")]//获取光标选中坐标(终点)privatestaticexternintGetInputFieldCursortFocusPosition();[DllImport("__Internal")]//设置光标选择privatestaticexternvoidSetInputFieldCursortPosition(intselectionStart,intselectionEnd);privateboolcaptureAllKeyboardInput{get{returnWebGLInput.captureAllKeyboardInput;}set{WebGLInput.captureAllKeyboardInput=value;}}privatefloattimer;privateCoroutineoverlayhtml;privateCoroutinesetposCoroutine;publicoverridevoidOnPointerClick(PointerEventDataeventData){base.OnPointerClick(eventData);captureAllKeyboardInput=false;ShowInputFieldDialog(text);if(IsInputFieldDialogActive()&&overlayhtml!=null){//更新光标if(setposCoroutine!=null){SetSelection();}else{setposCoroutine=StartCoroutine(DelySetPostion());}}else{//打开html端的输入框overlayhtml=StartCoroutine(this.OverlayHtmlCoroutine());}}privateIEnumeratorDelySetPostion(){captureAllKeyboardInput=true;yieldreturnnull;SetSelection();captureAllKeyboardInput=false;setposCoroutine=null;System.GC.Collect();}privateIEnumeratorOverlayHtmlCoroutine(){yieldreturnDelySetPostion();//设置选中对象为while(IsInputFieldDialogActive()&&isFocused){yieldreturnnull;vartextFromHtml=GetInputFieldValue();if(textFromHtml!=this.text){this.text=textFromHtml;ForceLabelUpdate();yieldreturnnull;}if(!captureAllKeyboardInput&&setposCoroutine==null&&!Input.GetMouseButton(0)){UpdateCaretPositions();yieldreturnnull;}}HideInputFieldDialog();EventSystem.current.SetSelectedGameObject(null);captureAllKeyboardInput=true;overlayhtml=null;System.GC.Collect();}/// <summary>/// 设置选中区域/// </summary>privatevoidSetSelection(){varselectionStart=selectionAnchorPosition<selectionFocusPosition?selectionAnchorPosition:selectionFocusPosition;varselectionEnd=selectionAnchorPosition>selectionFocusPosition?selectionAnchorPosition:selectionFocusPosition;SetInputFieldCursortPosition(selectionStart,selectionEnd);}/// <summary>/// 从html更新caretPosition/// </summary>privatevoidUpdateCaretPositions(){varcpos=GetInputFieldCursortPosition();varfpos=GetInputFieldCursortFocusPosition();varchanged=false;if(cpos!=caretPosition){caretPosition=cpos;changed=true;}if(fpos!=selectionFocusPosition){selectionFocusPosition=fpos;changed=true;}if(changed){ForceLabelUpdate();}}#endif//注意Time.timeScale = 0 会无法更新信息//private void Update()//{// if(Input.GetMouseButtonDown(1) && isFocused)// {// Debug.Log("caretPosition:" + caretPosition);//光标坐标// Debug.Log("currentSelectionState:" + currentSelectionState);//选中状态// Debug.Log("selectionAnchorPosition:" + selectionAnchorPosition);//选择起点// Debug.Log("selectionFocusPosition:" + selectionFocusPosition);//选择结束点// }//}}

用这个脚本替换系统自带的 InputField 组件 即可
经过这两步以后,就可以实现输入中文了

5.AB包问题
相信我们在做资源更新时,会用到AB包,不过在打包成WebGL时,我们要注意了,就是我们在设置PlayerSettings时,Other Settings–>Strip Engine Code 这个选项一定不要勾选,否则加载不出来资源.

6.播放音频问题
个人建议:使用系统自带的播放音频的组件去播放音频,不要使用一些文字转语音的插件,很多这类插件是不支持网页版的.
7.模板
个人建议:在我们发布webgl时,我们可以自定义自己喜欢的模板,发布的时候选择它,这样的话我们就不用每次发布完后,还要再去调整一遍样式,如下图所示

至于具体的怎样去创建模板,我就不再一一讲解了,官网上有教程,需要的小伙伴可以出查看

至此 我把我这个项目中遇到的一些问题写出来,供大家参考,我们相互学习,共同进步.

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询