Add ability to edit position curve in timeline with a gizmo in a viewport
This commit is contained in:
@@ -241,6 +241,15 @@ namespace FlaxEditor.GUI
|
|||||||
/// <param name="value">The keyframe value.</param>
|
/// <param name="value">The keyframe value.</param>
|
||||||
public abstract void SetKeyframeValue(int index, object value);
|
public abstract void SetKeyframeValue(int index, object value);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the existing keyframe value (as boxed object).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The keyframe index.</param>
|
||||||
|
/// <param name="value">The keyframe value.</param>
|
||||||
|
/// <param name="tangentIn">The keyframe 'In' tangent value (boxed).</param>
|
||||||
|
/// <param name="tangentOut">The keyframe 'Out' tangent value (boxed).</param>
|
||||||
|
public abstract void SetKeyframeValue(int index, object value, object tangentIn, object tangentOut);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the keyframe point (in keyframes space).
|
/// Gets the keyframe point (in keyframes space).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1289,6 +1289,18 @@ namespace FlaxEditor.GUI
|
|||||||
OnEdited();
|
OnEdited();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void SetKeyframeValue(int index, object value, object tangentIn, object tangentOut)
|
||||||
|
{
|
||||||
|
var k = _keyframes[index];
|
||||||
|
k.Value = (T)value;
|
||||||
|
_keyframes[index] = k;
|
||||||
|
|
||||||
|
UpdateKeyframes();
|
||||||
|
UpdateTooltips();
|
||||||
|
OnEdited();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Float2 GetKeyframePoint(int index, int component)
|
public override Float2 GetKeyframePoint(int index, int component)
|
||||||
{
|
{
|
||||||
@@ -2011,6 +2023,20 @@ namespace FlaxEditor.GUI
|
|||||||
OnEdited();
|
OnEdited();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void SetKeyframeValue(int index, object value, object tangentIn, object tangentOut)
|
||||||
|
{
|
||||||
|
var k = _keyframes[index];
|
||||||
|
k.Value = (T)value;
|
||||||
|
k.TangentIn = (T)tangentIn;
|
||||||
|
k.TangentOut = (T)tangentOut;
|
||||||
|
_keyframes[index] = k;
|
||||||
|
|
||||||
|
UpdateKeyframes();
|
||||||
|
UpdateTooltips();
|
||||||
|
OnEdited();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Float2 GetKeyframePoint(int index, int component)
|
public override Float2 GetKeyframePoint(int index, int component)
|
||||||
{
|
{
|
||||||
|
|||||||
203
Source/Editor/GUI/Timeline/EditCurveTrackGizmo.cs
Normal file
203
Source/Editor/GUI/Timeline/EditCurveTrackGizmo.cs
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
|
using FlaxEditor.Gizmo;
|
||||||
|
using FlaxEditor.GUI.Timeline.Tracks;
|
||||||
|
using FlaxEditor.GUI.Timeline.Undo;
|
||||||
|
using FlaxEditor.SceneGraph;
|
||||||
|
using FlaxEngine;
|
||||||
|
|
||||||
|
namespace FlaxEditor.GUI.Timeline
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gizmo for editing position curve. Managed by the <see cref="SceneAnimationTimeline"/>.
|
||||||
|
/// </summary>
|
||||||
|
sealed class EditCurveTrackGizmo : TransformGizmoBase
|
||||||
|
{
|
||||||
|
public const float KeyframeSize = 10.0f;
|
||||||
|
public const float TangentSize = 6.0f;
|
||||||
|
|
||||||
|
private readonly SceneAnimationTimeline _timeline;
|
||||||
|
private CurvePropertyTrack _track;
|
||||||
|
private int _keyframe = -1;
|
||||||
|
private int _item = -1;
|
||||||
|
private byte[] _curveEditingStartData;
|
||||||
|
|
||||||
|
public int Keyframe => _keyframe;
|
||||||
|
public int Item => _item;
|
||||||
|
|
||||||
|
public EditCurveTrackGizmo(IGizmoOwner owner, SceneAnimationTimeline timeline)
|
||||||
|
: base(owner)
|
||||||
|
{
|
||||||
|
_timeline = timeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectKeyframe(CurvePropertyTrack track, int keyframe, int item)
|
||||||
|
{
|
||||||
|
_track = track;
|
||||||
|
_keyframe = keyframe;
|
||||||
|
_item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override BoundingSphere FocusBounds
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_track == null)
|
||||||
|
return BoundingSphere.Empty;
|
||||||
|
var curve = (BezierCurveEditor<Vector3>)_track.Curve;
|
||||||
|
var keyframes = curve.Keyframes;
|
||||||
|
var k = keyframes[_keyframe];
|
||||||
|
if (_item == 1)
|
||||||
|
k.Value += k.TangentIn;
|
||||||
|
else if (_item == 2)
|
||||||
|
k.Value += k.TangentOut;
|
||||||
|
return new BoundingSphere(k.Value, KeyframeSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override int SelectionCount => _track != null ? 1 : 0;
|
||||||
|
|
||||||
|
protected override SceneGraphNode GetSelectedObject(int index)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Transform GetSelectedTransform(int index)
|
||||||
|
{
|
||||||
|
if (_track == null)
|
||||||
|
return Transform.Identity;
|
||||||
|
var curve = (BezierCurveEditor<Vector3>)_track.Curve;
|
||||||
|
var keyframes = curve.Keyframes;
|
||||||
|
var k = keyframes[_keyframe];
|
||||||
|
if (_item == 1)
|
||||||
|
k.Value += k.TangentIn;
|
||||||
|
else if (_item == 2)
|
||||||
|
k.Value += k.TangentOut;
|
||||||
|
return new Transform(k.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void GetSelectedObjectsBounds(out BoundingBox bounds, out bool navigationDirty)
|
||||||
|
{
|
||||||
|
bounds = BoundingBox.Empty;
|
||||||
|
navigationDirty = false;
|
||||||
|
if (_track == null)
|
||||||
|
return;
|
||||||
|
var curve = (BezierCurveEditor<Vector3>)_track.Curve;
|
||||||
|
var keyframes = curve.Keyframes;
|
||||||
|
var k = keyframes[_keyframe];
|
||||||
|
if (_item == 1)
|
||||||
|
k.Value += k.TangentIn;
|
||||||
|
else if (_item == 2)
|
||||||
|
k.Value += k.TangentOut;
|
||||||
|
bounds = new BoundingBox(k.Value - KeyframeSize, k.Value + KeyframeSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool IsSelected(SceneGraphNode obj)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnStartTransforming()
|
||||||
|
{
|
||||||
|
base.OnStartTransforming();
|
||||||
|
|
||||||
|
// Start undo
|
||||||
|
_curveEditingStartData = EditTrackAction.CaptureData(_track);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnEndTransforming()
|
||||||
|
{
|
||||||
|
base.OnEndTransforming();
|
||||||
|
|
||||||
|
// End undo
|
||||||
|
var after = EditTrackAction.CaptureData(_track);
|
||||||
|
if (!Utils.ArraysEqual(_curveEditingStartData, after))
|
||||||
|
_track.Timeline.AddBatchedUndoAction(new EditTrackAction(_track.Timeline, _track, _curveEditingStartData, after));
|
||||||
|
_curveEditingStartData = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApplyTransformation(ref Vector3 translationDelta, ref Quaternion rotationDelta, ref Vector3 scaleDelta)
|
||||||
|
{
|
||||||
|
base.OnApplyTransformation(ref translationDelta, ref rotationDelta, ref scaleDelta);
|
||||||
|
|
||||||
|
var curve = (BezierCurveEditor<Vector3>)_track.Curve;
|
||||||
|
var keyframes = curve.Keyframes;
|
||||||
|
var k = keyframes[_keyframe];
|
||||||
|
if (_item == 0)
|
||||||
|
k.Value += translationDelta;
|
||||||
|
else if (_item == 1)
|
||||||
|
k.TangentIn += translationDelta;
|
||||||
|
else if (_item == 2)
|
||||||
|
k.TangentOut += translationDelta;
|
||||||
|
curve.SetKeyframeValue(_keyframe, k.Value, k.TangentIn, k.TangentOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Pick()
|
||||||
|
{
|
||||||
|
if (_track == null)
|
||||||
|
return;
|
||||||
|
var selectRay = Owner.MouseRay;
|
||||||
|
var curve = (BezierCurveEditor<Vector3>)_track.Curve;
|
||||||
|
var keyframes = curve.Keyframes;
|
||||||
|
for (var i = 0; i < keyframes.Count; i++)
|
||||||
|
{
|
||||||
|
var k = keyframes[i];
|
||||||
|
|
||||||
|
var sphere = new BoundingSphere(k.Value, KeyframeSize);
|
||||||
|
if (sphere.Intersects(ref selectRay))
|
||||||
|
{
|
||||||
|
SelectKeyframe(_track, i, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!k.TangentIn.IsZero)
|
||||||
|
{
|
||||||
|
var t = k.Value + k.TangentIn;
|
||||||
|
var box = BoundingBox.FromSphere(new BoundingSphere(t, TangentSize));
|
||||||
|
if (box.Intersects(ref selectRay))
|
||||||
|
{
|
||||||
|
SelectKeyframe(_track, i, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!k.TangentOut.IsZero)
|
||||||
|
{
|
||||||
|
var t = k.Value + k.TangentOut;
|
||||||
|
var box = BoundingBox.FromSphere(new BoundingSphere(t, TangentSize));
|
||||||
|
if (box.Intersects(ref selectRay))
|
||||||
|
{
|
||||||
|
SelectKeyframe(_track, i, 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float dt)
|
||||||
|
{
|
||||||
|
base.Update(dt);
|
||||||
|
|
||||||
|
// Deactivate when track gets deselected
|
||||||
|
if (_track != null && !_timeline.SelectedTracks.Contains(_track))
|
||||||
|
Owner.Gizmos.Active = Owner.Gizmos.Get<TransformGizmo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnActivated()
|
||||||
|
{
|
||||||
|
base.OnActivated();
|
||||||
|
|
||||||
|
ActiveMode = Mode.Translate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnDeactivated()
|
||||||
|
{
|
||||||
|
// Clear selection
|
||||||
|
_track = null;
|
||||||
|
_keyframe = -1;
|
||||||
|
_item = -1;
|
||||||
|
|
||||||
|
base.OnDeactivated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using FlaxEngine;
|
||||||
using FlaxEditor.Content;
|
using FlaxEditor.Content;
|
||||||
|
using FlaxEditor.Gizmo;
|
||||||
using FlaxEditor.GUI.Drag;
|
using FlaxEditor.GUI.Drag;
|
||||||
using FlaxEditor.GUI.Timeline.Tracks;
|
using FlaxEditor.GUI.Timeline.Tracks;
|
||||||
using FlaxEditor.SceneGraph;
|
using FlaxEditor.SceneGraph;
|
||||||
using FlaxEngine;
|
|
||||||
|
|
||||||
namespace FlaxEditor.GUI.Timeline
|
namespace FlaxEditor.GUI.Timeline
|
||||||
{
|
{
|
||||||
@@ -25,6 +26,7 @@ namespace FlaxEditor.GUI.Timeline
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SceneAnimationPlayer _player;
|
private SceneAnimationPlayer _player;
|
||||||
|
private EditCurveTrackGizmo _curveTrackGizmo;
|
||||||
private bool _showSelected3dTrack = true;
|
private bool _showSelected3dTrack = true;
|
||||||
internal Guid _id;
|
internal Guid _id;
|
||||||
|
|
||||||
@@ -239,6 +241,19 @@ namespace FlaxEditor.GUI.Timeline
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SelectKeyframeGizmo(CurvePropertyTrack track, int keyframe, int item)
|
||||||
|
{
|
||||||
|
var mainGizmo = Editor.Instance.MainTransformGizmo;
|
||||||
|
if (!mainGizmo.IsActive)
|
||||||
|
return; // Skip when using vertex painting or terrain or foliage tools
|
||||||
|
if (_curveTrackGizmo == null)
|
||||||
|
{
|
||||||
|
_curveTrackGizmo = new EditCurveTrackGizmo(mainGizmo.Owner, this);
|
||||||
|
}
|
||||||
|
_curveTrackGizmo.SelectKeyframe(track, keyframe, item);
|
||||||
|
_curveTrackGizmo.Activate();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnPlay()
|
public override void OnPlay()
|
||||||
{
|
{
|
||||||
@@ -289,8 +304,17 @@ namespace FlaxEditor.GUI.Timeline
|
|||||||
UpdatePlaybackState();
|
UpdatePlaybackState();
|
||||||
|
|
||||||
// Draw all selected 3D position tracks as Bezier curve in editor viewport
|
// Draw all selected 3D position tracks as Bezier curve in editor viewport
|
||||||
if (ShowSelected3dTrack)
|
if (!VisibleInHierarchy || !EnabledInHierarchy)
|
||||||
{
|
{
|
||||||
|
// Disable curve transform gizmo to normal gizmo
|
||||||
|
if (_curveTrackGizmo != null && _curveTrackGizmo.IsActive)
|
||||||
|
_curveTrackGizmo.Owner.Gizmos.Get<TransformGizmo>().Activate();
|
||||||
|
}
|
||||||
|
else if (ShowSelected3dTrack)
|
||||||
|
{
|
||||||
|
bool select = FlaxEngine.Input.GetMouseButtonDown(MouseButton.Left);
|
||||||
|
Ray selectRay = Editor.Instance.MainTransformGizmo.Owner.MouseRay;
|
||||||
|
const float coveredAlpha = 0.1f;
|
||||||
foreach (var track in SelectedTracks)
|
foreach (var track in SelectedTracks)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
@@ -302,31 +326,44 @@ namespace FlaxEditor.GUI.Timeline
|
|||||||
{
|
{
|
||||||
var curve = (BezierCurveEditor<Vector3>)curveTrack.Curve;
|
var curve = (BezierCurveEditor<Vector3>)curveTrack.Curve;
|
||||||
var keyframes = curve.Keyframes;
|
var keyframes = curve.Keyframes;
|
||||||
|
var selectedKeyframe = _curveTrackGizmo?.Keyframe ?? -1;
|
||||||
|
var selectedItem = _curveTrackGizmo?.Item ?? -1;
|
||||||
for (var i = 0; i < keyframes.Count; i++)
|
for (var i = 0; i < keyframes.Count; i++)
|
||||||
{
|
{
|
||||||
var k = keyframes[i];
|
var k = keyframes[i];
|
||||||
|
|
||||||
DebugDraw.DrawSphere(new BoundingSphere(k.Value, 10.0f), Color.Red);
|
var selected = selectedKeyframe == i && selectedItem == 0;
|
||||||
DebugDraw.DrawSphere(new BoundingSphere(k.Value, 9.5f), new Color(1, 0, 0, 0.1f), 0, false);
|
var sphere = new BoundingSphere(k.Value, EditCurveTrackGizmo.KeyframeSize);
|
||||||
|
DebugDraw.DrawSphere(sphere, selected ? Color.Yellow : Color.Red);
|
||||||
|
sphere.Radius *= 0.95f;
|
||||||
|
DebugDraw.DrawSphere(sphere, new Color(1, 0, 0, coveredAlpha), 0, false);
|
||||||
|
if (select && sphere.Intersects(ref selectRay))
|
||||||
|
SelectKeyframeGizmo(curveTrack, i, 0);
|
||||||
|
|
||||||
if (!k.TangentIn.IsZero)
|
if (!k.TangentIn.IsZero)
|
||||||
{
|
{
|
||||||
|
selected = selectedKeyframe == i && selectedItem == 1;
|
||||||
var t = k.Value + k.TangentIn;
|
var t = k.Value + k.TangentIn;
|
||||||
DebugDraw.DrawLine(k.Value, t, Color.Yellow);
|
DebugDraw.DrawLine(k.Value, t, Color.Yellow);
|
||||||
DebugDraw.DrawLine(k.Value, t, Color.Yellow.AlphaMultiplied(0.1f), 0, false);
|
DebugDraw.DrawLine(k.Value, t, Color.Yellow.AlphaMultiplied(coveredAlpha), 0, false);
|
||||||
var box = BoundingBox.FromSphere(new BoundingSphere(t, 6.0f));
|
var box = BoundingBox.FromSphere(new BoundingSphere(t, EditCurveTrackGizmo.TangentSize));
|
||||||
DebugDraw.DrawBox(box, Color.AliceBlue);
|
DebugDraw.DrawBox(box, selected ? Color.Yellow : Color.AliceBlue);
|
||||||
DebugDraw.DrawBox(box, Color.AliceBlue.AlphaMultiplied(0.1f), 0, false);
|
DebugDraw.DrawBox(box, Color.AliceBlue.AlphaMultiplied(coveredAlpha), 0, false);
|
||||||
|
if (select && box.Intersects(ref selectRay))
|
||||||
|
SelectKeyframeGizmo(curveTrack, i, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!k.TangentOut.IsZero)
|
if (!k.TangentOut.IsZero)
|
||||||
{
|
{
|
||||||
|
selected = selectedKeyframe == i && selectedItem == 2;
|
||||||
var t = k.Value + k.TangentOut;
|
var t = k.Value + k.TangentOut;
|
||||||
DebugDraw.DrawLine(k.Value, t, Color.Yellow);
|
DebugDraw.DrawLine(k.Value, t, Color.Yellow);
|
||||||
DebugDraw.DrawLine(k.Value, t, Color.Yellow.AlphaMultiplied(0.1f), 0, false);
|
DebugDraw.DrawLine(k.Value, t, Color.Yellow.AlphaMultiplied(coveredAlpha), 0, false);
|
||||||
var box = BoundingBox.FromSphere(new BoundingSphere(t, 6.0f));
|
var box = BoundingBox.FromSphere(new BoundingSphere(t, EditCurveTrackGizmo.TangentSize));
|
||||||
DebugDraw.DrawBox(box, Color.AliceBlue);
|
DebugDraw.DrawBox(box, selected ? Color.Yellow : Color.AliceBlue);
|
||||||
DebugDraw.DrawBox(box, Color.AliceBlue.AlphaMultiplied(0.1f), 0, false);
|
DebugDraw.DrawBox(box, Color.AliceBlue.AlphaMultiplied(coveredAlpha), 0, false);
|
||||||
|
if (select && box.Intersects(ref selectRay))
|
||||||
|
SelectKeyframeGizmo(curveTrack, i, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
@@ -341,6 +378,18 @@ namespace FlaxEditor.GUI.Timeline
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnDestroy()
|
||||||
|
{
|
||||||
|
if (_curveTrackGizmo != null)
|
||||||
|
{
|
||||||
|
_curveTrackGizmo.Destroy();
|
||||||
|
_curveTrackGizmo = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void OnShowViewContextMenu(ContextMenu.ContextMenu menu)
|
protected override void OnShowViewContextMenu(ContextMenu.ContextMenu menu)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,15 +12,17 @@ namespace FlaxEditor.Gizmo
|
|||||||
[HideInEditor]
|
[HideInEditor]
|
||||||
public abstract class GizmoBase
|
public abstract class GizmoBase
|
||||||
{
|
{
|
||||||
|
private IGizmoOwner _owner;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the gizmo owner.
|
/// Gets the gizmo owner.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IGizmoOwner Owner { get; }
|
public IGizmoOwner Owner => _owner;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this gizmo is active.
|
/// Gets a value indicating whether this gizmo is active.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsActive => Owner.Gizmos.Active == this;
|
public bool IsActive => _owner.Gizmos.Active == this;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this gizmo is using mouse currently (eg. user moving objects).
|
/// Gets a value indicating whether this gizmo is using mouse currently (eg. user moving objects).
|
||||||
@@ -39,8 +41,8 @@ namespace FlaxEditor.Gizmo
|
|||||||
protected GizmoBase(IGizmoOwner owner)
|
protected GizmoBase(IGizmoOwner owner)
|
||||||
{
|
{
|
||||||
// Link
|
// Link
|
||||||
Owner = owner;
|
_owner = owner;
|
||||||
Owner.Gizmos.Add(this);
|
_owner.Gizmos.Add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -94,5 +96,25 @@ namespace FlaxEditor.Gizmo
|
|||||||
public virtual void Draw(ref RenderContext renderContext)
|
public virtual void Draw(ref RenderContext renderContext)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Activates thi gizmo mode.
|
||||||
|
/// </summary>
|
||||||
|
public void Activate()
|
||||||
|
{
|
||||||
|
_owner.Gizmos.Active = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the gizmo from the owner.
|
||||||
|
/// </summary>
|
||||||
|
public void Destroy()
|
||||||
|
{
|
||||||
|
if (_owner != null)
|
||||||
|
{
|
||||||
|
_owner.Gizmos.Remove(this);
|
||||||
|
_owner = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user