From d2ab30e7a69bfe7efda63ae75812207377917bd3 Mon Sep 17 00:00:00 2001
From: miepzerino <o.skotnik@gmail.com>
Date: Sun, 30 Mar 2025 18:50:27 +0000
Subject: [PATCH] Merge branch 'Flexalon-UI-Layouts' into develop
---
Assets/Flexalon/Runtime/Core/FlexalonObject.cs | 829 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 829 insertions(+), 0 deletions(-)
diff --git a/Assets/Flexalon/Runtime/Core/FlexalonObject.cs b/Assets/Flexalon/Runtime/Core/FlexalonObject.cs
new file mode 100644
index 0000000..0aa448c
--- /dev/null
+++ b/Assets/Flexalon/Runtime/Core/FlexalonObject.cs
@@ -0,0 +1,829 @@
+using UnityEngine;
+
+namespace Flexalon
+{
+ /// <summary> To control the size of an object, add a Flexalon Object
+ /// component to it and edit the width, height, or depth properties. </summary>
+ [DisallowMultipleComponent, AddComponentMenu("Flexalon/Flexalon Object"), HelpURL("https://www.flexalon.com/docs/flexalonObject")]
+ public class FlexalonObject : FlexalonComponent
+ {
+ /// <summary> The fixed size of the object. </summary>
+ public Vector3 Size
+ {
+ get => new Vector3(_width, _height, _depth);
+ set
+ {
+ Width = value.x;
+ Height = value.y;
+ Depth = value.z;
+ }
+ }
+
+ /// <summary> The relative size of the object. </summary>
+ public Vector3 SizeOfParent
+ {
+ get => new Vector3(_widthOfParent, _heightOfParent, _depthOfParent);
+ set
+ {
+ WidthOfParent = value.x;
+ HeightOfParent = value.y;
+ DepthOfParent = value.z;
+ }
+ }
+
+ [SerializeField]
+ private SizeType _widthType = SizeType.Component;
+ /// <summary> The width type of the object. </summary>
+ public SizeType WidthType
+ {
+ get { return _widthType; }
+ set {
+ _widthType = value;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _width = 1;
+ /// <summary> The fixed width of the object. </summary>
+ public float Width
+ {
+ get { return _width; }
+ set {
+ _width = Mathf.Max(value, 0);
+ _widthType = SizeType.Fixed;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _widthOfParent = 1;
+ /// <summary> The relative width of the object. </summary>
+ public float WidthOfParent
+ {
+ get { return _widthOfParent; }
+ set {
+ _widthOfParent = Mathf.Max(value, 0);
+ _widthType = SizeType.Fill;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private SizeType _heightType = SizeType.Component;
+ /// <summary> The height type of the object. </summary>
+ public SizeType HeightType
+ {
+ get { return _heightType; }
+ set {
+ _heightType = value;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _height = 1;
+ /// <summary> The fixed height of the object. </summary>
+ public float Height
+ {
+ get { return _height; }
+ set {
+ _height = Mathf.Max(value, 0);
+ _heightType = SizeType.Fixed;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _heightOfParent = 1;
+ /// <summary> The relative height of the object. </summary>
+ public float HeightOfParent
+ {
+ get { return _heightOfParent; }
+ set {
+ _heightOfParent = Mathf.Max(value, 0);
+ _heightType = SizeType.Fill;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private SizeType _depthType = SizeType.Component;
+ /// <summary> The depth type of the object. </summary>
+ public SizeType DepthType
+ {
+ get { return _depthType; }
+ set {
+ _depthType = value;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _depth = 1;
+ /// <summary> The fixed depth of the object. </summary>
+ public float Depth
+ {
+ get { return _depth; }
+ set {
+ _depth = Mathf.Max(value, 0);
+ _depthType = SizeType.Fixed;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _depthOfParent = 1;
+ /// <summary> The relative depth of the object. </summary>
+ public float DepthOfParent
+ {
+ get { return _depthOfParent; }
+ set {
+ _depthOfParent = Mathf.Max(value, 0);
+ _depthType = SizeType.Fill;
+ MarkDirty();
+ }
+ }
+
+ /// <summary> The min fixed size of the object. </summary>
+ public Vector3 MinSize
+ {
+ get => new Vector3(_minWidth, _minHeight, _minDepth);
+ set
+ {
+ MinWidth = value.x;
+ MinHeight = value.y;
+ MinDepth = value.z;
+ }
+ }
+
+ /// <summary> The min relative size of the object. </summary>
+ public Vector3 MinSizeOfParent
+ {
+ get => new Vector3(_minWidthOfParent, _minHeightOfParent, _minDepthOfParent);
+ set
+ {
+ MinWidthOfParent = value.x;
+ MinHeightOfParent = value.y;
+ MinDepthOfParent = value.z;
+ }
+ }
+
+ [SerializeField]
+ private MinMaxSizeType _minWidthType = MinMaxSizeType.None;
+ /// <summary> The min width type of the object. </summary>
+ public MinMaxSizeType MinWidthType
+ {
+ get { return _minWidthType; }
+ set {
+ _minWidthType = value;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _minWidth = 0;
+ /// <summary> The min fixed min width of the object. </summary>
+ public float MinWidth
+ {
+ get { return _minWidth; }
+ set {
+ _minWidth = Mathf.Max(value, 0);
+ _minWidthType = MinMaxSizeType.Fixed;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _minWidthOfParent = 0;
+ /// <summary> The min relative width of the object. </summary>
+ public float MinWidthOfParent
+ {
+ get { return _minWidthOfParent; }
+ set {
+ _minWidthOfParent = Mathf.Max(value, 0);
+ _minWidthType = MinMaxSizeType.Fill;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private MinMaxSizeType _minHeightType = MinMaxSizeType.None;
+ /// <summary> The min height type of the object. </summary>
+ public MinMaxSizeType MinHeightType
+ {
+ get { return _minHeightType; }
+ set {
+ _minHeightType = value;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _minHeight = 0;
+ /// <summary> The min fixed height of the object. </summary>
+ public float MinHeight
+ {
+ get { return _minHeight; }
+ set {
+ _minHeight = Mathf.Max(value, 0);
+ _minHeightType = MinMaxSizeType.Fixed;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _minHeightOfParent = 0;
+ /// <summary> The min relative height of the object. </summary>
+ public float MinHeightOfParent
+ {
+ get { return _minHeightOfParent; }
+ set {
+ _minHeightOfParent = Mathf.Max(value, 0);
+ _minHeightType = MinMaxSizeType.Fill;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private MinMaxSizeType _minDepthType = MinMaxSizeType.None;
+ /// <summary> The min depth type of the object. </summary>
+ public MinMaxSizeType MinDepthType
+ {
+ get { return _minDepthType; }
+ set {
+ _minDepthType = value;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _minDepth = 0;
+ /// <summary> The min fixed depth of the object. </summary>
+ public float MinDepth
+ {
+ get { return _minDepth; }
+ set {
+ _minDepth = Mathf.Max(value, 0);
+ _minDepthType = MinMaxSizeType.Fixed;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _minDepthOfParent = 0;
+ /// <summary> The min relative depth of the object. </summary>
+ public float MinDepthOfParent
+ {
+ get { return _minDepthOfParent; }
+ set {
+ _minDepthOfParent = Mathf.Max(value, 0);
+ _minDepthType = MinMaxSizeType.Fill;
+ MarkDirty();
+ }
+ }
+
+ /// <summary> The max fixed size of the object. </summary>
+ public Vector3 MaxSize
+ {
+ get => new Vector3(_maxWidth, _maxHeight, _maxDepth);
+ set
+ {
+ MaxWidth = value.x;
+ MaxHeight = value.y;
+ MaxDepth = value.z;
+ }
+ }
+
+ /// <summary> The max relative size of the object. </summary>
+ public Vector3 MaxSizeOfParent
+ {
+ get => new Vector3(_maxWidthOfParent, _maxHeightOfParent, _maxDepthOfParent);
+ set
+ {
+ MaxWidthOfParent = value.x;
+ MaxHeightOfParent = value.y;
+ MaxDepthOfParent = value.z;
+ }
+ }
+
+ [SerializeField]
+ private MinMaxSizeType _maxWidthType = MinMaxSizeType.None;
+ /// <summary> The max width type of the object. </summary>
+ public MinMaxSizeType MaxWidthType
+ {
+ get { return _maxWidthType; }
+ set {
+ _maxWidthType = value;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _maxWidth = 1;
+ /// <summary> The max fixed max width of the object. </summary>
+ public float MaxWidth
+ {
+ get { return _maxWidth; }
+ set {
+ _maxWidth = Mathf.Max(value, 0);
+ _maxWidthType = MinMaxSizeType.Fixed;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _maxWidthOfParent = 1;
+ /// <summary> The max relative width of the object. </summary>
+ public float MaxWidthOfParent
+ {
+ get { return _maxWidthOfParent; }
+ set {
+ _maxWidthOfParent = Mathf.Max(value, 0);
+ _maxWidthType = MinMaxSizeType.Fill;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private MinMaxSizeType _maxHeightType = MinMaxSizeType.None;
+ /// <summary> The max height type of the object. </summary>
+ public MinMaxSizeType MaxHeightType
+ {
+ get { return _maxHeightType; }
+ set {
+ _maxHeightType = value;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _maxHeight = 1;
+ /// <summary> The max fixed height of the object. </summary>
+ public float MaxHeight
+ {
+ get { return _maxHeight; }
+ set {
+ _maxHeight = Mathf.Max(value, 0);
+ _maxHeightType = MinMaxSizeType.Fixed;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _maxHeightOfParent = 1;
+ /// <summary> The max relative height of the object. </summary>
+ public float MaxHeightOfParent
+ {
+ get { return _maxHeightOfParent; }
+ set {
+ _maxHeightOfParent = Mathf.Max(value, 0);
+ _maxHeightType = MinMaxSizeType.Fill;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private MinMaxSizeType _maxDepthType = MinMaxSizeType.None;
+ /// <summary> The max depth type of the object. </summary>
+ public MinMaxSizeType MaxDepthType
+ {
+ get { return _maxDepthType; }
+ set {
+ _maxDepthType = value;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _maxDepth = 1;
+ /// <summary> The max fixed depth of the object. </summary>
+ public float MaxDepth
+ {
+ get { return _maxDepth; }
+ set {
+ _maxDepth = Mathf.Max(value, 0);
+ _maxDepthType = MinMaxSizeType.Fixed;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _maxDepthOfParent = 1;
+ /// <summary> The max relative depth of the object. </summary>
+ public float MaxDepthOfParent
+ {
+ get { return _maxDepthOfParent; }
+ set {
+ _maxDepthOfParent = Mathf.Max(value, 0);
+ _maxDepthType = MinMaxSizeType.Fill;
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private Vector3 _offset = Vector3.zero;
+ /// <summary> Use offset to add an offset to the final position of the gameObject after layout is complete. </summary>
+ public Vector3 Offset
+ {
+ get { return _offset; }
+ set { _offset = value; MarkDirty(); }
+ }
+
+ [SerializeField]
+ private Vector3 _scale = Vector3.one;
+ /// <summary> Use rotation to scale the size of the gameObject before layout runs.
+ /// This will generate a new size to encapsulate the scaled object. </summary>
+ public Vector3 Scale
+ {
+ get { return _scale; }
+ set { _scale = value; MarkDirty(); }
+ }
+
+ [SerializeField]
+ private Quaternion _rotation = Quaternion.identity;
+ /// <summary> Use rotation to set the rotation of the gameObject before layout runs.
+ /// This will generate a new size to encapsulate the rotated object. </summary>
+ public Quaternion Rotation
+ {
+ get { return _rotation; }
+ set { _rotation = value; MarkDirty(); }
+ }
+
+ [SerializeField]
+ private float _marginLeft;
+ /// <summary> Margin to add additional space around a gameObject. </summary>
+ public float MarginLeft
+ {
+ get { return _marginLeft; }
+ set { _marginLeft = value; MarkDirty(); }
+ }
+
+ [SerializeField]
+ private float _marginRight;
+ /// <summary> Margin to add additional space around a gameObject. </summary>
+ public float MarginRight
+ {
+ get { return _marginRight; }
+ set { _marginRight = value; MarkDirty(); }
+ }
+
+ [SerializeField]
+ private float _marginTop;
+ /// <summary> Margin to add additional space around a gameObject. </summary>
+ public float MarginTop
+ {
+ get { return _marginTop; }
+ set { _marginTop = value; MarkDirty(); }
+ }
+
+ [SerializeField]
+ private float _marginBottom;
+ /// <summary> Margin to add additional space around a gameObject. </summary>
+ public float MarginBottom
+ {
+ get { return _marginBottom; }
+ set { _marginBottom = value; MarkDirty(); }
+ }
+
+ [SerializeField]
+ private float _marginFront;
+ /// <summary> Margin to add additional space around a gameObject. </summary>
+ public float MarginFront
+ {
+ get { return _marginFront; }
+ set { _marginFront = value; MarkDirty(); }
+ }
+
+ [SerializeField]
+ private float _marginBack;
+ /// <summary> Margin to add additional space around a gameObject. </summary>
+ public float MarginBack
+ {
+ get { return _marginBack; }
+ set { _marginBack = value; MarkDirty(); }
+ }
+
+ /// <summary> Margin to add additional space around a gameObject. </summary>
+ public Directions Margin
+ {
+ get => new Directions(new float[] {
+ _marginRight, _marginLeft, _marginTop, _marginBottom, _marginBack, _marginFront});
+ set
+ {
+ _marginRight = value[0];
+ _marginLeft = value[1];
+ _marginTop = value[2];
+ _marginBottom = value[3];
+ _marginBack = value[4];
+ _marginFront = value[5];
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private float _paddingLeft;
+ /// <summary> Padding to reduce available space inside a layout. </summary>
+ public float PaddingLeft
+ {
+ get { return _paddingLeft; }
+ set { _paddingLeft = value; MarkDirty(); }
+ }
+
+ [SerializeField]
+ private float _paddingRight;
+ /// <summary> Padding to reduce available space inside a layout. </summary>
+ public float PaddingRight
+ {
+ get { return _paddingRight; }
+ set { _paddingRight = value; MarkDirty(); }
+ }
+
+ [SerializeField]
+ private float _paddingTop;
+ /// <summary> Padding to reduce available space inside a layout. </summary>
+ public float PaddingTop
+ {
+ get { return _paddingTop; }
+ set { _paddingTop = value; MarkDirty(); }
+ }
+
+ [SerializeField]
+ private float _paddingBottom;
+ /// <summary> Padding to reduce available space inside a layout. </summary>
+ public float PaddingBottom
+ {
+ get { return _paddingBottom; }
+ set { _paddingBottom = value; MarkDirty(); }
+ }
+
+ [SerializeField]
+ private float _paddingFront;
+ /// <summary> Padding to reduce available space inside a layout. </summary>
+ public float PaddingFront
+ {
+ get { return _paddingFront; }
+ set { _paddingFront = value; MarkDirty(); }
+ }
+
+ [SerializeField]
+ private float _paddingBack;
+ /// <summary> Padding to reduce available space inside a layout. </summary>
+ public float PaddingBack
+ {
+ get { return _paddingBack; }
+ set { _paddingBack = value; MarkDirty(); }
+ }
+
+ /// <summary> Padding to reduce available space inside a layout. </summary>
+ public Directions Padding
+ {
+ get => new Directions(new float[] {
+ _paddingRight, _paddingLeft, _paddingTop, _paddingBottom, _paddingBack, _paddingFront});
+ set
+ {
+ _paddingRight = value[0];
+ _paddingLeft = value[1];
+ _paddingTop = value[2];
+ _paddingBottom = value[3];
+ _paddingBack = value[4];
+ _paddingFront = value[5];
+ MarkDirty();
+ }
+ }
+
+ [SerializeField]
+ private bool _skipLayout;
+ /// <summary> Skip layout for this object. </summary>
+ public bool SkipLayout
+ {
+ get => _skipLayout;
+ set
+ {
+ _skipLayout = value;
+ MarkDirty();
+ }
+ }
+
+ /// <inheritdoc />
+ protected override void ResetProperties()
+ {
+ _node.SetFlexalonObject(null);
+ }
+
+ /// <inheritdoc />
+ protected override void UpdateProperties()
+ {
+ _node.SetFlexalonObject(this);
+ }
+
+#if false
+ private Transform _lastParent;
+
+ /// <inheritdoc />
+ public override void DoUpdate()
+ {
+ if (Application.isPlaying || Node.Dirty)
+ {
+ return;
+ }
+
+ // Don't update prefab instances
+ if (UnityEditor.PrefabUtility.IsPartOfPrefabInstance(gameObject))
+ {
+ return;
+ }
+
+ var result = _node.Result;
+
+ // Don't do any of this if the parent changed.
+ if (_lastParent != transform.parent)
+ {
+ _lastParent = transform.parent;
+ result.TargetScale = transform.localScale;
+ result.TransformScale = transform.localScale;
+ result.TargetRotation = transform.localRotation;
+ result.TransformRotation = transform.localRotation;
+ result.TargetPosition = transform.localPosition;
+ result.TransformPosition = transform.localPosition;
+ }
+
+ // Detect changes to the object's position, rotation, scale, and rect size which may happen
+ // when the developer uses the transform control, enters new values in the
+ // inspector, or various other scenarios. Maintain those edits
+ // by modifying the offset, rotation, and scale on the FlexalonObject.
+
+ bool isRectTransform = false;
+ if (transform is RectTransform rectTransform)
+ {
+ if (_widthType == SizeType.Fixed)
+ {
+ if (rectTransform.rect.size.x != _width)
+ {
+ // Avoid recording changes here to avoid screen size changes causing edits.
+ _width = rectTransform.rect.size.x;
+ }
+ }
+
+ if (_heightType == SizeType.Fixed)
+ {
+ if (rectTransform.rect.size.y != _height)
+ {
+ // Avoid recording changes here to avoid screen size changes causing edits.
+ _height = rectTransform.rect.size.y;
+ }
+ }
+
+ isRectTransform = true;
+ }
+
+ bool shouldScale = _node.Adapter.TryGetScale(_node, out var s);
+ if (shouldScale && result.TransformScale != transform.localScale)
+ {
+ UnityEditor.Undo.RecordObject(this, "Scale change");
+ UnityEditor.PrefabUtility.RecordPrefabInstancePropertyModifications(this);
+ UnityEditor.Undo.RecordObject(result, "Scale change");
+ UnityEditor.PrefabUtility.RecordPrefabInstancePropertyModifications(result);
+ Flexalon.RecordFrameChanges = true;
+ _scale = Math.Mul(Scale, Math.Div(transform.localScale, result.TransformScale));
+ if (float.IsNaN(_scale.x) || Mathf.Abs(_scale.x) < 1e-5f) _scale.x = 0;
+ if (float.IsNaN(_scale.y) || Mathf.Abs(_scale.y) < 1e-5f) _scale.y = 0;
+ if (float.IsNaN(_scale.z) || Mathf.Abs(_scale.z) < 1e-5f) _scale.z = 0;
+ if (Mathf.Abs(1f - _scale.x) < 1e-5f) _scale.x = 1;
+ if (Mathf.Abs(1f - _scale.y) < 1e-5f) _scale.y = 1;
+ if (Mathf.Abs(1f - _scale.z) < 1e-5f) _scale.z = 1;
+ result.TargetScale = transform.localScale;
+ result.TransformScale = transform.localScale;
+ _node.Parent?.MarkDirty();
+
+ if (_node.Constraint != null)
+ {
+ _node.MarkDirty();
+ }
+ else
+ {
+ _node.ApplyScaleAndRotation();
+ }
+
+ // The scale and rect transform controls affect both position and scale,
+ // That's not expected in a layout, so early out here to avoid setting the position.
+ return;
+ }
+
+ bool inLayoutOrConstraint =
+ (_node.Parent != null && !_node.Parent.Dirty && transform.parent == _node.Parent.GameObject.transform) ||
+ (_node.Constraint != null && _node.Constraint.Target != null);
+
+ if (inLayoutOrConstraint)
+ {
+ if (!isRectTransform && result.TransformPosition != transform.localPosition)
+ {
+ UnityEditor.Undo.RecordObject(this, "Offset change");
+ UnityEditor.PrefabUtility.RecordPrefabInstancePropertyModifications(this);
+ UnityEditor.Undo.RecordObject(result, "Offset change");
+ UnityEditor.PrefabUtility.RecordPrefabInstancePropertyModifications(result);
+
+ if (transform is RectTransform offsetRectTransform)
+ {
+ }
+
+ if (Node.Constraint != null && Node.Constraint.Target != null)
+ {
+ _offset += Quaternion.Inverse(Node.Constraint.Target.transform.rotation) * (transform.localPosition - result.TransformPosition);
+ }
+ else
+ {
+ _offset += Math.Mul(Node.Parent.Result?.ComponentScale ?? Vector3.one, (transform.localPosition - result.TransformPosition));
+ }
+
+ if (float.IsNaN(_offset.x) || Mathf.Abs(_offset.x) < 1e-5f) _offset.x = 0;
+ if (float.IsNaN(_offset.y) || Mathf.Abs(_offset.y) < 1e-5f) _offset.y = 0;
+ if (float.IsNaN(_offset.z) || Mathf.Abs(_offset.z) < 1e-5f) _offset.z = 0;
+
+ result.TargetPosition = transform.localPosition;
+ result.TransformPosition = transform.localPosition;
+ }
+
+ if (result.TransformRotation != transform.localRotation)
+ {
+ UnityEditor.Undo.RecordObject(this, "Rotation change");
+ UnityEditor.PrefabUtility.RecordPrefabInstancePropertyModifications(this);
+ UnityEditor.Undo.RecordObject(result, "Rotation change");
+ UnityEditor.PrefabUtility.RecordPrefabInstancePropertyModifications(result);
+ Flexalon.RecordFrameChanges = true;
+
+ if (Node.Constraint != null && Node.Constraint.Target != null)
+ {
+ _rotation = Quaternion.Inverse(Node.Constraint.Target.transform.rotation) * transform.rotation;
+ }
+ else
+ {
+ _rotation *= transform.localRotation * Quaternion.Inverse(result.TransformRotation);
+ }
+
+ if (float.IsNaN(_rotation.x) || Mathf.Abs(_rotation.x) < 1e-5f) _rotation.x = 0;
+ if (float.IsNaN(_rotation.y) || Mathf.Abs(_rotation.y) < 1e-5f) _rotation.y = 0;
+ if (float.IsNaN(_rotation.z) || Mathf.Abs(_rotation.z) < 1e-5f) _rotation.z = 0;
+ if (float.IsNaN(_rotation.w) || Mathf.Abs(1 - _rotation.w) < 1e-5f) _rotation.w = 1;
+
+ _rotation.Normalize();
+ result.TargetRotation = transform.localRotation;
+ result.TransformRotation = transform.localRotation;
+ _node.Parent?.MarkDirty();
+
+ if (_node.Constraint != null)
+ {
+ _node.MarkDirty();
+ }
+ else
+ {
+ _node.ApplyScaleAndRotation();
+ }
+ }
+ }
+ else
+ {
+ if (result.TransformRotation != transform.localRotation)
+ {
+ UnityEditor.Undo.RecordObject(result, "Rotation change");
+ UnityEditor.PrefabUtility.RecordPrefabInstancePropertyModifications(result);
+ result.TargetRotation = transform.localRotation;
+ result.TransformRotation = transform.localRotation;
+ _node.ApplyScaleAndRotation();
+ }
+ }
+ }
+#endif
+
+ protected override void Initialize()
+ {
+ base.Initialize();
+ if (transform is RectTransform || (transform.parent && transform.parent is RectTransform))
+ {
+ _width = 100;
+ _height = 100;
+ _maxWidth = 100;
+ _maxHeight = 100;
+ }
+ }
+
+ protected override void Upgrade(int fromVersion)
+ {
+#if UNITY_UI
+ // UPGRADE FIX: In v4.0 canvas no longer scales to fit layout size.
+ // Instead, scale needs to be set on the FlexalonObject.
+ if (fromVersion < 4 && TryGetComponent<Canvas>(out var canvas))
+ {
+ _widthType = SizeType.Component;
+ _heightType = SizeType.Component;
+
+ if (canvas.renderMode == RenderMode.WorldSpace)
+ {
+ _scale = canvas.transform.localScale;
+ _node.Result.AdapterBounds = new Bounds(Vector3.zero, (transform as RectTransform).rect.size);
+ }
+ }
+#endif
+ }
+ }
+}
\ No newline at end of file
--
Gitblit v1.10.0