一、Unity概述
1、了解Unity的定位
使用 Unity 编辑器可创建 2D 和 3D 游戏、应用程序和体验。----Unity用户手册
Unity制作的游戏和应用,可以输出在各种平台运行的。
2、Unity的能力
从用户手册的列表了解得到,Unity包含:
Unity Editor,Unity 2D,图形,物理系统,网络,脚本,音频,动画,UI,AI,AR,Unity服务等。
Unity是整合美术产物,音频,脚本的一个强大平台,这一点与2D时期的Flash很相似,但功能强大很多。
二、Unity开发环境
1、安装
- https://unity.com/download 下载安装Unity Hub, Unity Hub用于管理不同版本的Unity Editor;
2. 登录Unity Hub后,可以选择获取Personal License开发;
3. 安装Unity Editor,勾选Android Build Support,可勾选VS作为C#.NET的IDE,如图;
- 一般项目会统一Unity Editor的版本,对于旧版本的Unity Editor,可以在https://unity3d.com/unity/qa/lts-releases 下载;
5. 除VS以外,jetbrains的Rider编写脚本更方便,
下载地址:https://www.jetbrains.com/rider/download/;
2、Unity Editor介绍
1. ToolBar:包括手形工具,移动工具,旋转工具,缩放工具,矩形变换工具,旋转、移动或缩放,播放按钮等工具;
2. Hierarchy窗口:此处列出场景中的所有游戏对象。游戏中的每个对象都是游戏对象 (GameObject)。
3. Scene视图: 在此区域,你可以通过选择和移动游戏3D 空间中的对象来编辑当前场景。
4. Inspector窗口:此区域显示与当前所选对象相关的所有设置,包括Component和Component的属性。
5. Project窗口:这是你管理项目资源的位置,包括图像、3D 模型和声音文件等。
3、Transform介绍
1. 新增的GameObject均默认有Transform的Component;
2. Transform在3D类型的GameObject上,控制GameObject的位置,旋转,缩放;
3. Rect Transform在2D UI(UGUI)的GameObject上,控制GameObject的位置,大小,锚点,中心,旋转,缩放等;
备注:UGUI的GameObject默认都需要放在Canvas下,Canvas也是GameObject;
三、Unity重要概念
1、重要概念
1. Scene(场景)
游戏通常由一个或多个Scene组成。小型游戏可能仅有一个Scene,而大型游戏可能有数百个Scene。Scene需要展示内容,需要添加GameObject。
2. GameObject(游戏对象)
在 Unity 中每个对象都作为GameObject存在。使用一个或多个Component装饰GameObject,可以赋予GameObject特定的功能。
3. Component(组件)
GameObject默认附带了一个变换Component,可以控制游戏对象在 3D(或 2D)游戏空间中的位置属性。在 Inspector 可以手动添加其他Component,一般。
4. Prefab(预制件)
Prefab用作模板,可以存储特定GameObject的Component和属性,并可以在Scene中创建Prefab的多个实例。例如一个固定样式的按钮就可以做成Prefab。
5. 给GameObject添加Component的脚本,一般继承MonoBehavior,MonoBehavior有系列的生命周期方法。
6. Unity的主线程是GL线程,与Android的主线程不一样;
7. Unity定时任务等,推荐使用协程,而不是Update中每一帧都检查;
8. Unity的脚本可以反射调用Android的Java类和方法;
9. Android的Java代码可以调用Unity中MonoBehavior脚本的方法,脚本方法运行在GL线程,故没有返回值;
10. Unity中使用的是左手坐标系;
11. 在UGUI中,即2D坐标系也保持x轴向右,y轴向下的规则,且原点在左上方,
这一点与Android的中y轴向下的坐标系不一样;
2、MonoBehavior生命周期
图片链接:https://docs.unity3d.com/uploads/Main/monobehaviour_flowchart.svg
MonoBehavior常用生命周期方法:
> Awake >OnEnable >Start
> FixedUpdate >Update > LateUpdate
> OnApplicationQuit >OnDisable
1. Awake执行在GameObject被实例化后,方法里可以一些初始化操作,
例如Component引用,子GameObject引用等;
2. Start只执行一次,第一次OnEnable执行以后和第一帧绘制前;
3. OnEnable和OnDisable关联GameObject的active状态,调用setActive时有对应回调;
4. Update每一帧绘制前执行;
3、MonoBehavior脚本获取引用
1. 获取GameObject
a)脚本被添加在的GameObject,直接获取变量gameObejct;
b)获取父GameObject
GameObject gb1 = gameObject.transform.parent;
c)获取子GameObject
Transform t1 = gameObject.transform.Find("gameObjectName");
GameObject gb1 = t1.gameObject;
Transform t2 = transform.GetChild(index);
GameObject gb2 = t2.gameObject;
d)全局搜索GameObject
GameObject gb1 = GameObject.Find("gameObjectName");
GameObject gb2 = GameObject.FindGameObjectWithTag("tag");
GameObject[] gbs1 = GameObject.FindGameObjectsWithTag("tag");
2. 获取Component
a)获取当前GameObject其他脚本对象,例如: Text
Text textComponent = gameObject.GetComponent();
Text[] textComponents gameObject.GetComponents();
b)获取子GameObject其他脚本对象,例如: Text
Text textComponent = gameObject.GetComponentInChildren();
Text[] textComponents gameObject.GetComponentsInChildren();
c)获取父GameObject其他脚本对象,例如: Text
Text textComponent = gameObject.GetComponentInParent();
Text[] textComponents gameObject.GetComponentsInParent();
4、Unity与Android通信
1. C#调用Java
Unity提供反射接口调用Java的类方法
a)执行静态方法
Object obj = UnityService.get();
AndroidJavaClass androidJavaClass = new AndroidJavaClass("com.xiaopeng.musicradio.commonui.mono.UnityService");
AndroidJavaObject androidJavaObject = androidJavaClass.CallStatic("get");
b) 执行对象方法
UnityService.get().sendMessage("proxyName", "method");
AndroidJavaClass androidJavaClass = new AndroidJavaClass("com.xiaopeng.musicradio.commonui.mono.UnityService");
AndroidJavaObject androidJavaObject = androidJavaClass.CallStatic("get");
androidJavaObject.Call("sendMessage", "proxyName", "method");
2. Java调用C#
a)调用MonoBehavior的方法
假设场景中添加一个Text类型GameObject,定义gameObjectName为t_user_name;
并添加名为UserName的脚本,有回调方法OnUserNameUpdated;
public class UserName : MonoBehaviour
{
public void OnUserNameUpdated(string username)
{
Debug.Log("OnUserNameUpdated:" + username);
Text text = gameObject.GetComponent();
text.text = username;
}
}
UnityPlayer.UnitySendMessage("t_user_name", "OnUserNameUpdated", "username");
b)使用AndroidJavaProxy,调用Java方法时,传入Java监听接口映射的AndroidJavaProxy对象;
Java代码中,调用监听方法回调方法;
例如:Unity界面中添加按钮,弹出Android原生日期选择日期,C#通过AndroidJavaProxy得到数据;
class ExampleClass : MonoBehaviour
{
private static DateTime selectedDate = DateTime.Now;
class DateCallback : AndroidJavaProxy
{
public DateCallback() : base("android.app.DatePickerDialog$OnDateSetListener") {}
void onDateSet(AndroidJavaObject view, int year, int monthOfYear, int dayOfMonth)
{
selectedDate = new DateTime(year, monthOfYear + 1, dayOfMonth);
}
}
void OnGUI()
{
if (GUI.Button(15, 15, 450, 75), string.Format("{0:yyyy-MM-dd}", selectedDate)))
{
AndroidJavaClass activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic("currentActivity");
activity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
{
new AndroidJavaObject("android.app.DatePickerDialog", activity, new DateCallback(), selectedDate.Year, selectedDate.Month - 1, selectedDate.Day).Call("show");
}));
}
}
}
3. Unity脚本与Android Java层的数据序列化
Json:C#和Java定义相同的Bean类,一端把对象转为json字符串,另一端将json字符串解析为对象;
ProtoBuffer:两端协定一个proto文件,生成C#类文件和Java类文件,一端把对象数据序列化为byte数组,另一端将byte数组反序列化为对象;
5、打包Apk
1. Unity打包
a)菜单点击File > Build Settings;
b)选择Android;
c)可以通过Player Settings配置各项打包参数;
配置包名版本等
自定义签名
可选自定义Android的配置文件:
d)执行Build;
2. Android打包
a)菜单点击File > Build Settings,勾选Export Project,执行Export;
b)导出unityLibrary,引入到Android工程;
c)Android工程settings.gradle添加依赖unityLibrary后,可打包运行;
参考资料:
1. Unity Hub的Learn中有大量官方教学教程;
2. 推荐从Roll-a-Ball开始熟悉Unity3D;
3. Unity官方:脚本编程;