美文网首页
Unity 3D/2D 手机游戏开发 从学习到产品(第四版)

Unity 3D/2D 手机游戏开发 从学习到产品(第四版)

作者: 学识浅薄的胖 | 来源:发表于2021-10-22 17:39 被阅读0次

    书籍作者: 金玺曾 著
    ISBN:9787302525813
    推荐程度: 无编程基础的新手,不推荐。

    在学习 Unity 3D 的过程中,从图书馆借来了此书。该书最新为第四版,于2019年4月出版。在阅读学习过程中,发现书中存在不少瑕疵,特此记录,防止重复踩坑。

    书中大部分工程使用的 Unity 版本为 2018.2.6f1,本人使用的 Unity 版本为 2019.4.31f1c1 。版本不同,部分界面和功能也存在差异,过时的函数也会列入勘误项。


    第 1 章 Unity 基础

    • 第 5 页的 Survival Shooter Tutorial 在 Unity Assets Store 已经无法找到,随便下个免费的看看即可,这个工程后续没有用到,这里只是举例使用官方商店。

    第 2 章 太空射击游戏

    • 第 27 页的设置星空背景的材质 Shader 为 Unlit/Texture, 这里2019的界面直接搜Unlit是无法出这个 Shader, 要搜索Texture, 选择Texture / Unlit/Texture才行。

    • 第 30 页按照步骤设置完星空的动画效果之后,会发现动画根本不能循环,这里指的是图片虽然会将 OffsetY 的值从 0 变为 -1,但是界面效果并非星空在不断前进,而是一张图慢慢滚过,已经隐藏的部分不会接在尾部。坑!这里需要找到星空素材的 png 图,在 Inspector 里找到 Warp Mode 值改为 Repeat ,这样星空才能不断滚动。

    • 第 36 页右键 Create -> Prefabs 创建空的预置体,这个在 2019 无法实现,除非选中一个 FBX 素材可以创建 Prefab Variant,所以还是放到 Hierarchy 上再拖入 Project 就好。

    • 第 49 页提到 Gizmos 文件夹的创建,这里注意是在 Assets 文件夹里面创建,它这里表述为在 Project 窗口的根目录创建,很不准确。

    • 第 50 页创建 UI 界面,刚来使用 Unity 的新手,要注意此处创建的 UI 界面均基于 XY 坐标系,即在三维坐标中垂直于 Z 轴,Z 为 0。可以理解为,UI界面在游戏世界的头顶,有另一个摄像机会把 UI 界面投射到玩家屏幕。

    • 第 54 页 Player.cs 中的 OnTriggerEnter 条件判断,不能直接写 other.tag != "PlayerRocket" 这里会出现玩家飞船与后面书籍中添加的 Quad 射线碰撞层发生碰撞,所以最好换成 other.tag == "Enemy" || other.tag == "EnemyRocket"

    • 第 54 - 55 页, 创建了一个类名为 TitleScreen 的脚本,但文件名竟然是 TitleSceen.cs,低级拼写错误,需与类名保持一致。

    • 第 55 页创建 UI -> Image 时,选择背景贴图,这里说默认 png 是 Texture 类型。而 2019 里默认就是 Sprite 类型,也不存在 Texture 类型,可直接选择使用。

    • 第 60 页创建 ProcessModel.cs 文件,其中这句代码无法使用。GameObject tar = AssertDatabase.LoadAssetAtPath<GameObject>(importer.assetPath); 这里始终获取的 tar 值为 null 。同时存在过时函数,原语句 PrefabUtility.CreatePrefab("Assets/Prefabs/Enemy2c.prefab",tar); ,在 2019 替换为 PrefabUtility.SaveAsPrefabAsset(tar, "Assets/Prefabs/Enemy2c.prefab");

    第 3 章 第一人称射击游戏

    • 第 72 页锁定鼠标的代码过时,原代码 Screen.lockCursor = true; ,在 2019 更改为 Cursor.lockState = CursorLockMode.Locked;

    • 第 74 页设置 Navigation Static 时,应注意 level 模型下面的三个 GameObject 也需要选中并设置,不然无法使用 Navigation 窗口的 Bake 功能,会导致敌人 AI 原地踏步。

    • 第 77 页设置动画的过渡条件时,应注意选中连接线后,将 Has Exit Time 选项去掉勾选,不然敌人在执行动画的时候,即使达成了条件,会延迟触发条件,而不是只触发一次。例如,敌人 attack 一次应立即 idle ,如果不取消该选项,则会延迟进入 idle ,导致多次进入 attack 的错误逻辑。

    • 第 91 页为敌人设置在小地图上显示的球体,此处没有详细说明步骤,新手比较费解。 其中描述:创建一个球体并命名为 dummy,将其材质设置为 Self-Illumin / Diffuse。这里实际步骤应为,在 Project 窗口内,右键 Create -> Material ,创建一个材质球,并将其颜色 Main Color 调整为 #FF0000 ,其 Shader 设置为 Legacy Shaders / Self-Illumin / Diffuse,需要注意的是 2019 内,直接搜索 LegacySelf-Illumin 均无法查到,需输入Diffuse 再从列表中选择。创建材质球后,打开Zombie的 prefab ,在其下面右键 Create -> 3D Object -> Sphere , 命名为 dummy 并设置材质为刚创建的 Red 材质球。

    第 4 章 塔防游戏

    • 第 121 页遍历敌人,需要在敌人脚本初始化时,往公共数组更新敌人。而此处描述为 打开 Enemy.cs 脚本, 在 Start 和 DestroyMe 函数中分别更新 List 中的敌人。这里忽略了 AirEnemy.cs 脚本, 因为 Start 是私有函数,即使 AirEnemy 继承 Enemy,私有函数也不会生效, AirEnemy.cs 也需要在 Start 内加上更新 List 的语句,而 DestroyMe 是公有函数,直接继承。

    • 第 127 页 Archer.cs 中函数过时,原代码为Vector3 pos = this.m_model.transform.FindChild("atkpoint").position;,在 2019 应改为 Vector3 pos = this.m_model.transform.Find("atkpoint").position;

    • 第 131 页为敌人添加血条 UI 代码,不仅需要为 Enemy.cs 添加,同样也需要为 AirEnemy.cs 添加, 将新增的变量改为protected类型,并把void Start()改为protected,或者直接在 AirEnemy.cs 中粘贴相同代码。这样所有敌人才会渲染血条。

    第 6 章 与 Web 服务器的交互

    • 第 168 页, WWW 类在 2019 以后不再推荐使用,取而代之的是 UnityWebRequest, 代码修改为 UnityWebRequest www = new UnityWebRequest.Get("http://127.0.0.1/test.php?username=get&password=12345");,获取文本代码改为 m_info = www.downloadHandler.text;

    • 第 169 页, POST 方法的使用也已经弃用,应改为以下代码

    List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
    formData.Add(new MultipartFormDataSection("username", "post"));
    formData.Add(new MultipartFormDataSection("password", "6789"));
    
    UnityWebRequest www = UnityWebRequest.Post("http://127.0.0.1/test.php", formData);
    
    yield return www.SendWebRequest();
    
    • 第 170 页,关于上传/下载图片的方法也发生了改变。2019 版本后可修改为以下代码:
    byte[] bs = m_uploadImg.EncodeToJPG();
    
    List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
    formData.Add(new MultipartFormFileSection("image", bs, "screenshot", "image/jpeg"));
    
    // POST 文件数据
    UnityWebRequest www = UnityWebRequest.Post("http://127.0.0.1/test.php", formData);
    yield return www.SendWebRequest();
    
    // ... 
    
    // 接收部分
    m_downloadImg = new Texture2D((int)img.rectTransform.rect.width, (int)img.rectTransform.rect.height);
    
    m_downloadImg.LoadImage(www.downloadHandler.data);
    
    Sprite sprite = Sprite.Create(m_downloadImg, new Rect(0, 0, m_downloadImg.width, m_downloadImg.height), new Vector2(0.5f, 0.5f));
    img.sprite = sprite;
    
    • 第 172 页,同理下载声音文件也更换了方法。当使用 GET 请求时,多媒体文件的下载有特殊的类配合使用,2019 版本后可使用以下代码:
    UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip("http://127.0.0.1/music.wav", AudioType.WAV);
    
    yield return www.SendWebRequest();
    
    if (www.isNetworkError || www.isHttpError)
    {
            this.updateResult(www.error);
            yield return null;
    }
    else
    {
            if (www.isDone)
            {
                    m_soundClip = DownloadHandlerAudioClip.GetContent(www);
                    GetComponent<AudioSource>().PlayOneShot(m_soundClip);
            }
     }
    
    • 第 176 页,定义的用户数据类,如果使用 Unity 自带的 JsonUtility 进行 JSON 序列化,需要在对应类上添加 [Serializable]特性。同时,需要注意的是,JsonUtility 的FromJson()方法,区分大小写,并且不支持属性的序列化。在 Unity 内声明序列化类时,只能使用字段,而不能声明为属性。例如:
    // 正确的声明
    [Serializable]
    public class HighScore
    {
        public int? id;
        public string name;
        public int score;
    }
    
    // JsonUtility 无法转化的声明
    [Serializable]
    public class HighScore
    {
        public int? id { get; set; }
        public string name { get; set; }
        public int score { get; set; }
    }
    

    第 7 章 TCP UDP 实例

    • 第 185 页 这里的 TCP 服务器代码里,作者的变量命名有些错误,在之前的章节也有出现。例如,把长度int length经常写成int lenght,估计是写高度写惯了int height

    第 10 章 Android 游戏移植

    • 第 262 页的 AssetBuilder.cs 内, BuildAssets 方法内应优先判断路径是否存在,否则路径不存在时报错。可参照第 264 页的 BuildAssetsAuto 方法前几行:
    string path = "Assets/Bundle/Win";
    if (!System.IO.Directory.Exist(path){
        System.IO.Directory.CreateDirectory(path);
    }
    

    不过,如果使用的是UnityEngine.Windows.Directory.CreateDirectory方法,不会自动创建不存在的子目录。

    第 11 章 Unity 新 GUI 完全攻略

    • 第 275 页这里提到选择Create Editable Copy创建出字体副本,这时候在 Project 窗口会出现三个文件,分别是arial.fontsettingsarial.matarial_copy.png,这里需要把前两者都重新命名为arial_copy,不然字体选择里会识别两个为arial字体。

    • 第 276 页,这里提到显示字体可能是白色的,无法显示 PS 中的艺术字体。需要在 Project 窗口,选中替换的arial_copy.png图片,在 Inspector 窗口中检查设置Alpha Is Transparent已勾选,同时 Default 选项卡中的 Format 应选择 Automatic 或者 RGBA 32bit,如果选择的是Alpha 8则图片会变成黑白。

    • 第 283 页,2019 的 Inspector 窗口中将选中颜色Selected Color 也可以单独设置,所以文中描述Highlighted Color 不仅为高亮状态,还代表选中状态,在 2019后的版本不适用。

    相关文章

      网友评论

          本文标题:Unity 3D/2D 手机游戏开发 从学习到产品(第四版)

          本文链接:https://www.haomeiwen.com/subject/lnzdoltx.html