This commit is contained in:
Даниил Заикин
2026-06-17 20:44:53 +03:00
parent 9d153773c2
commit b133e7c656
1880 changed files with 244545 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 240c6ee064ec9b34888740ebc2d7c2dc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 17f68a8caf6b5114cb7a2da31ec06100
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 785482a2098d2c2438ec3a1cfb189376
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,375 @@
#if UNITY_EDITOR
using System;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
public class CameraScreenshotTool : EditorWindow
{
private enum CaptureMode
{
CameraOnly,
GameView
}
private Camera[] sceneCameras = Array.Empty<Camera>();
private string[] cameraNames = Array.Empty<string>();
private int selectedCameraIndex = -1;
private Camera targetCamera;
private int width = 1920;
private int height = 1080;
private string fileName = "screenshot";
private string folderName = "Screenshots";
private bool addTimestamp = true;
private bool openFolder = true;
private bool includeUI = false;
private CaptureMode captureMode = CaptureMode.CameraOnly;
private Vector2 scroll;
[MenuItem("Tools/QA/Camera Screenshot Tool")]
public static void Init()
{
var window = GetWindow<CameraScreenshotTool>("Screenshot Tool");
window.minSize = new Vector2(380, 360);
window.RefreshCameraList();
}
private void OnEnable()
{
RefreshCameraList();
EditorApplication.hierarchyChanged += RefreshCameraList;
}
private void OnDisable()
{
EditorApplication.hierarchyChanged -= RefreshCameraList;
}
private void OnFocus()
{
RefreshCameraList();
}
private void OnGUI()
{
scroll = EditorGUILayout.BeginScrollView(scroll);
GUILayout.Space(6);
DrawCameraSection();
GUILayout.Space(10);
DrawCaptureSection();
GUILayout.Space(10);
DrawResolutionSection();
GUILayout.Space(10);
DrawOutputSection();
GUILayout.Space(12);
DrawCaptureButton();
EditorGUILayout.EndScrollView();
}
private void DrawCameraSection()
{
EditorGUILayout.LabelField("Camera", EditorStyles.boldLabel);
using (new EditorGUILayout.HorizontalScope())
{
EditorGUI.BeginChangeCheck();
selectedCameraIndex = EditorGUILayout.Popup("Scene Camera", selectedCameraIndex, cameraNames);
if (EditorGUI.EndChangeCheck())
{
targetCamera = GetCameraByIndex(selectedCameraIndex);
}
if (GUILayout.Button("Refresh", GUILayout.Width(70)))
{
RefreshCameraList();
}
}
EditorGUI.BeginChangeCheck();
targetCamera = (Camera)EditorGUILayout.ObjectField("Target Camera", targetCamera, typeof(Camera), true);
if (EditorGUI.EndChangeCheck())
{
SyncDropdownWithTargetCamera();
}
if (targetCamera == null)
{
EditorGUILayout.HelpBox("Выбери камеру со сцены.", MessageType.Info);
}
else
{
EditorGUILayout.HelpBox(
$"Selected: {targetCamera.name}\n" +
$"Enabled: {targetCamera.enabled}\n" +
$"Type: {targetCamera.cameraType}",
MessageType.None
);
}
}
private void DrawCaptureSection()
{
EditorGUILayout.LabelField("Capture", EditorStyles.boldLabel);
captureMode = (CaptureMode)EditorGUILayout.EnumPopup("Mode", captureMode);
includeUI = EditorGUILayout.Toggle("Include UI", includeUI);
if (includeUI)
{
EditorGUILayout.HelpBox(
"Overlay UI обычно не попадает в CameraOnly. Для UI-захвата лучше использовать GameView mode.",
MessageType.Warning
);
}
if (captureMode == CaptureMode.CameraOnly && includeUI)
{
EditorGUILayout.HelpBox(
"В режиме CameraOnly попадут World Space и часть Screen Space - Camera UI. " +
"Screen Space - Overlay UI обычно не попадет.",
MessageType.Info
);
}
if (captureMode == CaptureMode.GameView)
{
EditorGUILayout.HelpBox(
"GameView mode захватывает итоговую картинку, включая overlay UI, " +
"но итоговое разрешение зависит от размера GameView.",
MessageType.Info
);
}
}
private void DrawResolutionSection()
{
EditorGUILayout.LabelField("Resolution", EditorStyles.boldLabel);
width = Mathf.Max(1, EditorGUILayout.IntField("Width", width));
height = Mathf.Max(1, EditorGUILayout.IntField("Height", height));
using (new EditorGUILayout.HorizontalScope())
{
if (GUILayout.Button("HD"))
{
width = 1280;
height = 720;
}
if (GUILayout.Button("Full HD"))
{
width = 1920;
height = 1080;
}
if (GUILayout.Button("2K"))
{
width = 2560;
height = 1440;
}
if (GUILayout.Button("4K"))
{
width = 3840;
height = 2160;
}
}
}
private void DrawOutputSection()
{
EditorGUILayout.LabelField("Output", EditorStyles.boldLabel);
fileName = EditorGUILayout.TextField("File Name", fileName);
folderName = EditorGUILayout.TextField("Folder", folderName);
addTimestamp = EditorGUILayout.Toggle("Add Timestamp", addTimestamp);
openFolder = EditorGUILayout.Toggle("Open Folder", openFolder);
}
private void DrawCaptureButton()
{
bool canCapture =
captureMode == CaptureMode.GameView ||
targetCamera != null;
GUI.enabled = canCapture;
if (GUILayout.Button("Capture Screenshot", GUILayout.Height(36)))
{
Capture();
}
GUI.enabled = true;
}
private void Capture()
{
string path = BuildOutputPath();
try
{
if (captureMode == CaptureMode.GameView)
{
CaptureGameView(path);
}
else
{
CaptureFromCamera(path, targetCamera, includeUI);
}
Debug.Log($"Screenshot saved: {path}");
AssetDatabase.Refresh();
if (openFolder)
{
EditorUtility.RevealInFinder(path);
}
}
catch (Exception e)
{
Debug.LogError($"Screenshot capture failed: {e}");
}
}
private void CaptureFromCamera(string path, Camera cam, bool withUI)
{
if (cam == null)
throw new InvalidOperationException("Target camera is null.");
int w = Mathf.Max(1, width);
int h = Mathf.Max(1, height);
RenderTexture rt = new RenderTexture(w, h, 24, RenderTextureFormat.ARGB32);
Texture2D tex = new Texture2D(w, h, TextureFormat.RGBA32, false);
RenderTexture previousActive = RenderTexture.active;
RenderTexture previousTarget = cam.targetTexture;
try
{
// Для CameraOnly UI overlay не поддерживается полноценно.
// Но world-space и screen-space camera UI могут попасть,
// если canvas привязан к этой камере.
cam.targetTexture = rt;
RenderTexture.active = rt;
cam.Render();
tex.ReadPixels(new Rect(0, 0, w, h), 0, 0);
tex.Apply();
byte[] bytes = tex.EncodeToPNG();
File.WriteAllBytes(path, bytes);
}
finally
{
cam.targetTexture = previousTarget;
RenderTexture.active = previousActive;
DestroyImmediate(rt);
DestroyImmediate(tex);
}
}
private void CaptureGameView(string path)
{
// В этом режиме includeUI фактически всегда true по смыслу,
// потому что захватывается итоговый GameView.
// Разрешение тут зависит от фактического размера GameView.
ScreenCapture.CaptureScreenshot(path);
}
private string BuildOutputPath()
{
string projectPath = Path.GetFullPath(Path.Combine(Application.dataPath, ".."));
string targetFolder = Path.Combine(projectPath, folderName);
if (!Directory.Exists(targetFolder))
Directory.CreateDirectory(targetFolder);
string safeName = string.IsNullOrWhiteSpace(fileName) ? "screenshot" : fileName;
foreach (char c in Path.GetInvalidFileNameChars())
safeName = safeName.Replace(c, '_');
if (addTimestamp)
{
safeName += "_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
}
return Path.Combine(targetFolder, safeName + ".png");
}
private void RefreshCameraList()
{
sceneCameras = FindObjectsByType<Camera>(FindObjectsSortMode.None)
.Where(c => c.gameObject.scene.IsValid())
.OrderBy(c => c.name)
.ToArray();
if (sceneCameras.Length == 0)
{
cameraNames = new[] { "No cameras found" };
selectedCameraIndex = -1;
targetCamera = null;
Repaint();
return;
}
cameraNames = sceneCameras
.Select(c =>
{
string tag = c.CompareTag("MainCamera") ? " [Main]" : "";
string state = c.enabled ? "" : " [Disabled]";
return $"{c.name}{tag}{state}";
})
.ToArray();
if (targetCamera == null)
{
targetCamera = sceneCameras.FirstOrDefault(c => c.CompareTag("MainCamera")) ?? sceneCameras[0];
}
SyncDropdownWithTargetCamera();
Repaint();
}
private void SyncDropdownWithTargetCamera()
{
if (targetCamera == null || sceneCameras == null || sceneCameras.Length == 0)
{
selectedCameraIndex = -1;
return;
}
selectedCameraIndex = Array.IndexOf(sceneCameras, targetCamera);
if (selectedCameraIndex < 0 && sceneCameras.Length > 0)
{
selectedCameraIndex = 0;
targetCamera = sceneCameras[0];
}
}
private Camera GetCameraByIndex(int index)
{
if (sceneCameras == null || index < 0 || index >= sceneCameras.Length)
return null;
return sceneCameras[index];
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1477c0a9d0abda84690e1cecd71c4caf
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 39209d28d8fba0146af050a1df2e7f91
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 390693d164cfc554d86ed64d284ceb66
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,167 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!43 &4300000
Mesh:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Cylinder
serializedVersion: 11
m_SubMeshes:
- serializedVersion: 2
firstByte: 0
indexCount: 144
topology: 0
baseVertex: 0
firstVertex: 0
vertexCount: 50
localAABB:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 1, y: 0.5, z: 1}
m_Shapes:
vertices: []
shapes: []
channels: []
fullWeights: []
m_BindPose: []
m_BoneNameHashes:
m_RootBoneNameHash: 0
m_BonesAABB: []
m_VariableBoneCountWeights:
m_Data:
m_MeshCompression: 0
m_IsReadable: 1
m_KeepVertices: 1
m_KeepIndices: 1
m_IndexFormat: 0
m_IndexBuffer: 00000300010000000200030002000500030002000400050004000700050004000600070006000900070006000800090008000b00090008000a000b000a000d000b000a000c000d000c000f000d000c000e000f000e0011000f000e001000110010001300110010001200130012001500130012001400150014001700150014001600170016001900170016001800190018001b00190018001a001b001a001d001b001a001c001d001c001f001d001c001e001f001e0021001f001e002000210020002300210020002200230022002500230022002400250024002700250024002600270026002900270026002800290028002b00290028002a002b002a002d002b002a002c002d002c002f002d002c002e002f002e0031002f002e0030003100
m_VertexData:
serializedVersion: 3
m_VertexCount: 50
m_Channels:
- stream: 0
offset: 0
format: 0
dimension: 3
- stream: 0
offset: 12
format: 0
dimension: 3
- stream: 0
offset: 0
format: 0
dimension: 0
- stream: 0
offset: 0
format: 0
dimension: 0
- stream: 0
offset: 0
format: 0
dimension: 0
- stream: 0
offset: 0
format: 0
dimension: 0
- stream: 0
offset: 0
format: 0
dimension: 0
- stream: 0
offset: 0
format: 0
dimension: 0
- stream: 0
offset: 0
format: 0
dimension: 0
- stream: 0
offset: 0
format: 0
dimension: 0
- stream: 0
offset: 0
format: 0
dimension: 0
- stream: 0
offset: 0
format: 0
dimension: 0
- stream: 0
offset: 0
format: 0
dimension: 0
- stream: 0
offset: 0
format: 0
dimension: 0
m_DataSize: 1200
_typelessdata: 0000803f000000bf0000000054cf7dbf00000000aca805be0000803f0000003f0000000054cf7dbf00000000aca805beea46773f000000bfee83843e682274bf00000000f7119abeea46773f0000003fee83843eb2f179bf0000000056695dbed7b35d3f000000bf0000003fa8e057bf00000000c89809bfd7b35d3f0000003f0000003fe21963bf000000006a50ecbef304353f000000bff304353fb7e82cbf0000000011c83cbff304353f0000003ff304353f11c83cbf00000000b6e82cbfffffff3e000000bfd8b35d3f6950ecbe00000000e31963bfffffff3e0000003fd8b35d3fc99809bf00000000a7e057bfef83843e000000bfea46773f4e695dbe00000000b1f179bfef83843e0000003fea46773ff3119abe00000000682274bf2ebd3bb3000000bf0000803fa593333d00000000fcc07fbf2ebd3bb30000003f0000803fa59333bd00000000fcc07fbff28384be000000bfea46773ff7119a3e00000000662274bff28384be0000003fea46773f54695d3e00000000b2f179bf010000bf000000bfd7b35d3fca98093f00000000a7e057bf010000bf0000003fd7b35d3f6d50ec3e00000000e11963bff30435bf000000bff304353f12c83c3f00000000b8e82cbff30435bf0000003ff304353fb8e82c3f0000000012c83cbfd7b35dbf000000bf0100003fe219633f000000006850ecbed7b35dbf0000003f0100003fa7e0573f00000000c89809bfeb4677bf000000bfea83843eb1f1793f000000004e695dbeeb4677bf0000003fea83843e6722743f00000000f5119abe000080bf000000bf2ebdbbb3fcc07f3f00000000bf93333d000080bf0000003f2ebdbbb3fec07f3f00000000829333bdea4677bf000000bfef8384be6522743f00000000fc119a3eea4677bf0000003fef8384beb1f1793f000000005e695d3ed5b35dbf000000bf030000bfa7e0573f00000000c998093fd5b35dbf0000003f030000bfe119633f000000006d50ec3ef10435bf000000bff50435bfb6e82c3f0000000014c83c3ff10435bf0000003ff50435bf11c83c3f00000000b8e82c3ffdffffbe000000bfd8b35dbf6950ec3e00000000e319633ffdffffbe0000003fd8b35dbfc798093f00000000a9e0573fec8384be000000bfeb4677bf4f695d3e00000000b2f1793fec8384be0000003feb4677bff6119a3e000000006822743f2ede4c32000000bf000080bfbf9333bd00000000fcc07f3f2ede4c320000003f000080bf8293333d00000000fcc07f3fed83843e000000bfea4677bff5119abe000000006822743fed83843e0000003fea4677bf54695dbe00000000b3f1793ffdffff3e000000bfd8b35dbfcb9809bf00000000a6e0573ffdffff3e0000003fd8b35dbf6d50ecbe00000000e219633ff704353f000000bfef0435bf14c83cbf00000000b6e82c3ff704353f0000003fef0435bfb7e82cbf0000000011c83c3fdab35d3f000000bff8ffffbee51963bf000000006150ec3edab35d3f0000003ff8ffffbeabe057bf00000000c698093feb46773f000000bfe78384beb3f179bf0000000043695d3eeb46773f0000003fe78384be692274bf00000000ec119a3e0000803f000000bf2ebd3b3455cf7dbf000000009ea8053e0000803f0000003f2ebd3b3455cf7dbf000000009ea8053e
m_CompressedMesh:
m_Vertices:
m_NumItems: 0
m_Range: 0
m_Start: 0
m_Data:
m_BitSize: 0
m_UV:
m_NumItems: 0
m_Range: 0
m_Start: 0
m_Data:
m_BitSize: 0
m_Normals:
m_NumItems: 0
m_Range: 0
m_Start: 0
m_Data:
m_BitSize: 0
m_Tangents:
m_NumItems: 0
m_Range: 0
m_Start: 0
m_Data:
m_BitSize: 0
m_Weights:
m_NumItems: 0
m_Data:
m_BitSize: 0
m_NormalSigns:
m_NumItems: 0
m_Data:
m_BitSize: 0
m_TangentSigns:
m_NumItems: 0
m_Data:
m_BitSize: 0
m_FloatColors:
m_NumItems: 0
m_Range: 0
m_Start: 0
m_Data:
m_BitSize: 0
m_BoneIndices:
m_NumItems: 0
m_Data:
m_BitSize: 0
m_Triangles:
m_NumItems: 0
m_Data:
m_BitSize: 0
m_UVInfo: 0
m_LocalAABB:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 1, y: 0.5, z: 1}
m_MeshUsageFlags: 0
m_CookingOptions: 30
m_BakedConvexCollisionMesh:
m_BakedTriangleCollisionMesh:
'm_MeshMetrics[0]': 1
'm_MeshMetrics[1]': 1
m_MeshOptimizationFlags: 1
m_StreamData:
serializedVersion: 2
offset: 0
size: 0
path:
@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 3554d6a17caef8148b1220e9e2e79454
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 4300000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 318546
packageName: Collider Visualizer
packageVersion: 1.0.0
assetPath: Assets/ColliderVisualizer/Meshes/Cylinder.mesh
uploadId: 752951
File diff suppressed because one or more lines are too long
@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 2150e3d3605f3f54087ca225c7af31aa
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 4300000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 318546
packageName: Collider Visualizer
packageVersion: 1.0.0
assetPath: Assets/ColliderVisualizer/Meshes/LowerHalfSphere.mesh
uploadId: 752951
File diff suppressed because one or more lines are too long
@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: ea110afe4078082468955a8ec59d1ee0
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 4300000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 318546
packageName: Collider Visualizer
packageVersion: 1.0.0
assetPath: Assets/ColliderVisualizer/Meshes/UpperHalfSphere.mesh
uploadId: 752951
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 72dfab8be846ad645b03d0bebd460d8b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,631 @@
namespace ColliderVisualizer
{
using System;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Collider visualizer.
/// </summary>
[ExecuteAlways]
[RequireComponent(typeof(Collider))]
public class ColliderVisualizer : MonoBehaviour
{
private static readonly int ColorPropertyID = Shader.PropertyToID("_Color");
private static readonly int[,] BoxEdges =
{
{ 0, 1 }, { 1, 3 }, { 3, 2 }, { 2, 0 },
{ 4, 5 }, { 5, 7 }, { 7, 6 }, { 6, 4 },
{ 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 }
};
/// <summary>
/// The need to draw the collider fill has changed.
/// </summary>
public event Action onNeedDrawSolidChanged = delegate { };
/// <summary>
/// The need to draw collider boundaries has changed.
/// </summary>
public event Action onNeedDrawWireChanged = delegate { };
/// <summary>
/// The fill color has changed.
/// </summary>
public event Action onSolidColorChanged = delegate { };
/// <summary>
/// The border color has changed.
/// </summary>
public event Action onWireColorChanged = delegate { };
/// <summary>
/// Need to draw a fill.
/// </summary>
public bool NeedDrawSolid
{
get => drawSolid;
set
{
if (drawSolid != value)
{
drawSolid = value;
onNeedDrawSolidChanged();
}
}
}
/// <summary>
/// You need to draw boundaries.
/// </summary>
public bool NeedDrawWire
{
get => drawWire;
set
{
if (drawWire != value)
{
drawWire = value;
onNeedDrawWireChanged();
}
}
}
/// <summary>
/// Fill color.
/// </summary>
public Color SolidColor
{
get => solidColor;
set
{
if (solidColor != value)
{
solidColor = value;
onSolidColorChanged();
}
}
}
/// <summary>
/// Border color.
/// </summary>
public Color WireColor
{
get => wireColor;
set
{
if (wireColor != value)
{
wireColor = value;
onWireColorChanged();
}
}
}
[Header("Rendering")] [SerializeField] private bool drawSolid = true;
[SerializeField] private bool drawWire = true;
[SerializeField] private Color solidColor = new Color(0f, 1f, 0f, 0.15f);
[SerializeField] private Color wireColor = Color.green;
[Header("Wire Quality")]
[SerializeField, Range(3, 64)] private int wireSegments = 24;
[SerializeField, HideInInspector, Range(0, 100000)] private int maxMeshTriangles = 0; // 0 = without limit
[SerializeField, Range(2, 32)] private int capsuleArcSegments = 8;
[SerializeField, HideInInspector] private Mesh meshBox;
[SerializeField, HideInInspector] private Mesh meshSphere;
[SerializeField, HideInInspector] private Mesh meshCylinder;
[SerializeField, HideInInspector] private Mesh upperHalfSphere;
[SerializeField, HideInInspector] private Mesh lowerHalfSphere;
[SerializeField, HideInInspector] private Shader coloredShader;
private Material solidMat;
private Material wireMat;
private Collider col;
private Transform _transform;
private void Start() => Initialize();
/// <summary>
/// Initializes the component.
/// </summary>
public void Initialize()
{
col = GetComponent<Collider>();
if (col == null) return;
_transform = transform;
RemoveMaterials();
solidMat = new Material(coloredShader);
wireMat = new Material(coloredShader);
}
private void OnRenderObject()
{
if (!enabled || col == null) return;
if (drawSolid)
{
solidMat.SetColor(ColorPropertyID, solidColor);
solidMat.SetPass(0);
DrawSolid(col);
}
if (drawWire)
{
wireMat.SetColor(ColorPropertyID, wireColor);
wireMat.SetPass(0);
if (col is SphereCollider or CapsuleCollider)
{
GL.Begin(GL.LINES);
GL.Color(wireColor);
DrawWire(col);
GL.End();
}
else
{
GL.PushMatrix();
GL.MultMatrix(transform.localToWorldMatrix);
GL.Begin(GL.LINES);
GL.Color(wireColor);
DrawWire(col);
GL.End();
GL.PopMatrix();
}
}
}
private void OnDestroy()
{
if (Application.isPlaying)
{
RemoveMaterials();
}
}
private void RemoveMaterials()
{
#if UNITY_EDITOR
if (solidMat != null)
{
DestroyImmediate(solidMat);
}
if (wireMat != null)
{
DestroyImmediate(wireMat);
}
#else
if (solidMat != null)
{
Destroy(solidMat);
}
if (wireMat != null)
{
Destroy(wireMat);
}
#endif
}
private void DrawSolid(Collider collider)
{
switch (collider)
{
case BoxCollider box:
Graphics.DrawMeshNow(meshBox,
Matrix4x4.TRS(_transform.position + _transform.rotation * Vector3.Scale(box.center, _transform.lossyScale), _transform.rotation, Vector3.Scale(box.size, _transform.lossyScale)));
break;
case SphereCollider sphere:
float scaledRadius = sphere.radius * MaxAbsAxis(_transform.lossyScale);
Graphics.DrawMeshNow(meshSphere,
Matrix4x4.TRS(_transform.position + _transform.rotation * Vector3.Scale(sphere.center, _transform.lossyScale), _transform.rotation, Vector3.one * scaledRadius * 2f));
break;
case CapsuleCollider capsule:
DrawCapsuleSolid(capsule);
break;
case MeshCollider meshCol:
if (meshCol.sharedMesh != null)
Graphics.DrawMeshNow(meshCol.sharedMesh, _transform.localToWorldMatrix);
break;
}
}
private void DrawWire(Collider collider)
{
switch (collider)
{
case BoxCollider box:
DrawWireCube(box.center, box.size);
break;
case SphereCollider sphere:
DrawWireSphere(sphere);
break;
case CapsuleCollider capsule:
DrawWireCapsule(capsule);
break;
case MeshCollider meshCol:
DrawWireMesh(meshCol);
break;
}
}
private float MaxAbsAxis(Vector3 v) =>
Mathf.Max(Mathf.Abs(v.x), Mathf.Abs(v.y), Mathf.Abs(v.z));
#region Box
private void DrawWireCube(Vector3 center, Vector3 size)
{
Vector3 half = size * 0.5f;
Vector3[] pts = new Vector3[8];
for (int i = 0; i < 8; i++)
{
pts[i] = new Vector3(
((i & 1) == 0 ? -1 : 1) * half.x,
((i & 2) == 0 ? -1 : 1) * half.y,
((i & 4) == 0 ? -1 : 1) * half.z
) + center;
}
for (int i = 0; i < BoxEdges.GetLength(0); i++)
{
GL.Vertex(pts[BoxEdges[i, 0]]);
GL.Vertex(pts[BoxEdges[i, 1]]);
}
}
#endregion
#region Sphere
private void DrawWireSphere(SphereCollider sphere)
{
float scaledRadius = sphere.radius * MaxAbsAxis(transform.lossyScale);
float angleStep = 360f / wireSegments;
for (int i = 0; i < wireSegments; i++)
{
float a0 = Mathf.Deg2Rad * i * angleStep;
float a1 = Mathf.Deg2Rad * (i + 1) * angleStep;
Vector3 c = _transform.TransformPoint(sphere.center);
// XY
Vector3 p0 = c + _transform.rotation * new Vector3(Mathf.Cos(a0), Mathf.Sin(a0), 0) * scaledRadius;
Vector3 p1 = c + _transform.rotation * new Vector3(Mathf.Cos(a1), Mathf.Sin(a1), 0) * scaledRadius;
GL.Vertex(p0);
GL.Vertex(p1);
// XZ
p0 = c + _transform.rotation * new Vector3(Mathf.Cos(a0), 0, Mathf.Sin(a0)) * scaledRadius;
p1 = c + _transform.rotation * new Vector3(Mathf.Cos(a1), 0, Mathf.Sin(a1)) * scaledRadius;
GL.Vertex(p0);
GL.Vertex(p1);
// YZ
p0 = c + _transform.rotation * new Vector3(0, Mathf.Cos(a0), Mathf.Sin(a0)) * scaledRadius;
p1 = c + _transform.rotation * new Vector3(0, Mathf.Cos(a1), Mathf.Sin(a1)) * scaledRadius;
GL.Vertex(p0);
GL.Vertex(p1);
}
}
#endregion
#region Capsule
private void DrawCapsuleSolid(CapsuleCollider capsule)
{
float radius = capsule.radius;
float height = capsule.height;
Vector3 center = capsule.center;
float cylinderHeight = Mathf.Max(0f, height - 2f * radius);
Quaternion rotation = transform.rotation;
Vector3 up = Vector3.up;
Vector3 lossyScale = transform.lossyScale;
float heightScale = 1f;
float radiusScale = 1f;
switch (capsule.direction)
{
case 0: // X-axis
up = Vector3.right;
rotation *= Quaternion.Euler(0, 0, -90);
heightScale = lossyScale.x;
radiusScale = Mathf.Max(lossyScale.y, lossyScale.z);
break;
case 1: // Y-axis
up = Vector3.up;
heightScale = lossyScale.y;
radiusScale = Mathf.Max(lossyScale.x, lossyScale.z);
break;
case 2: // Z-axis
up = Vector3.forward;
rotation *= Quaternion.Euler(90, 0, 0);
heightScale = lossyScale.z;
radiusScale = Mathf.Max(lossyScale.x, lossyScale.y);
break;
}
Vector3 worldCenter = transform.TransformPoint(center);
Vector3 worldUp = transform.TransformDirection(up);
float scaledRadius = radius * radiusScale;
float scaledHeight = (height * heightScale) - 2f * scaledRadius;
scaledHeight = Mathf.Max(0f, scaledHeight);
Vector3 top = worldCenter + worldUp * (scaledHeight * 0.5f);
Vector3 bottom = worldCenter - worldUp * (scaledHeight * 0.5f);
Vector3 cylinderScale = new Vector3(scaledRadius, scaledHeight, scaledRadius);
Vector3 sphereScale = Vector3.one * scaledRadius;
Graphics.DrawMeshNow(meshCylinder, Matrix4x4.TRS(worldCenter, rotation, cylinderScale));
Graphics.DrawMeshNow(upperHalfSphere, Matrix4x4.TRS(top, rotation, sphereScale));
Graphics.DrawMeshNow(lowerHalfSphere, Matrix4x4.TRS(bottom, rotation, sphereScale));
}
private void DrawWireCapsule(CapsuleCollider capsule)
{
Vector3 center = capsule.center;
float radius = capsule.radius;
float height = capsule.height;
Vector3 up = Vector3.up;
Vector3 right = Vector3.right;
Vector3 forward = Vector3.forward;
Quaternion rotation = transform.rotation;
Vector3 scale = transform.lossyScale;
Vector3 position = transform.position;
switch (capsule.direction)
{
case 0:
up = Vector3.right;
right = Vector3.up;
forward = Vector3.forward;
break;
case 1:
up = Vector3.up;
right = Vector3.right;
forward = Vector3.forward;
break;
case 2:
up = Vector3.forward;
right = Vector3.right;
forward = Vector3.up;
break;
}
float heightScale = Mathf.Abs(Vector3.Dot(scale, up));
float radiusScale = Mathf.Max(
Mathf.Abs(Vector3.Dot(scale, right)),
Mathf.Abs(Vector3.Dot(scale, forward))
);
float scaledRadius = radius * radiusScale;
float scaledHeight = height * heightScale;
float cylinderHeight = Mathf.Max(0f, scaledHeight - 2f * scaledRadius);
Vector3 worldCenter = position + rotation * Vector3.Scale(center, scale);
Vector3 worldUp = rotation * up;
Vector3 worldRight = rotation * right;
Vector3 worldForward = rotation * forward;
Vector3 top = worldCenter + worldUp * (cylinderHeight * 0.5f);
Vector3 bottom = worldCenter - worldUp * (cylinderHeight * 0.5f);
DrawWireCapsuleBody(top, bottom, worldUp, worldRight, worldForward, scaledRadius);
DrawWireCapsuleCap(top, worldUp, worldRight, worldForward, scaledRadius, true);
DrawWireCapsuleCap(bottom, worldUp, worldRight, worldForward, scaledRadius, false);
}
private void DrawWireCapsuleBody(Vector3 top, Vector3 bottom, Vector3 up, Vector3 right, Vector3 forward, float radius)
{
float angleStep = 360f / wireSegments;
for (int i = 0; i < wireSegments; i++)
{
float angle0 = Mathf.Deg2Rad * i * angleStep;
float angle1 = Mathf.Deg2Rad * (i + 1) * angleStep;
Vector3 dir0 = (right * Mathf.Cos(angle0) + forward * Mathf.Sin(angle0)) * radius;
Vector3 dir1 = (right * Mathf.Cos(angle1) + forward * Mathf.Sin(angle1)) * radius;
GL.Vertex(top + dir0);
GL.Vertex(bottom + dir0);
GL.Vertex(top + dir0);
GL.Vertex(top + dir1);
GL.Vertex(bottom + dir0);
GL.Vertex(bottom + dir1);
}
}
private void DrawWireCapsuleCap(Vector3 center, Vector3 up, Vector3 right, Vector3 forward, float radius, bool isTop)
{
int arcSegments = capsuleArcSegments;
float arcStep = 90f / arcSegments;
for (int i = 0; i < 360; i += 360 / wireSegments)
{
float rad = Mathf.Deg2Rad * i;
Vector3 baseDir = (right * Mathf.Cos(rad) + forward * Mathf.Sin(rad)).normalized;
Vector3 from = baseDir * radius;
Vector3 axis = Vector3.Cross(baseDir, up).normalized;
if (!isTop)
axis = -axis;
Quaternion rot = Quaternion.AngleAxis(arcStep, axis);
for (int j = 0; j < arcSegments; j++)
{
Vector3 to = rot * from;
GL.Vertex(center + from);
GL.Vertex(center + to);
from = to;
}
}
}
private Mesh GenerateHalfSphereMesh(bool upper = true, int longitude = 24, int latitude = 12)
{
Mesh mesh = new Mesh();
mesh.name = upper ? "UpperHalfSphere" : "LowerHalfSphere";
List<Vector3> vertices = new();
List<int> triangles = new();
int latStart = upper ? 0 : latitude / 2;
int latEnd = upper ? latitude / 2 : latitude;
for (int lat = latStart; lat <= latEnd; lat++)
{
float a1 = Mathf.PI * lat / latitude;
float sin1 = Mathf.Sin(a1);
float cos1 = Mathf.Cos(a1);
for (int lon = 0; lon <= longitude; lon++)
{
float a2 = 2f * Mathf.PI * lon / longitude;
float sin2 = Mathf.Sin(a2);
float cos2 = Mathf.Cos(a2);
Vector3 vertex = new Vector3(sin1 * cos2, cos1, sin1 * sin2);
vertices.Add(vertex);
}
}
int vertsPerRow = longitude + 1;
for (int lat = 0; lat < (latEnd - latStart); lat++)
{
for (int lon = 0; lon < longitude; lon++)
{
int current = lat * vertsPerRow + lon;
int next = current + vertsPerRow;
triangles.Add(current);
triangles.Add(next);
triangles.Add(current + 1);
triangles.Add(current + 1);
triangles.Add(next);
triangles.Add(next + 1);
}
}
mesh.SetVertices(vertices);
mesh.SetTriangles(triangles, 0);
mesh.RecalculateNormals();
mesh.RecalculateBounds();
return mesh;
}
private Mesh GenerateOpenCylinder(int segments = 24)
{
Mesh mesh = new Mesh();
mesh.name = "OpenCylinder";
List<Vector3> vertices = new();
List<int> triangles = new();
for (int i = 0; i <= segments; i++)
{
float angle = 2f * Mathf.PI * i / segments;
float x = Mathf.Cos(angle);
float z = Mathf.Sin(angle);
vertices.Add(new Vector3(x, -0.5f, z));
vertices.Add(new Vector3(x, 0.5f, z));
}
for (int i = 0; i < segments; i++)
{
int baseIndex = i * 2;
triangles.Add(baseIndex);
triangles.Add(baseIndex + 3);
triangles.Add(baseIndex + 1);
triangles.Add(baseIndex);
triangles.Add(baseIndex + 2);
triangles.Add(baseIndex + 3);
}
mesh.SetVertices(vertices);
mesh.SetTriangles(triangles, 0);
mesh.RecalculateNormals();
mesh.RecalculateBounds();
return mesh;
}
#endregion
#region Mesh
private void DrawWireMesh(MeshCollider meshCollider)
{
var mesh = meshCollider.sharedMesh;
if (mesh == null) return;
var vertices = mesh.vertices;
var triangles = mesh.triangles;
int triangleCount = triangles.Length / 3;
if (maxMeshTriangles > 0 && triangleCount > maxMeshTriangles)
triangleCount = maxMeshTriangles;
for (int i = 0; i < triangleCount * 3; i += 3)
{
int i0 = triangles[i];
int i1 = triangles[i + 1];
int i2 = triangles[i + 2];
GL.Vertex(vertices[i0]);
GL.Vertex(vertices[i1]);
GL.Vertex(vertices[i1]);
GL.Vertex(vertices[i2]);
GL.Vertex(vertices[i2]);
GL.Vertex(vertices[i0]);
}
}
#endregion
}
}
@@ -0,0 +1,24 @@
fileFormatVersion: 2
guid: 0de9c2653c954307856264ec248eab4d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- meshBox: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
- meshSphere: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
- meshCylinder: {fileID: 4300000, guid: 3554d6a17caef8148b1220e9e2e79454, type: 2}
- upperHalfSphere: {fileID: 4300000, guid: ea110afe4078082468955a8ec59d1ee0, type: 2}
- lowerHalfSphere: {fileID: 4300000, guid: 2150e3d3605f3f54087ca225c7af31aa, type: 2}
- coloredShader: {fileID: 4800000, guid: 38859b428448107418ad51fa96d642e7, type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 318546
packageName: Collider Visualizer
packageVersion: 1.0.0
assetPath: Assets/ColliderVisualizer/Scripts/ColliderVisualizer.cs
uploadId: 752951
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6a585ee9d00f3614a9797391c5eb902d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,22 @@
namespace ColliderVisualizer.Editor
{
using UnityEditor;
using UnityEngine;
/// <summary>
/// Rendering the <see cref="ColliderVisualizer"/> component in the Inspector.
/// </summary>
[CustomEditor(typeof(ColliderVisualizer))]
public class ColliderVisualizerEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (GUILayout.Button("Reinitialize"))
{
((ColliderVisualizer)target).Initialize();
}
}
}
}
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: b96329cd891b4003b1ad8561043f743e
timeCreated: 1745442290
AssetOrigin:
serializedVersion: 1
productId: 318546
packageName: Collider Visualizer
packageVersion: 1.0.0
assetPath: Assets/ColliderVisualizer/Scripts/Editor/ColliderVisualizerEditor.cs
uploadId: 752951
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6042617990f969344bd70fc3314adfa7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,49 @@
Shader "ColliderVisualizer/SolidAndWire"
{
Properties
{
_Color ("Color", Color) = (0, 1, 0, 0.15)
}
SubShader
{
Tags { "RenderType"="Transparent" "Queue"="Transparent" }
LOD 100
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 _Color;
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 pos : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return _Color;
}
ENDCG
}
}
}
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 38859b428448107418ad51fa96d642e7
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 318546
packageName: Collider Visualizer
packageVersion: 1.0.0
assetPath: Assets/ColliderVisualizer/Shaders/SolidAndWireShader.shader
uploadId: 752951
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 91765bf42ea9b5844a9b2e323a8ff6ca
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 1894414b42fe5e343b181b818b714b55
folderAsset: yes
timeCreated: 1552910252
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 878e70decc5254841b8310d665bf6844
timeCreated: 1556081593
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 140739
packageName: Free Fly Camera
packageVersion: 1.2
assetPath: Assets/FreeFlyCamera/Documentation/FreeFlyCamera_ru.pdf
uploadId: 396755
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: eeaac17fd74c9fb4592e12afe1203aab
folderAsset: yes
timeCreated: 1549511058
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,218 @@
//===========================================================================//
// FreeFlyCamera (Version 1.2) //
// (c) 2019 Sergey Stafeyev //
//===========================================================================//
using UnityEngine;
[RequireComponent(typeof(Camera))]
public class FreeFlyCamera : MonoBehaviour
{
#region UI
[Space]
[SerializeField]
[Tooltip("The script is currently active")]
private bool _active = true;
[Space]
[SerializeField]
[Tooltip("Camera rotation by mouse movement is active")]
private bool _enableRotation = true;
[SerializeField]
[Tooltip("Sensitivity of mouse rotation")]
private float _mouseSense = 1.8f;
[Space]
[SerializeField]
[Tooltip("Camera zooming in/out by 'Mouse Scroll Wheel' is active")]
private bool _enableTranslation = true;
[SerializeField]
[Tooltip("Velocity of camera zooming in/out")]
private float _translationSpeed = 55f;
[Space]
[SerializeField]
[Tooltip("Camera movement by 'W','A','S','D','Q','E' keys is active")]
private bool _enableMovement = true;
[SerializeField]
[Tooltip("Camera movement speed")]
private float _movementSpeed = 10f;
[SerializeField]
[Tooltip("Speed of the quick camera movement when holding the 'Left Shift' key")]
private float _boostedSpeed = 50f;
[SerializeField]
[Tooltip("Boost speed")]
private KeyCode _boostSpeed = KeyCode.LeftShift;
[SerializeField]
[Tooltip("Move up")]
private KeyCode _moveUp = KeyCode.E;
[SerializeField]
[Tooltip("Move down")]
private KeyCode _moveDown = KeyCode.Q;
[Space]
[SerializeField]
[Tooltip("Acceleration at camera movement is active")]
private bool _enableSpeedAcceleration = true;
[SerializeField]
[Tooltip("Rate which is applied during camera movement")]
private float _speedAccelerationFactor = 1.5f;
[Space]
[SerializeField]
[Tooltip("This keypress will move the camera to initialization position")]
private KeyCode _initPositonButton = KeyCode.R;
#endregion UI
private CursorLockMode _wantedMode;
private float _currentIncrease = 1;
private float _currentIncreaseMem = 0;
private Vector3 _initPosition;
private Vector3 _initRotation;
#if UNITY_EDITOR
private void OnValidate()
{
if (_boostedSpeed < _movementSpeed)
_boostedSpeed = _movementSpeed;
}
#endif
private void Start()
{
_initPosition = transform.position;
_initRotation = transform.eulerAngles;
}
private void OnEnable()
{
if (_active)
_wantedMode = CursorLockMode.Locked;
}
// Apply requested cursor state
private void SetCursorState()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
Cursor.lockState = _wantedMode = CursorLockMode.None;
}
if (Input.GetMouseButtonDown(0))
{
_wantedMode = CursorLockMode.Locked;
}
// Apply cursor state
Cursor.lockState = _wantedMode;
// Hide cursor when locking
Cursor.visible = (CursorLockMode.Locked != _wantedMode);
}
private void CalculateCurrentIncrease(bool moving)
{
_currentIncrease = Time.deltaTime;
if (!_enableSpeedAcceleration || _enableSpeedAcceleration && !moving)
{
_currentIncreaseMem = 0;
return;
}
_currentIncreaseMem += Time.deltaTime * (_speedAccelerationFactor - 1);
_currentIncrease = Time.deltaTime + Mathf.Pow(_currentIncreaseMem, 3) * Time.deltaTime;
}
private void Update()
{
if (!_active)
return;
SetCursorState();
if (Cursor.visible)
return;
// Translation
if (_enableTranslation)
{
transform.Translate(Vector3.forward * Input.mouseScrollDelta.y * Time.deltaTime * _translationSpeed);
}
// Movement
if (_enableMovement)
{
Vector3 deltaPosition = Vector3.zero;
float currentSpeed = _movementSpeed;
if (Input.GetKey(_boostSpeed))
currentSpeed = _boostedSpeed;
if (Input.GetKey(KeyCode.W))
deltaPosition += transform.forward;
if (Input.GetKey(KeyCode.S))
deltaPosition -= transform.forward;
if (Input.GetKey(KeyCode.A))
deltaPosition -= transform.right;
if (Input.GetKey(KeyCode.D))
deltaPosition += transform.right;
if (Input.GetKey(_moveUp))
deltaPosition += transform.up;
if (Input.GetKey(_moveDown))
deltaPosition -= transform.up;
// Calc acceleration
CalculateCurrentIncrease(deltaPosition != Vector3.zero);
transform.position += deltaPosition * currentSpeed * _currentIncrease;
}
// Rotation
if (_enableRotation)
{
// Pitch
transform.rotation *= Quaternion.AngleAxis(
-Input.GetAxis("Mouse Y") * _mouseSense,
Vector3.right
);
// Paw
transform.rotation = Quaternion.Euler(
transform.eulerAngles.x,
transform.eulerAngles.y + Input.GetAxis("Mouse X") * _mouseSense,
transform.eulerAngles.z
);
}
// Return to init position
if (Input.GetKeyDown(_initPositonButton))
{
transform.position = _initPosition;
transform.eulerAngles = _initRotation;
}
}
}
@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: 436275a13d4459746955fc6db5953473
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 140739
packageName: Free Fly Camera
packageVersion: 1.2
assetPath: Assets/FreeFlyCamera/Scripts/FreeFlyCamera.cs
uploadId: 396755
@@ -0,0 +1,24 @@
You are using asset FreeFlyCamera (Version 1.1)
It emulates control of the Scene editor camera in Play mode (in-game screen).
It is very convenient for quick scene adding and to use it for transition in it while staying in play mode. Load the asset and just drag the script to the main camera “FreeFlyCamera.cs” ready to use.
You can change parameters of rotation rate, movement, increase of transition speed, acceleration. You can activate/deactivate the rotation, transition, acceleration of movement speed.
If you have any questions or suggestions, you can send them to my email: sergeystafeyev@gmail.com.
--------------------------------------------------------
Вы используете ассет FreeFlyCamera (Версия 1.1)
Эмулирует управление камерой редактора сцены в режиме игры (на игровом экране).
Очень удобно быстро добавить на сцену, и использовать для перемещения по ней в игровом режиме. Загрузите ассет, и просто перетащите на основную камеру скрипт "FreeFlyCamera.cs" - готово к использованию.
Можно изменить параметры скорости вращения, перемещения, увеличения скорости перемещения, ускорения. Можно активировать/деактивировать вращение, перемещение, ускорение скорости движения.
Если у Вас есть какие-либо вопросы или предложения, можете отправить их на мой электронный адрес: sergeystafeyev@gmail.com.
@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 4884ccef30647b541924654c47c779bb
timeCreated: 1556081593
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 140739
packageName: Free Fly Camera
packageVersion: 1.2
assetPath: Assets/FreeFlyCamera/readme.txt
uploadId: 396755
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7b40a9ba704bbe642874d2bce0f83a26
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b520f278fadc2ac4fa9f2f58770e8b12
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,411 @@
#if UNITY_EDITOR
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
[InitializeOnLoad]
public static class GitBranchToolbar
{
private const string ToolbarElementName = "GitBranchToolbar";
private const double RefreshInterval = 2.0;
private const double ToolbarCheckInterval = 0.25;
private const float Height = 18f;
private static VisualElement toolbarElement;
private static string cachedBranchName = "...";
private static GitState cachedState = GitState.Unknown;
private static double nextRefreshTime;
private static double nextToolbarCheckTime;
private enum GitState
{
Unknown,
NoRepository,
Branch,
DetachedHead
}
static GitBranchToolbar()
{
RefreshBranchInfo(force: true);
EditorApplication.update += OnEditorUpdate;
EditorApplication.delayCall += AddToolbarUI;
AssemblyReloadEvents.afterAssemblyReload += OnAfterAssemblyReload;
}
private static void OnAfterAssemblyReload()
{
EditorApplication.delayCall += AddToolbarUI;
}
private static void OnEditorUpdate()
{
if (EditorApplication.timeSinceStartup >= nextRefreshTime)
{
RefreshBranchInfo();
}
EnsureToolbarExists();
}
private static void EnsureToolbarExists()
{
if (EditorApplication.timeSinceStartup < nextToolbarCheckTime)
return;
nextToolbarCheckTime = EditorApplication.timeSinceStartup + ToolbarCheckInterval;
var toolbarType = typeof(Editor).Assembly.GetType("UnityEditor.Toolbar");
if (toolbarType == null)
return;
var toolbars = Resources.FindObjectsOfTypeAll(toolbarType);
if (toolbars == null || toolbars.Length == 0)
return;
foreach (var toolbar in toolbars)
{
TryInjectIntoToolbar(toolbarType, toolbar);
}
}
private static void AddToolbarUI()
{
var toolbarType = typeof(Editor).Assembly.GetType("UnityEditor.Toolbar");
if (toolbarType == null)
return;
var toolbars = Resources.FindObjectsOfTypeAll(toolbarType);
if (toolbars == null || toolbars.Length == 0)
return;
foreach (var toolbar in toolbars)
{
TryInjectIntoToolbar(toolbarType, toolbar);
}
}
private static void TryInjectIntoToolbar(Type toolbarType, UnityEngine.Object toolbar)
{
var rootField = toolbarType.GetField("m_Root", BindingFlags.NonPublic | BindingFlags.Instance);
if (rootField == null)
return;
if (rootField.GetValue(toolbar) is not VisualElement root)
return;
var rightContainer = root.Q("ToolbarZoneRightAlign");
if (rightContainer == null)
return;
var existing = rightContainer.Q<IMGUIContainer>(ToolbarElementName);
if (existing != null)
{
toolbarElement = existing;
return;
}
var newElement = new IMGUIContainer(DrawGUI);
newElement.name = ToolbarElementName;
newElement.style.flexShrink = 0;
newElement.style.flexGrow = 0;
newElement.style.minWidth = 70;
newElement.style.maxWidth = 130;
newElement.style.marginLeft = 4;
newElement.style.marginRight = 0;
newElement.style.overflow = Overflow.Hidden;
newElement.style.alignSelf = Align.FlexEnd;
rightContainer.Add(newElement);
toolbarElement = newElement;
}
private static void DrawGUI()
{
RefreshBranchInfo();
var indicatorColor = GetBackgroundColor(cachedState, cachedBranchName);
var textColor = GetTextColor(cachedState);
string displayText = GetShortBranchName(cachedBranchName, cachedState);
Rect rect = GUILayoutUtility.GetRect(
GUIContent.none,
GUIStyle.none,
GUILayout.Height(Height),
GUILayout.MinWidth(80),
GUILayout.MaxWidth(220)
);
const float dotSize = 8f;
const float leftPadding = 4f;
const float gap = 6f;
const float rightPadding = 0f;
Rect dotRect = new Rect(
rect.x + leftPadding,
rect.y + Mathf.Round((rect.height - dotSize) * 0.5f),
dotSize,
dotSize
);
Rect labelRect = new Rect(
dotRect.xMax + gap,
rect.y,
rect.width - leftPadding - dotSize - gap - rightPadding,
rect.height
);
GUI.Label(
labelRect,
new GUIContent(displayText, cachedBranchName),
GetLabelStyle(textColor)
);
EditorGUI.DrawRect(dotRect, indicatorColor);
EditorGUIUtility.AddCursorRect(rect, MouseCursor.Link);
if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition))
{
ShowContextMenu();
Event.current.Use();
}
}
private static string GetShortBranchName(string branchName, GitState state)
{
if (state == GitState.DetachedHead)
return "DETACHED";
if (state == GitState.NoRepository)
return "No Repo";
if (state == GitState.Unknown)
return "...";
if (string.IsNullOrWhiteSpace(branchName))
return "...";
const int maxLen = 18;
if (branchName.Length <= maxLen)
return branchName;
return branchName.Substring(0, maxLen - 1) + "…";
}
private static void DrawBackground(Rect rect, Color color)
{
var oldColor = GUI.color;
GUI.color = color;
GUI.Box(rect, GUIContent.none, EditorStyles.toolbarButton);
GUI.color = oldColor;
}
private static GUIStyle GetLabelStyle(Color textColor)
{
var style = new GUIStyle(EditorStyles.label)
{
alignment = TextAnchor.MiddleLeft,
fontStyle = FontStyle.Bold,
clipping = TextClipping.Clip,
padding = new RectOffset(0, 0, 0, 0),
margin = new RectOffset(0, 0, 0, 0),
fixedHeight = (int)Height
};
style.normal.textColor = textColor;
style.hover.textColor = textColor;
style.active.textColor = textColor;
style.focused.textColor = textColor;
return style;
}
private static GUIContent GetDisplayContent()
{
return cachedState switch
{
GitState.Branch => new GUIContent($"{cachedBranchName + "TEST TEST TEST"}", cachedBranchName),
GitState.DetachedHead => new GUIContent("DETACHED"),
GitState.NoRepository => new GUIContent("No Repo"),
_ => new GUIContent("...")
};
}
private static Color GetBackgroundColor(GitState state, string branchName)
{
string normalized = (branchName ?? string.Empty).Trim();
return state switch
{
GitState.NoRepository => new Color(0.25f, 0.25f, 0.25f, 1f),
GitState.DetachedHead => new Color(0.45f, 0.30f, 0.10f, 1f),
GitState.Branch when normalized.Equals("main", StringComparison.OrdinalIgnoreCase)
=> Color.red,
GitState.Branch when normalized.Equals("develop", StringComparison.OrdinalIgnoreCase)
=> Color.blue,
GitState.Branch when normalized.StartsWith("feature-", StringComparison.OrdinalIgnoreCase)
=> Color.green,
GitState.Branch when normalized.StartsWith("feature/", StringComparison.OrdinalIgnoreCase)
=> new Color(0.12f, 0.28f, 0.45f, 1f),
GitState.Branch when normalized.StartsWith("hotfix-", StringComparison.OrdinalIgnoreCase)
=> Color.yellow,
GitState.Branch when normalized.StartsWith("hotfix/", StringComparison.OrdinalIgnoreCase)
=> new Color(0.45f, 0.20f, 0.10f, 1f),
GitState.Branch when normalized.StartsWith("bugfix-", StringComparison.OrdinalIgnoreCase)
=> Color.gray,
GitState.Branch => new Color(0.18f, 0.35f, 0.22f, 1f),
_ => new Color(0.22f, 0.22f, 0.22f, 1f)
};
}
private static Color GetTextColor(GitState state)
{
return state switch
{
GitState.NoRepository => new Color(0.85f, 0.85f, 0.85f),
_ => Color.white
};
}
private static void ShowContextMenu()
{
var menu = new GenericMenu();
menu.AddDisabledItem(new GUIContent($"Branch: {cachedBranchName}"));
if (cachedState == GitState.Branch || cachedState == GitState.DetachedHead)
{
menu.AddItem(new GUIContent("Copy Branch Name"), false, () =>
{
EditorGUIUtility.systemCopyBuffer = cachedBranchName;
Debug.Log($"Copied Git branch name: {cachedBranchName}");
});
}
else
{
menu.AddDisabledItem(new GUIContent("Copy Branch Name"));
}
menu.AddSeparator("");
menu.AddItem(new GUIContent("Refresh"), false, () =>
{
RefreshBranchInfo(force: true);
});
menu.ShowAsContext();
}
private static void RefreshBranchInfo(bool force = false)
{
if (!force && EditorApplication.timeSinceStartup < nextRefreshTime)
return;
nextRefreshTime = EditorApplication.timeSinceStartup + RefreshInterval;
try
{
string projectRoot = Path.GetFullPath(Path.Combine(Application.dataPath, ".."));
string gitDir = FindGitDirectory(projectRoot);
if (string.IsNullOrEmpty(gitDir))
{
cachedBranchName = "No Git";
cachedState = GitState.NoRepository;
return;
}
string headPath = Path.Combine(gitDir, "HEAD");
if (!File.Exists(headPath))
{
cachedBranchName = "No Git";
cachedState = GitState.NoRepository;
return;
}
string headContent = File.ReadAllText(headPath).Trim();
if (headContent.StartsWith("ref:", StringComparison.OrdinalIgnoreCase))
{
const string headsPrefix = "refs/heads/";
int headsIndex = headContent.IndexOf(headsPrefix, StringComparison.OrdinalIgnoreCase);
if (headsIndex >= 0)
{
cachedBranchName = headContent.Substring(headsIndex + headsPrefix.Length).Trim();
}
else
{
cachedBranchName = headContent
.Replace("ref:", string.Empty)
.Trim()
.Split('/')
.LastOrDefault() ?? "unknown";
}
cachedState = GitState.Branch;
}
else
{
cachedBranchName = "DETACHED";
cachedState = GitState.DetachedHead;
}
}
catch
{
cachedBranchName = "Git ?";
cachedState = GitState.Unknown;
}
}
private static string FindGitDirectory(string startDirectory)
{
var dir = new DirectoryInfo(startDirectory);
while (dir != null)
{
string gitPath = Path.Combine(dir.FullName, ".git");
if (Directory.Exists(gitPath))
return gitPath;
if (File.Exists(gitPath))
{
string content = File.ReadAllText(gitPath).Trim();
const string prefix = "gitdir:";
if (content.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
string relativePath = content.Substring(prefix.Length).Trim();
string resolvedPath = Path.GetFullPath(Path.Combine(dir.FullName, relativePath));
if (Directory.Exists(resolvedPath))
return resolvedPath;
}
}
dir = dir.Parent;
}
return null;
}
}
#endif
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9e93a5acbb3e741409543d32ad2762d0
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c39b3ae8e85687347a6abe01c32b86e2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because one or more lines are too long
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: f1c5c604e6d27cc4d86e81f45c704e11
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/README.html
uploadId: 480834
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 66686847ee1fa044bb15dfe473666178
folderAsset: yes
timeCreated: 1507995546
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 1f67e408a6d0adf4ab29d095ccd8b116
folderAsset: yes
timeCreated: 1507998942
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c76425e719cd4424d868674bcfb233f2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class AllowNestingAttribute : DrawerAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 95b49d3abe880c044adbe7faf6b7b4ec
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/AllowNestingAttribute.cs
uploadId: 480834
@@ -0,0 +1,24 @@
using System;
using UnityEngine;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class AnimatorParamAttribute : DrawerAttribute
{
public string AnimatorName { get; private set; }
public AnimatorControllerParameterType? AnimatorParamType { get; private set; }
public AnimatorParamAttribute(string animatorName)
{
AnimatorName = animatorName;
AnimatorParamType = null;
}
public AnimatorParamAttribute(string animatorName, AnimatorControllerParameterType animatorParamType)
{
AnimatorName = animatorName;
AnimatorParamType = animatorParamType;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 7373332cb77b42744a415d6b4add445d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/AnimatorParamAttribute.cs
uploadId: 480834
@@ -0,0 +1,30 @@
using System;
using UnityEngine;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class CurveRangeAttribute : DrawerAttribute
{
public Vector2 Min { get; private set; }
public Vector2 Max { get; private set; }
public EColor Color { get; private set; }
public CurveRangeAttribute(Vector2 min, Vector2 max, EColor color = EColor.Clear)
{
Min = min;
Max = max;
Color = color;
}
public CurveRangeAttribute(EColor color)
: this(Vector2.zero, Vector2.one, color)
{
}
public CurveRangeAttribute(float minX, float minY, float maxX, float maxY, EColor color = EColor.Clear)
: this(new Vector2(minX, minY), new Vector2(maxX, maxY), color)
{
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: bbdf3fb8882c7514c9a01108122cda7e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/CurveRangeAttribute.cs
uploadId: 480834
@@ -0,0 +1,11 @@
using UnityEngine;
namespace NaughtyAttributes
{
/// <summary>
/// Base class for all drawer attributes
/// </summary>
public class DrawerAttribute : PropertyAttribute, INaughtyAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 9df37fdebccf65c4da5b0a14f6dad5f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/DrawerAttribute.cs
uploadId: 480834
@@ -0,0 +1,57 @@
using System.Collections;
using System;
using System.Collections.Generic;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class DropdownAttribute : DrawerAttribute
{
public string ValuesName { get; private set; }
public DropdownAttribute(string valuesName)
{
ValuesName = valuesName;
}
}
public interface IDropdownList : IEnumerable<KeyValuePair<string, object>>
{
}
public class DropdownList<T> : IDropdownList
{
private List<KeyValuePair<string, object>> _values;
public DropdownList()
{
_values = new List<KeyValuePair<string, object>>();
}
public void Add(string displayName, T value)
{
_values.Add(new KeyValuePair<string, object>(displayName, value));
}
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
return _values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public static explicit operator DropdownList<object>(DropdownList<T> target)
{
DropdownList<object> result = new DropdownList<object>();
foreach (var kvp in target)
{
result.Add(kvp.Key, kvp.Value);
}
return result;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 2cb864a1092cec04f8a4dbb556e8ed31
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/DropdownAttribute.cs
uploadId: 480834
@@ -0,0 +1,9 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class EnumFlagsAttribute : DrawerAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: e8b31eb6d7299e54d89dcabc4cad0e6a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/EnumFlagsAttribute.cs
uploadId: 480834
@@ -0,0 +1,9 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class ExpandableAttribute : DrawerAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 60926d6ca7f9ced469e9248ff1192da6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/Expandable.cs
uploadId: 480834
@@ -0,0 +1,20 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true, Inherited = true)]
public class HorizontalLineAttribute : DrawerAttribute
{
public const float DefaultHeight = 2.0f;
public const EColor DefaultColor = EColor.Gray;
public float Height { get; private set; }
public EColor Color { get; private set; }
public HorizontalLineAttribute(float height = DefaultHeight, EColor color = DefaultColor)
{
Height = height;
Color = color;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 2fdd6f99acca2fd42a4f3162d585ce95
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/HorizontalLineAttribute.cs
uploadId: 480834
@@ -0,0 +1,24 @@
using System;
namespace NaughtyAttributes
{
public enum EInfoBoxType
{
Normal,
Warning,
Error
}
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true, Inherited = true)]
public class InfoBoxAttribute : DrawerAttribute
{
public string Text { get; private set; }
public EInfoBoxType Type { get; private set; }
public InfoBoxAttribute(string text, EInfoBoxType type = EInfoBoxType.Normal)
{
Text = text;
Type = type;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: afd1d6323740c734893fa8397c53113b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/InfoBoxAttribute.cs
uploadId: 480834
@@ -0,0 +1,9 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class InputAxisAttribute : DrawerAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 85033978c18810f46af271bbe94cf4aa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/InputAxisAttribute.cs
uploadId: 480834
@@ -0,0 +1,9 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class LayerAttribute : DrawerAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 668d19ebe071176448d1af816a9a0ce0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/LayerAttribute.cs
uploadId: 480834
@@ -0,0 +1,17 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class MinMaxSliderAttribute : DrawerAttribute
{
public float MinValue { get; private set; }
public float MaxValue { get; private set; }
public MinMaxSliderAttribute(float minValue, float maxValue)
{
MinValue = minValue;
MaxValue = maxValue;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 4aaa73f574deaa54187cb54aae571b24
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/MinMaxSliderAttribute.cs
uploadId: 480834
@@ -0,0 +1,37 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class ProgressBarAttribute : DrawerAttribute
{
public string Name { get; private set; }
public float MaxValue { get; set; }
public string MaxValueName { get; private set; }
public EColor Color { get; private set; }
public ProgressBarAttribute(string name, float maxValue, EColor color = EColor.Blue)
{
Name = name;
MaxValue = maxValue;
Color = color;
}
public ProgressBarAttribute(string name, string maxValueName, EColor color = EColor.Blue)
{
Name = name;
MaxValueName = maxValueName;
Color = color;
}
public ProgressBarAttribute(float maxValue, EColor color = EColor.Blue)
: this("", maxValue, color)
{
}
public ProgressBarAttribute(string maxValueName, EColor color = EColor.Blue)
: this("", maxValueName, color)
{
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: e19e4db6f4d08f849aa8ea8155cd2760
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/ProgressBarAttribute.cs
uploadId: 480834
@@ -0,0 +1,9 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class ResizableTextAreaAttribute : DrawerAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 56d9a4b795ef4a94d86b94e55fb81240
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/ResizableTextAreaAttribute.cs
uploadId: 480834
@@ -0,0 +1,9 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class SceneAttribute : DrawerAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: e054de18423364f4688b72a0f2a472b6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/SceneAttribute.cs
uploadId: 480834
@@ -0,0 +1,20 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class ShowAssetPreviewAttribute : DrawerAttribute
{
public const int DefaultWidth = 64;
public const int DefaultHeight = 64;
public int Width { get; private set; }
public int Height { get; private set; }
public ShowAssetPreviewAttribute(int width = DefaultWidth, int height = DefaultHeight)
{
Width = width;
Height = height;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 4b7dd9b44abc0054cb5cd68d74be2c1a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/ShowAssetPreviewAttribute.cs
uploadId: 480834
@@ -0,0 +1,9 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class SortingLayerAttribute : DrawerAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: b7564ee02deb3974a85d8617eea098fb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/SortingLayerAttribute.cs
uploadId: 480834
@@ -0,0 +1,9 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class TagAttribute : DrawerAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 8903399bbd7c9d745a7b9188ab6c8320
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/TagAttribute.cs
uploadId: 480834
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5cf879ed72221e740a7aa02ef9c366a7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
using System;
namespace NaughtyAttributes
{
public enum EButtonEnableMode
{
/// <summary>
/// Button should be active always
/// </summary>
Always,
/// <summary>
/// Button should be active only in editor
/// </summary>
Editor,
/// <summary>
/// Button should be active only in playmode
/// </summary>
Playmode
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class ButtonAttribute : SpecialCaseDrawerAttribute
{
public string Text { get; private set; }
public EButtonEnableMode SelectedEnableMode { get; private set; }
public ButtonAttribute(string text = null, EButtonEnableMode enabledMode = EButtonEnableMode.Always)
{
this.Text = text;
this.SelectedEnableMode = enabledMode;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: e8fe363a25ec5e24a9dd510bb0b4a0d4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes_SpecialCase/ButtonAttribute.cs
uploadId: 480834
@@ -0,0 +1,9 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class ReorderableListAttribute : SpecialCaseDrawerAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 6189b48f4055e6c47aa132632d898fa6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes_SpecialCase/ReorderableListAttribute.cs
uploadId: 480834
@@ -0,0 +1,9 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class ShowNativePropertyAttribute : SpecialCaseDrawerAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: a8e9b7b71c94a1f459336a24cfe04b1b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes_SpecialCase/ShowNativePropertyAttribute.cs
uploadId: 480834
@@ -0,0 +1,9 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class ShowNonSerializedFieldAttribute : SpecialCaseDrawerAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 8ea09f60df536734184a8920ff8bda6f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes_SpecialCase/ShowNonSerializedFieldAttribute.cs
uploadId: 480834
@@ -0,0 +1,8 @@
using System;
namespace NaughtyAttributes
{
public class SpecialCaseDrawerAttribute : Attribute, INaughtyAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 95a59093f8ed1af48a8be75fa3050a3c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes_SpecialCase/SpecialCaseDrawerAttribute.cs
uploadId: 480834
@@ -0,0 +1,8 @@
using System;
namespace NaughtyAttributes
{
public interface INaughtyAttribute
{
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: edda855906d15e541b46efd812fd70f3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/INaughtyAttribute.cs
uploadId: 480834
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 64c95d02a2004854585e8d923d6680d0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,15 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class BoxGroupAttribute : MetaAttribute, IGroupAttribute
{
public string Name { get; private set; }
public BoxGroupAttribute(string name = "")
{
Name = name;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 07da8af1e3be52c4789678bf4138ae11
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/MetaAttributes/BoxGroupAttribute.cs
uploadId: 480834
@@ -0,0 +1,26 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class DisableIfAttribute : EnableIfAttributeBase
{
public DisableIfAttribute(string condition)
: base(condition)
{
Inverted = true;
}
public DisableIfAttribute(EConditionOperator conditionOperator, params string[] conditions)
: base(conditionOperator, conditions)
{
Inverted = true;
}
public DisableIfAttribute(string enumName, object enumValue)
: base(enumName, enumValue as Enum)
{
Inverted = true;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 52a0d5c249ac8fd42a4fb4d61bc2f797
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/MetaAttributes/DisableIfAttribute.cs
uploadId: 480834
@@ -0,0 +1,26 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class EnableIfAttribute : EnableIfAttributeBase
{
public EnableIfAttribute(string condition)
: base(condition)
{
Inverted = false;
}
public EnableIfAttribute(EConditionOperator conditionOperator, params string[] conditions)
: base(conditionOperator, conditions)
{
Inverted = false;
}
public EnableIfAttribute(string enumName, object enumValue)
: base(enumName, enumValue as Enum)
{
Inverted = false;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: a616ae826c8ebae45a89d6a8cb68a843
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/MetaAttributes/EnableIfAttribute.cs
uploadId: 480834
@@ -0,0 +1,39 @@
using System;
namespace NaughtyAttributes
{
public abstract class EnableIfAttributeBase : MetaAttribute
{
public string[] Conditions { get; private set; }
public EConditionOperator ConditionOperator { get; private set; }
public bool Inverted { get; protected set; }
/// <summary>
/// If this not null, <see cref="Conditions"/>[0] is name of an enum variable.
/// </summary>
public Enum EnumValue { get; private set; }
public EnableIfAttributeBase(string condition)
{
ConditionOperator = EConditionOperator.And;
Conditions = new string[1] { condition };
}
public EnableIfAttributeBase(EConditionOperator conditionOperator, params string[] conditions)
{
ConditionOperator = conditionOperator;
Conditions = conditions;
}
public EnableIfAttributeBase(string enumName, Enum enumValue)
: this(enumName)
{
if (enumValue == null)
{
throw new ArgumentNullException(nameof(enumValue), "This parameter must be an enum value.");
}
EnumValue = enumValue;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 8ba6385cd022e164b89ead1937173ddc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 129996
packageName: NaughtyAttributes
packageVersion: 2.1.4
assetPath: Assets/NaughtyAttributes/Scripts/Core/MetaAttributes/EnableIfAttributeBase.cs
uploadId: 480834
@@ -0,0 +1,15 @@
using System;
namespace NaughtyAttributes
{
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class FoldoutAttribute : MetaAttribute, IGroupAttribute
{
public string Name { get; private set; }
public FoldoutAttribute(string name)
{
Name = name;
}
}
}

Some files were not shown because too many files have changed in this diff Show More