223 lines
4.7 KiB
C#
223 lines
4.7 KiB
C#
|
using UnityEngine;
|
||
|
using UnityEditor;
|
||
|
using TPSBR;
|
||
|
|
||
|
[CustomEditor(typeof(RecoilPattern))]
|
||
|
public class RecoilPatternEditor : UnityEditor.Editor
|
||
|
{
|
||
|
private int _textureSize;
|
||
|
private Texture2D _texture;
|
||
|
private Color[] _pixels;
|
||
|
|
||
|
private Vector2 _inputValue = Vector2.one;
|
||
|
|
||
|
public override void OnInspectorGUI()
|
||
|
{
|
||
|
DrawDefaultInspector();
|
||
|
|
||
|
var rect = GetTextureRect();
|
||
|
if (rect.width > 1f && (int)rect.width != _textureSize)
|
||
|
{
|
||
|
_textureSize = (int)rect.width;
|
||
|
_pixels = new Color[_textureSize * _textureSize];
|
||
|
}
|
||
|
|
||
|
if (Event.current.type == EventType.Repaint)
|
||
|
{
|
||
|
_texture = GetTexture();
|
||
|
}
|
||
|
|
||
|
GUILayout.Box(_texture, GUILayout.Width(_textureSize), GUILayout.Height(_textureSize));
|
||
|
|
||
|
GUILayout.Label("Batch Change", EditorStyles.boldLabel);
|
||
|
_inputValue = EditorGUILayout.Vector2Field("Input Value", _inputValue);
|
||
|
|
||
|
if (GUILayout.Button("Multiply Start Values") == true)
|
||
|
{
|
||
|
Undo.RecordObject(target, "Multiply Start Values");
|
||
|
|
||
|
var pattern = target as RecoilPattern;
|
||
|
|
||
|
for (int i = 0; i < pattern.RecoilStartValues.Length; i++)
|
||
|
{
|
||
|
pattern.RecoilStartValues[i] *= _inputValue;
|
||
|
}
|
||
|
|
||
|
EditorUtility.SetDirty(target);
|
||
|
}
|
||
|
|
||
|
if (GUILayout.Button("Multiply Endless Values") == true)
|
||
|
{
|
||
|
Undo.RecordObject(target, "Multiply Endless Values");
|
||
|
|
||
|
var pattern = target as RecoilPattern;
|
||
|
|
||
|
for (int i = 0; i < pattern.RecoilEndlessValues.Length; i++)
|
||
|
{
|
||
|
pattern.RecoilEndlessValues[i] *= _inputValue;
|
||
|
}
|
||
|
|
||
|
EditorUtility.SetDirty(target);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// PRIVATE METHODS
|
||
|
|
||
|
private Rect GetTextureRect()
|
||
|
{
|
||
|
var lastRect = GUILayoutUtility.GetLastRect();
|
||
|
|
||
|
var textureRect = new Rect();
|
||
|
textureRect.width = lastRect.width * 0.9f;
|
||
|
textureRect.height = textureRect.width;
|
||
|
textureRect.position = lastRect.position + new Vector2(lastRect.width * 0.05f, lastRect.height + 10f);
|
||
|
|
||
|
return textureRect;
|
||
|
}
|
||
|
|
||
|
private Texture2D GetTexture()
|
||
|
{
|
||
|
var texture = new Texture2D(_textureSize, _textureSize);
|
||
|
|
||
|
if (_textureSize < 10)
|
||
|
return texture;
|
||
|
|
||
|
var pattern = target as RecoilPattern;
|
||
|
|
||
|
FillColor(Color.black);
|
||
|
|
||
|
int center = (int) (_textureSize * 0.5f);
|
||
|
int bottom = (int) (_textureSize * 0.1f);
|
||
|
int top = _textureSize - bottom;
|
||
|
|
||
|
DrawVerticalLine(center);
|
||
|
DrawHorizontalLine(bottom);
|
||
|
|
||
|
int textureRange = top - bottom;
|
||
|
int minRange = 7;
|
||
|
int range = Mathf.Max(Mathf.CeilToInt(GetRange(pattern)), minRange);
|
||
|
|
||
|
float scale = Mathf.Max(1f, textureRange / range);
|
||
|
|
||
|
Vector2 position = new Vector2Int(center, bottom);
|
||
|
|
||
|
// Center point
|
||
|
DrawPoint((int)position.x, (int)position.y);
|
||
|
|
||
|
// Start pattern
|
||
|
int count = pattern.RecoilStartValues.SafeCount();
|
||
|
for (int i = 0; i < count; i++)
|
||
|
{
|
||
|
position += pattern.RecoilStartValues[i] * scale;
|
||
|
|
||
|
if (i == count - 1 && pattern.RecoilEndlessValues.SafeCount() > 0)
|
||
|
{
|
||
|
DrawHorizontalLine((int)position.y, true);
|
||
|
}
|
||
|
|
||
|
DrawPoint((int)position.x, (int)position.y);
|
||
|
}
|
||
|
|
||
|
// Endless pattern
|
||
|
count = pattern.RecoilEndlessValues.SafeCount();
|
||
|
for (int i = 0; i < count; i++)
|
||
|
{
|
||
|
position += pattern.RecoilEndlessValues[i] * scale;
|
||
|
|
||
|
if (i == pattern.RecoilEndlessValues.Length - 1)
|
||
|
{
|
||
|
DrawHorizontalLine((int)position.y, true);
|
||
|
}
|
||
|
|
||
|
DrawPoint((int)position.x, (int)position.y);
|
||
|
}
|
||
|
|
||
|
// Continue with endless pattern
|
||
|
for (int i = 0; i < count; i++)
|
||
|
{
|
||
|
position += pattern.RecoilEndlessValues[i] * scale;
|
||
|
DrawPoint((int)position.x, (int)position.y);
|
||
|
}
|
||
|
|
||
|
texture.SetPixels(_pixels);
|
||
|
texture.Apply();
|
||
|
|
||
|
return texture;
|
||
|
}
|
||
|
|
||
|
private void DrawVerticalLine(int x)
|
||
|
{
|
||
|
for (int y = 0; y < _textureSize; y++)
|
||
|
{
|
||
|
SetPixel(x, y, Color.blue);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void DrawHorizontalLine(int y, bool dotted = false)
|
||
|
{
|
||
|
int dotCount = 0;
|
||
|
bool draw = true;
|
||
|
|
||
|
for (int x = 0; x < _textureSize; x++)
|
||
|
{
|
||
|
if (dotted == true && dotCount > 5)
|
||
|
{
|
||
|
draw = !draw;
|
||
|
dotCount = 0;
|
||
|
}
|
||
|
|
||
|
dotCount++;
|
||
|
|
||
|
if (draw == true)
|
||
|
{
|
||
|
SetPixel(x, y, Color.blue);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void DrawPoint(int x, int y)
|
||
|
{
|
||
|
SetPixel(x, y, Color.red);
|
||
|
SetPixel(x + 1, y + 1, Color.red);
|
||
|
SetPixel(x - 1, y + 1, Color.red);
|
||
|
SetPixel(x + 1, y - 1, Color.red);
|
||
|
SetPixel(x - 1, y - 1, Color.red);
|
||
|
}
|
||
|
|
||
|
private void SetPixel(int x, int y, Color color)
|
||
|
{
|
||
|
if (x < 0 || y < 0)
|
||
|
return;
|
||
|
|
||
|
if (x >= _textureSize || y >= _textureSize)
|
||
|
return;
|
||
|
|
||
|
_pixels[x + y * _textureSize] = color;
|
||
|
}
|
||
|
|
||
|
private void FillColor(Color color)
|
||
|
{
|
||
|
for (int i = 0; i < _pixels.Length; i++)
|
||
|
{
|
||
|
_pixels[i] = color;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private float GetRange(RecoilPattern recoil)
|
||
|
{
|
||
|
float range = 0f;
|
||
|
|
||
|
for (int i = 0; i < recoil.RecoilStartValues.SafeCount(); i++)
|
||
|
{
|
||
|
range += recoil.RecoilStartValues[i].y;
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < recoil.RecoilEndlessValues.SafeCount(); i++)
|
||
|
{
|
||
|
range += recoil.RecoilEndlessValues[i].y;
|
||
|
}
|
||
|
|
||
|
return range;
|
||
|
}
|
||
|
}
|