浏览代码

gestures update

/siyaoH-1.17-PlatformMessage
siyao 4 年前
当前提交
72f420a3
共有 13 个文件被更改,包括 954 次插入296 次删除
  1. 3
      com.unity.uiwidgets/Runtime/engine2/UIWidgetsPanel.cs
  2. 393
      com.unity.uiwidgets/Runtime/gestures/converter.cs
  3. 75
      com.unity.uiwidgets/Runtime/gestures/events.cs
  4. 95
      com.unity.uiwidgets/Runtime/gestures/multitap.cs
  5. 14
      com.unity.uiwidgets/Runtime/gestures/pointer_router.cs
  6. 8
      com.unity.uiwidgets/Runtime/gestures/pointer_signal_resolver.cs
  7. 4
      com.unity.uiwidgets/Runtime/gestures/recognizer.cs
  8. 32
      com.unity.uiwidgets/Runtime/gestures/scale.cs
  9. 3
      com.unity.uiwidgets/Runtime/gestures/tap.cs
  10. 6
      com.unity.uiwidgets/Runtime/widgets/basic.cs
  11. 73
      Samples/UIWidgetsSamples_2019_4/Assets/CountDemo.cs
  12. 537
      Samples/UIWidgetsSamples_2019_4/Assets/CountDemo.unity
  13. 7
      Samples/UIWidgetsSamples_2019_4/Assets/CountDemo.unity.meta

3
com.unity.uiwidgets/Runtime/engine2/UIWidgetsPanel.cs


public TextFont[] fonts;
static object fontsToObject(TextFont[] textFont) {
if (textFont == null || textFont.Length == 0) {
return null;
}
var result = new object[textFont.Length];
for (int i = 0; i < textFont.Length; i++) {
var font = new Dictionary<string, object>();

393
com.unity.uiwidgets/Runtime/gestures/converter.cs


using UnityEngine;
namespace Unity.UIWidgets.gestures {
class _PointerState {
public _PointerState(Offset lastPosition) {
this.lastPosition = lastPosition ?? Offset.zero;
}
public int pointer {
get { return _pointer; }
}
int _pointer;
// pointers 0 ~ 9 are preserved for special unique inputs
static int _pointerCount = 10;
// special pointer id:
// mouse scroll
const int scrollPointer = 5;
public void initScrollPointer() {
_pointer = scrollPointer;
}
public void startNewPointer() {
_pointerCount += 1;
_pointer = _pointerCount;
}
public bool down {
get { return _down; }
}
bool _down = false;
public void setDown() {
D.assert(!_down);
_down = true;
}
public void setUp() {
D.assert(_down);
_down = false;
}
public Offset lastPosition;
public Offset deltaTo(Offset to) {
return to - lastPosition;
}
public override string ToString() {
return $"_PointerState(pointer: {pointer}, down: {down}, lastPosition: {lastPosition})";
}
public partial class gesture_ {
case PointerDeviceKind.mouse:
return buttons;
return buttons;
case PointerDeviceKind.stylus:
case PointerDeviceKind.invertedStylus:
return buttons | kPrimaryButton;
return buttons;
// We have no information about the device but we know we never want
// buttons to be 0 when the pointer is down.
return buttons == 0 ? kPrimaryButton : buttons;
}
}
}

static readonly Dictionary<int, _PointerState> _pointers = new Dictionary<int, _PointerState>();
static void clearPointers() {
_pointers.Clear();
}
static _PointerState _ensureStateForPointer(PointerData datum, Offset position) {
return _pointers.putIfAbsent(
datum.device,
() => new _PointerState(position));
}
Offset delta = new Offset(datum.physicalDeltaX, datum.physicalDeltaY) / devicePixelRatio;
var radiusMinor = _toLogicalPixels(datum.radiusMinor, devicePixelRatio);
var radiusMajor = _toLogicalPixels(datum.radiusMajor, devicePixelRatio);
var radiusMin = _toLogicalPixels(datum.radiusMin, devicePixelRatio);

switch (datum.change) {
case PointerChange.add: {
D.assert(!_pointers.ContainsKey(datum.device));
_PointerState state = _ensureStateForPointer(datum, position);
D.assert(state.lastPosition == position);
yield return new PointerAddedEvent(
timeStamp: timeStamp,
kind: kind,
device: datum.device,
position: position,
obscured: datum.obscured,
pressureMin: datum.pressureMin,
pressureMax: datum.pressureMax,
distance: datum.distance,
distanceMax: datum.distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: datum.orientation,
tilt: datum.tilt
);
break;
}
case PointerChange.down: {
_PointerState state = _ensureStateForPointer(datum, position);
if (state.down) {
if (datum.signalKind == null || datum.signalKind == ui.PointerSignalKind.none) {
switch (datum.change) {
case PointerChange.add: {
yield return new PointerAddedEvent(
timeStamp: timeStamp,
kind: kind,
device: datum.device,
position: position,
obscured: datum.obscured,
pressureMin: datum.pressureMin,
pressureMax: datum.pressureMax,
distance: datum.distance,
distanceMax: datum.distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: datum.orientation,
tilt: datum.tilt
);
if (state.lastPosition != position) {
// a hover event to be here.
state.lastPosition = position;
}
state.startNewPointer();
state.setDown();
yield return new PointerDownEvent(
timeStamp: timeStamp,
pointer: state.pointer,
kind: kind,
device: datum.device,
position: position
);
}
break;
case PointerChange.move: {
bool alreadyAdded = _pointers.ContainsKey(datum.device);
if (!alreadyAdded) {
case PointerChange.hover: {
yield return new PointerHoverEvent(
timeStamp: timeStamp,
kind: kind,
device: datum.device,
position: position,
delta: delta,
buttons: datum.buttons,
obscured: datum.obscured,
pressureMin: datum.pressureMin,
pressureMax: datum.pressureMax,
distance: datum.distance,
distanceMax: datum.distanceMax,
size: datum.size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: datum.orientation,
tilt: datum.tilt,
synthesized: datum.synthesized
);
D.assert(_pointers.ContainsKey(datum.device));
_PointerState state = _pointers[datum.device];
if (!state.down) {
break;
case PointerChange.down: {
yield return new PointerDownEvent(
timeStamp: timeStamp,
pointer: datum.pointerIdentifier,
kind: kind,
device: datum.device,
position: position,
buttons: gesture_._synthesiseDownButtons(datum.buttons, kind),
obscured: datum.obscured,
pressure: datum.pressure,
pressureMin: datum.pressureMin,
pressureMax: datum.pressureMax,
distanceMax: datum.distanceMax,
size: datum.size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: datum.orientation,
tilt: datum.tilt
);
D.assert(state.down);
Offset offset = position - state.lastPosition;
state.lastPosition = position;
yield return new PointerMoveEvent(
timeStamp: timeStamp,
pointer: state.pointer,
kind: kind,
device: datum.device,
position: position,
delta: offset
);
}
break;
case PointerChange.hover: {
yield return new PointerHoverEvent(
timeStamp: timeStamp,
kind: kind,
device: datum.device,
position: position
);
break;
}
// case PointerChange.scroll: {
// var _scrollData = (ScrollData) datum;
// _PointerState state = _ensureStateForPointer(datum, position);
// state.initScrollPointer();
//
// if (state.lastPosition != position) {
// state.lastPosition = position;
// }
//
// Offset scrollDelta = new Offset(_scrollData.scrollX, _scrollData.scrollY) / devicePixelRatio;
// yield return new PointerScrollEvent(
// timeStamp: timeStamp,
// pointer: state.pointer,
// kind: kind,
// device: _scrollData.device,
// position: position,
// scrollDelta: scrollDelta
// );
// break;
// }
case PointerChange.up:
case PointerChange.cancel: {
_PointerState state = _pointers.getOrDefault(datum.device);
if (state == null || !state.down) {
}
D.assert(state.down);
if (position != state.lastPosition) {
Offset offset = position - state.lastPosition;
state.lastPosition = position;
case PointerChange.move: {
Debug.LogError("need add synthesized into PointerData");
pointer: state.pointer,
pointer: datum.pointerIdentifier,
delta: offset,
synthesized: true
delta: delta,
buttons: gesture_._synthesiseDownButtons(datum.buttons, kind),
obscured: datum.obscured,
pressure: datum.pressure,
pressureMin: datum.pressureMin,
pressureMax: datum.pressureMax,
distanceMax: datum.distanceMax,
size: datum.size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: datum.orientation,
tilt: datum.tilt,
platformData: datum.platformData,
synthesized: datum.synthesized
D.assert(position == state.lastPosition);
state.setUp();
if (datum.change == PointerChange.up) {
break;
case PointerChange.up:
pointer: state.pointer,
pointer: datum.pointerIdentifier,
position: position
position: position,
buttons: datum.buttons,
obscured: datum.obscured,
pressure: datum.pressure,
pressureMin: datum.pressureMin,
pressureMax: datum.pressureMax,
distance: datum.distance,
distanceMax: datum.distanceMax,
size: datum.size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: datum.orientation,
tilt: datum.tilt
}
else {
break;
case PointerChange.cancel: {
pointer: state.pointer,
pointer: datum.pointerIdentifier,
position: position
position: position,
buttons: datum.buttons,
obscured: datum.obscured,
pressureMin: datum.pressureMin,
pressureMax: datum.pressureMax,
distance: datum.distance,
distanceMax: datum.distanceMax,
size: datum.size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: datum.orientation,
tilt: datum.tilt
}
break;
case PointerChange.remove: {
D.assert(_pointers.ContainsKey(datum.device));
_PointerState state = _pointers[datum.device];
if (state.down) {
yield return new PointerCancelEvent(
break;
case ui.PointerChange.remove:
yield return new PointerRemovedEvent(
pointer: state.pointer,
position: position
position: position,
obscured: datum.obscured,
pressureMin: datum.pressureMin,
pressureMax: datum.pressureMax,
distanceMax: datum.distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax
}
if (position != state.lastPosition) {
yield return new PointerHoverEvent(
break;
}
}
else {
switch (datum.signalKind) {
case ui.PointerSignalKind.scroll:
Offset scrollDelta =
new Offset(datum.scrollDeltaX, datum.scrollDeltaY) / devicePixelRatio;
yield return new PointerScrollEvent(
position: position
position: position,
scrollDelta: scrollDelta
}
_pointers.Remove(datum.device);
yield return new PointerRemovedEvent(
timeStamp: timeStamp,
kind: kind,
device: datum.device,
position: position
);
break;
break;
case ui.PointerSignalKind.none:
D.assert(false); // This branch should already have 'none' filtered out.
break;
case ui.PointerSignalKind.unknown:
// Ignore unknown signals.
break;
#if UNITY_EDITOR
// case PointerChange.dragFromEditorMove: {
// _PointerState state = _ensureStateForPointer(datum, position);
// state.startNewPointer();
// yield return new PointerDragFromEditorHoverEvent(
// timeStamp: timeStamp,
// pointer: state.pointer,
// kind: kind,
// device: datum.device,
// position: position
// );
// }
// break;
// case PointerChange.dragFromEditorRelease: {
// _PointerState state = _ensureStateForPointer(datum, position);
// state.startNewPointer();
// yield return new PointerDragFromEditorReleaseEvent(
// timeStamp: timeStamp,
// pointer: state.pointer,
// kind: kind,
// device: datum.device,
// position: position
// );
// }
// break;
#endif
}
}
}

75
com.unity.uiwidgets/Runtime/gestures/events.cs


using Object = UnityEngine.Object;
namespace Unity.UIWidgets.gestures {
public partial class gesture_ {
public const int kPrimaryButton = 0x01;
public const int kSecondaryButton = 0x02;
public const int kPrimaryMouseButton = kPrimaryButton;
public const int kSecondaryMouseButton = kSecondaryButton;
public const int kStylusContact = kPrimaryButton;
public const int kPrimaryStylusButton = kSecondaryButton;
public const int kMiddleMouseButton = 0x04;
public const int kSecondaryStylusButton = 0x04;
public const int kBackMouseButton = 0x08;
public const int kForwardMouseButton = 0x10;
public const int kTouchContact = kPrimaryButton;
public static int kMaxUnsignedSMI {
get {
Debug.LogError("Update this for io and web");
return -1;
}
}
public int nthMouseButton(int number) => (kPrimaryMouseButton << (number - 1)) & kMaxUnsignedSMI;
public int nthStylusButton(int number) => (kPrimaryStylusButton << (number - 1)) & kMaxUnsignedSMI;
public int smallestButton(int buttons) => buttons & (-buttons);
public bool isSingleButton(int buttons) => buttons != 0 && (smallestButton(buttons) == buttons);
}
public abstract class PointerEvent : Diagnosticable {
public PointerEvent(
TimeSpan timeStamp,

Offset position = null,
Offset localPosition = null,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distance = 0.0f,

position: position,
localPosition: localPosition,
obscured: obscured,
pressure: pressure,
pressure: 0,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,

Offset position = null,
Offset localPosition = null,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distanceMax = 0.0f,

localPosition: localPosition,
device: device,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distanceMax: distanceMax,

Offset localDelta = null,
int buttons = 0,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distance = 0.0f,

localDelta: localDelta,
buttons: buttons,
obscured: obscured,
pressure: pressure,
pressure: 0,
pressureMin: pressureMin,
pressureMax: pressureMax,
size: size,

Offset localDelta = null,
int buttons = 0,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distance = 0.0f,

buttons: buttons,
down: down,
obscured: obscured,
pressure: pressure,
pressure: 0,
pressureMin: pressureMin,
pressureMax: pressureMax,
size: size,

buttons: hover?.buttons ?? 0,
down: hover?.down ?? false,
obscured: hover?.obscured ?? false,
pressure: hover?.pressure ?? 0.0f,
pressureMin: hover?.pressureMin ?? 1.0f,
pressureMax: hover?.pressureMax ?? 1.0f,
distance: hover?.distance ?? 0.0f,

Offset localDelta = null,
int buttons = 0,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,
float pressureMax = 1.0f,
float distance = 0.0f,

buttons: buttons,
down: down,
obscured: obscured,
pressure: pressure,
pressure: 0,
pressureMin: pressureMin,
pressureMax: pressureMax,
size: size,

buttons: hover?.buttons ?? 0,
down: hover?.down ?? false,
obscured: hover?.obscured ?? false,
pressure: hover?.pressure ?? 0.0f,
pressureMin: hover?.pressureMin ?? 1.0f,
pressureMax: hover?.pressureMax ?? 1.0f,
distance: hover?.distance ?? 0.0f,

int device = 0,
Offset position = null,
Offset localPosition = null,
int buttons = 0,
int buttons = gesture_.kPrimaryButton,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,

Offset localPosition = null,
Offset delta = null,
Offset localDelta = null,
int buttons = 0,
int buttons = gesture_.kPrimaryButton,
bool obscured = false,
float pressure = 0.0f,
float pressureMin = 1.0f,

float radiusMax = 0.0f,
float orientation = 0.0f,
float tilt = 0.0f,
int platformdData = 0,
int platformData = 0,
bool synthesized = false,
Matrix4 transform = null,
PointerMoveEvent original = null

radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
platformData: platformdData,
platformData: platformData,
synthesized: synthesized,
transform: transform,
original: original) {

radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
// platformData: platformData,
platformData: platformData,
synthesized: synthesized,
transform: transform,
original: original as PointerMoveEvent ?? this

public class PointerScrollEvent : PointerSignalEvent {
public PointerScrollEvent(
TimeSpan timeStamp,
int pointer,
TimeSpan? timeStamp = null,
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = null,

PointerScrollEvent original = null)
: base(
timeStamp,
timeStamp ?? TimeSpan.Zero,
pointer: pointer,
device: device,
position: position,
localPosition: localPosition,

if (transform == null || transform == this.transform) {
return this;
}
pointer: pointer,
kind: kind,
device: device,
position: position,

int device = 0,
Offset position = null,
Offset localPosition = null,
Object[] objectReferences = null,
Object[] objectReferences = null,
Matrix4 transform = null,
PointerDragFromEditorReleaseEvent original = null
) : base(

95
com.unity.uiwidgets/Runtime/gestures/multitap.cs


TimeSpan doubleTapMinTime,
GestureArenaEntry entry = null
) {
D.assert(evt != null);
initialButtons = evt.buttons;
_doubleTapMinTimeCountdown = new _CountdownZoned(duration: doubleTapMinTime);
this.entry = entry;
}

internal readonly Offset _initialGlobalPosition;
internal readonly int initialButtons;
internal readonly _CountdownZoned _doubleTapMinTimeCountdown;
bool _isTrackingPointer = false;

public bool hasElapsedMinTime() {
return _doubleTapMinTimeCountdown.timeout;
}
public bool hasSameButton(PointerDownEvent evt) {
return evt.buttons == initialButtons;
}
}

public GestureDoubleTapCallback onDoubleTap;
protected override bool isPointerAllowed(PointerDownEvent evt) {
if (_firstTap == null) {
switch (evt.buttons) {
case gesture_.kPrimaryButton:
if (onDoubleTap == null)
return false;
break;
default:
return false;
}
}
return base.isPointerAllowed(evt as PointerDownEvent);
}
if (_firstTap != null &&
!_firstTap.isWithinGlobalTolerance(evt, Constants.kDoubleTapSlop)) {
return;
if (_firstTap != null) {
if (!_firstTap.isWithinGlobalTolerance(evt, Constants.kDoubleTapSlop)) {
// Ignore out-of-bounds second taps.
return;
}
else if (!_firstTap.hasElapsedMinTime() ||
!_firstTap.hasSameButton(evt as PointerDownEvent)) {
// Restart when the second tap is too close to the first, or when buttons
// mismatch.
_reset();
_trackFirstTap(evt);
return;
}
_trackFirstTap(evt);
}
void _trackFirstTap(PointerEvent evt) {
evt: evt,
evt: evt as PointerDownEvent,
entry: GestureBinding.instance.gestureArena.add(evt.pointer, this),
doubleTapMinTime: Constants.kDoubleTapMinTime
);

}
void _registerSecondTap(_TapTracker tracker) {
var initialPosition = tracker._initialGlobalPosition;
if (onDoubleTap != null) {
invokeCallback<object>("onDoubleTap", () => {
onDoubleTap(new DoubleTapDetails(initialPosition));
return null;
});
}
_checkUp(tracker);
_reset();
}

if (_doubleTapTimer != null) {
_doubleTapTimer.cancel();
_doubleTapTimer = null;
}
}
void _checkUp(_TapTracker tracker) {
// D.assert(buttons == kPrimaryButton);
if (onDoubleTap != null) {
invokeCallback<object>("onDoubleTap", () => {
onDoubleTap(new DoubleTapDetails(tracker._initialGlobalPosition));
return null;
});
}
}

);
if (onTapDown != null) {
invokeCallback<object>("onTapDown", () => {
onTapDown(evt.pointer, new TapDownDetails(
globalPosition: evt.position,
onTapDown(evt.pointer, new TapDownDetails(globalPosition: evt.position,
kind: evt.kind));
kind: evt.kind
));
return null;
});
}

if (onTapUp != null) {
invokeCallback<object>("onTapUp",
() => {
onTapUp(pointer, new TapUpDetails(globalPosition: position.global, localPosition: position.local));
onTapUp(pointer, new TapUpDetails(
localPosition: position.local,
globalPosition: position.global
));
return null;
});
}

() => {
onLongTapDown(pointer, new TapDownDetails(
globalPosition: lastPosition.global,
localPosition: lastPosition.local));
localPosition: lastPosition.local
));
return null;
});
}

public override string debugDescription {
get { return "multitap"; }
}
}
delegate bool _RouteEntryPredicate(_RouteEntry entry);
class _RouteEntry {
public _RouteEntry(
PointerRoute route,
Matrix4 transform
) {
this.route = route;
this.transform = transform;
}
public readonly PointerRoute route;
public readonly Matrix4 transform;
static _RouteEntryPredicate isRoutePredicate(PointerRoute route) {
return (_RouteEntry entry) => entry.route == route;
}
}
}

14
com.unity.uiwidgets/Runtime/gestures/pointer_router.cs


public delegate void PointerRoute(PointerEvent evt);
public class PointerRouter {
readonly Dictionary<int, Dictionary<PointerRoute, Matrix4>> _routeMap = new Dictionary<int, Dictionary<PointerRoute, Matrix4>>();
readonly Dictionary<int, Dictionary<PointerRoute, Matrix4>> _routeMap =
new Dictionary<int, Dictionary<PointerRoute, Matrix4>>();
pointer,
pointer,
public void removeRoute(int pointer, PointerRoute route) {
D.assert(_routeMap.ContainsKey(pointer));
var routes = _routeMap[pointer];

}
}
public void removeGlobalRoute(PointerRoute route) {
D.assert(_globalRoutes.ContainsKey(route));
_globalRoutes.Remove(route);

new Dictionary<PointerRoute, Matrix4>(routes)
);
}
public void _dispatchEventToRoutes(
PointerEvent evt,
Dictionary<PointerRoute, Matrix4> referenceRoutes,

8
com.unity.uiwidgets/Runtime/gestures/pointer_signal_resolver.cs


public delegate void PointerSignalResolvedCallback(PointerSignalEvent evt);
public class PointerSignalResolver {
public bool _isSameEvent(PointerSignalEvent event1, PointerSignalEvent event2) {
return (event1.original ?? event1) == (event2.original ?? event2);
}
PointerSignalResolvedCallback _firstRegisteredCallback;
PointerSignalEvent _currentEvent;

D.assert(callback != null);
D.assert(_currentEvent == null || _currentEvent == evt);
D.assert(_currentEvent == null || _isSameEvent(_currentEvent, evt));
if (_firstRegisteredCallback != null) {
return;
}

return;
}
D.assert((_currentEvent.original ?? _currentEvent) == evt);
D.assert(_isSameEvent(_currentEvent, evt));
try {
_firstRegisteredCallback(_currentEvent);
}

4
com.unity.uiwidgets/Runtime/gestures/recognizer.cs


protected virtual void resolvePointer(int pointer, GestureDisposition disposition) {
GestureArenaEntry entry = _entries[pointer];
if (entry != null) {
entry.resolve(disposition);
_entries.Remove(pointer);
entry.resolve(disposition);
_entries.Remove(pointer);
}
}

32
com.unity.uiwidgets/Runtime/gestures/scale.cs


}
public class ScaleStartDetails {
public ScaleStartDetails(Offset focalPoint = null) {
public ScaleStartDetails(
Offset focalPoint = null,
Offset localFocalPoint = null
) {
this.localFocalPoint = localFocalPoint ?? this.focalPoint;
public readonly Offset localFocalPoint;
return $"ScaleStartDetails(focalPoint: {focalPoint}";
return $"ScaleStartDetails(focalPoint: {focalPoint}, localFocalPoint: {localFocalPoint})";
}
}

Offset focalPoint = null,
Offset localFocalPoint = null,
float scale = 1.0f,
float horizontalScale = 1.0f,
float verticalScale = 1.0f,

localFocalPoint = localFocalPoint ?? this.focalPoint;
D.assert(scale >= 0.0f);
D.assert(horizontalScale >= 0.0f);

}
public readonly Offset focalPoint;
public readonly Offset localFocalPoint;
public readonly float scale;

public override string ToString() {
return
$"ScaleUpdateDetails(focalPoint: {focalPoint}, scale: {scale}, horizontalScale: {horizontalScale}, verticalScale: {verticalScale}, rotation: {rotation}";
$"ScaleUpdateDetails(focalPoint: {focalPoint}, localFocalPoint: {localFocalPoint}, scale: {scale}, horizontalScale: {horizontalScale}, verticalScale: {verticalScale}, rotation: {rotation}";
}
}

public class ScaleGestureRecognizer : OneSequenceGestureRecognizer {
public ScaleGestureRecognizer(object debugOwner, PointerDeviceKind? kind = null) : base(debugOwner: debugOwner,
kind: kind) { }
kind: kind) {
}
public GestureScaleStartCallback onStart;

_ScaleState _state = _ScaleState.ready;
Matrix4 _lastTransform;
Offset _initialFocalPoint;
Offset _currentFocalPoint;

}
public override void addAllowedPointer(PointerDownEvent evt) {
startTrackingPointer(evt.pointer);
startTrackingPointer(evt.pointer, evt.transform);
_velocityTrackers[evt.pointer] = new VelocityTracker();
if (_state == _ScaleState.ready) {
_state = _ScaleState.possible;

}
_pointerLocations[evt.pointer] = evt.position;
shouldStartIfAccepted = true;
shouldStartIfAccepted = true;
_lastTransform = evt.transform;
}
else if (evt is PointerDownEvent) {
_pointerLocations[evt.pointer] = evt.position;

_lastTransform = evt.transform;
_lastTransform = evt.transform;
}
_updateLines();

horizontalScale: _horizontalScaleFactor,
verticalScale: _verticalScaleFactor,
focalPoint: _currentFocalPoint,
localFocalPoint: PointerEvent.transformPosition(_lastTransform, _currentFocalPoint),
rotation: _computeRotationFactor()
));
return null;

D.assert(_state == _ScaleState.started);
if (onStart != null) {
invokeCallback<object>("onStart", () => {
onStart(new ScaleStartDetails(focalPoint: _currentFocalPoint));
onStart(new ScaleStartDetails(
focalPoint: _currentFocalPoint,
localFocalPoint: PointerEvent.transformPosition(_lastTransform, _currentFocalPoint)
));
return null;
});
}

3
com.unity.uiwidgets/Runtime/gestures/tap.cs


bool _sentTapDown = false;
bool _wonArenaForPrimaryPointer = false;
OffsetPair _finalPosition;
PointerDownEvent _down;
PointerUpEvent _up;

protected override void handlePrimaryPointer(PointerEvent evt) {
if (evt is PointerUpEvent) {
_up = (PointerUpEvent) evt;
_finalPosition = new OffsetPair(global: evt.position, local: evt.localPosition);
_checkUp();
} else if (evt is PointerCancelEvent) {
resolve(GestureDisposition.rejected);

6
com.unity.uiwidgets/Runtime/widgets/basic.cs


) :
base(key: key, child: child) {
D.assert(behavior != null);
this.onPointerDown = onPointerDown;
this.onPointerMove = onPointerMove;
this.onPointerUp = onPointerUp;
this.onPointerCancel = onPointerCancel;
this.onPointerSignal = onPointerSignal;
this.behavior = behavior;
}
public readonly PointerDownEventListener onPointerDown;

73
Samples/UIWidgetsSamples_2019_4/Assets/CountDemo.cs


using System.Collections.Generic;
using Unity.UIWidgets.cupertino;
using Unity.UIWidgets.engine2;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine.UI;
using Text = Unity.UIWidgets.widgets.Text;
using ui_ = Unity.UIWidgets.widgets.ui_;
namespace UIWidgetsSample
{
public class CountDemo : UIWidgetsPanel
{
protected void OnEnable()
{
base.OnEnable();
}
protected override void main()
{
ui_.runApp(new MyApp());
}
class MyApp : StatelessWidget
{
public override Widget build(BuildContext context)
{
return new CupertinoApp(
home: new CounterApp()
);
}
}
}
internal class CounterApp : StatefulWidget
{
public override State createState()
{
return new CountDemoState();
}
}
internal class CountDemoState : State<CounterApp>
{
private int count = 0;
public override Widget build(BuildContext context)
{
return new Container(
color: Color.white,
child: new Column(children: new List<Widget>()
{
new Text($"count: {count}"),
new CupertinoButton(
onPressed: () =>
{
setState(() =>
{
count++;
});
},
child: new Container(
color: Color.black,
width: 100,
height: 40
)
),
}
)
);
}
}
}

537
Samples/UIWidgetsSamples_2019_4/Assets/CountDemo.unity


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 1
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &314921619
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 314921623}
- component: {fileID: 314921622}
- component: {fileID: 314921621}
- component: {fileID: 314921620}
m_Layer: 5
m_Name: Canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &314921620
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 314921619}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!114 &314921621
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 314921619}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
--- !u!223 &314921622
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 314921619}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &314921623
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 314921619}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 1777874941}
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!1 &624009034
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 624009037}
- component: {fileID: 624009036}
- component: {fileID: 624009035}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &624009035
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 624009034}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
m_CancelButton: Cancel
m_InputActionsPerSecond: 10
m_RepeatDelay: 0.5
m_ForceModuleActive: 0
--- !u!114 &624009036
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 624009034}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
m_Name:
m_EditorClassIdentifier:
m_FirstSelected: {fileID: 0}
m_sendNavigationEvents: 1
m_DragThreshold: 10
--- !u!4 &624009037
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 624009034}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1344837310
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1344837313}
- component: {fileID: 1344837312}
- component: {fileID: 1344837311}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &1344837311
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1344837310}
m_Enabled: 1
--- !u!20 &1344837312
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1344837310}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &1344837313
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1344837310}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1763163838
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1763163840}
- component: {fileID: 1763163839}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &1763163839
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1763163838}
m_Enabled: 1
serializedVersion: 10
m_Type: 1
m_Shape: 0
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_CullingMatrixOverride:
e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
m_UseCullingMatrixOverride: 0
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingLayerMask: 1
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
m_UseBoundingSphereOverride: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &1763163840
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1763163838}
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &1777874940
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1777874941}
- component: {fileID: 1777874942}
- component: {fileID: 1777874943}
m_Layer: 5
m_Name: RawImage
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1777874941
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1777874940}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 314921623}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 100, y: 100}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &1777874942
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1777874940}
m_CullTransparentMesh: 0
--- !u!114 &1777874943
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1777874940}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bb0c6b34bc87472499dccfb52a9bcbde, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Texture: {fileID: 0}
m_UVRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
fonts: []
devicePixelRatioOverride: 0
hardwareAntiAliasing: 0

7
Samples/UIWidgetsSamples_2019_4/Assets/CountDemo.unity.meta


fileFormatVersion: 2
guid: c157694a3a510e34aaf716cf9438dea5
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存