Skip to content
This repository was archived by the owner on Apr 29, 2021. It is now read-only.

Prepare for publishing to Package Manager #207

Open
wants to merge 80 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
9283ede
Tmp store.
May 16, 2019
b49f06b
Merge branch 'yczhang' into packman
May 17, 2019
079fc57
Update documentation.
May 17, 2019
733f91a
Implement packman script.
May 17, 2019
786e6b6
Implement asset store script.
May 17, 2019
51f26d9
Merge branch 'yczhang' into asset_store
May 20, 2019
63655ce
Copy Resources for sample.
May 20, 2019
6bc50b8
Update Menu Organization: Move everything into Window/UIWidgets.
May 20, 2019
ea17a50
Merge branch 'yczhang' into packman
May 20, 2019
886b4cc
Update Documentation.
May 21, 2019
e034f28
Merge branch 'yczhang' into asset_store
May 21, 2019
1735cfb
Update script and Documentation.
May 21, 2019
b043c91
Merge branch 'master' into yczhang
May 21, 2019
9af2353
Merge branch 'yczhang' into packman
May 21, 2019
8e59c50
Merge branch 'yczhang' into asset_store
May 21, 2019
e3b38cf
Update packman script.
May 21, 2019
6c018d8
Align with master.
May 21, 2019
b83d325
Improve packman.
May 21, 2019
b041d71
Improve packman.
May 21, 2019
de33c16
Update Documentation to multi-file structure.
May 22, 2019
d6de8ee
Update packman script.
May 22, 2019
b9e5b34
Update packman to generate documentation automatically.
May 22, 2019
22878a1
Fix packman script: copy README-ZH.
May 22, 2019
9bfd832
Merge branch 'yczhang' into asset_store
May 22, 2019
0902a2b
Update document.
May 22, 2019
131edec
Update packman script.
May 22, 2019
792a80a
Modify Images.
May 22, 2019
075a3da
Remove video.
May 23, 2019
31f031f
Fix error on 2019.2+.
May 24, 2019
156986c
Update packman alignment version.
May 24, 2019
926f37a
Merge branch 'asset_store' into yczhang
May 24, 2019
044a981
Merge branch 'master' into yczhang
Jun 4, 2019
d46cea0
Merge branch 'master' into yczhang
Jun 10, 2019
27b1c41
Merge branch 'master' into yczhang
Aug 22, 2019
47c8f52
Merge branch 'master' into yczhang
Aug 27, 2019
ba2314c
Change version to upload to packman.
Aug 27, 2019
11613e1
Merge branch 'master' of https://github.com/UnityTech/UIWidgets into …
Aug 28, 2019
726689e
Update packman uiwidgets target version.
Aug 28, 2019
548ed4c
Update the packman script, add the procedures to execute manually
Aug 28, 2019
4d1673a
Remove references to ugui.
Aug 28, 2019
4ba3ed3
Correct menus.
Aug 28, 2019
6151840
Update README.
Aug 28, 2019
c06d04f
Merge branch 'master' into yczhang
Oct 21, 2019
80d972e
Update uiwidgets version.
Oct 21, 2019
50275e3
Merge branch 'master' into yczhang
Oct 24, 2019
e0a2bec
Update version.
Oct 24, 2019
c8a2c6d
Merge branch 'master' into yczhang
Nov 8, 2019
7a22186
Update uiwidgets version.
Nov 11, 2019
85cef92
Merge branch 'master' into yczhang
Nov 13, 2019
e3ce7d7
Update UIWidgets version.
Nov 14, 2019
a71f5c2
Merge branch 'master' into yczhang
Nov 15, 2019
616b05c
Update uiwidgets version.
Nov 18, 2019
ea7d7cb
Merge branch 'master' of https://github.com/UnityTech/UIWidgets into …
Nov 18, 2019
3535924
Remove samples.
Nov 18, 2019
792b17e
Remove Tests/Resources.
Nov 18, 2019
a91e164
Remove Tests.
Nov 18, 2019
370b92e
Fix README.
Nov 18, 2019
c1a19fb
Merge branch 'master' into yczhang
Nov 19, 2019
f0c8495
Update UIWidgets version.
Nov 21, 2019
5160995
Merge branch 'master' into yczhang
Nov 25, 2019
152f2f7
Update packman scripts.
Nov 25, 2019
235f488
Update UIWidgets Version.
Nov 25, 2019
795ced5
Automatic resource importer.
Nov 26, 2019
3cf8e85
Update Unity Version.
Nov 29, 2019
988f051
Merge branch 'master' of https://github.com/UnityTech/UIWidgets into …
Nov 29, 2019
4fc5ee1
[Feature] Panel Raycast Filter
IIzzaya Nov 7, 2019
1334379
[Fix] Wrong Spelling Name
IIzzaya Nov 7, 2019
d1ebb51
[Raycast] Update
IIzzaya Nov 8, 2019
dd78120
[Raycast] Add UIWidgetsRaycastablePanel
IIzzaya Nov 9, 2019
368dc8f
[Raycast] Remove Debug.Log
IIzzaya Nov 9, 2019
e5b9bd5
[Raycast] Move Files' Location
IIzzaya Nov 30, 2019
abd4336
Update UIWidgets version.
Dec 6, 2019
d8b1506
Merge pull request #366 from IIzzaya/dev_raycast
zhuxingwei Dec 17, 2019
2b4c7ad
Add !UNITY_EDITOR for WebGLInput
Jan 2, 2020
844bac8
Merge branch 'fix_webgl' into yczhang
Jan 2, 2020
bcc17f2
Merge branch 'master' of github.com:UnityTech/UIWidgets into fix_tabl…
zhuxingwei Jan 2, 2020
0158191
fix potential dead loop
zhuxingwei Jan 2, 2020
a4dd4aa
Merge pull request #401 from UnityTech/fix_table_deadloop
Jan 2, 2020
e3c8bcc
Update UIWidgets version.
Jan 2, 2020
b2bdac4
Merge branch 'dev' into yczhang
Jan 2, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README-ZH.md
Original file line number Diff line number Diff line change
@@ -262,7 +262,6 @@ EmojiUtils.configuration = new EmojiResourceConfiguration(

我们提供了一个包装好的`UnityObjectDetector`组件以及`onRelease`回调函数,借此您可以实现简单地将物体(例如Hierarchy内的场景物体、Project窗口下的文件等)拖拽至区域内,来获得`UnityEngine.Object[] `类型的引用并进行操作。


## 调试UIWidgets应用程序

#### 定义UIWidgets_DEBUG
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -298,7 +298,6 @@ EmojiUtils.configuration = new EmojiResourceConfiguration(

With the provided packaged stateful widget `UnityObjectDetector` and its `onRelease` callback function, you can easily drag some objects (for example GameObject from Hierarchy, files from Project Window, etc) into the area, get the UnityEngine.Object[] references and make further modification.


## Debug UIWidgets Application

#### Define UIWidgets_DEBUG
2 changes: 1 addition & 1 deletion Runtime/debugger/inspector_window.cs
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ public class WidgetsInpsectorWindow : EditorWindow {

List<Action> m_UpdateActions = new List<Action>();

[MenuItem("Window/Analysis/UIWidgets Inspector")]
[MenuItem("Window/UIWidgets/Inspector")]
public static void Init() {
WidgetsInpsectorWindow window =
(WidgetsInpsectorWindow) GetWindow(typeof(WidgetsInpsectorWindow));
139 changes: 139 additions & 0 deletions Runtime/editor/UIWidgetsResourcesImporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#if UNITY_EDITOR
using UnityEngine.Serialization;
using System.IO;
using UnityEngine;
using UnityEditor;

namespace Unity.UIWidgets.editor
{
[System.Serializable]
public class UIWidgetsResourcesImporter
{
bool m_UIWidgetsResourcesImported;

public void OnDestroy()
{
}

public void OnGUI()
{
string packageFullPath = GetPackageFullPath();
m_UIWidgetsResourcesImported = Directory.Exists("Assets/UIWidgetsResources") ||
Directory.Exists(packageFullPath + "/Runtime/Resources/fonts");
// Display options to import Essential resources
GUILayout.BeginVertical(EditorStyles.helpBox);
{
GUILayout.Label("UIWidgets Resources", EditorStyles.boldLabel);
GUILayout.Label("We need to add resources to your project that are essential for using UIWidgets. " +
"These new resources will be placed at the root of your project in the \"UIWidgetsResources\" folder.",
new GUIStyle(EditorStyles.label) { wordWrap = true } );
GUILayout.Space(5f);

GUI.enabled = !m_UIWidgetsResourcesImported;
if (GUILayout.Button("Import UIWidgets Resources"))
{
AssetDatabase.importPackageCompleted += ImportCallback;

AssetDatabase.ImportPackage(packageFullPath + "/Package Resources/UIWidgetsResources.unitypackage", false);
}
GUILayout.Space(5f);
GUI.enabled = true;
}
GUILayout.EndVertical();
GUILayout.Space(5f);
}

internal void RegisterResourceImportCallback()
{
AssetDatabase.importPackageCompleted += ImportCallback;
}

void ImportCallback(string packageName)
{
if (packageName == "UIWidgetsResources")
{
m_UIWidgetsResourcesImported = true;

#if UNITY_2018_3_OR_NEWER
SettingsService.NotifySettingsProviderChanged();
#endif
}

Debug.Log("[" + packageName + "] have been imported.");

AssetDatabase.importPackageCompleted -= ImportCallback;
}

static string GetPackageFullPath()
{
string packagePath = Path.GetFullPath("Packages/com.unity.uiwidgets");
if (Directory.Exists(packagePath))
{
return packagePath;
}

packagePath = Path.GetFullPath("Packages/UIWidgets");
if (Directory.Exists(packagePath))
{
return packagePath;
}

packagePath = Path.GetFullPath("Assets/UIWidgets");
if (Directory.Exists(packagePath))
{
return packagePath;
}

return null;
}
}

public class UIWidgetsResourcesImporterWindow : EditorWindow
{
[FormerlySerializedAs("m_ResourceImporter")] [SerializeField]
UIWidgetsResourcesImporter resourcesImporter;

public static void ShowResourcesImporterWindow()
{
var window = GetWindow<UIWidgetsResourcesImporterWindow>();
window.titleContent = new GUIContent("UIWidgets Resources Importer");
window.Focus();
}

void OnEnable()
{
SetEditorWindowSize();

if (resourcesImporter == null)
resourcesImporter = new UIWidgetsResourcesImporter();
resourcesImporter.RegisterResourceImportCallback();
}

void OnDestroy()
{
resourcesImporter.OnDestroy();
}

void OnGUI()
{
resourcesImporter.OnGUI();
}

void OnInspectorUpdate()
{
Repaint();
}

void SetEditorWindowSize()
{
EditorWindow editorWindow = this;

Vector2 windowSize = new Vector2(640, 110);
editorWindow.minSize = windowSize;
editorWindow.maxSize = windowSize;
}
}

}

#endif
11 changes: 11 additions & 0 deletions Runtime/editor/UIWidgetsResourcesImporter.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions Runtime/engine/UIWidgetsPanel.cs
Original file line number Diff line number Diff line change
@@ -138,6 +138,13 @@ void _handleViewMetricsChanged(string method, List<JSONNode> args) {
this._displayMetrics.onViewMetricsChanged();
}

protected virtual void InitWindowAdapter() {
D.assert(this._windowAdapter == null);
this._windowAdapter = new UIWidgetWindowAdapter(this);

this._windowAdapter.OnEnable();
}

protected override void OnEnable() {
base.OnEnable();

@@ -153,10 +160,7 @@ protected override void OnEnable() {
_repaintEvent = new Event {type = EventType.Repaint};
}

D.assert(this._windowAdapter == null);
this._windowAdapter = new UIWidgetWindowAdapter(this);

this._windowAdapter.OnEnable();
this.InitWindowAdapter();

Widget root;
using (this._windowAdapter.getScope()) {
8 changes: 8 additions & 0 deletions Runtime/engine/raycastable.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

125 changes: 125 additions & 0 deletions Runtime/engine/raycastable/RaycastManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
using UnityEngine;

namespace Unity.UIWidgets.engine.raycast {
public class RaycastableRect {
bool _isDirty = true;

public bool isDirty {
get { return this._isDirty; }
}

public float left;
public float right;
public float top;
public float bottom;

public void MarkDirty() {
this._isDirty = true;
}

public void UnmarkDirty() {
this._isDirty = false;
}

public void UpdateRect(float left, float top, float width, float height) {
this.left = left;
this.right = left + width;
this.top = top;
this.bottom = top + height;
}

public bool CheckInRect(Vector2 pos) {
return pos.x >= this.left &&
pos.x < this.right &&
pos.y >= this.top &&
pos.y < this.bottom;
}
}

public class RaycastManager {
static RaycastManager _instance;

public static RaycastManager instance {
get {
if (_instance == null) {
_instance = new RaycastManager();
}

return _instance;
}
}

public readonly Dictionary<int, Dictionary<int, RaycastableRect>> raycastHandlerMap =
new Dictionary<int, Dictionary<int, RaycastableRect>>();

public static void NewWindow(int windowHashCode) {
if (!instance.raycastHandlerMap.ContainsKey(windowHashCode)) {
instance.raycastHandlerMap.Add(windowHashCode, new Dictionary<int, RaycastableRect>());
}
}

public static void DisposeWindow(int windowHashCode) {
if (instance.raycastHandlerMap.ContainsKey(windowHashCode)) {
instance.raycastHandlerMap.Remove(windowHashCode);
}
}

public static void AddToList(int widgetHashCode, int windowHashCode) {
D.assert(instance.raycastHandlerMap.ContainsKey(windowHashCode), () =>
$"Raycast Handler Map doesn't contain Window {windowHashCode}, " +
$"Make sure using UIWidgetsRaycastablePanel instead of UIWidgetsPanel " +
$"while using RaycastableContainer.");
D.assert(!instance.raycastHandlerMap[windowHashCode].ContainsKey(widgetHashCode), () =>
$"Raycast Handler Map already contains Widget {widgetHashCode} at Window {windowHashCode}");

instance.raycastHandlerMap[windowHashCode][widgetHashCode] = new RaycastableRect();
}

public static void MarkDirty(int widgetHashCode, int windowHashCode) {
D.assert(instance.raycastHandlerMap.ContainsKey(windowHashCode), () =>
$"Raycast Handler Map doesn't contain Window {windowHashCode}");
D.assert(instance.raycastHandlerMap[windowHashCode].ContainsKey(widgetHashCode), () =>
$"Raycast Handler Map doesn't contain Widget {widgetHashCode} at Window {windowHashCode}");

instance.raycastHandlerMap[windowHashCode][widgetHashCode].MarkDirty();
}

public static void UpdateSizeOffset(int widgetHashCode, int windowHashCode, Size size, Offset offset) {
D.assert(instance.raycastHandlerMap.ContainsKey(windowHashCode), () =>
$"Raycast Handler Map doesn't contain Window {windowHashCode}");
D.assert(instance.raycastHandlerMap[windowHashCode].ContainsKey(widgetHashCode), () =>
$"Raycast Handler Map doesn't contain Widget {widgetHashCode} at Window {windowHashCode}");

if (instance.raycastHandlerMap[windowHashCode][widgetHashCode].isDirty) {
instance.raycastHandlerMap[windowHashCode][widgetHashCode]
.UpdateRect(offset.dx, offset.dy, size.width, size.height);
instance.raycastHandlerMap[windowHashCode][widgetHashCode].UnmarkDirty();
}
}

public static void RemoveFromList(int widgetHashCode, int windowHashCode) {
D.assert(instance.raycastHandlerMap.ContainsKey(windowHashCode), () =>
$"Raycast Handler Map doesn't contain Window {windowHashCode}");
D.assert(instance.raycastHandlerMap[windowHashCode].ContainsKey(widgetHashCode), () =>
$"Raycast Handler Map doesn't contain Widget {widgetHashCode} at Window {windowHashCode}");

instance.raycastHandlerMap[windowHashCode].Remove(widgetHashCode);
}

public static bool CheckCastThrough(int windowHashCode, Vector2 pos) {
D.assert(instance.raycastHandlerMap.ContainsKey(windowHashCode), () =>
$"Raycast Handler Map doesn't contain Window {windowHashCode}");

foreach (var item in instance.raycastHandlerMap[windowHashCode]) {
if (item.Value.CheckInRect(pos)) {
return false;
}
}

return true;
}
}
}
11 changes: 11 additions & 0 deletions Runtime/engine/raycastable/RaycastManager.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

106 changes: 106 additions & 0 deletions Runtime/engine/raycastable/RaycastableContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;

namespace Unity.UIWidgets.engine.raycast {
class RaycastableBox : SingleChildRenderObjectWidget {
public RaycastableBox(
Key key = null,
Widget child = null
) : base(key, child) {
this.windowHashCode = Window.instance.GetHashCode();
}

readonly int windowHashCode;

public override RenderObject createRenderObject(BuildContext context) {
return new RenderRaycastableBox(
windowHashCode: this.windowHashCode,
widget: this
);
}

public override Element createElement() {
return new _RaycastableBoxRenderElement(windowHashCode: this.windowHashCode, widget: this);
}
}

class RenderRaycastableBox : RenderProxyBox {
public RenderRaycastableBox(
int windowHashCode,
RaycastableBox widget
) {
this.widgetHashCode = widget.GetHashCode();
this.windowHashCode = windowHashCode;
}

readonly int widgetHashCode;
readonly int windowHashCode;

public override void paint(PaintingContext context, Offset offset) {
RaycastManager.UpdateSizeOffset(this.widgetHashCode, this.windowHashCode, this.size, offset);

base.paint(context, offset);
}
}

class _RaycastableBoxRenderElement : SingleChildRenderObjectElement {
public _RaycastableBoxRenderElement(
int windowHashCode,
RaycastableBox widget
) : base(widget) {
this.windowHashCode = windowHashCode;
}

public new RaycastableBox widget {
get { return base.widget as RaycastableBox; }
}

int widgetHashCode;
int windowHashCode;

public override void mount(Element parent, object newSlot) {
this.widgetHashCode = this.widget.GetHashCode();
RaycastManager.AddToList(this.widgetHashCode, this.windowHashCode);
base.mount(parent, newSlot);
}

public override void update(Widget newWidget) {
RaycastManager.MarkDirty(this.widgetHashCode, this.windowHashCode);
base.update(newWidget);
}

public override void unmount() {
RaycastManager.RemoveFromList(this.widgetHashCode, this.windowHashCode);
base.unmount();
}
}

public class RaycastableContainer : StatelessWidget {
public RaycastableContainer(
Widget child = null,
Key key = null
) : base(key) {
this.child = child;
}

public readonly Widget child;

public override Widget build(BuildContext context) {
Widget current = this.child;

if (this.child == null) {
current = new LimitedBox(
maxWidth: 0.0f,
maxHeight: 0.0f,
child: new ConstrainedBox(constraints: BoxConstraints.expand())
);
}

current = new RaycastableBox(child: current);

return current;
}
}
}
11 changes: 11 additions & 0 deletions Runtime/engine/raycastable/RaycastableContainer.cs.meta
40 changes: 40 additions & 0 deletions Runtime/engine/raycastable/UIWidgetsRaycastablePanel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Unity.UIWidgets.engine;
using UnityEngine;

namespace Unity.UIWidgets.engine.raycast {
[RequireComponent(typeof(RectTransform))]
public class UIWidgetsRaycastablePanel : UIWidgetsPanel, ICanvasRaycastFilter {
int windowHashCode;

protected override void InitWindowAdapter() {
base.InitWindowAdapter();
this.windowHashCode = this.window.GetHashCode();
RaycastManager.NewWindow(this.windowHashCode);
}

protected override void OnDisable() {
base.OnDisable();
RaycastManager.DisposeWindow(this.windowHashCode);
}

public bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera) {
if (!this.enabled) {
return true;
}

Vector2 local;
RectTransformUtility.ScreenPointToLocalPointInRectangle(this.rectTransform, screenPoint, eventCamera,
out local);

Rect rect = this.rectTransform.rect;

// Convert top left corner as reference origin point.
local.x += this.rectTransform.pivot.x * rect.width;
local.y -= this.rectTransform.pivot.y * rect.height;
local.x = local.x / this.devicePixelRatio;
local.y = -local.y / this.devicePixelRatio;

return !RaycastManager.CheckCastThrough(this.windowHashCode, local);
}
}
}
11 changes: 11 additions & 0 deletions Runtime/engine/raycastable/UIWidgetsRaycastablePanel.cs.meta
11 changes: 8 additions & 3 deletions Runtime/rendering/table.cs
Original file line number Diff line number Diff line change
@@ -841,12 +841,17 @@ List<float> _computeColumnWidths(BoxConstraints constraints) {
float deficit = tableWidth - maxWidthConstraint;

int availableColumns = this.columns;
float minimumDeficit = 0.00000001f;
while (deficit > 0.0f && totalFlex > minimumDeficit) {

//(Xingwei Zhu) this deficit is double and set to be 0.00000001f in flutter.
//since we use float by default, making it larger should make sense in most cases
float minimumDeficit = 0.0001f;
while (deficit > minimumDeficit && totalFlex > minimumDeficit) {
float newTotalFlex = 0.0f;
for (int x = 0; x < this.columns; x++) {
if (flexes[x] != null) {
float newWidth = widths[x] - deficit * flexes[x].Value / totalFlex;
//(Xingwei Zhu) in case deficit * flexes[x].Value / totalFlex => 0 if deficit is really small, leading to dead loop,
//we amend it with a default larger value to ensure that this loop will eventually end
float newWidth = widths[x] - Mathf.Max(minimumDeficit, deficit * flexes[x].Value / totalFlex);
D.assert(newWidth.isFinite());
if (newWidth <= minWidths[x]) {
deficit -= widths[x] - minWidths[x];
2 changes: 1 addition & 1 deletion Runtime/service/keyboard.cs
Original file line number Diff line number Diff line change
@@ -364,7 +364,7 @@ void _handleMethodCall(string method, List<JSONNode> args) {
}
}

#if UNITY_WEBGL
#if UNITY_WEBGL && !UNITY_EDITOR
class UIWidgetsWebGLKeyboardDelegate : AbstractUIWidgetsKeyboardDelegate {

public override void show() {
2 changes: 1 addition & 1 deletion Runtime/service/text_input.cs
Original file line number Diff line number Diff line change
@@ -590,7 +590,7 @@ public static TextInputConnection attach(TextInputClient client, TextInputConfig
else {
keyboardDelegate = new UIWidgetsTouchScreenKeyboardDelegate();
}
#elif UNITY_WEBGL
#elif UNITY_WEBGL && !UNITY_EDITOR
keyboardDelegate = new UIWidgetsWebGLKeyboardDelegate();
#else
keyboardDelegate = new DefaultKeyboardDelegate();
18 changes: 18 additions & 0 deletions Runtime/ui/painting/txt/font_manager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Unity.UIWidgets.editor;
using Unity.UIWidgets.foundation;
using UnityEngine;

@@ -35,6 +36,23 @@ public class FontManager {

public void addFont(Font font, string familyName,
FontWeight fontWeight = null, FontStyle fontStyle = FontStyle.normal) {
if (font == null) {
D.assert(() => {
Debug.LogWarning($"Font missing (when adding font for {familyName})!");
return true;
});
#if UNITY_EDITOR
if (Resources.Load("fonts/MaterialIcons-Regular") == null) {
D.assert(() => {
Debug.Log("It appears that you have not imported UIWidgetsResources.");
return true;
});
UIWidgetsResourcesImporterWindow.ShowResourcesImporterWindow();
}
#endif
return;
}

fontWeight = fontWeight ?? FontWeight.normal;

D.assert(font != null);
10 changes: 10 additions & 0 deletions Runtime/ui/txt/emoji.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Unity.UIWidgets.editor;
using Unity.UIWidgets.foundation;
using UnityEngine;

@@ -434,6 +435,15 @@ public static EmojiResourceConfiguration configuration {
_image = new Image(Resources.Load<Texture2D>(value.spriteSheetAssetName));
}
catch (Exception e) {
#if UNITY_EDITOR
if (Resources.Load("images/EmojiIOS13.2") == null) {
D.assert(() => {
Debug.Log("It appears that you have not imported UIWidgetsResources.");
return true;
});
UIWidgetsResourcesImporterWindow.ShowResourcesImporterWindow();
}
#endif
_image = null;
Debug.LogError(e.StackTrace);
}
349 changes: 349 additions & 0 deletions Scripts/asset_store
Original file line number Diff line number Diff line change
@@ -0,0 +1,349 @@
#!/bin/sh

function usage() {
echo "$0 <path to target project>"
echo
echo "path to target project : the project to upload to asset store"
exit -1
}

if [ "$#" != "1" ]; then
usage
fi

target_project=$1
echo "Copying to $target_project"

if ! [ -d $target_project ]; then
echo "Target project does not exist!"
exit -1
fi

target_dir=$target_project/Assets/UIWidgets
rm -rf $target_dir
echo "rm -rf $target_dir"
mkdir -p $target_dir
echo "mkdir -p $target_dir"

cp -R ../Runtime $target_dir/Runtime
echo "Copied Runtime"

cp -R ../Editor $target_dir/Editor
echo "Copied Editor"

cp -R ../Samples $target_dir/Samples
echo "Copied Samples"

cp -R ../Tests/Resources $target_dir/Resources
echo "Copied Resources"

rm -f $target_dir/Samples/UIWidgetSample/Resources/file_example_MOV_480_700kB.mov*

mkdir -p $target_dir/Documentation
cat > $target_dir/Documentation/README.txt << END
# UIWidgets
## Introduction
UIWidgets is a plugin package for Unity Editor which helps developers to create, debug and deploy efficient,
cross-platform Apps using the Unity Engine.
UIWidgets is mainly derived from Flutter (https://github.com/flutter/flutter). However, taking advantage of
the powerful Unity Engine, it offers developers many new features to improve their Apps
as well as the develop workflow significantly.
#### Efficiency
Using the latest Unity rendering SDKs, a UIWidgets App can run very fast and keep >60fps in most times.
#### Cross-Platform
A UIWidgets App can be deployed on all kinds of platforms including PCs, mobile devices and web page directly, like
any other Unity projects.
#### Multimedia Support
Except for basic 2D UIs, developers are also able to include 3D Models, audios, particle-systems to their UIWidgets Apps.
#### Developer-Friendly
A UIWidgets App can be debug in the Unity Editor directly with many advanced tools like
CPU/GPU Profiling, FPS Profiling.
## Requirement
#### Unity
Install Unity 2018.3 or above. You can download the latest Unity on https://unity3d.com/get-unity/download.
#### UIWidgets Package
Visit our Github repository https://github.com/UnityTech/UIWidgets
to download the latest UIWidgets package.
Move the downloaded package folder into the Package folder of your Unity project.
Generally, you can make it using a console (or terminal) application by just a few commands as below:
cd <YourProjectPath>/Packages
git clone https://github.com/UnityTech/UIWidgets.git com.unity.uiwidgets
## Getting Start
#### i. Overview
In this tutorial, we will create a very simple UIWidgets App as the kick-starter. The app contains
only a text label and a button. The text label will count the times of clicks upon the button.
First of all, please open or create a Unity Project and open it with Unity Editor.
And then open Project Settings, go to Player section and add "UIWidgets_DEBUG" to the Scripting Define Symbols field.
This enables the debug mode of UIWidgets for your development. Remove this for your release build afterwards.
#### ii. Scene Build
A UIWidgets App is usually built upon a Unity UI Canvas. Please follow the steps to create a
UI Canvas in Unity.
1. Create a new Scene by "File -> New Scene";
1. Create a UI Canvas in the scene by "GameObject -> UI -> Canvas";
1. Add a Panel (i.e., Panel 1) to the UI Canvas by right click on the Canvas and select "UI -> Panel". Then remove the
Image Component from the Panel.
#### iii. Create Widget
A UIWidgets App is written in C# Scripts. Please follow the steps to create an App and play it
in Unity Editor.
1. Create a new C# Script named "UIWidgetsExample.cs" and paste the following codes into it.
using System.Collections.Generic;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.engine;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using FontStyle = Unity.UIWidgets.ui.FontStyle;
namespace UIWidgetsSample {
public class UIWidgetsExample : UIWidgetsPanel {
protected override void OnEnable() {
// if you want to use your own font or font icons.
// FontManager.instance.addFont(Resources.Load<Font>(path: "path to your font"), "font family name");
// load custom font with weight & style. The font weight & style corresponds to fontWeight, fontStyle of
// a TextStyle object
// FontManager.instance.addFont(Resources.Load<Font>(path: "path to your font"), "Roboto", FontWeight.w500,
// FontStyle.italic);
// add material icons, familyName must be "Material Icons"
// FontManager.instance.addFont(Resources.Load<Font>(path: "path to material icons"), "Material Icons");
base.OnEnable();
}
protected override Widget createWidget() {
return new WidgetsApp(
home: new ExampleApp(),
pageRouteBuilder: (RouteSettings settings, WidgetBuilder builder) =>
new PageRouteBuilder(
settings: settings,
pageBuilder: (BuildContext context, Animation<float> animation,
Animation<float> secondaryAnimation) => builder(context)
)
);
}
class ExampleApp : StatefulWidget {
public ExampleApp(Key key = null) : base(key) {
}
public override State createState() {
return new ExampleState();
}
}
class ExampleState : State<ExampleApp> {
int counter = 0;
public override Widget build(BuildContext context) {
return new Column(
children: new List<Widget> {
new Text("Counter: " + this.counter),
new GestureDetector(
onTap: () => {
this.setState(()
=> {
this.counter++;
});
},
child: new Container(
padding: EdgeInsets.symmetric(20, 20),
color: Colors.blue,
child: new Text("Click Me")
)
)
}
);
}
}
}
}
1. Save this script and attach it to Panel 1 as its component.
1. Press the "Play" Button to start the App in Unity Editor.
#### iv. Build App
Finally, the UIWidgets App can be built to packages for any specific platform by the following steps.
1. Open the Build Settings Panel by "File -> Build Settings..."
1. Choose a target platform and click "Build". Then the Unity Editor will automatically assemble
all relevant resources and generate the final App package.
#### How to load images?
1. Put your images files in Resources folder. e.g. image1.png.
2. You can add image1@2.png and image1@3.png in the same folder to support HD screens.
3. Use Image.asset("image1") to load the image. Note: as in Unity, ".png" is not needed.
UIWidgets supports Gif as well!
1. Suppose you have loading1.gif. Rename it to loading1.gif.bytes and copy it to Resources folder.
2. You can add loading1@2.gif.bytes and loading1@3.gif.bytes in the same folder to support HD screens.
3. Use Image.asset("loading1.gif") to load the gif images.
#### Using Window Scope
If you see the error AssertionError: Window.instance is null or null pointer error of Window.instance,
it means the code is not running in the window scope. In this case, you can enclose your code
with window scope as below:
using(WindowProvider.of(your gameObject with UIWidgetsPanel).getScope()) {
// code dealing with UIWidgets,
// e.g. setState(() => {....})
}
This is needed if the code is in methods
not invoked by UIWidgets. For example, if the code is in completed callback of UnityWebRequest,
you need to enclose them with window scope.
Please see "./Samples/UIWidgetSample/HttpRequestSample.cs" for detail.
For callback/event handler methods from UIWidgets (e.g Widget.build, State.initState...), you don't need do
it yourself, since the framework ensure it's in window scope.
#### Show Status Bar on Android
Status bar is always hidden by default when an Unity project is running on an Android device. If you
want to show the status bar in your App, this
solution (https://github.com/Over17/UnityShowAndroidStatusBar) seems to be
compatible to UIWidgets, therefore can be used as a good option before we release our
full support solution on this issue.
Besides,
please set "Render Outside Safe Area" to true in the "Player Settings" to make this plugin working properly on Android P or later.
#### Automatically Adjust Frame Rate
To build an App that is able to adjust the frame rate automatically, please open Project Settings, and
in the Quality tab, set the "V Sync Count" option of the target platform to "Don't Sync". The default
logic is to set the frame rate to 25 when the screen is static, and change the frame rate to 60 whenever
the screen changes. If you would like to modify the behavior of speeding up or cooling down the frame
rate, please set Window.onFrameRateSpeedUp and/or Window.onFrameRateCoolDown to your own functions.
#### WebGL Canvas Device Pixel Ratio Plugin
The width and height of the Canvas in browser may differ from the number of pixels the Canvas occupies on the screen.
Therefore, the image may blur in the built WebGL program.
The Plugin Plugins/platform/webgl/UIWidgetsCanvasDevicePixelRatio_20xx.x.jslib (2018.3 and 2019.1 for now) solves this issue.
Please select the plugin of the Unity version corresponding to your project, and disable other versions of this plugin, as
follows: select this plugin in the Project panel, and uncheck WebGL under Select platforms for plugin in the Inspector panel.
If you need to disable this plugin for any reason, please disable all the versions of this plugin as described above.
This plugin overrides the following parameters in the Unity WebGL building module:
JS_SystemInfo_GetWidth
JS_SystemInfo_GetHeight
JS_SystemInfo_GetCurrentCanvasWidth
JS_SystemInfo_GetCurrentCanvasHeight
\$Browser
\$JSEvents
If you would like to implement your own WebGL plugin, and your plugin overrides at least one of the above parameters,
you need to disable the UIWidgetsCanvasDevicePixelRatio plugin in the above mentioned way to avoid possible conflicts.
If you still need the function provided by this plugin, you can manually apply the modification to Unity WebGL
building module introduced in this plugin. All the modifications introduced in UIWidgetsCanvasDevicePixelRatio are
marked by ////////// Modification Start //////////// and ////////// Modification End ////////////.
In the marked codes, all the multiplications and divisions with devicePixelRatio are introduced by our modification.
To learn about the original script in detail, please refer to SystemInfo.js and UnityNativeJS/UnityNative.js in
PlaybackEngines/WebGLSupport/BuildTools/lib in your Unity Editor installation.
#### Image Import Setting
Unity, by default, resizes the width and height of an imported image to the nearest integer that is a power of 2.
In UIWidgets, you should almost always disable this by selecting the image in the "Project" panel, then in the
"Inspector" panel set the "Non Power of 2" option (in "Advanced") to "None", to prevent your image from being
resized unexpectedly.
## Debug UIWidgets Application
#### Define UIWidgets_DEBUG
It's recommended to define the UIWidgets_DEBUG script symbol in editor, this will turn on
debug assertion in UIWidgets, which will help to find potential bugs earlier. To do this:
please go to Player Settings -> Other Settings -> Configuration -> Scripting Define Symbols,
and add UIWidgets_DEBUG.
The symbol is for debug purpose, please remove it from your release build.
#### UIWidgets Inspector
The UIWidgets Inspector tool is for visualizing and exploring the widget trees. You can find it
via Window/Analysis/UIWidgets inspector in Editor menu.
Note
* UIWidgets_DEBUG needs to be define for inspector to work properly.
* Inspector currently only works in Editor Play Mode, inspect standalone built application is not supported for now.
## Learn
#### Samples
You can find many UIWidgets App samples in the UIWidgets package in the Samples folder.
Feel free to try them out and make modifications to see the results.
To get started, the UIWidgetsTheatre scene provides you
a list of carefully selected samples to start with.
You can also try UIWidgets-based Editor windows by clicking UIWidgetsTest on the main menu
and open one of the dropdown samples.
#### Wiki
The develop team is still working on the UIWidgets Wiki. However, since UIWidgets is mainly derived from Flutter,
you can refer to Flutter Wiki to access detailed descriptions of UIWidgets APIs
from those of their Flutter counterparts.
Meanwhile, you can join the discussion channel at (https://connect.unity.com/g/uiwidgets)
#### FAQ
Can I create standalone App using UIWidgets? Yes
Can I use UIWidgets to build game UIs? Yes
Can I develop Unity Editor plugins using UIWidgets? Yes
Is UIWidgets a extension of UGUI/NGUI? No
Is UIWidgets just a copy of Flutter? No
Can I create UI with UIWidgets by simply drag&drop? No
Do I have to pay for using UIWidgets? No
Any IDE recommendation for UIWidgets? Rider, VSCode(Open .sln)
## Contact Us
Keven Gu (kg@unity3d.com)
Xingwei Zhu (xingwei.zhu@unity3d.com)
Fan Zhang (fzhang@unity3d.com)
Yuncong Zhang (yuncong.zhang@unity3d.com)
END

124 changes: 124 additions & 0 deletions Scripts/packman
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/bin/sh

repo_url="git@github.cds.internal.unity3d.com:unity/com.unity.uiwidgets.git"
package_name="com.unity.uiwidgets"
target_version="844bac835"

function usage() {
echo "$0 [path to target repository]"
echo
echo "path to target repository : The repository to upload to package manager ends with "
echo " com.unity.uiwidgets. If not provided, will clone from"
echo " $repo_url"
exit -1
}

if [ "$0" != "./`basename $0`" ]; then
echo "This script must be invoked in the folder containing this script."
exit -1
fi

if [ "$1" == "-h" ]; then
usage
fi

if [ "$#" != "1" ]; then
tmpdir=`mktemp -d`
target_repository="$tmpdir/$package_name"
echo "Repository path not provided. Will clone from"
echo "$repo_url"
echo "to $tmpdir/$package_name"
git clone $repo_url $target_repository
else
target_repository=`cd $1; pwd; cd - > /dev/null`
fi

# Check the validity of the target directory
if ! [ -d "$target_repository" ]; then
echo "Target respository ($target_repository) does not exist!"
exit -1
fi

current_directory=`pwd`
cd $target_repository
if [ "`git remote get-url origin`" != "$repo_url" ]; then
cd $current_directory
echo "Target repository is not pointing to $repo_url"
exit -1
fi
cd $current_directory

echo "Copying to $target_repository"

# Copy the UIWidgets Repository to a temporary dir and
# checkout to target_version
tmpdir=`mktemp -d`
curr_repo_name=$(basename `cd ..; pwd; cd - > /dev/null`) # Should be UIWidgets
cp -R ../.. $tmpdir
echo "Switching to $tmpdir/$curr_repo_name"
cd $tmpdir/$curr_repo_name
git reset --hard $target_version # Cleanup any possible local change
if [ "$?" != "0" ]; then
echo "Failed to setup the repo of target version"
exit -1
fi

rm -rf $target_repository/Documentation~
mkdir $target_repository/Documentation~
sed '/README-ZH.md/d ; s/CONTRIBUTING.md/CONTRIBUTING/g' README.md > $target_repository/Documentation~/com.unity.uiwidgets.md
cp $target_repository/Documentation~/{com.unity.uiwidgets.md,index.md}
cat > $target_repository/Documentation~/CONTRIBUTING.md << END
This repository exists for the sole purpose of publishing to package manager. Please contribute to https://github.com/UnityTech/UIWidgets instead.
END
cat CONTRIBUTING.md >> $target_repository/Documentation~/CONTRIBUTING.md
sed '/README-ZH.md/d ; s/CONTRIBUTING.md/CONTRIBUTING/g' README-ZH.md > $target_repository/Documentation~/index-zh.md
cat > $target_repository/Documentation~/TableOfContents.md << END
* [UIWidgets Documentation](index)
* [UIWidgets中文文档](index-zh)
END
echo "Copied Documentation"

rm -rf $target_repository/Runtime
cp -R Runtime $target_repository/
echo "Copied Runtime"

rm -rf $target_repository/Runtime/Plugins
rm -rf $target_repository/Runtime/Plugins.meta
rm -rf $target_repository/Runtime/Resources/images
rm -rf $target_repository/Runtime/Resources/images.meta
rm -rf $target_repository/Runtime/Resources/fonts
rm -rf $target_repository/Runtime/Resources/fonts.meta
echo "Removed Resources and Plugins"

rm -rf $target_repository/Editor
cp -R Editor $target_repository/
echo "Copied Editor"

echo "Cloning Samples"
rm -rf $target_repository/Samples
git clone https://github.com/UIWidgets/UIWidgetsSamples.git $target_repository/Samples
rm -rf $target_repository/Samples/.git
echo "Cloned Samples"

cp README.md* $target_repository
echo "Copied README"

cd $target_repository
git add .
git commit -m "Update to $curr_repo_name:$target_version"

echo "Please complete the following steps mannually"
echo
echo "cd $target_repository"
echo "Update CHANGELOG.md, adding entry for the new version."
echo "Update package.json, changing the version number."
echo "Update the resource package in 'Package Resources' folder, if needed."
echo "git commit"
echo "git push"
echo "Visit https://yamato.cds.internal.unity3d.com/jobs/242-com.unity.uiwidgets and wait for the jobs to succeed."
echo "Update the tags:"
echo "git tag rc-x.x.x-preview.x && git push -u origin rc-x.x.x-preview.x"
echo "Waiting for the jobs to succeed"
echo "git tag vx.x.x-preview.x && git push -u origin vx.x.x-preview.x"
echo "Waiting for the jobs to succeed"
7 changes: 7 additions & 0 deletions Scripts/packman.meta
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "com.unity.uiwidgets",
"displayName":"UIWidgets",
"version": "1.5.4-preview.1",
"version": "1.5.4-preview.5",
"unity": "2018.4",
"description": "UIWidgets allows you to build beautiful cross-platform apps through Unity",
"dependencies": {