GitHub
5 年前
当前提交
e609ffe0
共有 11 个文件被更改,包括 330 次插入 和 9 次删除
-
12Runtime/engine/UIWidgetsPanel.cs
-
4Runtime/material/app.cs
-
11Runtime/rendering/table.cs
-
8Runtime/engine/raycastable.meta
-
11Runtime/engine/raycastable/RaycastManager.cs.meta
-
11Runtime/engine/raycastable/RaycastableContainer.cs.meta
-
11Runtime/engine/raycastable/UIWidgetsRaycastablePanel.cs.meta
-
125Runtime/engine/raycastable/RaycastManager.cs
-
106Runtime/engine/raycastable/RaycastableContainer.cs
-
40Runtime/engine/raycastable/UIWidgetsRaycastablePanel.cs
|
|||
fileFormatVersion: 2 |
|||
guid: d8e15e1221dae40e68226ec6d8ed8ddb |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 9574f12b230354e6f87fc5fc0c98c96e |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 9af0c7d6aab134f5ba187ff34acf2377 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: e5265d12f7193408b90993bdf987f058 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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; |
|||
} |
|||
} |
|||
} |
|
|||
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; |
|||
} |
|||
} |
|||
} |
|
|||
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); |
|||
} |
|||
} |
|||
} |
撰写
预览
正在加载...
取消
保存
Reference in new issue