Compare commits

...

10 Commits

Author SHA1 Message Date
073dd25857 修复一些内容 2025-09-23 04:14:31 +08:00
ce56cca782 修改了一些bug,并补充了一些函数 2025-09-21 17:33:31 +08:00
f8aea1c383 修补一些bug 2025-09-15 12:01:54 +08:00
249836d1ec 同上一条 2025-09-07 19:42:18 +08:00
6de8b3ebc5 终于修复了PropertyItem多层预制体的收纳/展开rect错误 2025-09-07 17:50:20 +08:00
427b916dd2 修复File.Refresh 2025-09-04 16:24:27 +08:00
f6384a4a8c 对Hierarchy进行提升 2025-09-02 18:02:03 +08:00
f9f80aa559 更新一些冲突内容 2025-09-02 01:12:08 +08:00
5365ab6441 Save 2025-09-01 00:04:29 +08:00
2c784ff343 修复了一些代码上的漏洞与预制体上的错误 2025-08-31 19:42:33 +08:00
36 changed files with 1918 additions and 579 deletions

61
Convention/Editor/File.cs Normal file
View File

@@ -0,0 +1,61 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Convention.SO;
using UnityEditor;
using UnityEngine;
namespace Convention
{
public class FileEditor : AbstractCustomEditor
{
[MenuItem("Convention/AssetBundle/Create for Android")]
static void CreatAssetBundle()
{
string path = Path.Combine(Application.streamingAssetsPath, "AssetBundle", "Android");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.None, BuildTarget.Android);
UnityEngine.Debug.Log("Android Finish!");
}
[MenuItem("Convention/AssetBundle/Create for IOS")]
static void BuildAllAssetBundlesForIOS()
{
string dirName = "AssetBundles/IOS/IOS";
if (!Directory.Exists(dirName))
{
Directory.CreateDirectory(dirName);
}
BuildPipeline.BuildAssetBundles(dirName, BuildAssetBundleOptions.None, BuildTarget.iOS);
UnityEngine.Debug.Log("IOS Finish!");
}
[MenuItem("Convention/AssetBundle/Create for Windows")]
static void CreatPCAssetBundleForwINDOWS()
{
string path = Path.Combine(Application.streamingAssetsPath, "AssetBundle", "Windows");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
UnityEngine.Debug.Log("Windows Finish!");
}
[MenuItem("Convention/AssetBundle/Create for Mac")]
static void CreatPCAssetBundleForMac()
{
string path = Path.Combine(Application.streamingAssetsPath, "AssetBundle", "Mac");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.None, BuildTarget.StandaloneOSX);
UnityEngine.Debug.Log("Mac Finish!");
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0fde7509f09639547adff8534a7d9698
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c35ac0f81d1249a46909cd5f6156b761
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,12 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Convention;
using UnityEditor;
using Convention.WindowsUI;
[CustomEditor(typeof(ModernUIButton))]
public class ModernUIButtonEditor : AbstractCustomEditor
{
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b297501dc7cdd2149ab976e2fb8f88f0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,97 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!244 &-6002849048023987392
AudioMixerEffectController:
m_ObjectHideFlags: 3
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_EffectID: ceab011db4879ba41ad52c5eeea147e4
m_EffectName: Pitch Shifter
m_MixLevel: cd15d53e9c8be5142b26dca79aa9887e
m_Parameters:
- m_ParameterName: Pitch
m_GUID: a397a80ee8dae584d8bf0cca5579369b
- m_ParameterName: FFT size
m_GUID: a4a905f7c52f4b94e99ba9e6040d409e
- m_ParameterName: Overlap
m_GUID: 7671900607ffbac4ca75e8a96523d3a2
- m_ParameterName: Max channels
m_GUID: 088381d8f17bda842aa440a34123a808
m_SendTarget: {fileID: 0}
m_EnableWetMix: 0
m_Bypass: 0
--- !u!241 &24100000
AudioMixerController:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Master
m_OutputGroup: {fileID: 0}
m_MasterGroup: {fileID: 24300002}
m_Snapshots:
- {fileID: 24500006}
m_StartSnapshot: {fileID: 24500006}
m_SuspendThreshold: -80
m_EnableSuspend: 1
m_UpdateMode: 0
m_ExposedParameters:
- guid: b0ebf2901c1aeb344b2a87ae242df1b5
name: MasterPitch
- guid: a397a80ee8dae584d8bf0cca5579369b
name: PitchShifterPitch
m_AudioMixerGroupViews:
- guids:
- a3c32b9d162f19a419568f094319d0c7
name: View
m_CurrentViewIndex: 0
m_TargetSnapshot: {fileID: 24500006}
--- !u!243 &24300002
AudioMixerGroupController:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Master
m_AudioMixer: {fileID: 24100000}
m_GroupID: a3c32b9d162f19a419568f094319d0c7
m_Children: []
m_Volume: 068965e8a514a9a44863437ee299ef13
m_Pitch: b0ebf2901c1aeb344b2a87ae242df1b5
m_Send: 00000000000000000000000000000000
m_Effects:
- {fileID: 24400004}
- {fileID: -6002849048023987392}
m_UserColorIndex: 0
m_Mute: 0
m_Solo: 0
m_BypassEffects: 0
--- !u!244 &24400004
AudioMixerEffectController:
m_ObjectHideFlags: 3
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_EffectID: a8d7e4c02308ae44f9fc51dc9de13a3e
m_EffectName: Attenuation
m_MixLevel: 529a1bce94cdf3b43af8d5ba16028c5c
m_Parameters: []
m_SendTarget: {fileID: 0}
m_EnableWetMix: 0
m_Bypass: 0
--- !u!245 &24500006
AudioMixerSnapshotController:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Snapshot
m_AudioMixer: {fileID: 24100000}
m_SnapshotID: 92ac84973c010d04fbc3a98fc121b6ce
m_FloatValues:
b0ebf2901c1aeb344b2a87ae242df1b5: 1
a397a80ee8dae584d8bf0cca5579369b: 1
m_TransitionOverrides: {}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8d8c64a4848e9d849a8e2eddaae1c049
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 24100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -18,7 +18,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
m_IsActive: 1
--- !u!224 &6739692666707570911
RectTransform:
m_ObjectHideFlags: 0

View File

@@ -482,7 +482,7 @@ MonoBehaviour:
m_Calls: []
m_text: Assets
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 3994fc09180bdb54484d538bb5d127b4, type: 2}
m_fontAsset: {fileID: 0}
m_sharedMaterial: {fileID: -8493678639131513909, guid: 3994fc09180bdb54484d538bb5d127b4, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}

View File

@@ -1106,7 +1106,7 @@ MonoBehaviour:
m_ChildAlignment: 0
m_Spacing: 2
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 0
m_ChildControlHeight: 0
m_ChildScaleWidth: 0

View File

@@ -58,11 +58,11 @@ MonoBehaviour:
m_ChildAlignment: 0
m_Spacing: 0
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 0
m_ChildControlHeight: 0
m_ChildScaleWidth: 0
m_ChildScaleHeight: 0
m_ChildScaleHeight: 1
m_ReverseArrangement: 0
--- !u!114 &2447206846939804910
MonoBehaviour:
@@ -77,6 +77,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_rawButton: {fileID: 6792858692426831327}
m_modernButton: {fileID: 0}
layerTab: 7.5
layerHeight: 15
dropdownImage: {fileID: 7630776060629663467}
@@ -327,6 +328,18 @@ PrefabInstance:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 860861549860063477, guid: 14851ab435cb18448974bf76e92d8952, type: 3}
propertyPath: m_AllContextPlane.Array.size
value: 1
objectReference: {fileID: 0}
- target: {fileID: 860861549860063477, guid: 14851ab435cb18448974bf76e92d8952, type: 3}
propertyPath: m_AllContextPlane.Array.data[0].root
value:
objectReference: {fileID: 8975345697986449064}
- target: {fileID: 860861549860063477, guid: 14851ab435cb18448974bf76e92d8952, type: 3}
propertyPath: m_AllContextPlane.Array.data[0].plane
value:
objectReference: {fileID: 8975345697986449064}
- target: {fileID: 2372686227554923148, guid: 14851ab435cb18448974bf76e92d8952, type: 3}
propertyPath: m_AnchorMax.y
value: 0

View File

@@ -439,6 +439,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_rawButton: {fileID: 3558458297121154720}
m_modernButton: {fileID: 0}
layerTab: 7.5
layerHeight: 15
dropdownImage: {fileID: 240697464900702333}
@@ -1127,7 +1128,7 @@ PrefabInstance:
- target: {fileID: 3241788778710343315, guid: 37924db2d27cd6e49bf8002531a08095, type: 3}
propertyPath: m_fontAsset
value:
objectReference: {fileID: 11400000, guid: 3994fc09180bdb54484d538bb5d127b4, type: 2}
objectReference: {fileID: 0}
- target: {fileID: 3241788778710343315, guid: 37924db2d27cd6e49bf8002531a08095, type: 3}
propertyPath: m_fontSizeMax
value: 12

View File

@@ -141,7 +141,7 @@ Material:
- _Anisotropy: 0
- _BlendMode: 0
- _CoatMask: 0
- _ColorLevel: 1
- _ColorLevel: 0.1
- _CullMode: 2
- _CullModeForward: 2
- _Cutoff: 0.5

View File

@@ -6,7 +6,7 @@ using UnityEngine;
namespace Convention.VFX
{
public class DreamTeckSplinePointBuilder : MonoAnyBehaviour, ILoadedInHierarchy
public class DreamTeckSplinePointBuilder : MonoBehaviour, ILoadedInHierarchy
{
public enum InjectType
{
@@ -15,7 +15,6 @@ namespace Convention.VFX
Broken = SplinePoint.Type.Broken,
SmoothFree = SplinePoint.Type.SmoothFree
};
[Setting, InspectorDraw] public PerformanceIndicator.PerformanceMode performanceMode = PerformanceIndicator.PerformanceMode.Speed;
[Content] public List<LinePoint> childPoints = new();
[Resources, SerializeField, HopeNotNull, InspectorDraw] private SplineComputer m_splineComputer;
@@ -100,23 +99,6 @@ namespace Convention.VFX
m_splineRenderer = GetComponent<SplineRenderer>();
}
private void LateUpdate()
{
if ((int)performanceMode >= (int)PerformanceIndicator.PerformanceMode.L6)
{
RebuildAll();
m_splineRenderer.Rebuild();
}
else if ((int)performanceMode >= (int)PerformanceIndicator.PerformanceMode.L6)
{
if (childPoints.Count != knots.Count)
RebuildAll();
else
ResetPoints();
m_splineRenderer.Rebuild();
}
}
public static void SetKnot([In, ArgPackage] ref SplinePoint point, [In, ArgPackage] LinePoint linePoint)
{
point.position = linePoint.transform.localPosition;

File diff suppressed because one or more lines are too long

View File

@@ -34,7 +34,14 @@ MonoBehaviour:
- Assembly-CSharp-firstpass
- Cinemachine
- CW.Common
- Dreamteck.Splines
- Dreamteck.Utilities
- EasySave3
- glTFast
- glTFast.Documentation.Examples
- glTFast.dots
- glTFast.Export
- glTFast.Newtonsoft
- LeanCommon
- LeanGUI
- LeanTransition

8
Convention/[IL2CPP].meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1f28191148868da4eb919b1b1d5c2399
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,254 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Debug = UnityEngine.Debug;
// ReSharper disable InconsistentNaming
#if PLATFORM_WINDOWS
namespace Convention.IL2CPP
{
/// <summary>
/// <para>rainwl/CreateAndTerminateProcessWithIL2CPP: In Unity,if we use IL2CPP as scripting backend,System.Diagnotics.Process could not be supported (github.com)
/// </para>
/// <para>When developing with Unity, if you choose IL2CPP as the scripting backend, it brings along several challenges.
/// First, code that relies on C# reflection is not supported. Common libraries like Protocol Buffers and log4net, which use reflection, require modifications.
/// </para>
/// <para>Secondly, the System.Diagnostics.Process namespace is also unsupported.If you need to launch an external application, an alternative approach is necessary.Unfortunately, Unity lacks sufficient resources to modify IL2CPP to support Process. The solutions available online are quite scarce, with only one GitHub repository providing a potential workaround.However, this solution is not readily usable due to various issues.
/// Given this situation, I've developed a method utilizing kernel32 API calls to achieve launching and closing external processes, as well as terminating processes with specific names.
/// </para>
/// </summary>
public static class ProcessLauncher
{
#region DLL Import
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool CreateProcessW(
string lpApplicationName,
string lpCommandLine,
IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes,
bool bInheritHandles,
uint dwCreationFlags,
IntPtr lpEnvironment,
string lpCurrentDirectory,
[In] ref StartUpInfo lpStartupInfo,
out ProcessInformation lpProcessInformation
);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool TerminateProcess(IntPtr hProcess, uint uExitCode);
[DllImport("kernel32.dll")]
// ReSharper disable once IdentifierTypo
public static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags, uint th32ProcessID);
[DllImport("kernel32.dll")]
private static extern bool Process32First(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
[DllImport("kernel32.dll")]
private static extern bool Process32Next(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll")]
private static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
#endregion
#region Fields
[StructLayout(LayoutKind.Sequential)]
private struct PROCESSENTRY32
{
public uint dwSize;
public uint cntUsage;
public uint th32ProcessID;
public IntPtr th32DefaultHeapID;
public uint th32ModuleID;
public uint cntThreads;
public uint th32ParentProcessID;
public int pcPriClassBase;
public uint dwFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szExeFile;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct StartUpInfo
{
public int cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public int dwX;
public int dwY;
public int dwXSize;
public int dwYSize;
public int dwXCountChars;
public int dwYCountChars;
public int dwFillAttribute;
public int dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
public struct ProcessInformation
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
// ReSharper disable once FieldCanBeMadeReadOnly.Local
public static List<ProcessInformation> processList = new List<ProcessInformation>();
#endregion
#region Process Methods
public static ProcessInformation StartExternalProcess(string programPath, string arguments, string currentDirectory)
{
// const string programPath = @"E:\FleX-1.2.0\NvFlexDemoReleaseCUDA_x64.exe";
// const string arguments = "-surgeryType=0";
var startupInfo = new StartUpInfo();
startupInfo.cb = Marshal.SizeOf(startupInfo);
var success = CreateProcessW(
programPath,
arguments,
IntPtr.Zero,
IntPtr.Zero,
false,
0,
IntPtr.Zero,
currentDirectory,
ref startupInfo,
out var processInfo
);
if (success)
{
processList.Add(processInfo);
return processInfo;
}
else
{
throw new Exception("Unable to start process, error code: " + Marshal.GetLastWin32Error());
}
}
public static void TerminateExternalProcess(ProcessInformation processInfo)
{
// ReSharper disable once InvertIf
if (processInfo.hProcess != IntPtr.Zero)
{
var success = TerminateProcess(processInfo.hProcess, 0);
if (success)
{
Debug.Log("The external process is shut down");
}
else
{
Debug.LogError("Unable to shut down external process, error code:" + Marshal.GetLastWin32Error());
}
}
}
public static void CloseProcessByName(string processName, IntPtr snapShot)
{
var processEntry = new PROCESSENTRY32
{
dwSize = (uint)Marshal.SizeOf(typeof(PROCESSENTRY32))
};
// ReSharper disable once InvertIf
if (Process32First(snapShot, ref processEntry))
{
do
{
// ReSharper disable once InvertIf
if (processEntry.szExeFile.Equals(processName, StringComparison.OrdinalIgnoreCase))
{
var processHandle = OpenProcess(processEntry.th32ProcessID);
// ReSharper disable once InvertIf
if (processHandle != IntPtr.Zero)
{
TerminateProcess(processHandle, 0); // Terminate the process
CloseHandle(processHandle);
break;
}
}
} while (Process32Next(snapShot, ref processEntry));
}
}
private static IntPtr OpenProcess(uint processId)
{
const uint processTerminate = 0x0001;
return OpenProcess(processTerminate, false, processId);
}
#endregion
#region Test Methods
//private ProcessInformation _processInfo1;
//private ProcessInformation _processInfo2;
//private void Update()
//{
// if (Input.GetKeyDown(KeyCode.A))
// {
// _processInfo1 =
// StartExternalProcess(@"D:\Projects\Log[]\LogInsights\src\LogInsights\bin\x64\Release\LogInsights.exe",
// null, null);
// _processInfo2 = StartExternalProcess(@"C:\Windows\System32\cmd.exe", null, null);
// }
// if (Input.GetKeyDown(KeyCode.B))
// {
// TerminateExternalProcess(_processInfo1);
// }
// if (Input.GetKeyDown(KeyCode.C))
// {
// TerminateExternalProcess(_processInfo2);
// }
// // ReSharper disable once InvertIf
// if (Input.GetKeyDown(KeyCode.D))
// {
// var snapshot = CreateToolhelp32Snapshot(2, 0);
// CloseProcessByName("cmd.exe", snapshot);
// CloseProcessByName("LogInsights.exe", snapshot);
// CloseHandle(snapshot);
// }
//}
//private void OnDestroy()
//{
// foreach (var processInfo in processList)
// {
// TerminateProcess(processInfo.hProcess, 0);
// Debug.Log("The external process is shut down,error code: " + processInfo.dwProcessId);
// }
//}
#endregion
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c723354975719bd4abffd154b6d1fa3d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -14,13 +14,18 @@ namespace Convention
public abstract void LoadAudioClip(AudioClip clip);
public abstract AudioClip GetAudioClip();
public abstract float GetClockTime();
public abstract void SetClockTime(float value);
public AudioClip CurrentClip
{
get => GetAudioClip();
set => LoadAudioClip(value);
}
public float CurrentTime => GetClockTime();
public float CurrentTime
{
get => GetClockTime();
set => SetClockTime(value);
}
public abstract bool IsPlaying();
@@ -187,9 +192,7 @@ namespace Convention
get
{
if (source == null)
source = this.SeekComponent<AudioSource>();
if (source == null)
source = this.gameObject.AddComponent<AudioSource>();
source = this.GetOrAddComponent<AudioSource>();
return source;
}
set
@@ -207,9 +210,16 @@ namespace Convention
}
public override float GetClockTime()
{
if (Source.clip == null)
return 0;
return (float)Source.timeSamples / (float)Source.clip.frequency;
}
public override void SetClockTime(float value)
{
Source.time = value;
}
public override bool IsPlaying()
{
return Source.isPlaying;
@@ -239,7 +249,7 @@ namespace Convention
}
public override void SetSpeed(float speed)
{
SetSpeed(speed, 1.0f, "Master", "MasterPitch", "PitchShifterPitch", true);
SetSpeed(speed, "Master", "MasterPitch", "PitchShifterPitch", true);
}
public override void SetVolume(float volume)
{
@@ -247,7 +257,6 @@ namespace Convention
}
public void SetSpeed(float speed,
float TargetPitchValue,
string TargetGroupName,
string TargetPitch_Attribute_Name,
string TargetPitchshifterPitch_Attribute_Name,
@@ -255,19 +264,19 @@ namespace Convention
{
if (Mixer != null)
{
if (TargetPitchValue > 0)
if (speed > 0)
{
Source.pitch = 1;
Mixer.SetFloat(TargetPitch_Attribute_Name, TargetPitchValue);
float TargetPitchshifterPitchValue = 1.0f / TargetPitchValue;
Mixer.SetFloat(TargetPitch_Attribute_Name, speed);
float TargetPitchshifterPitchValue = 1.0f / speed;
Mixer.SetFloat(TargetPitchshifterPitch_Attribute_Name, TargetPitchshifterPitchValue);
Source.outputAudioMixerGroup = Mixer.FindMatchingGroups(TargetGroupName)[0];
}
else
{
Source.pitch = -1;
Mixer.SetFloat(TargetPitch_Attribute_Name, -TargetPitchValue);
float TargetPitchshifterPitchValue = -1.0f / TargetPitchValue;
Mixer.SetFloat(TargetPitch_Attribute_Name, -speed);
float TargetPitchshifterPitchValue = -1.0f / speed;
Mixer.SetFloat(TargetPitchshifterPitch_Attribute_Name, TargetPitchshifterPitchValue);
Source.outputAudioMixerGroup = Mixer.FindMatchingGroups(TargetGroupName)[0];
}
@@ -412,18 +421,19 @@ namespace Convention
BandNegativeCheck();
}
void Update()
{
float[] spectrum = new float[256];
AudioListener.GetSpectrumData(spectrum, 0, FFTWindow.Rectangular);
for (int i = 1; i < spectrum.Length - 1; i++)
{
Debug.DrawLine(new Vector3(i - 1, spectrum[i] + 10, 0), new Vector3(i, spectrum[i + 1] + 10, 0), Color.red);
Debug.DrawLine(new Vector3(i - 1, Mathf.Log(spectrum[i - 1]) + 10, 2), new Vector3(i, Mathf.Log(spectrum[i]) + 10, 2), Color.cyan);
Debug.DrawLine(new Vector3(Mathf.Log(i - 1), spectrum[i - 1] - 10, 1), new Vector3(Mathf.Log(i), spectrum[i] - 10, 1), Color.green);
Debug.DrawLine(new Vector3(Mathf.Log(i - 1), Mathf.Log(spectrum[i - 1]), 3), new Vector3(Mathf.Log(i), Mathf.Log(spectrum[i]), 3), Color.blue);
}
}
//void Update()
//{
// float[] spectrum = new float[256];
// AudioListener.GetSpectrumData(spectrum, 0, FFTWindow.Rectangular);
// for (int i = 1; i < spectrum.Length - 1; i++)
// {
// Debug.DrawLine(new Vector3(i - 1, spectrum[i] + 10, 0), new Vector3(i, spectrum[i + 1] + 10, 0), Color.red);
// Debug.DrawLine(new Vector3(i - 1, Mathf.Log(spectrum[i - 1]) + 10, 2), new Vector3(i, Mathf.Log(spectrum[i]) + 10, 2), Color.cyan);
// Debug.DrawLine(new Vector3(Mathf.Log(i - 1), spectrum[i - 1] - 10, 1), new Vector3(Mathf.Log(i), spectrum[i] - 10, 1), Color.green);
// Debug.DrawLine(new Vector3(Mathf.Log(i - 1), Mathf.Log(spectrum[i - 1]), 3), new Vector3(Mathf.Log(i), Mathf.Log(spectrum[i]), 3), Color.blue);
// }
//}
}
}

View File

@@ -1,6 +1,3 @@
using System.Collections;
using System.Collections.Generic;
using Cinemachine;
using Convention.WindowsUI.Variant;
using UnityEngine;
using UnityEngine.InputSystem;
@@ -29,6 +26,16 @@ namespace Convention
}
}
public void SetMoveSpeed(float value)
{
moveSpeed = value;
}
public void SetRotationSpeed(float value)
{
rotationSpeed = value;
}
private void Start()
{
m_IsFocus = false;
@@ -36,37 +43,70 @@ namespace Convention
private void Update()
{
Vector3 dxyz = Vector3.zero;
Vector3 rxyz = Vector3.zero;
if (Keyboard.current[Key.W].isPressed || Keyboard.current[Key.UpArrow].isPressed)
dxyz += TargetFollow.forward;
if (Keyboard.current[Key.A].isPressed || Keyboard.current[Key.LeftArrow].isPressed)
dxyz += -TargetFollow.right;
if (Keyboard.current[Key.D].isPressed || Keyboard.current[Key.RightArrow].isPressed)
dxyz += TargetFollow.right;
if (Keyboard.current[Key.S].isPressed || Keyboard.current[Key.DownArrow].isPressed)
dxyz += -TargetFollow.forward;
if (Keyboard.current[Key.Space].isPressed)
dxyz += TargetFollow.up;
if (Keyboard.current[Key.LeftShift].isPressed)
dxyz += -TargetFollow.up;
var drotation = Vector3.zero;
if (isFocus)
{
var temp = Mouse.current.delta.ReadValue();
drotation = new(-temp.y, temp.x, 0);
Vector3 dxyz = Vector3.zero;
//Vector3 rxyz = Vector3.zero;
if (Keyboard.current[Key.W].isPressed || Keyboard.current[Key.UpArrow].isPressed)
{
var temp = TargetFollow.forward;
//temp.y = 0;
dxyz += temp.normalized;
}
if (Keyboard.current[Key.A].isPressed || Keyboard.current[Key.LeftArrow].isPressed)
{
var temp = TargetFollow.right;
temp.y = 0;
dxyz -= temp.normalized;
}
if (Keyboard.current[Key.D].isPressed || Keyboard.current[Key.RightArrow].isPressed)
{
var temp = TargetFollow.right;
temp.y = 0;
dxyz += temp.normalized;
}
if (Keyboard.current[Key.S].isPressed || Keyboard.current[Key.DownArrow].isPressed)
{
var temp = TargetFollow.forward;
//temp.y = 0;
dxyz -= temp.normalized;
}
if (Keyboard.current[Key.Space].isPressed)
dxyz += Vector3.up;
#if !UNITY_EDITOR
if (Keyboard.current[Key.LeftShift].isPressed)
#else
if (Keyboard.current[Key.Q].isPressed)
#endif
dxyz -= Vector3.up;
var drotation = Vector3.zero;
{
var temp = Mouse.current.delta.ReadValue();
drotation = new(-temp.y, temp.x, 0);
}
//
TargetFollow.Translate(dxyz * moveSpeed, Space.World);
TargetFollow.Rotate(drotation * rotationSpeed, Space.Self);
//
if (Keyboard.current[Key.Escape].isPressed)
isFocus = false;
if (Keyboard.current[Key.LeftCtrl].isPressed && Keyboard.current[Key.LeftShift].isPressed)
{
if(Keyboard.current[Key.Z].isPressed)
{
TargetFollow.localPosition = Vector3.zero;
}
else
{
TargetFollow.localEulerAngles = new(0, TargetFollow.eulerAngles.y, 0);
}
}
}
//
TargetFollow.Translate(dxyz * moveSpeed, Space.Self);
TargetFollow.Rotate(drotation * rotationSpeed, Space.Self);
//
if (Keyboard.current[Key.Escape].isPressed)
isFocus = false;
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
@@ -435,6 +436,21 @@ namespace Convention
throw new InvalidCastException($"\"{str}\" is cannt convert to type<{type}>");
}
public static object ConventValue([In] Type type, [In] string str)
{
var parse_method = type.GetMethod("Parse");
if (parse_method != null &&
(parse_method.ReturnType.IsSubclassOf(type) || parse_method.ReturnType == type) &&
parse_method.GetParameters().Length == 1 &&
parse_method.GetParameters()[0].ParameterType == typeof(string))
{
return parse_method.Invoke(null, new object[] { str });
}
throw new InvalidCastException($"\"{str}\" is cannt convert to type<{type}>");
}
public static string Combine([In] params object[] args)
{
if (args.Length == 0)
@@ -1048,33 +1064,62 @@ namespace Convention
public class ActionStepCoroutineWrapper
{
private List<KeyValuePair<YieldInstruction, Action>> steps = new();
private class YieldInstructionWrapper
{
public YieldInstruction UnityYieldInstruction;
public CustomYieldInstruction CustomYieldInstruction;
public YieldInstructionWrapper()
{
}
public YieldInstructionWrapper(YieldInstruction unityYieldInstruction)
{
this.UnityYieldInstruction = unityYieldInstruction;
}
public YieldInstructionWrapper(CustomYieldInstruction customYieldInstruction)
{
this.CustomYieldInstruction = customYieldInstruction;
}
}
private List<KeyValuePair<YieldInstructionWrapper, Action>> steps = new();
public ActionStepCoroutineWrapper Update(Action action)
{
steps.Add(new(null, action));
steps.Add(new(new(), action));
return this;
}
public ActionStepCoroutineWrapper Wait(float time, Action action)
{
steps.Add(new(new WaitForSeconds(time), action));
steps.Add(new(new(new WaitForSeconds(time)), action));
return this;
}
public ActionStepCoroutineWrapper FixedUpdate(Action action)
{
steps.Add(new(new WaitForFixedUpdate(), action));
steps.Add(new(new (new WaitForFixedUpdate()), action));
return this;
}
public ActionStepCoroutineWrapper Next(Action action)
{
steps.Add(new(new WaitForEndOfFrame(), action));
steps.Add(new(new(new WaitForEndOfFrame()), action));
return this;
}
private static IEnumerator Execute(List<KeyValuePair<YieldInstruction, Action>> steps)
public ActionStepCoroutineWrapper Until(Func<bool> pr, Action action)
{
steps.Add(new(new(new WaitUntil(pr)), action));
return this;
}
private static IEnumerator Execute(List<KeyValuePair<YieldInstructionWrapper, Action>> steps)
{
foreach (var (waiting, action) in steps)
{
action();
yield return waiting;
if (waiting.UnityYieldInstruction != null)
yield return waiting.UnityYieldInstruction;
else
yield return waiting.CustomYieldInstruction;
}
}
~ActionStepCoroutineWrapper()
@@ -1083,7 +1128,7 @@ namespace Convention
}
public void Invoke()
{
StartCoroutine(Execute(new List<KeyValuePair<YieldInstruction, Action>>(steps)));
StartCoroutine(Execute(new List<KeyValuePair<YieldInstructionWrapper, Action>>(steps)));
steps.Clear();
}
}
@@ -1252,35 +1297,47 @@ namespace Convention
return false;
}
public static List<MemberInfo> SeekMemberInfoFromType(
[In] Type targetType,
[In, Opt] IEnumerable<Type> attrs, [In, Opt] IEnumerable<Type> types,
[In, Opt] Type untilBase = null
)
{
List<MemberInfo> result = new();
result.AddRange(targetType.GetMembers(BindingFlags.Public | BindingFlags.Instance));
while (targetType != null && targetType != typeof(object) && targetType != untilBase)
{
result.AddRange(
from info in targetType.GetMembers(BindingFlags.NonPublic | BindingFlags.Instance)
where attrs == null || HasCustomAttribute(info, attrs)
where types == null || (GetMemberValueType(info, out var type) && types.Contains(type))
select info
);
targetType = targetType.BaseType;
}
return result;
}
public static List<MemberInfo> SeekMemberInfo(
[In] object target,
[In, Opt] IEnumerable<Type> attrs, [In, Opt] IEnumerable<Type> types,
[In, Opt] Type untilBase = null
)
{
Type _CurType = target.GetType();
List<MemberInfo> result = new();
result.AddRange(_CurType.GetMembers(BindingFlags.Public | BindingFlags.Instance));
while (_CurType != null && _CurType != typeof(object) && _CurType != untilBase)
{
result.AddRange(
from info in _CurType.GetMembers(BindingFlags.NonPublic | BindingFlags.Instance)
where attrs == null || HasCustomAttribute(info, attrs)
where types == null || (GetMemberValueType(info, out var type) && types.Contains(type))
select info
);
_CurType = _CurType.BaseType;
}
return result;
return SeekMemberInfoFromType(target.GetType(), attrs, types, untilBase);
}
public static List<MemberInfo> SeekMemberInfo([In] object target, IEnumerable<string> names, BindingFlags flags = BindingFlags.Public | BindingFlags.Instance)
public static List<MemberInfo> SeekMemberInfoFromType([In] Type target, IEnumerable<string> names,
BindingFlags flags = BindingFlags.Public | BindingFlags.Instance)
{
Type _CurType = target.GetType();
List<MemberInfo> result = _CurType.GetMembers(flags).ToList();
List<MemberInfo> result = target.GetMembers(flags).ToList();
HashSet<string> nameSet = names.ToHashSet();
result.RemoveAll(x => nameSet.Contains(x.Name) == false);
return result;
}
public static List<MemberInfo> SeekMemberInfo([In] object target, IEnumerable<string> names,
BindingFlags flags = BindingFlags.Public | BindingFlags.Instance)
{
return SeekMemberInfoFromType(target.GetType(), names, flags);
}
public static object InvokeMember([In] MemberInfo member, [In] object target, params object[] parameters)
{
if (member is MethodInfo method)
@@ -1463,7 +1520,7 @@ namespace Convention
}
public static void AdjustSizeToContainsChilds([In] RectTransform rectTransform, Vector2 min, Vector2 max, RectTransform.Axis? axis)
{
if (IsDisableAdjustSizeToContainsChilds2DeferUpdates)
if (IsDisableAdjustSizeToContainsChilds2DeferUpdates)
return;
LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform);
@@ -2117,5 +2174,21 @@ namespace Convention
return Activator.CreateInstance(type);
}
}
public static partial class ConventionUtility
{
public static byte[] ReadAllBytes(this BinaryReader reader)
{
const int bufferSize = 4096;
using (var ms = new MemoryStream())
{
byte[] buffer = new byte[bufferSize];
int count;
while ((count = reader.Read(buffer, 0, buffer.Length)) != 0)
ms.Write(buffer, 0, count);
return ms.ToArray();
}
}
}
}

View File

@@ -62,7 +62,7 @@ namespace Convention
private FileSystemInfo OriginInfo;
public ToolFile(string path)
{
FullPath = Path.GetFullPath(path);
FullPath = Path.GetFullPath(Environment.ExpandEnvironmentVariables(path));
Refresh();
}
public override string ToString()
@@ -79,6 +79,13 @@ namespace Convention
}
public string GetName(bool is_ignore_extension = false)
{
if (OriginInfo != null)
{
if (OriginInfo is FileInfo finfo)
return is_ignore_extension ? Path.GetFileNameWithoutExtension(finfo.FullName) : finfo.Name;
else if (OriginInfo is DirectoryInfo dinfo)
return dinfo.Name;
}
var result = this.FullPath[..(
(this.FullPath.Contains('.') && is_ignore_extension)
? this.FullPath.LastIndexOf('.')
@@ -89,8 +96,8 @@ namespace Convention
? ^1
: ^0
)];
return result[(Mathf.Max(result.Contains('/') ? result.LastIndexOf('/') : -1,
result.Contains('\\') ? result.LastIndexOf('\\') : -1) + 1)..];
//result.LastIndexOf('\\') return -1 when '\\' was not been contained
return result[(Mathf.Max(result.LastIndexOf('/'), result.LastIndexOf('\\')) + 1)..];
}
public string GetExtension()
{
@@ -154,9 +161,15 @@ namespace Convention
if (Exists() == false)
OriginInfo = null;
else if (IsDir())
{
OriginInfo = new DirectoryInfo(FullPath);
FullPath = Path.GetFullPath(FullPath);
}
else
{
OriginInfo = new FileInfo(FullPath);
FullPath = Path.GetFullPath(FullPath);
}
return this;
}
@@ -175,7 +188,7 @@ namespace Convention
if (IsFile() == false)
throw new InvalidOperationException("Target is not a file");
string result = "";
using (var fs = (this.OriginInfo as FileInfo).OpenText())
using (var fs = new StreamReader((this.OriginInfo as FileInfo).OpenRead()))
{
result = fs.ReadToEnd();
}
@@ -266,14 +279,21 @@ namespace Convention
public IEnumerator LoadAsAssetBundle([In] Action<AssetBundle> callback)
{
AssetBundleCreateRequest result = AssetBundle.LoadFromFileAsync(FullPath);
result.completed += x =>
{
if (x.isDone)
{
callback(result.assetBundle);
}
};
yield return result;
callback(result.assetBundle);
yield return null;
}
public IEnumerator LoadAsAssetBundle([In]Action<float> progress, [In] Action<AssetBundle> callback)
{
AssetBundleCreateRequest result = AssetBundle.LoadFromFileAsync(FullPath);
while (result.isDone == false)
{
progress(result.progress);
yield return null;
}
yield return result;
callback(result.assetBundle);
yield return null;
}
public string LoadAsUnknown(string suffix)

View File

@@ -51,12 +51,9 @@ namespace Convention
public ToolFile GetConfigFile() => DataDir | ConstConfigFile;
public ToolFile ConfigFile => GetConfigFile();
public ToolFile GetFile(string path, bool isMustExist = false)
public ToolFile GetFile(string path)
{
var file = DataDir | path;
if (isMustExist)
file.MustExistsPath();
return file;
return DataDir | path;
}
public bool EraseFile(string path)
{
@@ -130,12 +127,17 @@ namespace Convention
public class InternalProperty
{
public Dictionary<string, object> property = new();
public Dictionary<string, object> find = new();
}
public GlobalConfig SaveProperties()
{
var configFile = this.ConfigFile;
configFile.SaveAsJson(new InternalProperty() { property = data_pair });
configFile.SaveAsJson(new InternalProperty()
{
property = data_pair,
find = data_find
});
return this;
}
public GlobalConfig LoadProperties()
@@ -154,7 +156,7 @@ namespace Convention
public ToolFile GetLogFile()
{
return this.GetFile(ConfigFile.GetName(true) + "_log.txt", true);
return this.GetFile(ConfigFile.GetName(true) + "_log.txt").MustExistsPath();
}
public ToolFile LogFile => GetLogFile();
@@ -199,14 +201,18 @@ namespace Convention
Log("Error", message);
}
private Dictionary<string, object> data_find = new();
public object FindItem(string key, object @default = null)
{
if (Contains(key))
{
data_find.Remove(key);
return this[key];
}
else
{
data_find[key] = @default;
LogPropertyNotFound(key, @default);
return @default;
}

View File

@@ -0,0 +1,584 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_URP
using static Unity.Mathematics.math;
#endif
using static Convention.MathExtension;
namespace Convention
{
public static partial class MathExtension
{
#region EaseCurve
public static AnimationCurve MakeAnimationCurve(EaseCurveType type, float start, float end, float startValue, float endValue, int keyCount)
{
var curve = new AnimationCurve();
curve.keys = new Keyframe[keyCount];
for (int i = 0; i < keyCount; i++)
{
float t = i / (float)(keyCount - 1);
curve.keys[i] = new Keyframe(
Mathf.Lerp(start, end, t),
Mathf.Lerp(startValue, endValue, Evaluate(t, type))
);
}
return curve;
}
public enum EaseCurveType
{
Linear = 0,
InQuad = 1,
OutQuad = 2,
InOutQuad = 3,
InCubic = 4,
OutCubic = 5,
InOutCubic = 6,
InQuart = 7,
OutQuart = 8,
InOutQuart = 9,
InQuint = 10,
OutQuint = 11,
InOutQuint = 12,
InSine = 13,
OutSine = 14,
InOutSine = 15,
InExpo = 16,
OutExpo = 17,
InOutExpo = 18,
InCirc = 19,
OutCirc = 20,
InOutCirc = 21,
InBounce = 22,
OutBounce = 23,
InOutBounce = 24,
InElastic = 25,
OutElastic = 26,
InOutElastic = 27,
InBack = 28,
OutBack = 29,
InOutBack = 30,
Custom = 31
}
public static float Evaluate(float t, EaseCurveType curveType)
{
float from = 0;
float to = 1;
return curveType switch
{
EaseCurveType.Linear => Linear(from, to, t),
EaseCurveType.InQuad => InQuad(from, to, t),
EaseCurveType.OutQuad => OutQuad(from, to, t),
EaseCurveType.InOutQuad => InOutQuad(from, to, t),
EaseCurveType.InCubic => InCubic(from, to, t),
EaseCurveType.OutCubic => OutCubic(from, to, t),
EaseCurveType.InOutCubic => InOutCubic(from, to, t),
EaseCurveType.InQuart => InQuart(from, to, t),
EaseCurveType.OutQuart => OutQuart(from, to, t),
EaseCurveType.InOutQuart => InOutQuart(from, to, t),
EaseCurveType.InQuint => InQuint(from, to, t),
EaseCurveType.OutQuint => OutQuint(from, to, t),
EaseCurveType.InOutQuint => InOutQuint(from, to, t),
EaseCurveType.InSine => InSine(from, to, t),
EaseCurveType.OutSine => OutSine(from, to, t),
EaseCurveType.InOutSine => InOutSine(from, to, t),
EaseCurveType.InExpo => InExpo(from, to, t),
EaseCurveType.OutExpo => OutExpo(from, to, t),
EaseCurveType.InOutExpo => InOutExpo(from, to, t),
EaseCurveType.InCirc => InCirc(from, to, t),
EaseCurveType.OutCirc => OutCirc(from, to, t),
EaseCurveType.InOutCirc => InOutCirc(from, to, t),
EaseCurveType.InBounce => InBounce(from, to, t),
EaseCurveType.OutBounce => OutBounce(from, to, t),
EaseCurveType.InOutBounce => InOutBounce(from, to, t),
EaseCurveType.InElastic => InElastic(from, to, t),
EaseCurveType.OutElastic => OutElastic(from, to, t),
EaseCurveType.InOutElastic => InOutElastic(from, to, t),
EaseCurveType.InBack => InBack(from, to, t),
EaseCurveType.OutBack => OutBack(from, to, t),
EaseCurveType.InOutBack => InOutBack(from, to, t),
_ => throw new NotImplementedException()
};
}
public static float Linear(float from, float to, float t)
{
float c = to - from;
t /= 1f;
return c * t / 1f + from;
}
public static float InQuad(float from, float to, float t)
{
float c = to - from;
t /= 1f;
return c * t * t + from;
}
public static float OutQuad(float from, float to, float t)
{
float c = to - from;
t /= 1f;
return -c * t * (t - 2f) + from;
}
public static float InOutQuad(float from, float to, float t)
{
float c = to - from;
t /= 0.5f;
if (t < 1) return c / 2f * t * t + from;
t--;
return -c / 2f * (t * (t - 2) - 1) + from;
}
public static float InCubic(float from, float to, float t)
{
float c = to - from;
t /= 1f;
return c * t * t * t + from;
}
public static float OutCubic(float from, float to, float t)
{
float c = to - from;
t /= 1f;
t--;
return c * (t * t * t + 1) + from;
}
public static float InOutCubic(float from, float to, float t)
{
float c = to - from;
t /= 0.5f;
if (t < 1) return c / 2f * t * t * t + from;
t -= 2;
return c / 2f * (t * t * t + 2) + from;
}
public static float InQuart(float from, float to, float t)
{
float c = to - from;
t /= 1f;
return c * t * t * t * t + from;
}
public static float OutQuart(float from, float to, float t)
{
float c = to - from;
t /= 1f;
t--;
return -c * (t * t * t * t - 1) + from;
}
public static float InOutQuart(float from, float to, float t)
{
float c = to - from;
t /= 0.5f;
if (t < 1) return c / 2f * t * t * t * t + from;
t -= 2;
return -c / 2f * (t * t * t * t - 2) + from;
}
public static float InQuint(float from, float to, float t)
{
float c = to - from;
t /= 1f;
return c * t * t * t * t * t + from;
}
public static float OutQuint(float from, float to, float t)
{
float c = to - from;
t /= 1f;
t--;
return c * (t * t * t * t * t + 1) + from;
}
public static float InOutQuint(float from, float to, float t)
{
float c = to - from;
t /= 0.5f;
if (t < 1) return c / 2f * t * t * t * t * t + from;
t -= 2;
return c / 2f * (t * t * t * t * t + 2) + from;
}
public static float InSine(float from, float to, float t)
{
float c = to - from;
return -c * Mathf.Cos(t / 1f * (Mathf.PI / 2f)) + c + from;
}
public static float OutSine(float from, float to, float t)
{
float c = to - from;
return c * Mathf.Sin(t / 1f * (Mathf.PI / 2f)) + from;
}
public static float InOutSine(float from, float to, float t)
{
float c = to - from;
return -c / 2f * (Mathf.Cos(Mathf.PI * t / 1f) - 1) + from;
}
public static float InExpo(float from, float to, float t)
{
float c = to - from;
return c * Mathf.Pow(2, 10 * (t / 1f - 1)) + from;
}
public static float OutExpo(float from, float to, float t)
{
float c = to - from;
return c * (-Mathf.Pow(2, -10 * t / 1f) + 1) + from;
}
public static float InOutExpo(float from, float to, float t)
{
float c = to - from;
t /= 0.5f;
if (t < 1f) return c / 2f * Mathf.Pow(2, 10 * (t - 1)) + from;
t--;
return c / 2f * (-Mathf.Pow(2, -10 * t) + 2) + from;
}
public static float InCirc(float from, float to, float t)
{
float c = to - from;
t /= 1f;
return -c * (Mathf.Sqrt(1 - t * t) - 1) + from;
}
public static float OutCirc(float from, float to, float t)
{
float c = to - from;
t /= 1f;
t--;
return c * Mathf.Sqrt(1 - t * t) + from;
}
public static float InOutCirc(float from, float to, float t)
{
float c = to - from;
t /= 0.5f;
if (t < 1) return -c / 2f * (Mathf.Sqrt(1 - t * t) - 1) + from;
t -= 2;
return c / 2f * (Mathf.Sqrt(1 - t * t) + 1) + from;
}
public static float InBounce(float from, float to, float t)
{
float c = to - from;
return c - OutBounce(0f, c, 1f - t) + from; //does this work?
}
public static float OutBounce(float from, float to, float t)
{
float c = to - from;
if ((t /= 1f) < (1 / 2.75f))
{
return c * (7.5625f * t * t) + from;
}
else if (t < (2 / 2.75f))
{
return c * (7.5625f * (t -= (1.5f / 2.75f)) * t + .75f) + from;
}
else if (t < (2.5 / 2.75))
{
return c * (7.5625f * (t -= (2.25f / 2.75f)) * t + .9375f) + from;
}
else
{
return c * (7.5625f * (t -= (2.625f / 2.75f)) * t + .984375f) + from;
}
}
public static float InOutBounce(float from, float to, float t)
{
float c = to - from;
if (t < 0.5f) return InBounce(0, c, t * 2f) * 0.5f + from;
return OutBounce(0, c, t * 2 - 1) * 0.5f + c * 0.5f + from;
}
public static float InElastic(float from, float to, float t)
{
float c = to - from;
if (t == 0) return from;
if ((t /= 1f) == 1) return from + c;
float p = 0.3f;
float s = p / 4f;
return -(c * Mathf.Pow(2, 10 * (t -= 1)) * Mathf.Sin((t - s) * (2 * Mathf.PI) / p)) + from;
}
public static float OutElastic(float from, float to, float t)
{
float c = to - from;
if (t == 0) return from;
if ((t /= 1f) == 1) return from + c;
float p = 0.3f;
float s = p / 4f;
return (c * Mathf.Pow(2, -10 * t) * Mathf.Sin((t - s) * (2 * Mathf.PI) / p) + c + from);
}
public static float InOutElastic(float from, float to, float t)
{
float c = to - from;
if (t == 0) return from;
if ((t /= 0.5f) == 2) return from + c;
float p = 0.3f * 1.5f;
float s = p / 4f;
if (t < 1)
return -0.5f * (c * Mathf.Pow(2, 10 * (t -= 1f)) * Mathf.Sin((t - 2) * (2 * Mathf.PI) / p)) + from;
return c * Mathf.Pow(2, -10 * (t -= 1)) * Mathf.Sin((t - s) * (2f * Mathf.PI) / p) * 0.5f + c + from;
}
public static float InBack(float from, float to, float t)
{
float c = to - from;
float s = 1.70158f;
t /= 0.5f;
return c * t * t * ((s + 1) * t - s) + from;
}
public static float OutBack(float from, float to, float t)
{
float c = to - from;
float s = 1.70158f;
t = t / 1f - 1f;
return c * (t * t * ((s + 1) * t + s) + 1) + from;
}
public static float InOutBack(float from, float to, float t)
{
float c = to - from;
float s = 1.70158f;
t /= 0.5f;
if (t < 1) return c / 2f * (t * t * (((s *= (1.525f)) + 1) * t - s)) + from;
t -= 2;
return c / 2f * (t * t * (((s *= (1.525f)) + 1) * t + s) + 2) + from;
}
#endregion
#region DataFilter
public interface IBaseFilter<_Type>
{
_Type[][] Filtrate(_Type[][] source, int width, int length);
void FiltrateSource(_Type[][] source, int width, int length);
}
public interface ITreeFilter<_Type, _NextFilter> : IBaseFilter<_Type> where _NextFilter : IBaseFilter<_Type>
{
_Type[][] Filtrate(_Type[][] source, int width, int length, _NextFilter next);
}
public abstract class AbstractFilter : IBaseFilter<float>
{
protected abstract void DoFiltrate(float[][] source, float[][] result, int width, int length);
public float[][] Filtrate(float[][] source, int width, int length)
{
float[][] result = new float[width][];
for (int i = 0; i < width; i++)
{
result[i] = new float[length];
}
DoFiltrate(source, result, width, length);
return result;
}
public void FiltrateSource(float[][] source, int width, int length)
{
DoFiltrate(source, source, width, length);
}
}
public abstract class AbstractColorFilter : IBaseFilter<Color>
{
protected abstract void DoFiltrate(Color[][] source, Color[][] result, int width, int length);
public Color[][] Filtrate(Color[][] source, int width, int length)
{
Color[][] result = new Color[width][];
for (int i = 0; i < width; i++)
{
result[i] = new Color[length];
}
DoFiltrate(source, result, width, length);
return result;
}
public void FiltrateSource(Color[][] source, int width, int length)
{
DoFiltrate(source, source, width, length);
}
}
[Serializable]
public class TemplateLimitFilter : AbstractFilter
{
public float min;
public float max;
public float maxEnhance;
public float maxWeakened;
public int bufferSize;
private float[][] buffer;
private int header = 0;
public TemplateLimitFilter(float min, float max, float maxEnhance, float maxWeakened, int bufferSize)
{
this.min = min;
this.max = max;
this.maxEnhance = maxEnhance;
this.maxWeakened = maxWeakened;
this.bufferSize = bufferSize;
}
protected override void DoFiltrate(float[][] source, float[][] result, int width, int length)
{
InitBuffer(source, result, width, length);
for (int i = 0; i < width; i++)
{
ReadLine(source, result, i, width, length);
BuildLine(source, result, i, width, length);
}
ClearBuffer();
}
protected virtual void InitBuffer(float[][] source, float[][] result, int width, int length)
{
buffer ??= new float[bufferSize][];
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] = new float[length];
if (i < width)
for (int j = 0; j < length; j++)
{
buffer[i][j] = source[i][j];
}
}
}
protected virtual void ClearBuffer()
{
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] = null;
}
}
protected virtual void ReadLine(float[][] source, float[][] result, int offset, int width, int length)
{
//Move data to buffer
for (int i = 0, e = length; i < e; i++)
{
buffer[header][i] = source[offset][i];
}
//Push buffer header
header = (header + 1) % bufferSize;
}
protected virtual void BuildLine(float[][] source, float[][] result, int offset, int width, int length)
{
int tempHeader = header;
float[] line = new float[length];
do
{
//Mark data
for (int i = 0; i < length; i++)
{
float value = buffer[tempHeader][i];
int j = (tempHeader - 1) % bufferSize;
if (j < 0)
j = bufferSize + j;
float lastValue = buffer[j][i];
line[i] = Mathf.Clamp(Mathf.Clamp(value, lastValue - maxWeakened, lastValue + maxEnhance), min, max);
}
//Push buffer header
tempHeader = (tempHeader + 1) % bufferSize;
}
while (tempHeader != header);
for (int i = 0; i < length; i++)
{
result[offset][i] = line[i];
}
}
}
[Serializable]
public class TemplateColorLimitFilter : AbstractColorFilter
{
public Color min;
public Color max;
public Color maxEnhance;
public Color maxWeakened;
public TemplateColorLimitFilter(Color min, Color max, Color maxEnhance, Color maxWeakened)
{
this.min = min;
this.max = max;
this.maxEnhance = maxEnhance;
this.maxWeakened = maxWeakened;
}
protected override void DoFiltrate(Color[][] source, Color[][] result, int width, int length)
{
for (int i = 1; i < width; i++)
{
BuildLine(source, result, i, width, length);
}
}
protected virtual void BuildLine(Color[][] source, Color[][] result, int offset, int width, int length)
{
Color[] line = new Color[length];
//Mark data
for (int i = 0; i < length; i++)
{
int j = (offset - 1) % source.Length;
Color value = source[j][i];
Color lastValue = source[offset][i];
line[i] = new(BuildColorR(value, lastValue),
BuildColorG(value, lastValue),
BuildColorB(value, lastValue),
BuildColorA(value, lastValue));
}
for (int i = 0; i < length; i++)
{
result[offset][i] = line[i];
}
}
protected float BuildColorA(Color value, Color lastValue)
{
return Mathf.Clamp(Mathf.Clamp(value.a, lastValue.a - maxWeakened.a, lastValue.a + maxEnhance.a), min.a, max.a);
}
protected float BuildColorR(Color value, Color lastValue)
{
return Mathf.Clamp(Mathf.Clamp(value.r, lastValue.r - maxWeakened.r, lastValue.r + maxEnhance.r), min.r, max.r);
}
protected float BuildColorG(Color value, Color lastValue)
{
return Mathf.Clamp(Mathf.Clamp(value.g, lastValue.g - maxWeakened.g, lastValue.g + maxEnhance.g), min.g, max.g);
}
protected float BuildColorB(Color value, Color lastValue)
{
return Mathf.Clamp(Mathf.Clamp(value.b, lastValue.b - maxWeakened.b, lastValue.b + maxEnhance.b), min.b, max.b);
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 53c6be54f26ac234d9734eee0cd11766
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Convention
{
@@ -54,6 +55,11 @@ namespace Convention
public readonly Func<T, T, int> _comparer_func = null;
public readonly Comparator _comparator = Comparator.less;
public T GetTP(float p)
{
return _elements[(int)(Mathf.Clamp01(p) * _elements.Length)];
}
public int Size => _size;
public int Capacity => _capacity;
public int Count => _size;

View File

@@ -34,7 +34,7 @@ namespace Convention
{
colorKeys = new GradientColorKey[]
{
new GradientColorKey(Color.white, 1),
new GradientColorKey(Color.white, 0),
new GradientColorKey(Color.white, 1)
}
};

View File

@@ -8,27 +8,51 @@ namespace Convention.WindowsUI.Variant
{
[Setting, Range(0, 1), Percentage(0, 1)] public float Speed = 0.36f;
[Resources, OnlyNotNullMode] public RectTransform RectBox;
[Resources, OnlyNotNullMode] public RectTransform RopParent;
[Resources, OnlyNotNullMode] public RectTransform TopParent;
[Resources] public List<RectTransform> Targets = new();
[Content] public int TargetIndex;
[Content, OnlyPlayMode] public RectTransform Target;
public RectTransform Target { get; private set; }
private Stack<ConventionUtility.ActionStepCoroutineWrapper> Tasks = new();
public void SetTargetRectTransform(RectTransform target)
{
Target = target;
if (target == null)
{
Target = null;
RectTransformInfo.UpdateAnimationPlane(TopParent, RectBox, Speed, 0, true);
}
else
{
ConventionUtility.ActionStepCoroutineWrapper task = ConventionUtility.CreateSteps();
task.Next(() =>
{
if (gameObject.activeInHierarchy == false)
RectTransformInfo.UpdateAnimationPlane(TopParent, RectBox, 1, 0, true);
})
.Until(() => target.gameObject.activeInHierarchy == true && Tasks.Peek() == task, () => Target = target)
.Next(() => Tasks.TryPop(out var _))
.Invoke();
Tasks.Push(task);
}
}
public void SelectNextTarget()
{
Debug.Log(TargetIndex);
Target = Targets[TargetIndex = (TargetIndex + 1) % Targets.Count];
}
private void Start()
{
if (TopParent == null)
TopParent = transform.parent as RectTransform;
}
private void LateUpdate()
{
if (Target != null)
RectTransformInfo.UpdateAnimationPlane(Target, RectBox, Speed, 0, true);
else
RectTransformInfo.UpdateAnimationPlane(RopParent, RectBox, Speed, 0, true);
RectTransformInfo.UpdateAnimationPlane(TopParent, RectBox, Speed, 0, true);
}
}
}

View File

@@ -10,6 +10,11 @@ namespace Convention.WindowsUI.Variant
string HierarchyItemTitle { get; }
}
public interface IHierarchyItemClickEventListener
{
void OnHierarchyItemClick(HierarchyItem item);
}
public class HierarchyItem : PropertyListItem
{
[Content, HopeNotNull] public object m_target;
@@ -43,7 +48,7 @@ namespace Convention.WindowsUI.Variant
}
private void OnDestroy()
{
if (InspectorWindow.instance.GetTarget() == target)
if (InspectorWindow.instance != null && InspectorWindow.instance.GetTarget() == target)
{
InspectorWindow.instance.ClearWindow();
}
@@ -64,11 +69,17 @@ namespace Convention.WindowsUI.Variant
[Content]
public void OnFocusHierarchyItem()
{
if (target == null)
if (target != null)
{
throw new InvalidOperationException("target is null");
if (InspectorWindow.instance != null)
{
InspectorWindow.instance.SetTarget(target, this);
}
if(target is IHierarchyItemClickEventListener listener)
{
listener.OnHierarchyItemClick(this);
}
}
InspectorWindow.instance.SetTarget(target, this);
if (!IsEnableFocusWindow)
return;
if (FocusWindowIndictaor.instance != null)

View File

@@ -15,7 +15,7 @@ namespace Convention.WindowsUI.Variant
private Dictionary<object, HierarchyItem> AllReferenceItemLinker = new();
/// <summary>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>tab
///
/// </summary>
/// <param name="reference"></param>
/// <param name="item"></param>
@@ -125,6 +125,25 @@ namespace Convention.WindowsUI.Variant
});
}
}
public void MakeFocusOn(HierarchyItem target)
{
static void BFS(HierarchyItem t)
{
var next = t.Entry.GetParent();
if (next != null)
{
BFS(next.GetHierarchyItem());
next.GetHierarchyItem().IsFold = false;
}
}
BFS(target);
if (FocusWindowIndictaor.instance != null)
{
FocusWindowIndictaor.instance.SetTargetRectTransform(target.TextRectTransform);
}
}
}
}

View File

@@ -22,17 +22,35 @@ namespace Convention.WindowsUI.Variant
public BaseWindowBar.RegisteredPageWrapper GameWindowIndex { get; private set; }
public bool IsSelectSceneCamera { get; private set; }
public void CameraSelect(bool isScene)
{
SceneCamera.gameObject.SetActive(isScene);
ModuleCamera.gameObject.SetActive(!isScene);
if (m_GameObjectOnSceneOnly != null)
if (ModuleCamera == null)
{
m_GameObjectOnSceneOnly.SetActive(isScene);
IsSelectSceneCamera = true;
SceneCamera.gameObject.SetActive(true);
m_GameObjectOnSceneOnly.SetActive(true);
}
else
{
IsSelectSceneCamera = isScene;
SceneCamera.gameObject.SetActive(isScene);
ModuleCamera.gameObject.SetActive(!isScene);
if (m_GameObjectOnSceneOnly != null)
{
m_GameObjectOnSceneOnly.SetActive(isScene);
}
}
}
private void Update()
{
if(IsSelectSceneCamera==false&& ModuleCamera==null)
{
CameraSelect(true);
}
}
private void Start()
{
@@ -40,7 +58,7 @@ namespace Convention.WindowsUI.Variant
{
m_WindowManager = GetComponent<WindowManager>();
}
if(MainCamera==null)
if (MainCamera == null)
{
MainCamera = Camera.main.GetComponent<CinemachineBrain>();
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Convention.Internal;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
@@ -289,36 +290,9 @@ namespace Convention.WindowsUI.Variant
{
if (ref_value != null)
{
ConventionUtility.StartCoroutine(Adjuster(ref_value.transform as RectTransform));
}
if (parentWindow)
{
ConventionUtility.StartCoroutine(Adjuster(parentWindow.TargetWindowContent));
}
else
{
ConventionUtility.StartCoroutine(Adjuster2(parentEntry.ref_value.transform as RectTransform, parentEntry));
}
static IEnumerator Adjuster(RectTransform rectTransform)
{
if (rectTransform == null)
yield break;
LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform);
yield return null;
if (rectTransform == null)
yield break;
RectTransformExtension.AdjustSizeToContainsChilds(rectTransform);
}
static IEnumerator Adjuster2(RectTransform rectTransform, ItemEntry parentEntry)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform);
yield return null;
RectTransformExtension.AdjustSizeToContainsChilds(rectTransform);
yield return null;
parentEntry.ForceRebuildLayoutImmediate();
yield break;
RectTransformExtension.AdjustSizeToContainsChilds(ref_value.transform as RectTransform);
if (parentEntry != null)
parentEntry.ForceRebuildLayoutImmediate();
}
}
@@ -364,6 +338,8 @@ namespace Convention.WindowsUI.Variant
ForceRebuildLayoutImmediate();
}
public bool IsRemovingChilds { get; private set; } = false;
public void Release()
{
if ((parentWindow == null && parentEntry == null) || childs == null || rootWindow == null)
@@ -376,21 +352,18 @@ namespace Convention.WindowsUI.Variant
ref_value.gameObject.SetActive(false);
Destroy(ref_value.gameObject);
}
IsRemovingChilds = true;
foreach (var item in childs)
{
item.Release();
}
IsRemovingChilds = false;
if (parentWindow != null)
parentWindow.m_Entrys.Remove(this);
else
else if (GetParent().IsRemovingChilds == false)
parentEntry.childs.Remove(this);
ref_value = null;
}
~ItemEntry()
{
Release();
}
}
public interface IItemEntry
{

View File

@@ -9,9 +9,11 @@ namespace Convention.WindowsUI.Variant
{
public class PropertyListItem : WindowUIModule, ITitle, IText, IItemEntry, IActionInvoke
{
[Resources, SerializeField, OnlyNotNullMode] private Button m_rawButton;
[Resources, SerializeField, OnlyNotNullMode(nameof(m_rawButton))] private float layerTab = 7.5f;
[Resources, SerializeField, OnlyNotNullMode(nameof(m_rawButton))] private float layerHeight = 15f;
[Resources, SerializeField] private Button m_rawButton;
[Resources, SerializeField] private ModernUIButton m_modernButton;
public GameObject ButtonGameObject => m_rawButton == null ? m_modernButton.gameObject : m_rawButton.gameObject;
[Resources, SerializeField] private float layerTab = 7.5f;
[Resources, SerializeField] private float layerHeight = 15f;
[Resources, SerializeField, OnlyNotNullMode] private RectTransform dropdownImage;
[Resources, SerializeField, OnlyNotNullMode] private Text m_buttonText;
[Resources, SerializeField, OnlyNotNullMode, Header("Self Layer")] private RectTransform m_Layer;
@@ -44,10 +46,13 @@ namespace Convention.WindowsUI.Variant
protected virtual void Start()
{
m_rawButton.gameObject.AddComponent<RectTransformExtension.AdjustSizeIgnore>();
ButtonGameObject.AddComponent<RectTransformExtension.AdjustSizeIgnore>();
dropdownImage.gameObject.AddComponent<RectTransformExtension.AdjustSizeIgnore>();
m_buttonText.gameObject.AddComponent<RectTransformExtension.AdjustSizeIgnore>();
m_rawButton.onClick.AddListener(Switch);
if (m_rawButton != null)
m_rawButton.onClick.AddListener(Switch);
else
m_modernButton.AddListener(Switch);
TextRectTransform = m_buttonText.GetComponent<RectTransform>();
dropdownImage.eulerAngles = new(0, 0, IsFold ? 90 : 0);
}
@@ -79,7 +84,23 @@ namespace Convention.WindowsUI.Variant
public virtual string title { get => m_buttonText.title; set => m_buttonText.title = value; }
public virtual string text { get => m_buttonText.text; set => m_buttonText.text = value; }
public virtual bool interactable { get => m_rawButton.interactable; set => m_rawButton.interactable = value; }
public virtual bool interactable
{
get
{
if (m_rawButton != null)
return m_rawButton.interactable;
else
return m_modernButton.interactable;
}
set
{
if (m_rawButton != null)
m_rawButton.interactable = value;
else
m_modernButton.interactable = value;
}
}
public void Switch()
{
@@ -134,7 +155,10 @@ namespace Convention.WindowsUI.Variant
{
foreach (var item in action)
{
m_rawButton.onClick.AddListener(item);
if (m_rawButton != null)
m_rawButton.onClick.AddListener(item);
else
m_modernButton.AddListener(item);
}
return this;
}
@@ -143,14 +167,20 @@ namespace Convention.WindowsUI.Variant
{
foreach (var item in action)
{
m_rawButton.onClick.RemoveListener(item);
if (m_rawButton != null)
m_rawButton.onClick.RemoveListener(item);
else
m_modernButton.RemoveListener(item);
}
return this;
}
public IActionInvoke RemoveAllListeners()
{
m_rawButton.onClick.RemoveAllListeners();
if (m_rawButton != null)
m_rawButton.onClick.RemoveAllListeners();
else
m_modernButton.RemoveAllListeners();
return this;
}
}

View File

@@ -84,8 +84,8 @@ namespace Convention.WindowsUI.Variant
{
target.CreateItem(() =>
{
action.callback(rightTop);
ReleaseAllCustomMenu();
action.callback(rightTop);
}, action.name);
}
CustomMenuRelease.gameObject.SetActive(true);

View File

@@ -91,7 +91,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
Speed: 0.32
RectBox: {fileID: 6272003121708756342}
RopParent: {fileID: 8773560469810817739}
TopParent: {fileID: 0}
Targets:
- {fileID: 0}
- {fileID: 7709311530016948315}
@@ -100,7 +100,6 @@ MonoBehaviour:
- {fileID: 2403051311178796671}
- {fileID: 5377214671440830306}
TargetIndex: 0
Target: {fileID: 0}
--- !u!114 &7462675906960032546
MonoBehaviour:
m_ObjectHideFlags: 0