185 lines
5.4 KiB
C#
185 lines
5.4 KiB
C#
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
|
|
using System;
|
|
using FlaxEngine;
|
|
using FlaxEngine.GUI;
|
|
using Object = FlaxEngine.Object;
|
|
|
|
namespace FlaxEditor.Viewport.Previews
|
|
{
|
|
/// <summary>
|
|
/// Prefab asset preview editor viewport.
|
|
/// </summary>
|
|
/// <seealso cref="AssetPreview" />
|
|
public class PrefabPreview : AssetPreview
|
|
{
|
|
private Prefab _prefab;
|
|
private Actor _instance;
|
|
private UIControl _uiControlLinked;
|
|
internal bool _hasUILinked;
|
|
internal ContainerControl _uiParentLink;
|
|
|
|
/// <summary>
|
|
/// Gets or sets the prefab asset to preview.
|
|
/// </summary>
|
|
public Prefab Prefab
|
|
{
|
|
get => _prefab;
|
|
set
|
|
{
|
|
if (_prefab == value)
|
|
return;
|
|
|
|
// Unset and cleanup spawned instance
|
|
if (_instance)
|
|
{
|
|
var instance = _instance;
|
|
Instance = null;
|
|
Object.Destroy(instance);
|
|
}
|
|
|
|
_prefab = value;
|
|
|
|
if (_prefab)
|
|
{
|
|
// Load prefab
|
|
_prefab.WaitForLoaded();
|
|
|
|
// Spawn prefab
|
|
var instance = PrefabManager.SpawnPrefab(_prefab, null);
|
|
if (instance == null)
|
|
{
|
|
_prefab = null;
|
|
throw new Exception("Failed to spawn a prefab for the preview.");
|
|
}
|
|
|
|
// Set instance
|
|
Instance = instance;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the instance of the prefab spawned for the preview.
|
|
/// </summary>
|
|
public Actor Instance
|
|
{
|
|
get => _instance;
|
|
internal set
|
|
{
|
|
if (_instance == value)
|
|
return;
|
|
|
|
if (_instance)
|
|
{
|
|
// Unlink UI control
|
|
if (_uiControlLinked)
|
|
{
|
|
if (_uiControlLinked.Control?.Parent == _uiParentLink)
|
|
_uiControlLinked.Control.Parent = null;
|
|
_uiControlLinked = null;
|
|
}
|
|
foreach (var child in _uiParentLink.Children.ToArray())
|
|
{
|
|
if (child is CanvasRootControl canvasRoot)
|
|
{
|
|
canvasRoot.Canvas.EditorOverride(null, null);
|
|
}
|
|
}
|
|
|
|
// Remove for the preview
|
|
Task.RemoveCustomActor(_instance);
|
|
}
|
|
|
|
_instance = value;
|
|
_hasUILinked = false;
|
|
|
|
if (_instance)
|
|
{
|
|
// Add to the preview
|
|
Task.AddCustomActor(_instance);
|
|
UpdateLinkage();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UpdateLinkage()
|
|
{
|
|
// Clear flag
|
|
_hasUILinked = false;
|
|
|
|
// Link UI canvases to the preview (eg. after canvas added to the prefab)
|
|
LinkCanvas(_instance);
|
|
|
|
// Link UI control to the preview
|
|
var uiControl = _instance as UIControl;
|
|
if (_uiControlLinked == null &&
|
|
uiControl != null &&
|
|
uiControl.Control != null &&
|
|
uiControl.Control.Parent == null)
|
|
{
|
|
uiControl.Control.Parent = _uiParentLink;
|
|
_uiControlLinked = uiControl;
|
|
_hasUILinked = true;
|
|
}
|
|
else if (_uiControlLinked != null)
|
|
{
|
|
if (_uiControlLinked.Control != null &&
|
|
_uiControlLinked.Control.Parent == null)
|
|
_uiControlLinked.Control.Parent = _uiParentLink;
|
|
_hasUILinked = true;
|
|
}
|
|
|
|
// Use UI mode when root is empty UI Control
|
|
if (_uiControlLinked == null && uiControl != null && uiControl.Control == null)
|
|
{
|
|
_hasUILinked = true;
|
|
}
|
|
}
|
|
|
|
private void LinkCanvas(Actor actor)
|
|
{
|
|
if (actor is UICanvas uiCanvas)
|
|
{
|
|
uiCanvas.EditorOverride(Task, _uiParentLink);
|
|
if (uiCanvas.GUI.Parent == _uiParentLink)
|
|
_hasUILinked = true;
|
|
}
|
|
|
|
var children = actor.ChildrenCount;
|
|
for (int i = 0; i < children; i++)
|
|
LinkCanvas(actor.GetChild(i));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="PrefabPreview"/> class.
|
|
/// </summary>
|
|
/// <param name="useWidgets">if set to <c>true</c> use widgets.</param>
|
|
public PrefabPreview(bool useWidgets)
|
|
: base(useWidgets)
|
|
{
|
|
// Link to itself by default
|
|
_uiParentLink = this;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override void Update(float deltaTime)
|
|
{
|
|
base.Update(deltaTime);
|
|
|
|
if (_instance != null)
|
|
{
|
|
UpdateLinkage();
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override void OnDestroy()
|
|
{
|
|
Prefab = null;
|
|
|
|
base.OnDestroy();
|
|
}
|
|
}
|
|
}
|