View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0002935 | NoesisGUI | Unity | public | 2023-12-11 22:13 | 2024-01-24 21:33 |
| Reporter | stonstad | Assigned To | jsantos | ||
| Priority | normal | Severity | block | ||
| Status | resolved | Resolution | fixed | ||
| Product Version | 3.2.2 | ||||
| Target Version | 3.2.3 | Fixed in Version | 3.2.3 | ||
| Summary | 0002935: NoesisWorldUI should not recreate or evict state on GameObject.Enable/Disable | ||||
| Description | This isn't the correct behavior for Unity. In Unity, disabling a game object within the hierarchy should not mutate state -- or in this case, cause state to be evicted or reloaded. What would be more appropriate here is to just disable the renderer. I think what the developer is looking for is OnDestroy. | ||||
| Platform | Any | ||||
|
https://www.noesisengine.com/forums/viewtopic.php?p=16401#p16401 |
|
|
I am loading state in Awake(), and this is working well for me. |
|
|
Yes, it makes sense. We will study moving the loading/destruction to the Awake/OnDestroy methods, and leave Enable/Disable to just add/remove the loaded xaml to the View. |
|
|
I implemented it as mentioned above, could you try the attached script? |
|
|
NoesisWorldUI.cs (4,426 bytes)
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using UnityEngine;
using Noesis;
public class NoesisWorldUI : MonoBehaviour
{
[SerializeField]
private NoesisView _view;
public NoesisView View
{
get => _view;
set
{
if (_view != value)
{
_view = value;
RemoveContent();
FindContainer();
AddContent();
}
}
}
[SerializeField]
private string _container = "Root";
public string Container
{
get => _container;
set
{
if (_container != value)
{
_container = value;
RemoveContent();
FindContainer();
AddContent();
}
}
}
[SerializeField]
private NoesisXaml _xaml;
public NoesisXaml Xaml
{
get => _xaml;
set
{
if (_xaml != value)
{
_xaml = value;
RemoveContent();
LoadContent();
AddContent();
}
}
}
[SerializeField]
private float _scale = 0.005f;
public float Scale { get => _scale; set { _scale = value; } }
[SerializeField]
private Vector3 _offset = new Vector3();
public Vector3 Offset { get => _offset; set { _offset = value; } }
[SerializeField]
private bool _center = true;
public bool Center { get => _center; set { _center = value; } }
public FrameworkElement Content => _content;
private void Awake()
{
FindContainer();
LoadContent();
}
void OnEnable()
{
AddContent();
}
void OnDisable()
{
RemoveContent();
}
private void OnDestroy()
{
_content = null;
_transform = null;
_containerPanel = null;
_camera = null;
_view = null;
_xaml = null;
}
void Update()
{
if (_content != null && _camera != null)
{
float width = 0.0f;
float height = 0.0f;
if (Center)
{
_content.Measure(new Size(float.PositiveInfinity, float.PositiveInfinity));
width = _content.DesiredSize.Width;
height = _content.DesiredSize.Height;
}
Matrix4x4 mtx = transform.localToWorldMatrix * Matrix4x4.Translate(Offset) *
Matrix4x4.Scale(new Vector3(Scale, -Scale, Scale)) *
Matrix4x4.Translate(new Vector3(-0.5f * width, -0.5f * height, 0.00f));
_transform.Matrix = new Matrix3D
(
mtx[0, 0], mtx[1, 0], mtx[2, 0],
mtx[0, 1], mtx[1, 1], mtx[2, 1],
mtx[0, 2], mtx[1, 2], mtx[2, 2],
mtx[0, 3], mtx[1, 3], mtx[2, 3]
);
float z = (_camera.worldToCameraMatrix * transform.localToWorldMatrix).m23;
Panel.SetZIndex(_content, (int)(z * 100.0f));
}
}
void FindContainer()
{
_containerPanel = null;
_camera = null;
if (View != null && !string.IsNullOrEmpty(Container))
{
_containerPanel = View.Content?.FindName(Container) as Panel;
_camera = View.GetComponent<Camera>();
}
}
void LoadContent()
{
_content = null;
_transform = null;
if (Xaml != null)
{
_content = Xaml.Load() as FrameworkElement;
if (_content != null)
{
_transform = new MatrixTransform3D();
_content.Transform3D = _transform;
}
}
}
void AddContent()
{
if (enabled && _containerPanel != null && _content != null)
{
_containerPanel.Children.Add(_content);
}
}
void RemoveContent()
{
if (_containerPanel != null && _content != null)
{
_containerPanel.Children.Remove(_content);
}
}
private Panel _containerPanel;
private Camera _camera;
private FrameworkElement _content;
private MatrixTransform3D _transform;
}
|
|
|
Thank you Sergio. Very cool stuff. OK, I tried it out and it looks like View.Content? is null when FindContainer is called in Awake() I believe the cause is that this particular game object is not active in the hierarchy when WorldSpaceUI.Awake() is initially called. |
|
|
This might be related to 0002586. [DefaultExecutionOrder(100)] |
|
|
Attaching latest version that is coming with 3.2.3 NoesisWorldUI-2.cs (4,722 bytes)
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using UnityEngine;
using Noesis;
[DefaultExecutionOrder(100)]
public class NoesisWorldUI : MonoBehaviour
{
[SerializeField]
private NoesisView _view;
public NoesisView View
{
get => _view;
set
{
if (_view != value)
{
_view = value;
RemoveContent();
FindContainer();
AddContent();
}
}
}
[SerializeField]
private string _container = "Root";
public string Container
{
get => _container;
set
{
if (_container != value)
{
_container = value;
RemoveContent();
FindContainer();
AddContent();
}
}
}
[SerializeField]
private NoesisXaml _xaml;
public NoesisXaml Xaml
{
get => _xaml;
set
{
if (_xaml != value)
{
_xaml = value;
RemoveContent();
LoadContent();
AddContent();
}
}
}
[SerializeField]
private float _scale = 0.005f;
public float Scale { get => _scale; set { _scale = value; } }
[SerializeField]
private Vector3 _offset = new Vector3();
public Vector3 Offset { get => _offset; set { _offset = value; } }
[SerializeField]
private bool _center = true;
public bool Center { get => _center; set { _center = value; } }
public FrameworkElement Content => _content;
void OnEnable()
{
EnsureContainer();
EnsureContent();
AddContent();
}
void OnDisable()
{
RemoveContent();
}
void OnDestroy()
{
_content = null;
_transform = null;
_containerPanel = null;
_camera = null;
_view = null;
_xaml = null;
}
void Update()
{
if (_content != null && _camera != null)
{
float width = 0.0f;
float height = 0.0f;
if (Center)
{
_content.Measure(new Size(float.PositiveInfinity, float.PositiveInfinity));
width = _content.DesiredSize.Width;
height = _content.DesiredSize.Height;
}
Matrix4x4 mtx = transform.localToWorldMatrix * Matrix4x4.Translate(Offset) *
Matrix4x4.Scale(new Vector3(Scale, -Scale, Scale)) *
Matrix4x4.Translate(new Vector3(-0.5f * width, -0.5f * height, 0.00f));
_transform.Matrix = new Matrix3D
(
mtx[0, 0], mtx[1, 0], mtx[2, 0],
mtx[0, 1], mtx[1, 1], mtx[2, 1],
mtx[0, 2], mtx[1, 2], mtx[2, 2],
mtx[0, 3], mtx[1, 3], mtx[2, 3]
);
float z = (_camera.worldToCameraMatrix * transform.localToWorldMatrix).m23;
Panel.SetZIndex(_content, (int)(z * 100.0f));
}
}
void EnsureContainer()
{
if (_containerPanel == null)
{
FindContainer();
}
}
void FindContainer()
{
_containerPanel = null;
_camera = null;
if (View != null && !string.IsNullOrEmpty(Container))
{
_containerPanel = View.Content?.FindName(Container) as Panel;
_camera = View.GetComponent<Camera>();
}
}
void EnsureContent()
{
if (_content == null)
{
LoadContent();
}
}
void LoadContent()
{
_content = null;
_transform = null;
if (Xaml != null)
{
_content = Xaml.Load() as FrameworkElement;
if (_content != null)
{
_transform = new MatrixTransform3D();
_content.Transform3D = _transform;
}
}
}
void AddContent()
{
if (enabled)
{
if (_containerPanel != null && _content != null)
{
_containerPanel.Children.Add(_content);
}
}
}
void RemoveContent()
{
if (_containerPanel != null && _content != null)
{
_containerPanel.Children.Remove(_content);
}
}
private Panel _containerPanel;
private Camera _camera;
private FrameworkElement _content;
private MatrixTransform3D _transform;
}
|
|
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2023-12-11 22:13 | stonstad | New Issue | |
| 2023-12-11 22:14 | stonstad | Note Added: 0009007 | |
| 2023-12-11 22:38 | stonstad | Note Added: 0009008 | |
| 2023-12-12 12:50 | jsantos | Assigned To | => sfernandez |
| 2023-12-12 12:50 | jsantos | Status | new => assigned |
| 2023-12-12 12:50 | jsantos | Target Version | => 3.2.3 |
| 2023-12-12 13:05 | sfernandez | Note Added: 0009014 | |
| 2023-12-12 14:03 | sfernandez | Status | assigned => feedback |
| 2023-12-12 14:03 | sfernandez | Note Added: 0009017 | |
| 2023-12-12 14:03 | sfernandez | Note Added: 0009018 | |
| 2023-12-12 14:03 | sfernandez | File Added: NoesisWorldUI.cs | |
| 2023-12-12 15:58 | stonstad | Note Added: 0009019 | |
| 2023-12-12 15:58 | stonstad | File Added: image.png | |
| 2023-12-12 15:58 | stonstad | Status | feedback => assigned |
| 2023-12-12 20:33 | sfernandez | Status | assigned => feedback |
| 2023-12-12 20:33 | sfernandez | Note Added: 0009021 | |
| 2024-01-22 11:47 | sfernandez | Target Version | 3.2.3 => 3.2.4 |
| 2024-01-22 11:48 | sfernandez | Target Version | 3.2.4 => 3.2.3 |
| 2024-01-23 18:59 | sfernandez | Assigned To | sfernandez => |
| 2024-01-23 18:59 | sfernandez | Assigned To | => jsantos |
| 2024-01-23 18:59 | sfernandez | Status | feedback => assigned |
| 2024-01-24 21:33 | jsantos | Note Added: 0009116 | |
| 2024-01-24 21:33 | jsantos | File Added: NoesisWorldUI-2.cs | |
| 2024-01-24 21:33 | jsantos | Status | assigned => resolved |
| 2024-01-24 21:33 | jsantos | Resolution | open => fixed |
| 2024-01-24 21:33 | jsantos | Fixed in Version | => 3.2.3 |
| 2025-10-10 13:29 | jsantos | Category | Unity3D => Unity |