UnityWebGl项目总结(未完)

一、空包导出测试

1、直接导出会产生以下报错,无法加载


打包失败无法运行


这里我们需要勾选Decompression Fallback,重新打包输出测试


 打包成功(火狐浏览器)


那么这里我们就打包成功了(这里我随便加了几个模型)

需要注意的是:

我们可以使用火狐浏览器进行本地测试,具体配置方法参考这篇文章

(12条消息) Unity WebGL打包后怎么运行(火狐配置)_Zhangxian_12的博客-CSDN博客_unity webgl 火狐

另外我们也可以用nginx配置UnityWebgl文件,那么就可以使用其他浏览器在本地进行测试。

nginx: downloadhttp://nginx.org/en/download.html

1、第一步先下载nginx

2、这里我把nginx放到了C:\MyTool\nginx-1.23.0

3、打开之后发现并没有反应,于是查看报错日志

      C:\MyTool\nginx-1.23.0\logs\error.log

查询一下问题是因为端口被占用。具体解决办法参考以下文章

(13条消息) Windows上nginx启动报错:bind() to 0.0.0.0:80 failed_一千零一業的博客-CSDN博客

4、接着成功运行nginx

5、在浏览器中输入localhost出现以下页面,则本地测试配置成功了

 6、我们尝试在本地中加载图片(在C:\MyTool\nginx-1.23.0\html中添加一张图片命名为1.png)

 本地加载音乐也是没问题的

 总结以下上面的两种方法:

1、用火狐浏览器直接测试

优点:比较简单方便,不需要太多的后端知识也能够进行测试

缺点:(1)由于我们的测试文件全都放置在StreamingAssets文件当中,所以我们所以资源文件势必要实现放置在Unity的StreamingAssets文件夹当中,这样也会影响我们的打包速度。

           (2)我们只能限定使用火狐浏览器,局限性较大

 地址:path = Application.streamingAssetsPath + "/" + name;

2、配置nginx环境后进行本地环境测试

优点:不会受限于某个浏览器,使用较为方便,且不影响打包速度。

缺点:配置环境较为麻烦

地址:localhost/ + name;

二、开始建模环节

在空包测试确定没问题以后,我们就可以开始建模环节

需要注意的是,由于要在网页端浏览我们的三维模型,这时候我们的三维模型不宜做的复杂,尤其要保证好整个场景的面数(最好单面建模),贴图的大小和数量,避免后续浏览器带不动。

3Dmax模型

        这里我的整个场景模型13000个面,其实还可以更加精简。主要浪费模型面数的地方在于文字模型,文字其实可以使用贴图来搞定。我这里因为场景比较小影响不大,如果场景比较大的同学,建议文字用贴图来演示即可。

        其次是模型尽可能合并UV减少贴图数量

Unity3D模型

        Unity3D这部分我使用的是URP管线

        这次项目主要是在程序上踩了不少坑,场景美术这方面就不过多赘述,可以看看我之前做的视频。

【Unity3D学习】Unity3D场景快速烘培、从3Dmax到Unity3D工作流_哔哩哔哩_bilibili

三、程序方面

        1、UnityWebgl打包输出以后会生成这些文件。其中StreamingAssets是一个只读、不可写的目录; 该文件夹下的资源会保持原始格式(比如图片不会被引擎进行纹理压缩)。

        因此我们可以把所有的资源(包括多媒体文件、文本文件等)放在StreamingAssets中进行测试。

         (如图)一般我们要在UI的Image上显示图片,直接把图片转成Sprite然后拖拽进ImageSource Image即可

         (如图)当我们的图片放置在StreamingAssets中,则无法进行操作,那么这时候我们只能编写脚本来读取StreamingAssets下的图片。 

         由于我们后续是需要访问网络的,针对这点我们有四种选择:

 其中我自己尝试使用了WWW和UnityWebRequest。由于我使用的是较高的Unity2021版本,WWW已被官方弃用,所以我最终选择了使用UnityWebRequest。

 1、如何读取图片作为UI的Image

这里附上脚本

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;

public class LoadPic : MonoBehaviour
{
    public RawImage image;
    private void Start()
    {
        StartCoroutine(TextureReader("BasketballPlayer.png", loadPic));
    }
    private void loadPic(Texture texture)
    {
        image.texture = texture;
    }
    /// <summary>
    /// 读取streamingAsset中的图片
    /// </summary>
    /// <param name="mediaName"></param>
    /// <param name="action">传入一个方法组</param>
    /// <returns></returns>
    public static IEnumerator TextureReader(string name, UnityAction<Texture> action)
    {
        string path;
#if UNITY_WIN_STANDALONE || UNITY_IPHONE && !UNITY_EDITOR
        path = Application.streamingAssetsPath +"/" +name;
#else
        path = Application.streamingAssetsPath + "/" + name;
#endif
        UnityWebRequest unityWebRequest = UnityWebRequestTexture.GetTexture(path);
        yield return unityWebRequest.SendWebRequest();
        if (unityWebRequest.error != null)
            Debug.Log(unityWebRequest.error);
        else
        {
            byte[] bts = unityWebRequest.downloadHandler.data;
            if (action != null)
            {
                action(DownloadHandlerTexture.GetContent(unityWebRequest));
            }
        }
    }
}

 这里我们的图片就算加载成功了,我们把他打包出来,发现也没有问题

这里我们更换一张图片(注意命名一致),刷新一下网页图片也同步更新了。

这种方法便于我们后续进行测试

 2、如何读取图片作为材质贴图(主要使用在后续维护替换海报上)

把上面代码进行如下更改就好了

private void loadPic(Texture texture)
    {
        Plane.GetComponent<MeshRenderer>().material.mainTexture = texture;
        //image.texture = texture;
    }

3、加载Json文件

首先附上脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;

public class LoadJson : MonoBehaviour
{
    string s = "";
    string m_s = "";
    public Text textStudent;
    private void OnGUI()
    {
        if (GUI.Button(new Rect(0, 100, 100, 50), "LoadJson"))
            StartCoroutine(TextReader("Test.json", ShowJson));
    }

    /// <summary>
    /// 读取json文件
    /// </summary>
    /// <param name="s"></param>
    private void ShowJson(string s)
    {
        //json格式是utf-8 不带bom功能  ,不然会报错
        StudentItem studentItem = JsonUtility.FromJson<StudentItem>(s);
        foreach (StudentData studentData in studentItem.infoList)
        {
            {
                m_s += ("姓名:" + studentData.name + "  年龄:" + studentData.age + "  性别:" + studentData.sex + "\n");
            }
        }
        textStudent.text = m_s;

    }

    [System.Serializable]
    public struct StudentItem 
    {
        public StudentData[] infoList;
    }
    /// <summary>
    /// json文件信息
    /// </summary>
    [System.Serializable]
    public struct StudentData
    {
        public string name;
        public double age;
        public string sex;
    }

    /// <summary>
    /// 读取StreamingAsset中的配置文件
    /// </summary>
    /// <param name="configName"></param>
    /// <param name="action"></param>
    /// <returns></returns>
    public static IEnumerator TextReader(string configName, UnityAction<string> action = null)
    {
        string path;
#if UNITY_WIN_STANDALONE || UNITY_IPHONE &&!UNITY_EDITOR
        path ="file://"+ Application.streamingAssets                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
        Path + configName;
#else 
        path = Application.streamingAssetsPath + "/" + configName;
#endif
        UnityWebRequest unityWebRequest = UnityWebRequest.Get(path);
        yield return unityWebRequest.SendWebRequest();

        if (unityWebRequest.error != null)
            Debug.Log(unityWebRequest.error);
        else
        {
            string content = unityWebRequest.downloadHandler.text;
            if (action != null)
                action(content);
        }
    }
}

 效果演示

加载Json文件成功

这里我们试了一下外部修改Json文件,刷新浏览器后也能同步加载

 加载Json文件这里有几个坑

1、这里我用到的是Unity官方自带的解析Json方法,UnityEngine.JsonUtility,只能解决一些简单的问题,我这里只需要简单实现。如果要实现复杂功能还是需要第三方库。JsonUtility.FromJson只能解析首个对象,不能解析多个对象。所以我们的Json文件需要套个壳 [ ],让它变成一个元素。

2、json的保存必须是utf-8且无签名的,不然就会报错:ArgumentException: JSON parse error: Invalid value.

3、使用JsonUtility必须带序列化标签[System.Serializable]

4、注意字体类型,Unity自带的是Arial字体。但是Arial字体并不支持中文,打包UnityWebgl之后中文会消失。这里我们只需要自己找一个支持中文的字体更换即可(我这里用的是黑体)。

 3、加载CSV文件(同加载Json文件)

4、加载Txt文件(同加载Json文件)

【Unity3D学习】用Unity3D简单实现答题系统——可随机出题_哔哩哔哩_bilibili

这部分可以看看这个视频

5、加载视频文件

 (1)这里我在Unity内播放并无什么问题

(2)打包之后在浏览器中并没有反应(Edge,谷歌,火狐都试了),F12查看显示没有对应的编译器

 (3)我的解决办法是把视频加载方式改为了URL加载,把视频文件挪到StreamingAssets当中或者nginx路径内。

附上代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;

public class LoadVideo : MonoBehaviour
{
    VideoPlayer video;
    private void Awake()
    {
        video = GetComponent<VideoPlayer>();
        video.url = Application.streamingAssetsPath + "/01.mp4";
    }
}

这里的坑需要注意一下:

1、注意不要遗漏了"/"

2、注意视频文件的后缀;

3、最重要的一点!!!视频文件不能有中文!!!

最后打包出来所有浏览器(谷歌、Edge、火狐)均可正常播放

 6、加载PDF文件

这里我使用到了一个插件PDFViewer,效果如图所示。经过实测在UnityWebgl中也适用

 插件链接附上:

链接:https://pan.baidu.com/s/1Rco-7FWRT1_FYPmMcYVERg
提取码:7gvo

具体使用方法也不是很困难,这里就不写太多了。

**********************************************************************************************************

补充踩坑点:

1、Newtonsoft 解析 Json 在打包Webgl的时候会报错。可以改用LitJson

  • 16
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
在Java中,泛型是一种强类型机制,它可以让你在编译时检查类型错误,从而提高代码的安全性和可读性。在使用泛型时,我们经常会遇到父类和子类的泛型转换问题。 首先,我们需要明确一点:子类泛型不能转换成父类泛型。这是因为Java中的泛型是不协变的。例如,如果有一个类A和它的子类B,那么List<A>和List<B>之间是不存在继承关系的。 下面我们来看一个例子: ```java public class Animal { //... } public class Dog extends Animal { //... } public class Test { public static void main(String[] args) { List<Animal> list1 = new ArrayList<>(); List<Dog> list2 = new ArrayList<>(); list1 = list2; // 编译错误 } } ``` 在这个例子中,我们定义了Animal类和它的子类Dog。然后我们定义了两个List,分别是List<Animal>和List<Dog>。如果将List<Dog>赋值给List<Animal>,会出现编译错误。这是因为List<Animal>和List<Dog>之间不存在继承关系。 那么,如果我们想要让子类泛型转换成父类泛型,应该怎么办呢?这时我们可以使用通配符来解决问题。通配符可以表示任意类型,包括父类和子类。例如,我们可以将List<Dog>赋值给List<? extends Animal>,这样就可以实现子类泛型转换成父类泛型了。 下面我们来看一个使用通配符的例子: ```java public class Animal { //... } public class Dog extends Animal { //... } public class Test { public static void main(String[] args) { List<Animal> list1 = new ArrayList<>(); List<Dog> list2 = new ArrayList<>(); list1 = list2; // 编译错误 List<? extends Animal> list3 = new ArrayList<>(); list3 = list2; // 正确 } } ``` 在这个例子中,我们定义了List<? extends Animal>来表示任意继承自Animal的类型。然后我们将List<Dog>赋值给List<? extends Animal>,这样就可以实现子类泛型转换成父类泛型了。 总结一下,Java中的泛型是不协变的,子类泛型不能转换成父类泛型。如果需要实现子类泛型转换成父类泛型,可以使用通配符来解决问题。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值