Custom plugins
Introduction
You can override... everything. Enjoy and good luck.
Create a plugin
The MonoBehaviour
namespace MyProject {
[AddComponentMenu("")]
public class ColorMatrixMyTestPlugin : ColorMatrixPlugin {
#region editor
public override string EditorTitle => "My Test";
public override string EditorDescription => "This plugin is a test !";
#endregion
}
}
EditorTitle
is the label in the editorEditorDescription
is the description at bottom of content
Editor basics
namespace MyProject {
[AddComponentMenu("")]
public class ColorMatrixMyTestPlugin : ColorMatrixPlugin {
#region editor
public override string EditorTitle => "My Test";
public override string EditorDescription => "This plugin is a test !";
public override Texture2D EditorIcon => null;
public override string IconPath => "ColorMatrix_pluginTheme";
public override bool ActiveCustomEditor() { return true; }
public override bool Multiple() { return true; }
#endregion
}
}
EditorIcon
=> Create a texture. It is the module icon. default(null);IconPath
=> Get a texture using TextureUtility (from Resources folder or dll);ActiveCustomEditor()
: The plugin have a custom editor. default(false)Multiple()
: Single or multiple ? default(false)
Editor functions
public override void OnEditorEnable() { }
public override void OnEditorUpdate() { }
OnEditorEnable
: On the first editor draw.OnEditorUpdate
: On Update (only in editor mode and not playing)
Runtime functions
public override void BeforeUpdate(ColorMatrixElement element, int index) { }
public override void AfterLocalUpdate(ColorMatrixElement element, int index, Mat4x4 merged = null) { }
public override void AfterUpdate(Mat4x4 merged, bool fromParent = false) { }
public override void BeforeUpdate() { }
public override void AfterLocalUpdate() { }
public void BeforeInherit() { AfterLocalUpdate(); } // alias
public override void AfterUpdate() { }
public override ColorMatrix FindParent() { return null; }
public override void OnAwake(ref int maxMatrices) { }
public override void OnDestroyParentColorMatrix() { }
public override void OnRender(PropertiesController.PropertiesSetter ps) { }
public override bool RemoveDefaultRendering() { return false; }
BeforeUpdate(ColorMatrixElement element, int index)
: Before applying matrix. But element was updated.AfterLocalUpdate(ColorMatrixElement element, int index, Mat4x4 merged = null)
: After element merged to the ColorMatrix. merged is the result if element matrix has merged with another local matrix.AfterUpdate(Mat4x4 merged, bool fromParent = false)
: After a merge with parent. fromParent = true if parent matrix was not modified.BeforeUpdate()
: On update, before matrix updating. this.Matrices are equal to the preview frameAfterLocalUpdate()
: After all local matrix mergeAfterUpdate()
: After all matrix merge (local and parents). Just before rendering.FindParent()
: With this method you can override the inherit system.OnAwake(ref int maxMatrices)
: On ColorMatrix Awake. maxMatrices can be changed here if you want up or down the max ranges number. You can't change the max number at runtime.OnDestroyParentColorMatrix()
: The parent component was removed.OnRender(PropertiesController.PropertiesSetter ps)
: Here you can add your own properties.RemoveDefaultRendering()
: If true, default rendering is removed. Manage all the rendering in your OnRender method. default(false)
ColorMatrix methods preview
Update
==> plugins.BeforeUpdate();
Matrices = new List<Mat4x4>();
// local update
var cmes = GetComponents<ColorMatrixElement>().OrderBy(c => c.Index);
int index = 0;
foreach (var cme in cmes) {
cme.UpdateMatrix();
==> plugins.BeforeUpdate(cme, index);
// select a mergable matrix
var select = Matrices.FirstOrDefault(mat => Mergable(mat, cme.Matrix));
// merge matrices
if (select != null) {
select.Mult(cme.Matrix);
==> plugins.AfterLocalUpdate(cme, index, select);
}
// add a new range
else {
Matrices.Add(cme.Matrix.Clone());
==> plugins.AfterLocalUpdate(cme, index);
}
++index;
}
==> plugins.AfterLocalUpdate();
// inherit
if (_parent != null && _parent.Matrices != null) {
foreach (var pmat in _parent.Matrices) {
// select a mergeable matrix
var select = Matrices.FirstOrDefault(mat => Mergable(mat, pmat));
// apply ratio
var prat = pmat.Clone();
prat.Ratio(InheritRatio);
// merge matrices
if (select != null) {
select.Mult(prat);
==> plugins.AfterUpdate(select);
}
// add a new range
else {
Matrices.Add(prat);
==> plugins.AfterUpdate(prat, true);
}
}
}
==> plugins.AfterUpdate();
// render
RenderColorMatrix();
RenderColorMatrix
if (==> plugins.RemoveDefaultRendering()) {
==> plugins.OnRender(ref _renderer, ref _props);
return;
}
if (_props != null) {
_props.SetMatrixArray("_ColorMatrices", GenerateMatrixArray());
if (Matrices.Count > 0) {
_props.SetFloat("_MatrixCount", (float) Mathf.Min(Matrices.Count, _maxMatrices));
_props.SetFloat("_DebugCM", Debug == EDebug.Ranges ? 1f : 0f);
} else {
_props.SetFloat("_MatrixCount", 0f);
}
==> plugins.OnRender(ref _renderer, ref _props);
_renderer.SetPropertyBlock(_props);
}
GenerateMatrixArray
public Matrix4x4[] GenerateMatrixArray() {
List<Matrix4x4> response = new List<Matrix4x4>();
for (int i = 0; i < _maxMatrices; ++i) {
if (i < Matrices.Count) {
response.Add(Matrices[i].Matrix);
} else {
response.Add(CreateIdentityMatrix());
}
}
return response.ToArray();
}
Examples
ColorToColor
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace EODE.Wonderland {
[AddComponentMenu("")]
public class ColorMatrixColorToColorPlugin : ColorMatrixPlugin {
#region editor
public override string EditorTitle => "ColorToColor";
public override string EditorDescription {
get {
return "Apply a hue rotation to transform the first color to the second" +
"\nActual rotation : " + ActualRotation;
}
}
public override string IconPath => "ColorMatrix_pluginColor2Color";
public override bool Multiple() { return true; }
#endregion
public Color Origin;
public Color Destination;
[SerializeField][HideInInspector] Mat4x4 _rotation = new Mat4x4();
public float ActualRotation => (Destination.GetHue() - Origin.GetHue()) * 360f;
// update mat4x4 rotation
public override void OnEditorUpdate() {
UpdateRotation();
}
public void UpdateRotation() {
_rotation = new Mat4x4();
_rotation.HueRotate(ActualRotation);
}
// add the rotation before rendering
public override void AfterUpdate() {
var select = ColorMatrix.Matrices.FirstOrDefault(mat => ColorMatrix.Mergable(mat, _rotation));
if (select == null) {
select = new Mat4x4();
ColorMatrix.Matrices.Add(select);
}
select.Mult(_rotation.Matrix);
}
}
}
ColorMatrixThemeConditionPlugin
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace EODE.Wonderland {
[AddComponentMenu("")]
public class ColorMatrixThemeConditionPlugin : ColorMatrixPlugin {
#region editor
public override string EditorTitle => "Theme Condition";
public override string EditorDescription => "This plugin allow to enable a matrix according to the parent theme";
public override string IconPath => "ColorMatrix_pluginThemeCondition";
public override bool ActiveCustomEditor() { return true; }
public override bool Multiple() { return true; }
#endregion
[SerializeField][HideInInspector] int[] _activeConditions = new int[0];
[SerializeField][HideInInspector] int _selectedMatrix = -1;
protected ColorMatrixElement _target;
protected ColorMatrixThemePlugin _theme;
public virtual void Start() {
Init();
}
public virtual void Init() {
_target = FindColorMatrix(_selectedMatrix);
_theme = ParentColorMatrix != null ? ParentColorMatrix.GetComponent<ColorMatrixThemePlugin>() : null;
}
public override void BeforeUpdate() {
if (_target == null || _theme == null) return;
_target.LocalRatio = _theme.GetActualValue(_activeConditions);
}
ColorMatrix FindInheritColorMatrix(Transform tr) {
if (tr.parent == null) return null;
var parent = tr.parent.GetComponent<ColorMatrix>();
if (parent != null && parent.HasPlugin(typeof(ColorMatrixThemePlugin))) {
return parent;
}
return FindInheritColorMatrix(tr.parent.transform);
}
public override ColorMatrix FindInheritColorMatrix() {
return FindInheritColorMatrix(transform);
}
}
}