5.6中文乱码 unity3d

2018-02-06 20:25:09 weixin_33798152 阅读数 839

汉化效果

利用Attribute可以自定义一些属性,实现汉化:

汉化效果图

用法示例

TitleTest.cs

using UnityEngine;
using UnityEngine.Events;

[System.Serializable]
public class Item {
    [Title("名称")]
    public string name;
    [EnumName("类型")]
    public Type type = Type.A;

    public enum Type {
        [EnumName("消耗品")]
        A,
        [EnumName("任务道具")]
        B
    }
}

/// <summary>
/// 标题属性测试
/// <para>ZhangYu 2018-06-21</para>
/// </summary>
public class TitleTest : MonoBehaviour {

    [Title("等级")]
    public int level;
    [Title("姓名")]
    public string name;
    [EnumName("武器")]
    public Weapon weapon;
    [EnumName("铠甲")]
    public Armor armor;
    [Title("道具列表", "yellow")]
    public Item[] items;
    [Title("死亡回调方法", "#FF0000")]
    public UnityEvent onDead;
    [Title("复活回调方法", "#00FF00")]
    public UnityEvent onRevive;

    public enum Weapon {
        [EnumName("蛇矛")]
        A,
        [EnumName("胜宗刀")]
        B,
        [EnumName("青缸剑")]
        C,
        [EnumName("李广弓")]
        D
    }

    public enum Armor {
        [EnumName("钢甲")]
        One,
        [EnumName("火焰甲")]
        Two,
        [EnumName("青龙甲")]
        Three,
        [EnumName("藤甲")]
        Four
    }

    void Start () {
        
    }
    
}

Attribute脚本

TitleAttribute.cs

using UnityEngine;
#if UNITY_EDITOR
using System;
using UnityEditor;
using System.Reflection;
using System.Text.RegularExpressions;
#endif

/// <summary>
/// 标题属性
/// <para>ZhangYu 2018-06-21</para>
/// </summary>
#if UNITY_EDITOR
[AttributeUsage(AttributeTargets.Field)]
#endif
public class TitleAttribute : PropertyAttribute {

    /// <summary> 标题名称 </summary>
    public string title;
    /// <summary> 标题颜色 </summary>
    public string htmlColor;

    /// <summary> 在属性上方添加一个标题 </summary>
    /// <param name="title">标题名称</param>
    /// <param name="htmlColor">标题颜色</param>
    public TitleAttribute(string title, string htmlColor = "#FFFFFF") {
        this.title = title;
        this.htmlColor = htmlColor;
    }

}

#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(TitleAttribute))]
public class TitleAttributeDrawer : DecoratorDrawer {

    // 文本样式
    private GUIStyle style = new GUIStyle();

    public override void OnGUI(Rect position) {
        // 获取Attribute
        TitleAttribute attr = (TitleAttribute)attribute;

        // 转换颜色
        Color color = htmlToColor(attr.htmlColor);

        // 重绘GUI
        position = EditorGUI.IndentedRect(position);
        style.normal.textColor = color;
        GUI.Label(position, attr.title, style);
    }

    public override float GetHeight() {
        return base.GetHeight() - 4;
    }

    /// <summary> Html颜色转换为Color </summary>
    /// <param name="hex"></param>
    /// <returns></returns>
    private Color htmlToColor(string hex) {
        // 默认黑色
        if (string.IsNullOrEmpty(hex)) return Color.black;

        // 转换颜色
        hex = hex.ToLower();
        if (hex.IndexOf("#") == 0 && hex.Length == 7) {
            int r = Convert.ToInt32(hex.Substring(1, 2), 16);
            int g = Convert.ToInt32(hex.Substring(3, 2), 16);
            int b = Convert.ToInt32(hex.Substring(5, 2), 16);
            return new Color(r / 255f, g / 255f, b / 255f);
        } else if (hex == "red") {
            return Color.red;
        } else if (hex == "green") {
            return Color.green;
        } else if (hex == "blue") {
            return Color.blue;
        } else if (hex == "yellow") {
            return Color.yellow;
        } else if (hex == "black") {
            return Color.black;
        } else if (hex == "white") {
            return Color.white;
        } else if (hex == "cyan") {
            return Color.cyan;
        } else if (hex == "gray") {
            return Color.gray;
        } else if (hex == "grey") {
            return Color.grey;
        } else if (hex == "magenta") {
            return Color.magenta;
        } else {
            return Color.black;
        }
    }

}
#endif

/// <summary>
/// 设置枚举名称
/// <para>ZhangYu 2018-06-21</para>
/// </summary>

#if UNITY_EDITOR
[AttributeUsage(AttributeTargets.Field)]
#endif
public class EnumNameAttribute : PropertyAttribute {

    /// <summary> 枚举名称 </summary>
    public string name;

    public EnumNameAttribute(string name) {
        this.name = name;
    }

}

#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(EnumNameAttribute))]
public class EnumNameDrawer : PropertyDrawer {

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
        // 替换属性名称
        EnumNameAttribute rename = (EnumNameAttribute)attribute;
        label.text = rename.name;

        // 重绘GUI
        bool isElement = Regex.IsMatch(property.displayName, "Element \\d+");
        if (isElement) label.text = property.displayName;
        if (property.propertyType == SerializedPropertyType.Enum) {
            drawEnum(position, property, label);
        } else {
            EditorGUI.PropertyField(position, property, label, true);
        }
    }

    // 绘制枚举类型
    private void drawEnum(Rect position, SerializedProperty property, GUIContent label) {
        EditorGUI.BeginChangeCheck();

        // 获取枚举相关属性
        Type type = fieldInfo.FieldType;
        string[] names = property.enumNames;
        string[] values = new string[names.Length];
        while (type.IsArray) type = type.GetElementType();

        // 获取枚举所对应的名称
        for (int i = 0; i < names.Length; i++) {
            FieldInfo info = type.GetField(names[i]);
            EnumNameAttribute[] atts = (EnumNameAttribute[])info.GetCustomAttributes(typeof(EnumNameAttribute), false);
            values[i] = atts.Length == 0 ? names[i] : atts[0].name;
        }

        // 重绘GUI
        int index = EditorGUI.Popup(position, label.text, property.enumValueIndex, values);
        if (EditorGUI.EndChangeCheck() && index != -1) property.enumValueIndex = index;
    }

}
#endif

PS1:感谢雨松momo和他的文章:《Unity3D研究院之Inspector面板枚举的别名与排序(八十九)》
PS2:转载请注明原文地址:https://segmentfault.com/a/11...

2017-10-25 09:25:30 mmuu1987 阅读数 2179

 需求分析

        因项目需求,我们需要加载自定义的场景,这里的自定义是指,场景不会放在buildSetting里的场景,当然,不放在buildSetting里的场景,不算真的场景,只能是算半个,说白了就跟普通的assetBundle没啥区别,既然跟普通的加载方式没啥区别,那为何不叫加载资源呢,我们分析得出,既然是场景,肯定会有一些不同的地方,比如渲染设置(跟烘焙有关系的),环境设置,等等,这些就可跟一般的加载场景是有所区别的了。所以我们要做的是在加载资源的基础上,还原场景里面的设置。那就差不多等于是我们自己的加载场景了,这里用差不多,这几个字眼,其实我们是不可能百分百还原场景的设定的,因为官方没有在运行时提供相应的场景设置API。如图所示,给我们提供的API少得可怜,我们只能是提供多少就还原多少了。



       按上面的说话,既然场景打包可以这样搞,那我们就可以在加载资源或者叫加载场景的时候,分为两种方式

1,加载下一个场景的时候,可以把上一个场景的资源全部删掉,再重新设置下,下一个场景的场景设置,这样,就相当于切换场景了。

2,加载下一个场景的时候,调用官方提供的API,如图,然后再场景切换完成事件里,再加载下一个场景的资源和设定,听起来很麻烦,执行起来,更麻烦,我们现在就是用这种方法,发现一路都是坑,所以,强烈推荐第一种。下面我就说说我们用第二种遇到的坑(其实没必要往下看了,用第一种是最安全稳妥的,我们稳妥的设置好每个场景的设置就好


    我的做法就是,用Notepad++ 打开保存好的场景文件,细看里面的一些设置。场景烘焙打包,烘焙贴图打包是网上也有流程和方法,这里就不细说。如果有打开场景文件出现乱码的话,选择红线的方式即可。如图该设置可以在菜单Edit>ProjectSetting>Editor找到。可以看到场景文件无非就是记录场景里面的物体信息,每个物体的组件,组件里的参数,这些我们不用可以记下来,打包资源的时候,设定的参数都会随着资源一起打包出去,加载的时候直接加载就好了,比如旋转,缩放,位置等等,都不用我们操心。好了,那我们就好好的看看场景文件里面的带有setting的一些设置,

比如LithtmapSettings,还有RenderSettings等,其实我们按照场景文件所记录的设置,加载的时候设置好相应的参数就可以了,可惜,想法很美好!场景文件记录的参数有些不能够在发布后运行时设置,比如m_RenderSettings,还有LightmapSetting的很多参数,还有LightDataAssets,该资源就算你打包了,也没办法发布后运行时load进来然后解析设置参数,因为官方没有提供相应的API文档,所就如前面所说的,只能算是半个场景的打包,残次品,希望官方以后能够提供更多的关于场景打包方面的API给我们吧。所以,目前只能是API提供多少接口,我们就还原多少。


开发中遇到的坑

       5.6版本的跟5.3的SceneManager对比,有了蛮大的改动,5.6增加了几个事件,

一个是场景改变,一个是场景加载,一个是卸载后的,还有就是不能同步卸载场景了,只能异步卸载场景,不知道unity官方出于什么考虑才这样,感觉用起来麻烦了很多,或许我的这个需求太特别,才会用上去觉得很不爽吧。再者SceneManager.SetActiveScene的时候,先注册监听该事件,我是放在Start里




因为是自定义场景加载,所以我们代码创建一个新的场景,然后激活它,


如果你执行完上面的两句代码后创建物体,都会是在当前场景创建,并不会在激活的场景创建。这个坑应该官方提供了一个API解决,SceneManager.activeSceneChanged。 触发这个事件的条件是当场景切换完成的时候,也就是说,正式进入了激活的场景,所以,我们只能在这个事件触发后才可以在激活的场景里创建物体和卸载上一个场景的资源

      然而又来了一个新坑,卸载上一个场景资源是异步的,也就是当前场景加载完成后,如果你执行上一个场景卸载操作,然后把当前场景的烘焙贴图贴上去,很抱歉,unity也会立马当前场景的烘焙贴图删掉,也算是一个小BUG吧,补救办法就是延迟一帧后执行当前场景的烘焙贴图贴赋予的操作,这个操作并严谨,因为异步加载,并不确定什么时候unity会执行删除烘焙贴图的操作。但当我想到之前看到过文章说资源一般会在帧后面释放掉,我想,要是把当前场景的烘焙贴图放在yield return new WaitForEndOfFrame后面贴上去应该就没事了,料想到果真如此

      目前发现runtime全局光是跟LightDataAssets是紧密结合在一起的,当前unity版本LightDataAssets是无法动态加载,所以,实时全局光也不可能还原到,只能折中的利用灯光烘焙的贴图来代替,这是实时运行的API








      



2017-12-20 18:31:16 egostudio 阅读数 2026

最近在弄多语言,发现游戏中的字体库里面没有俄文导致显示俄文的时候不正常,没办法,只能切换语言的时候也切换支持俄文的字体库了,项目中使用NGUI的UILabel的地方,直接切换label.bitmapFont = realFont;就搞定了。没想到使用了TextMesh的地方,直接label.font=realFont;之后,文字显示就错乱了。如下图:


弄了大半天,考虑是不是Font.textureRebuilt的问题,发现这个事件根本就没调用。

最后终于发现了其中的猫腻...




原来切换之后,MeshRender里面的Meterial关联的还是旧字体的Meterial,因为Meterial不一样,里面的纹理也不一样,所以难怪会错乱。

知道问题就好办了,切换字体的时候,顺便修改下MeshRender的Meterials就搞定了。

if (label.font!=realFont) {
			label.font = realFont;
			//修复替换字体后文字错乱
			MeshRenderer meshRender = label.GetComponent<MeshRenderer> ();
			if (meshRender != null) {
				meshRender.materials = new Material[]{ realFont.material };
			}
		}


2020-05-19 18:39:56 msy7580237 阅读数 385

一图流。
在这里插入图片描述
本教程一共仅有三步操作,不涉及任何代码。
只需要跟着我配置,3分钟搞定Unity Text Mesh Pro的中文支持。

视频教程:
B站地址:https://www.bilibili.com/video/BV1a5411s73Q/

Unity

字库资源已上传。(资源挂了可以留言我补档

2013-06-11 23:56:29 ruishuang8520 阅读数 2193

原创文章如需转载请注明:转载自雨松MOMO程序研究院

本文链接地址:雨松MOMO《Unity 3D游戏开发》源码公布

下载源码时,首先大家请登陆图灵社区找到《Unity 3D游戏开发》这本书。

图灵社区网址:http://www.ituring.com.cn/book/1015

 

 

注意:源码的第六章和第十章文件超过500M。因为115网盘有限制500M以上的文件不能使用普通下载,需要使用优蛋下载,无需登陆下载安装即可,这一点很郁闷啊。。万恶的115 

Mac 下载地址 :  http://pc.115.com/download/mac/115_mac_v1.0.21.120627.dmg

Windows下载地址 :  http://pc.115.com/download/115UDown_3.3.1.13.exe

 

如上图所示

1 进入随书下载页面

2.点击“《Unity 3D游戏开发》源代码.txt”下载完毕后,打开该文件查找每章下载地址。

3. Mac 与 Windows下所有源码都是在最新的Unity3.5版本下进行编写,其它版本没有调试过不知道是否存在兼容错误等问题。

注意:如果你的操作系统是mac请在这里下载。

鉴于本书的源代码比较大,所以将其放到115网盘上了,详细链接地址如下:

http://115.com/file/e74xu18l#     Unity3D游戏开发第2章源码.zip
http://115.com/file/anwrkm92# Unity3D游戏开发第3章源码.zip
http://115.com/file/e74x5653# Unity3D游戏开发第4章源码.zip
http://115.com/file/anwrxayf# Unity3D游戏开发第5章源码.zip
http://115.com/file/dpbjp1gg# Unity3D游戏开发第6章源码.zip (非常抱歉,网盘超过500M的文件没有普通下载的,请使用优蛋下载)
http://115.com/file/dpbjkz8r# Unity3D游戏开发第7章源码.zip
http://115.com/file/be9n1ojb# Unity3D游戏开发第8章源码.zip
http://115.com/file/dpbj1j1h# Unity3D游戏开发第9章源码.zip
http://115.com/file/be91wx8t# Unity3D游戏开发第10章源码.zip 非常抱歉,网盘超过500M的文件没有普通下载的,请使用优蛋下载)


说明:因为所有文件是在Mac下压缩的,所以在Windows下解压时可能会出现名称乱码的情况。 如何查看源码在《Unity 3D游戏开发》中已经写的比较清楚,如果不清楚的读者还请仔细查看书籍。

 

2012年7月4日补充:

注意:如果你的操作系统是windows请在这里下载。

http://115.com/file/dpkphtih# Unity3D游戏开发第2章源码.zip

http://115.com/file/bemeqizo# Unity3D游戏开发第3章源码.zip

http://115.com/file/ancn78c4# Unity3D游戏开发第4章源码.zip

http://115.com/file/bemeqfm6# Unity3D游戏开发第5章源码.zip

http://115.com/file/e7j7ap8l# Unity3D游戏开发第6章源码.zip 非常抱歉,网盘超过500M的文件没有普通下载的,请使用优蛋下载)

http://115.com/file/ancejjx7# Unity3D游戏开发第7章源码.zip

http://115.com/file/bemjcaob# Unity3D游戏开发第8章源码.zip

http://115.com/file/ancec1co# Unity3D游戏开发第9章源码.zip

http://115.com/file/dpkpg9fy# Unity3D游戏开发第10章源码.zip 非常抱歉,网盘超过500M的文件没有普通下载的,请使用优蛋下载)

 

如下图所示,windows用户请注意,源码的所有路径不要包含中文路径,全部使用英文路径。如果含有中文在windows下将无法打开。切记切记!! (mac下可以出现中文路径)

 

解压后在对应章节的源码中找到场景文件,双击打开即可。

 

 

最后即可在windows中运行源码中的内容。

 

 

因为部分游戏工程中在编辑器中设定了某些特定的参数,所以MOMO感觉导出.unitypacakage并不是特别适合初学者,因为有关编辑器的选项不配置可能导致程序无法顺利运行。所以还是将完整的工程放出。

 

补充:《Unity 3D游戏开发》本书在国内各大网店均有销售,如果您想购买可直接在网店中搜索 “Unity 3D游戏开发”关键字 即可找到,雨松MOMO再次感谢大家的支持,愿我们在程序的路上一起努力,一起加油,哇咔咔。

 

欢迎大家常来 雨松MOMO程序研究院和我们一起讨论游戏开发。

本书的完整游戏目录如下:

目  录

第1章 基础知识 1

1.1 Unity简介 1

1.2 下载与安装 2

1.3 游戏界面对比 8

1.4 购买许可证 10

1.5 打包与发布 13

1.6 本章小结 16

第2章 编辑器的结构 17

2.1 游戏工程 17

2.1.1 创建工程 17

2.1.2 打开工程 19

2.2 Project视图 20

2.3 Hierarchy视图 23

2.4 Inspector视图 24

2.4.1 简介 24

2.4.2 平台设定 25

2.5 Scene视图 26

2.5.1 视图介绍 27

2.5.2 移动视图 28

2.5.3 场景工具 32

2.5.4 Scene视图控制条 33

2.6 Game视图 35

2.6.1 运行游戏 35

2.6.2 Game视图控制条 35

2.6.3 导出与导入 38

2.7 第一个游戏实例(拓展训练) 38

2.8 本章小结 42

第3章 GUI游戏界面 43

3.1 GUI高级控件 43

3.1.1 Label控件 43

3.1.2 Button控件 46

3.1.3 TextField控件 48

3.1.4 ToolBar控件 50

3.1.5 Slider控件 52

3.1.6 ScrollView控件 53

3.1.7 群组视图 55

3.1.8 窗口 56

3.1.9 GUI Skin 58

3.1.10 自定义风格组件 62

3.2 GUILayout游戏界面布局 64

3.2.1 GUI与GUILayout的区别 64

3.2.2 GUILayoutOption界面布局设置 66

3.2.3 线性布局 67

3.2.4 控件偏移 68

3.2.5 对齐方式 69

3.2.6 实例——添加与关闭窗口 71

3.2.7 设置字体 73

3.2.8 显示中文 75

3.3 2D贴图与帧动画 77

3.3.1 绘制贴图 77

3.3.2 绘制动画 79

3.3.3 实例——人物移动 81

3.3.4 实例——用Unity开发2D游戏 83

3.4 游戏实例——游戏主菜单 88

3.5 本章小结 90

第4章 Unity游戏脚本 91

4.1 MonoDevelop脚本编辑器 91

4.1.1 编辑器简介 91

4.1.2 调试 92

4.2 Unity脚本的生命周期 95

4.3 利用脚本来操作游戏对象 95

4.3.1 创建游戏对象 96

4.3.2 获取游戏对象 97

4.3.3 添加组件与修改组件 102

4.3.4 发送广播与消息 104

4.3.5 克隆游戏对象 105

4.3.6 脚本组件 106

4.4 用脚本来控制对象的变换 108

4.4.1 改变游戏对象的位置 109

4.4.2 旋转游戏对象 110

4.4.3 平移游戏对象 112

4.4.4 缩放游戏对象 113

4.5 用C#编写脚本 115

4.5.1 继承MonoBehaviour类 115

4.5.2 声明变量 116

4.5.3 调用方法 116

4.5.4 JavaScript与C#脚本之间的通信 119

4.6 工具类 122

4.6.1 时间 122

4.6.2 等待 123

4.6.3 随机数 124

4.6.4 数学 124

4.6.5 四元数 125

4.7 游戏实例——小地图的制作 126

4.8 本章小结 130

第5章 游戏元素 131

5.1 游戏地形 131

5.1.1 创建地形 131

5.1.2 地形参数 132

5.1.3 编辑地形 133

5.1.4 地形贴图 136

5.2 地形元素 140

5.2.1 树元素 140

5.2.2 草与网格元素 142

5.2.3 其他设置 144

5.3 光源 145

5.3.1 点光源(Point Light) 146

5.3.2 聚光灯 147

5.3.3 平行光 148

5.4 天空盒子 149

5.4.1 Skybox组件 149

5.4.2 在场景中添加天空盒子 151

5.5 常用编辑器组件 152

5.5.1 摄像机 152

5.5.2 摄像机的类型 153

5.5.3 定制导航菜单栏 155

5.5.4 预设 157

5.5.5 抗锯齿 159

5.6 游戏实例——摄像机切换镜头 162

5.7 本章小结 164

第6章 物理引擎 165

6.1 刚体 165

6.1.1 简单使用 165

6.1.2 物理管理器 167

6.1.3 力 168

6.1.4 碰撞与休眠 169

6.2 碰撞器 170

6.2.1 添加碰撞器 171

6.2.2 物理材质 171

6.3 角色控制器 173

6.3.1 第一人称 173

6.3.2 第三人称 175

6.3.3 控制组件 176

6.3.4 移动与飞行 178

6.3.5 碰撞监测 180

6.4 射线 182

6.4.1 射线的原理 182

6.4.2 碰撞监测 183

6.5 关节 185

6.5.1 关节介绍 185

6.5.2 实例——关节组件 186

6.6 粒子特效 188

6.6.1 粒子发射器 188

6.6.2 粒子动画 189

6.6.3 粒子渲染器 190

6.6.4 粒子效果实例 191

6.6.5 布料 193

6.6.6 路径渲染 196

6.7 游戏实例——击垮围墙 198

6.8 本章小结 200

第7章 输入与控制 201

7.1 键盘事件 201

7.1.1 按下事件 201

7.1.2 抬起事件 203

7.1.3 长按事件 205

7.1.4 任意键事件 205

7.1.5 实例——组合按键 206

7.2 鼠标事件 211

7.2.1 按下事件 211

7.2.2 抬起事件 212

7.2.3 长按事件 213

7.3 自定义按键事件 214

7.3.1 输入管理器 214

7.3.2 按键事件 215

7.3.3 按键轴 216

7.3.4 实例——观察模型 217

7.4 模型与动画 219

7.4.1 模型的载入 219

7.4.2 设置3D动画 220

7.4.3 播放3D动画 221

7.4.4 动画剪辑 222

7.4.5 动画的帧 224

7.5 GL图像库 226

7.5.1 绘制线 226

7.5.2 实例——绘制曲线 228

7.5.3 绘制四边形 230

7.5.4 绘制三角形 232

7.5.5 绘制3D几何图形 233

7.5.6 线渲染器 236

7.5.7 网格渲染 239

7.6 游戏实例——控制人物移动 241

7.7 本章小结 243

第8章 持久化数据 244

8.1 PlayerPrefs类 244

8.1.1 保存与读取数据 244

8.1.2 删除数据 245

8.1.3 实例——注册界面 245

8.2 自定义文件 247

8.2.1 文件的创建与写入 247

8.2.2 文件的读取 248

8.2.3 实例——读取笑话 250

8.3 应用程序 253

8.3.1 创建关卡 253

8.3.2 切换关卡 253

8.3.3 截屏 254

8.3.4 打开网页 255

8.3.5 退出游戏 256

8.4 资源数据库 256

8.4.1 加载资源 256

8.4.2 创建资源 257

8.4.3 创建文件夹 258

8.4.4 移动与复制 260

8.4.5 删除与刷新 260

8.4.6 实例——鼠标拖动模型 261

8.4.7 实例——鼠标拣选 264

8.5 游戏实例——接受任务 265

8.6 本章小结 270

第9章 多媒体与网络 271

9.1 游戏音频 271

9.1.1 音频介绍 271

9.1.2 添加音频 271

9.1.3 播放音频 273

9.2 游戏视频 275

9.2.1 创建视频 275

9.2.2 播放视频 276

9.2.3 GUI播放视频 278

9.3 网络 279

9.3.1 下载文件 279

9.3.2 自定义资源包 281

9.3.3 下载资源包 283

9.3.4 创建本地服务器 285

9.3.5 客户端连接服务器 289

9.3.6 实例——多人聊天服务器端 290

9.3.7 实例——多人聊天客户端 292

9.4 游戏实例——简单的网络游戏 297

9.5 本章小结 304

第10章 游戏实例——突出重围 305

10.1 游戏状态机 305

10.2 游戏界面 307

10.2.1 游戏主菜单 307

10.2.2 制作角色血条 311

10.2.3 制作图片数字 312

10.3 游戏逻辑 314

10.3.1 发射子弹与击打目标 314

10.3.2 敌人的AI 318

10.3.3 增加敌人预设 321

10.4 完整的游戏 322

10.5 本章小结 334

java电子书资源

阅读数 8621

centos

阅读数 14

个人学习积累

阅读数 177