Skip to content

Commit fe3c64a

Browse files
committed
Merge remote-tracking branch 'upstream/master' into text_edit
2 parents 8c5987f + 9715d21 commit fe3c64a

File tree

15 files changed

+371
-202
lines changed

15 files changed

+371
-202
lines changed

README-ZH.md

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
# UIWidgets
2+
3+
4+
## 介绍
5+
6+
UIWidgets是Unity编辑器的一个插件包,可帮助开发人员通过Unity引擎来创建、调试和部署高效的跨平台应用。
7+
8+
UIWidgets主要来自[Flutter](https://github.com/flutter/flutter)。但UIWidgets通过使用强大的Unity引擎为开发人员提供了许多新功能,显著地改进他们开发的应用性能和工作流程。
9+
10+
#### 效率
11+
通过使用最新的Unity渲染SDK,UIWidgets应用可以非常快速地运行并且大多数时间保持大于60fps的速度。
12+
13+
#### 跨平台
14+
与任何其他Unity项目一样,UIWidgets应用可以直接部署在各种平台上,包括PC,移动设备和网页等。
15+
16+
#### 多媒体支持
17+
除了基本的2D UI之外,开发人员还能够将3D模型,音频,粒子系统添加到UIWidgets应用中。
18+
19+
20+
#### 开发者友好
21+
开发者可以使用许多高级工具,如CPU/GPU Profiling和FPS Profiling,直接在Unity Editor中调试UIWidgets应用。
22+
23+
24+
## 使用要求
25+
26+
#### Unity
27+
安装 Unity 2018.3 或更高版本。 你可以从[https://unity3d.com/get-unity/download](https://unity3d.com/get-unity/download)下载最新的Unity。
28+
29+
#### UIWidgets包
30+
31+
访问我们的Github存储库 [https://github.com/UnityTech/UIWidgets](https://github.com/UnityTech/UIWidgets)下载最新的UIWidgets包。
32+
33+
将下载的包文件夹移动到 Unity项目 的 Package 文件夹中。
34+
35+
通常,你可以在控制台(或终端)应用程序中输入下面的代码来完成这个操作:
36+
37+
38+
```none
39+
cd <YourProjectPath>/Packages
40+
git clone https://github.com/UnityTech/UIWidgets.git com.unity.uiwidgets
41+
```
42+
43+
## 入门指南
44+
45+
#### 一、 概观
46+
在本教程中,我们将创建一个非常简单的UIWidgets应用。 该应用只包含文本标签和按钮。 文本标签将计算按钮上的点击次数。
47+
48+
首先,请打开或创建Unity项目并使用Unity编辑器打开它。
49+
50+
然后打开Project Settings,转到Player部分并将“UIWidgets_DEBUG”添加到Scripting Define Symbols字段中。
51+
52+
这样就启动了UIWidgets的调试模式。 在之后发布版本的时候清空这个字段。
53+
54+
#### 二、 场景构建
55+
56+
UIWidgets应用通常构建在Unity UI Canvas上。 请按照以下步骤在Unity中创建一个
57+
UI Canvas。
58+
1. 选择 File > New Scene来创建一个新场景。
59+
2. 选择 GameObject > UI > Canvas 在场景中创建UI Canvas。
60+
3. 右键单击Canvas并选择UI > Panel,将面板(即面板1)添加到UI Canvas中。 然后删除面板中的 **Image** 组件。
61+
62+
#### 三、创建小部件
63+
64+
UIWidgets应用是用**C#脚本**来编写的。 请按照以下步骤创建应用程序并在Unity编辑器中播放。
65+
1. 创建一个新C#脚本,命名为“ExampleCanvas.cs”,并将以下代码粘贴到其中。
66+
67+
```none
68+
using System.Collections.Generic;
69+
using Unity.UIWidgets.engine;
70+
using Unity.UIWidgets.foundation;
71+
using Unity.UIWidgets.material;
72+
using Unity.UIWidgets.painting;
73+
using Unity.UIWidgets.widgets;
74+
75+
namespace UIWidgetsSample {
76+
public class ExampleCanvas : WidgetCanvas {
77+
protected override void OnEnable() {
78+
base.OnEnable();
79+
80+
// Application.targetFrameRate = 60; // or higher if you want a smoother scrolling experience.
81+
82+
// if you want to use your own font or font icons.
83+
// FontManager.instance.addFont(Resources.Load<Font>(path: "path to your font"), "font family name");
84+
85+
// load custom font with weight & style. The font weight & style corresponds to fontWeight, fontStyle of
86+
// a TextStyle object
87+
// FontManager.instance.addFont(Resources.Load<Font>(path: "path to your font"), "Roboto", FontWeight.w500,
88+
// FontStyle.italic);
89+
90+
// add material icons, familyName must be "Material Icons"
91+
// FontManager.instance.addFont(Resources.Load<Font>(path: "path to material icons"), "Material Icons");
92+
}
93+
94+
protected override Widget getWidget() {
95+
return new ExampleApp();
96+
}
97+
98+
class ExampleApp : StatefulWidget {
99+
public ExampleApp(Key key = null) : base(key) {
100+
}
101+
102+
public override State createState() {
103+
return new ExampleState();
104+
}
105+
}
106+
107+
class ExampleState : State<ExampleApp> {
108+
int counter = 0;
109+
110+
public override Widget build(BuildContext context) {
111+
return new Column(
112+
children: new List<Widget> {
113+
new Text("Counter: " + this.counter),
114+
new GestureDetector(
115+
onTap: () => {
116+
this.setState(()
117+
=> {
118+
this.counter++;
119+
});
120+
},
121+
child: new Container(
122+
padding: EdgeInsets.symmetric(20, 20),
123+
color: Colors.blue,
124+
child: new Text("Click Me")
125+
)
126+
)
127+
}
128+
);
129+
}
130+
}
131+
}
132+
}
133+
```
134+
135+
2. 保存此脚本,并将其附加到Panel 1中作为其组件。
136+
3. 在Unity编辑器中,点击Play按钮来启动应用。
137+
138+
#### 四、构建应用程序
139+
140+
最后,你可以按以下步骤将UIWidgets应用构建成适用于任何特定平台的应用程序包。
141+
1. 选择**File** > **Build Settings...**打开Build Settings面板。
142+
2. 选择目标平台,点击Build。 之后Unity编辑器将自动组装所有相关资源并生成最终的应用程序包。
143+
144+
#### 如何加载图像?
145+
1. 将你的图像文件,如image1.png,放在Resources文件夹中。
146+
2. 你可以在同一文件夹中添加image1@2.pngimage1@3.png以支持高清屏幕显示。
147+
3. 使用Image.asset(“image1”)加载图像。 注意:因为是在Unity中,所以不需要添加.png后缀。
148+
149+
150+
UIWidgets也支持Gif!
151+
1. 假设你有一个loading1.gif文件,将其重命名为loading1.gif.bytes并复制到Resources文件夹。
152+
2. 你可以在同一文件夹中添加loading1@2.gif.bytesloading1@3.gif.bytes以支持高清屏幕显示。
153+
3. 使用Image.asset(“loading1.gif”)加载gif图像。
154+
155+
156+
## 调试UIWidgets应用程序
157+
158+
#### 定义UIWidgets_DEBUG
159+
我们建议在Unity编辑器中定义 UIWidgets_DEBUG 脚本符号,这将打开UIWidgets中的调试断言(debug assertion),有助于更早发现潜在的Bug。
160+
因此选择 **Player Settings** > **Other Settings** > **Configuration** > **Scripting Define Symbols** ,并添加 UIWidgets_DEBUG。
161+
该符号仅供调试使用,请在发布版本中删除它。
162+
163+
#### UIWidgets Inspector
164+
165+
UIWidgets Inspector工具用于可视化和浏览窗口小部件树。 你可以在Unity编辑器的**Window** > **Analysis** > **UIWidget Inspector** 中的找到它。
166+
167+
注意
168+
- 需要定义 UIWidgets_DEBUG 使inspector正常工作。
169+
- Inspector目前仅适用于编辑器的播放模式,目前不支持独立版本的应用程序。
170+
171+
172+
## 学习
173+
174+
#### 示例
175+
176+
你可以在**Samples**文件夹的UIWidgets包中找到许多UIWidgets应用示例。请随意尝试并进行修改以查看结果。
177+
178+
你也可以在支持**UIWidgets**的编辑器中,点击主菜单上的UIWidgets,并在下拉窗口中选择一个示例。
179+
180+
#### Wiki
181+
182+
目前开发团队仍在改进UIWidgets Wiki。 由于UIWidgets主要来源于Flutter,你也可以参考Flutter Wiki中与UIWidgets API对应部分的详细描述。
183+
184+
#### 常问问题解答
185+
186+
| 问题 | 回答 |
187+
| :-----------------------------------------------| ---------------------: |
188+
| 我可以使用UIWidgets创建独立应用吗? | 可以 |
189+
| 我可以使用UIWidgets构建游戏UI吗? | 可以 |
190+
| 我可以使用UIWidgets开发Unity编辑器插件吗? | 可以 |
191+
| UIWidgets是UGUI / NGUI的扩展吗? | 不是 |
192+
| UIWidgets只是Flutter的副本吗? | 不是 |
193+
| 我可以通过简单的拖放操作来创建带有UIWidgets的UI吗? | 不可以 |
194+
| 我是否需要付费使用UIWidgets? | 不需要 |
195+
| 有推荐的适用于UIWidgets的IDE吗? | Rider, VSCode(Open .sln) |
196+
197+
## 如何贡献
198+
如果你想加入我们,请通过Github与我们联系,我们将尽快回复。
199+
200+
#### 代码风格
201+
1. 导入自定义代码清理设置
202+
打开首选项 - >管理图层,选择“解决方案“<YourProjectName>“个人”,然后单击“添加图层”(“+”) > “打开设置文件...”。并打开<YourProjectPath> /Packages/com.unity.uiwidgets/下的文件“UIWidgetCleanupPlugin.DotSettings”。
203+
204+
2. 使用自定义代码清理设置清理代码样式
205+
打开代码 - >代码清理,根据需要选择一个清理范围,选择“UIWidgets”作为“代码清理配置文件”,然后单击“确定”。
206+
207+
208+
3. 优化代码样式规则
209+
编辑<YourProjectPath> /Packages/com.unity.uiwidgets/“下的”.editorconfig“文件。获得更多详细信息,请访问[https://www.jetbrains.com/help/rider/EditorConfig_Index.html](https://www.jetbrains.com/help/rider/EditorConfig_Index.html)
210+
211+
#### 生成njk代码
212+
213+
1. 转到脚本文件夹并运行npm install。
214+
```
215+
cd <YourProjectPath>/Packages/com.unity.uiwidgets/scripts
216+
npm install
217+
```
218+
2. 运行codegen命令。
219+
```
220+
node uiwidgets-cli.js codegen . generate mixin code
221+
```

README-ZH.md.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# UIWidgets
2+
[中文](README-ZH.md)
23

34

45
## Introduction
@@ -71,7 +72,7 @@ only a text label and a button. The text label will count the times of clicks up
7172

7273
First of all, please open or create a Unity Project and open it with Unity Editor.
7374

74-
And then open Project Settings, go to Player section and add "UIWidgets_DEBUG" to the Scripting Debug Symbols field.
75+
And then open Project Settings, go to Player section and add "UIWidgets_DEBUG" to the Scripting Define Symbols field.
7576
This enables the debug mode of UIWidgets for your development. Remove this for your release build afterwards.
7677

7778
#### ii. Scene Build
@@ -204,8 +205,10 @@ via *Window/Analysis/UIWidgets* inspector in Editor menu.
204205
## Learn
205206

206207
#### Samples
207-
You can find many UIWidgets App samples in the UIWidgets package in the **Samples** folder.
208+
You can find many UIWidgets App samples in the UIWidgets package in the **Samples** folder.
208209
Feel free to try them out and make modifications to see the results.
210+
To get started, the UIWidgetsTheatre scene provides you
211+
a list of carefully selected samples to start with.
209212

210213
You can also try UIWidgets-based Editor windows by clicking **UIWidgetsTest** on the main menu
211214
and open one of the dropdown samples.

Runtime/editor/editor_window.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,15 @@ protected virtual void OnGUI() {
5757
this._windowAdapter.OnGUI(Event.current);
5858
}
5959

60+
float? lastUpdateTime;
6061
protected virtual void Update() {
62+
if (this.lastUpdateTime != null) {
63+
float deltaTime = (float)EditorApplication.timeSinceStartup - this.lastUpdateTime.Value;
64+
PerformanceUtils.instance.updateDeltaTime(deltaTime);
65+
}
66+
67+
this.lastUpdateTime = (float) EditorApplication.timeSinceStartup;
68+
6169
this._windowAdapter.Update();
6270
}
6371

Runtime/ui/painting/path.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,19 @@ void _appendCommands(float[] commands) {
136136
var cmd = (PathCommand) commands[i];
137137
switch (cmd) {
138138
case PathCommand.moveTo:
139+
this._commandx = commands[i + 1];
140+
this._commandy = commands[i + 2];
141+
i += 3;
142+
break;
139143
case PathCommand.lineTo:
144+
this._expandBounds(this._commandx, this._commandy);
140145
this._expandBounds(commands[i + 1], commands[i + 2]);
141146
this._commandx = commands[i + 1];
142147
this._commandy = commands[i + 2];
143148
i += 3;
144149
break;
145150
case PathCommand.bezierTo:
151+
this._expandBounds(this._commandx, this._commandy);
146152
this._expandBounds(commands[i + 1], commands[i + 2]);
147153
this._expandBounds(commands[i + 3], commands[i + 4]);
148154
this._expandBounds(commands[i + 5], commands[i + 6]);
@@ -1115,6 +1121,7 @@ public void addPoint(float x, float y, PointFlags flags) {
11151121
void _addPoint(PathPoint point) {
11161122
if (this._paths.Count == 0) {
11171123
this.addPath();
1124+
this.addPoint(0, 0, PointFlags.corner);
11181125
}
11191126

11201127
var path = this._paths.Last();

Runtime/widgets/automatic_keep_alive.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ public override void dispose() {
239239
this.GetType() +
240240
" created a Ticker via its TickerProviderStateMixin, but at the time " +
241241
"dispose() was called on the mixin, that Ticker was still active. All Tickers must " +
242-
"be disposed before calling super.dispose(). Tickers used by AnimationControllers " +
242+
"be disposed before calling base.dispose(). Tickers used by AnimationControllers " +
243243
"should be disposed by calling dispose() on the AnimationController itself. " +
244244
"Otherwise, the ticker will leak.\n" +
245245
"The offending ticker was: " + ticker.toString(debugIncludeStack: true)

Runtime/widgets/framework.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2296,7 +2296,7 @@ public override void unmount() {
22962296
}
22972297

22982298
throw new UIWidgetsError(
2299-
this._state.GetType() + ".dispose failed to call super.dispose.\n" +
2299+
this._state.GetType() + ".dispose failed to call base.dispose.\n" +
23002300
"dispose() implementations must always call their superclass dispose() method, to ensure " +
23012301
"that all the resources used by the widget are fully released.");
23022302
});

Runtime/widgets/ticker_provider.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public override void dispose() {
6161
this + " was disposed with an active Ticker.\n" +
6262
this.GetType() + " created a Ticker via its SingleTickerProviderStateMixin, but at the time " +
6363
"dispose() was called on the mixin, that Ticker was still active. The Ticker must " +
64-
"be disposed before calling super.dispose(). Tickers used by AnimationControllers " +
64+
"be disposed before calling base.dispose(). Tickers used by AnimationControllers " +
6565
"should be disposed by calling dispose() on the AnimationController itself. " +
6666
"Otherwise, the ticker will leak.\n" +
6767
"The offending ticker was: " + this._ticker.toString(debugIncludeStack: true)
@@ -129,7 +129,7 @@ public override void dispose() {
129129
this.GetType() +
130130
" created a Ticker via its TickerProviderStateMixin, but at the time " +
131131
"dispose() was called on the mixin, that Ticker was still active. All Tickers must " +
132-
"be disposed before calling super.dispose(). Tickers used by AnimationControllers " +
132+
"be disposed before calling base.dispose(). Tickers used by AnimationControllers " +
133133
"should be disposed by calling dispose() on the AnimationController itself. " +
134134
"Otherwise, the ticker will leak.\n" +
135135
"The offending ticker was: " + ticker.toString(debugIncludeStack: true)

0 commit comments

Comments
 (0)