VectorFocus
Set your position data with a click
Loading...
Searching...
No Matches
Vector Focus

This package allows you to select the positions (vector2 and vector3) with or without array of your scriptable objects and monobehaviours using a simple click on your scene.

It also has these features:

  • Preview your vectors on the scene via IMGUI
  • Preview and associate values of your vectors using gameobjects
  • Graphical modification of preview elements (change colors, shape, text size ...) (see the complete list)
  • Callback to control the preview system.

Quick Start

  1. For a quick start you don't need to modify the configuration, it is only used to modify graphic elements during the preview. The activation of the package on a field is done by adding the attribute VectorFocus.Attribute.VectorFocusAttribute, for example if you have the following monobehaviour :
using UnityEngine;
public class SampleSpawner : MonoBehaviour
{
public Vector3 position;
}

Will become :

using UnityEngine;
using VectorFocus.Attribute;
public class SampleSpawner : MonoBehaviour
{
[VectorFocus]
public Vector3 position;
}
  1. Select a gameObject containing your monobehaviour and click on the field with the attribute in the inspector. An interactive bar will appear at the bottom left of the scene, you can now associate the value of your field by clicking on the scene.

Explanation of the toolbar

toolbar

The first button corresponds to the "pointer" mode, which is the default mode, it displays the field values on the scene using the GUI. When clicking on the scene, the field value automatically changes to the mouse position.

The second button corresponds to the 'gameObject' mode, the values are displayed by creating a gameObject (one per value), they are displayed in the hierarchy (at the bottom), each of them is positioned according to the value of its field. If you change its position, the value of the field will be automatically updated.

If you are in "gameObject" mode and the selected field is an array or a list, an additional button will appear to the right of the "gameObject" mode button. It allows to display the other vectors composing the array for an overview. This mode is not activated by default for performance reasons (an array composed of thousands of elements could slow down the editor)

The last button allows you to quit editing your field, clicking on another field or closing the inspector will do the same.

Configuration

To start you will need to associate the VectorFocus attribute to your field.

Once done you can open the configuration via the menu: window/VectorFocus/Configuration.

The configuration allows you to modify the preview of the values in "pointer" or "gameObject" mode.

  1. Choose the file where your monobehaviour or scriptable object is located.
  2. Choose the field with attribute you want to cutstomize.
  3. Select the field.

You can then modify the configuration it will be applied only on this field.

Description of the configuration fields:

When selecting a multiple field (array or list), all the elements can be displayed, those that do not come from the selected field will use the configurations with the word Others in suffix.

Pointer mode, standard

TextColor: Text color.

Text Color Others: Text color of an unselected element.

Font Size: Font size.

Font Size Others: Font size of an unselected item.

Scale: Scale of the shape.

Scale Others: Scale of the shape of an unselected element.

Shape: Shape used to represent the vector.

Shape Others: Shape used to represent the vector of a non selected element.

Shape Color: Color of the shape.

Shape Color Others: Color of the shape of an unselected item.

GameObject mode

Sprite: Sprite of the gameObject.

SpriteOrderInLayer: Order in layer of the sprite.

Property Path Sprite: Property Path to load the sprite.

Sprite Color: Color of the sprite.

Sprite Color Others: Color of the sprite of a not selected element.

Prefab: Prefab replacing the sprite.

Scale: Scale of the gameObject.

Scale Others: Scale of the gameObject of an unselected element.

Rotation: Rotation of the gameObject.

For the Property Path Sprite field you must fill in the propertyPath of a Sprite field attached to your entity.

Overloading of the configuration

At the technical level each field configuration is an instance of the VectorFocus.ConfigSkin.AbstractSkinVector class.

You can override the configuration of a field by creating a class inheriting from VectorFocus.ConfigSkin.AbstractSkinVector

Example:

using VectorFocus.ConfigSkin;
public class SampleSkinVector : AbstractSkinVector
{
}

Then on your vector field you can force the use of your skin :

using UnityEngine;
using VectorFocus.Attribute;
public class SampleSpawner : MonoBehaviour
{
[VectorFocus(SkinVectorTypeOverride = typeof(SampleSkinVector))]
public Vector3 position;
// added to illustrate the example
public bool isBig;
}

By going back to your skin you can override the methods to change the configuration :

using VectorFocus.ConfigSkin;
public class SampleSkinVector : AbstractSkinVector
{
// we prefer the text in yellow
public override Color? TextColor => Color.yellow;
// GetTargetObject retrieves the object that uses this skin
public override Vector3? GameObjectScale => GetTargetObject<SampleSpawner>().isBig ? Vector3.one * 2f : null;
}

If a method is not overridden or if we return null, the skin used will be the one of the configuration, if no skin is defined it will use the default skin VectorFocus.ConfigSkin.SkinVector.Default

Callback

After overloading a skin, it is possible to use a callback to fully modify the gameobject generated in "gameObject" mode.

In this example we will animate (turn on itself) the selected gameObject.

Important information, at each instantiation of gameObject during a preview, the component FocusBehaviour will be attached to the gameObject. This component inherits from Monobehaviour, it is used to sync the position of the gameObject with its selected field and to display the design according to the configuration.

First we have to create a class inheriting from the VectorFocus.IFocusBehaviourCallback interface

using VectorFocus;
using VectorFocus.ConfigSkin;
using UnityEditor;
public class SampleFocusCallback : IFocusBehaviourCallback
{
public void OnInit(FocusBehaviour focusBehaviour, AbstractSkinVector skinVector, SerializedProperty serializedProperty, bool isSelect)
{
}
}

Then define this callback in the configuration overload

using VectorFocus.ConfigSkin;
public class SampleSkinVector : AbstractSkinVector
{
public override IFocusBehaviourCallback CallbackFocusBehaviour { get => new SampleFocusCallback(); }
}

We can now take care of animating our gameObject.

using UnityEditor;
using UnityEngine;
using VectorFocus;
using VectorFocus.ConfigSkin;
public class SampleFocusCallback : IFocusBehaviourCallback
{
private FocusBehaviour _focusBehaviour;
private float _speed = 100f;
public void OnInit(FocusBehaviour focusBehaviour, AbstractSkinVector skinVector, SerializedProperty serializedProperty, bool isSelect)
{
// we can retrieve the main entity via the serializedProperty
var target = (SampleSpawner)serializedProperty.serializedObject.targetObject;
_focusBehaviour = focusBehaviour;
// we animate only if it is selected
if (isSelect)
{
focusBehaviour.OnDestroyAction += OnDestroyAction;
// we are in an editor context we must use EditorApplication.update to animate
EditorApplication.update += Animate;
}
}
private void Animate()
{
if (_focusBehaviour == null || _focusBehaviour.gameObject == null)
{
return;
}
_focusBehaviour.transform.Rotate(Vector3.up * Time.deltaTime * _speed);
}
private void OnDestroyAction(FocusBehaviour focusBehaviour)
{
EditorApplication.update -= Animate;
}
}

The OnInit method of the callback is called last, after the skin is applied.