You've already forked UniversalViewer
Initial files
This commit is contained in:
32
Assets/Scripts/AnimatorLooper.cs
Normal file
32
Assets/Scripts/AnimatorLooper.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class AnimatorLooper : MonoBehaviour
|
||||
{
|
||||
Animator anim;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
anim = GetComponentInChildren<Animator>();
|
||||
if(anim == null)
|
||||
{
|
||||
Destroy(this.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if(anim.GetCurrentAnimatorStateInfo(0).normalizedTime > 1)
|
||||
{
|
||||
anim.Play(anim.GetCurrentAnimatorStateInfo(0).fullPathHash, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void Toggle()
|
||||
{
|
||||
anim.speed = anim.speed == 1 ? 0 : 1;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/AnimatorLooper.cs.meta
Normal file
11
Assets/Scripts/AnimatorLooper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f06980719b3d51b43bb365c57b1a3fe2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/DragAndDrop.meta
Normal file
8
Assets/Scripts/DragAndDrop.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f18cf0e034e5eb342acef3516eab219b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
492
Assets/Scripts/DragAndDrop/B83.Win32.cs
Normal file
492
Assets/Scripts/DragAndDrop/B83.Win32.cs
Normal file
@@ -0,0 +1,492 @@
|
||||
/* * * * *
|
||||
* This is a collection of Win API helpers. Mainly dealing with window message hooks
|
||||
* and file drag&drop support for Windows standalone Unity applications.
|
||||
*
|
||||
* 2019.11.28 - Changed the "UnityDragAndDropHook" class to a static class. This
|
||||
* has been done for IL2CPP support. IL2CPP can not marshall instance method
|
||||
* callbacks passed to native code. So the callbacks must be static methods.
|
||||
* Therefore all fields involved also need to be static.
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Markus Göbel (Bunny83)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* * * * */
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace B83.Win32
|
||||
{
|
||||
public enum HookType : int
|
||||
{
|
||||
WH_JOURNALRECORD = 0,
|
||||
WH_JOURNALPLAYBACK = 1,
|
||||
WH_KEYBOARD = 2,
|
||||
WH_GETMESSAGE = 3,
|
||||
WH_CALLWNDPROC = 4,
|
||||
WH_CBT = 5,
|
||||
WH_SYSMSGFILTER = 6,
|
||||
WH_MOUSE = 7,
|
||||
WH_HARDWARE = 8,
|
||||
WH_DEBUG = 9,
|
||||
WH_SHELL = 10,
|
||||
WH_FOREGROUNDIDLE = 11,
|
||||
WH_CALLWNDPROCRET = 12,
|
||||
WH_KEYBOARD_LL = 13,
|
||||
WH_MOUSE_LL = 14
|
||||
}
|
||||
|
||||
// windows messages
|
||||
public enum WM : uint
|
||||
{
|
||||
NULL = 0x0000,
|
||||
CREATE = 0x0001,
|
||||
DESTROY = 0x0002,
|
||||
MOVE = 0x0003,
|
||||
SIZE = 0x0005,
|
||||
ACTIVATE = 0x0006,
|
||||
SETFOCUS = 0x0007,
|
||||
KILLFOCUS = 0x0008,
|
||||
ENABLE = 0x000A,
|
||||
SETREDRAW = 0x000B,
|
||||
SETTEXT = 0x000C,
|
||||
GETTEXT = 0x000D,
|
||||
GETTEXTLENGTH = 0x000E,
|
||||
PAINT = 0x000F,
|
||||
CLOSE = 0x0010,
|
||||
QUERYENDSESSION = 0x0011,
|
||||
QUERYOPEN = 0x0013,
|
||||
ENDSESSION = 0x0016,
|
||||
QUIT = 0x0012,
|
||||
ERASEBKGND = 0x0014,
|
||||
SYSCOLORCHANGE = 0x0015,
|
||||
SHOWWINDOW = 0x0018,
|
||||
WININICHANGE = 0x001A,
|
||||
SETTINGCHANGE = WININICHANGE,
|
||||
DEVMODECHANGE = 0x001B,
|
||||
ACTIVATEAPP = 0x001C,
|
||||
FONTCHANGE = 0x001D,
|
||||
TIMECHANGE = 0x001E,
|
||||
CANCELMODE = 0x001F,
|
||||
SETCURSOR = 0x0020,
|
||||
MOUSEACTIVATE = 0x0021,
|
||||
CHILDACTIVATE = 0x0022,
|
||||
QUEUESYNC = 0x0023,
|
||||
GETMINMAXINFO = 0x0024,
|
||||
PAINTICON = 0x0026,
|
||||
ICONERASEBKGND = 0x0027,
|
||||
NEXTDLGCTL = 0x0028,
|
||||
SPOOLERSTATUS = 0x002A,
|
||||
DRAWITEM = 0x002B,
|
||||
MEASUREITEM = 0x002C,
|
||||
DELETEITEM = 0x002D,
|
||||
VKEYTOITEM = 0x002E,
|
||||
CHARTOITEM = 0x002F,
|
||||
SETFONT = 0x0030,
|
||||
GETFONT = 0x0031,
|
||||
SETHOTKEY = 0x0032,
|
||||
GETHOTKEY = 0x0033,
|
||||
QUERYDRAGICON = 0x0037,
|
||||
COMPAREITEM = 0x0039,
|
||||
GETOBJECT = 0x003D,
|
||||
COMPACTING = 0x0041,
|
||||
[Obsolete]
|
||||
COMMNOTIFY = 0x0044,
|
||||
WINDOWPOSCHANGING = 0x0046,
|
||||
WINDOWPOSCHANGED = 0x0047,
|
||||
[Obsolete]
|
||||
POWER = 0x0048,
|
||||
COPYDATA = 0x004A,
|
||||
CANCELJOURNAL = 0x004B,
|
||||
NOTIFY = 0x004E,
|
||||
INPUTLANGCHANGEREQUEST = 0x0050,
|
||||
INPUTLANGCHANGE = 0x0051,
|
||||
TCARD = 0x0052,
|
||||
HELP = 0x0053,
|
||||
USERCHANGED = 0x0054,
|
||||
NOTIFYFORMAT = 0x0055,
|
||||
CONTEXTMENU = 0x007B,
|
||||
STYLECHANGING = 0x007C,
|
||||
STYLECHANGED = 0x007D,
|
||||
DISPLAYCHANGE = 0x007E,
|
||||
GETICON = 0x007F,
|
||||
SETICON = 0x0080,
|
||||
NCCREATE = 0x0081,
|
||||
NCDESTROY = 0x0082,
|
||||
NCCALCSIZE = 0x0083,
|
||||
NCHITTEST = 0x0084,
|
||||
NCPAINT = 0x0085,
|
||||
NCACTIVATE = 0x0086,
|
||||
GETDLGCODE = 0x0087,
|
||||
SYNCPAINT = 0x0088,
|
||||
NCMOUSEMOVE = 0x00A0,
|
||||
NCLBUTTONDOWN = 0x00A1,
|
||||
NCLBUTTONUP = 0x00A2,
|
||||
NCLBUTTONDBLCLK = 0x00A3,
|
||||
NCRBUTTONDOWN = 0x00A4,
|
||||
NCRBUTTONUP = 0x00A5,
|
||||
NCRBUTTONDBLCLK = 0x00A6,
|
||||
NCMBUTTONDOWN = 0x00A7,
|
||||
NCMBUTTONUP = 0x00A8,
|
||||
NCMBUTTONDBLCLK = 0x00A9,
|
||||
NCXBUTTONDOWN = 0x00AB,
|
||||
NCXBUTTONUP = 0x00AC,
|
||||
NCXBUTTONDBLCLK = 0x00AD,
|
||||
INPUT_DEVICE_CHANGE = 0x00FE,
|
||||
INPUT = 0x00FF,
|
||||
KEYFIRST = 0x0100,
|
||||
KEYDOWN = 0x0100,
|
||||
KEYUP = 0x0101,
|
||||
CHAR = 0x0102,
|
||||
DEADCHAR = 0x0103,
|
||||
SYSKEYDOWN = 0x0104,
|
||||
SYSKEYUP = 0x0105,
|
||||
SYSCHAR = 0x0106,
|
||||
SYSDEADCHAR = 0x0107,
|
||||
UNICHAR = 0x0109,
|
||||
KEYLAST = 0x0108,
|
||||
IME_STARTCOMPOSITION = 0x010D,
|
||||
IME_ENDCOMPOSITION = 0x010E,
|
||||
IME_COMPOSITION = 0x010F,
|
||||
IME_KEYLAST = 0x010F,
|
||||
INITDIALOG = 0x0110,
|
||||
COMMAND = 0x0111,
|
||||
SYSCOMMAND = 0x0112,
|
||||
TIMER = 0x0113,
|
||||
HSCROLL = 0x0114,
|
||||
VSCROLL = 0x0115,
|
||||
INITMENU = 0x0116,
|
||||
INITMENUPOPUP = 0x0117,
|
||||
MENUSELECT = 0x011F,
|
||||
MENUCHAR = 0x0120,
|
||||
ENTERIDLE = 0x0121,
|
||||
MENURBUTTONUP = 0x0122,
|
||||
MENUDRAG = 0x0123,
|
||||
MENUGETOBJECT = 0x0124,
|
||||
UNINITMENUPOPUP = 0x0125,
|
||||
MENUCOMMAND = 0x0126,
|
||||
CHANGEUISTATE = 0x0127,
|
||||
UPDATEUISTATE = 0x0128,
|
||||
QUERYUISTATE = 0x0129,
|
||||
CTLCOLORMSGBOX = 0x0132,
|
||||
CTLCOLOREDIT = 0x0133,
|
||||
CTLCOLORLISTBOX = 0x0134,
|
||||
CTLCOLORBTN = 0x0135,
|
||||
CTLCOLORDLG = 0x0136,
|
||||
CTLCOLORSCROLLBAR = 0x0137,
|
||||
CTLCOLORSTATIC = 0x0138,
|
||||
MOUSEFIRST = 0x0200,
|
||||
MOUSEMOVE = 0x0200,
|
||||
LBUTTONDOWN = 0x0201,
|
||||
LBUTTONUP = 0x0202,
|
||||
LBUTTONDBLCLK = 0x0203,
|
||||
RBUTTONDOWN = 0x0204,
|
||||
RBUTTONUP = 0x0205,
|
||||
RBUTTONDBLCLK = 0x0206,
|
||||
MBUTTONDOWN = 0x0207,
|
||||
MBUTTONUP = 0x0208,
|
||||
MBUTTONDBLCLK = 0x0209,
|
||||
MOUSEWHEEL = 0x020A,
|
||||
XBUTTONDOWN = 0x020B,
|
||||
XBUTTONUP = 0x020C,
|
||||
XBUTTONDBLCLK = 0x020D,
|
||||
MOUSEHWHEEL = 0x020E,
|
||||
MOUSELAST = 0x020E,
|
||||
PARENTNOTIFY = 0x0210,
|
||||
ENTERMENULOOP = 0x0211,
|
||||
EXITMENULOOP = 0x0212,
|
||||
NEXTMENU = 0x0213,
|
||||
SIZING = 0x0214,
|
||||
CAPTURECHANGED = 0x0215,
|
||||
MOVING = 0x0216,
|
||||
POWERBROADCAST = 0x0218,
|
||||
DEVICECHANGE = 0x0219,
|
||||
MDICREATE = 0x0220,
|
||||
MDIDESTROY = 0x0221,
|
||||
MDIACTIVATE = 0x0222,
|
||||
MDIRESTORE = 0x0223,
|
||||
MDINEXT = 0x0224,
|
||||
MDIMAXIMIZE = 0x0225,
|
||||
MDITILE = 0x0226,
|
||||
MDICASCADE = 0x0227,
|
||||
MDIICONARRANGE = 0x0228,
|
||||
MDIGETACTIVE = 0x0229,
|
||||
MDISETMENU = 0x0230,
|
||||
ENTERSIZEMOVE = 0x0231,
|
||||
EXITSIZEMOVE = 0x0232,
|
||||
DROPFILES = 0x0233,
|
||||
MDIREFRESHMENU = 0x0234,
|
||||
IME_SETCONTEXT = 0x0281,
|
||||
IME_NOTIFY = 0x0282,
|
||||
IME_CONTROL = 0x0283,
|
||||
IME_COMPOSITIONFULL = 0x0284,
|
||||
IME_SELECT = 0x0285,
|
||||
IME_CHAR = 0x0286,
|
||||
IME_REQUEST = 0x0288,
|
||||
IME_KEYDOWN = 0x0290,
|
||||
IME_KEYUP = 0x0291,
|
||||
MOUSEHOVER = 0x02A1,
|
||||
MOUSELEAVE = 0x02A3,
|
||||
NCMOUSEHOVER = 0x02A0,
|
||||
NCMOUSELEAVE = 0x02A2,
|
||||
WTSSESSION_CHANGE = 0x02B1,
|
||||
TABLET_FIRST = 0x02c0,
|
||||
TABLET_LAST = 0x02df,
|
||||
CUT = 0x0300,
|
||||
COPY = 0x0301,
|
||||
PASTE = 0x0302,
|
||||
CLEAR = 0x0303,
|
||||
UNDO = 0x0304,
|
||||
RENDERFORMAT = 0x0305,
|
||||
RENDERALLFORMATS = 0x0306,
|
||||
DESTROYCLIPBOARD = 0x0307,
|
||||
DRAWCLIPBOARD = 0x0308,
|
||||
PAINTCLIPBOARD = 0x0309,
|
||||
VSCROLLCLIPBOARD = 0x030A,
|
||||
SIZECLIPBOARD = 0x030B,
|
||||
ASKCBFORMATNAME = 0x030C,
|
||||
CHANGECBCHAIN = 0x030D,
|
||||
HSCROLLCLIPBOARD = 0x030E,
|
||||
QUERYNEWPALETTE = 0x030F,
|
||||
PALETTEISCHANGING = 0x0310,
|
||||
PALETTECHANGED = 0x0311,
|
||||
HOTKEY = 0x0312,
|
||||
PRINT = 0x0317,
|
||||
PRINTCLIENT = 0x0318,
|
||||
APPCOMMAND = 0x0319,
|
||||
THEMECHANGED = 0x031A,
|
||||
CLIPBOARDUPDATE = 0x031D,
|
||||
DWMCOMPOSITIONCHANGED = 0x031E,
|
||||
DWMNCRENDERINGCHANGED = 0x031F,
|
||||
DWMCOLORIZATIONCOLORCHANGED = 0x0320,
|
||||
DWMWINDOWMAXIMIZEDCHANGE = 0x0321,
|
||||
GETTITLEBARINFOEX = 0x033F,
|
||||
HANDHELDFIRST = 0x0358,
|
||||
HANDHELDLAST = 0x035F,
|
||||
AFXFIRST = 0x0360,
|
||||
AFXLAST = 0x037F,
|
||||
PENWINFIRST = 0x0380,
|
||||
PENWINLAST = 0x038F,
|
||||
APP = 0x8000,
|
||||
USER = 0x0400,
|
||||
CPL_LAUNCH = USER + 0x1000,
|
||||
CPL_LAUNCHED = USER + 0x1001,
|
||||
SYSTIMER = 0x118,
|
||||
}
|
||||
|
||||
// WH_CALLWNDPROC
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct CWPSTRUCT
|
||||
{
|
||||
public IntPtr lParam;
|
||||
public IntPtr wParam;
|
||||
public WM message;
|
||||
public IntPtr hwnd;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINT
|
||||
{
|
||||
public int x, y;
|
||||
public POINT(int aX, int aY)
|
||||
{
|
||||
x = aX;
|
||||
y = aY;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return "(" + x + ", " + y + ")";
|
||||
}
|
||||
}
|
||||
|
||||
//WH_GETMESSAGE
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct MSG
|
||||
{
|
||||
public IntPtr hwnd;
|
||||
public WM message;
|
||||
public IntPtr wParam;
|
||||
public IntPtr lParam;
|
||||
public ushort time;
|
||||
public POINT pt;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
public int Left, Top, Right, Bottom;
|
||||
|
||||
public RECT(int left, int top, int right, int bottom)
|
||||
{
|
||||
Left = left;
|
||||
Top = top;
|
||||
Right = right;
|
||||
Bottom = bottom;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return "(" + Left + ", " + Top + ", " + Right + ", " + Bottom + ")";
|
||||
}
|
||||
}
|
||||
|
||||
public delegate IntPtr HookProc(int code, IntPtr wParam, ref MSG lParam);
|
||||
public delegate bool EnumThreadDelegate(IntPtr Hwnd, IntPtr lParam);
|
||||
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
|
||||
public static class Window
|
||||
{
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool EnumThreadWindows(uint dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool IsWindowVisible(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
static extern int GetClassName(IntPtr hWnd, System.Text.StringBuilder lpClassName, int nMaxCount);
|
||||
public static string GetClassName(IntPtr hWnd)
|
||||
{
|
||||
var sb = new System.Text.StringBuilder(256);
|
||||
int count = GetClassName(hWnd, sb, 256);
|
||||
return sb.ToString(0, count);
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
static extern int GetWindowTextLength(IntPtr hWnd);
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder lpString, int nMaxCount);
|
||||
public static string GetWindowText(IntPtr hWnd)
|
||||
{
|
||||
int length = GetWindowTextLength(hWnd) + 2;
|
||||
var sb = new System.Text.StringBuilder(length);
|
||||
int count = GetWindowText(hWnd, sb, length);
|
||||
return sb.ToString(0, count);
|
||||
}
|
||||
}
|
||||
|
||||
public static class WinAPI
|
||||
{
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern uint GetCurrentThreadId();
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern IntPtr SetWindowsHookEx(HookType hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId);
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, ref MSG lParam);
|
||||
|
||||
[DllImport("shell32.dll")]
|
||||
public static extern void DragAcceptFiles(IntPtr hwnd, bool fAccept);
|
||||
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern uint DragQueryFile(IntPtr hDrop, uint iFile, System.Text.StringBuilder lpszFile, uint cch);
|
||||
[DllImport("shell32.dll")]
|
||||
public static extern void DragFinish(IntPtr hDrop);
|
||||
|
||||
[DllImport("shell32.dll")]
|
||||
public static extern void DragQueryPoint(IntPtr hDrop, out POINT pos);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
public static class UnityDragAndDropHook
|
||||
{
|
||||
public delegate void DroppedFilesEvent(List<string> aPathNames, POINT aDropPoint);
|
||||
public static event DroppedFilesEvent OnDroppedFiles;
|
||||
|
||||
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN
|
||||
|
||||
private static uint threadId;
|
||||
private static IntPtr mainWindow = IntPtr.Zero;
|
||||
private static IntPtr m_Hook;
|
||||
private static string m_ClassName = "UnityWndClass";
|
||||
|
||||
// attribute required for IL2CPP, also has to be a static method
|
||||
[AOT.MonoPInvokeCallback(typeof(EnumThreadDelegate))]
|
||||
private static bool EnumCallback(IntPtr W, IntPtr _)
|
||||
{
|
||||
if (Window.IsWindowVisible(W) && (mainWindow == IntPtr.Zero || (m_ClassName != null && Window.GetClassName(W) == m_ClassName)))
|
||||
{
|
||||
mainWindow = W;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void InstallHook()
|
||||
{
|
||||
threadId = WinAPI.GetCurrentThreadId();
|
||||
if (threadId > 0)
|
||||
Window.EnumThreadWindows(threadId, EnumCallback, IntPtr.Zero);
|
||||
|
||||
var hModule = WinAPI.GetModuleHandle(null);
|
||||
m_Hook = WinAPI.SetWindowsHookEx(HookType.WH_GETMESSAGE, Callback, hModule, threadId);
|
||||
// Allow dragging of files onto the main window. generates the WM_DROPFILES message
|
||||
WinAPI.DragAcceptFiles(mainWindow, true);
|
||||
}
|
||||
public static void UninstallHook()
|
||||
{
|
||||
WinAPI.UnhookWindowsHookEx(m_Hook);
|
||||
WinAPI.DragAcceptFiles(mainWindow, false);
|
||||
m_Hook = IntPtr.Zero;
|
||||
}
|
||||
|
||||
// attribute required for IL2CPP, also has to be a static method
|
||||
[AOT.MonoPInvokeCallback(typeof(HookProc))]
|
||||
private static IntPtr Callback(int code, IntPtr wParam, ref MSG lParam)
|
||||
{
|
||||
if (code == 0 && lParam.message == WM.DROPFILES)
|
||||
{
|
||||
POINT pos;
|
||||
WinAPI.DragQueryPoint(lParam.wParam, out pos);
|
||||
|
||||
// 0xFFFFFFFF as index makes the method return the number of files
|
||||
uint n = WinAPI.DragQueryFile(lParam.wParam, 0xFFFFFFFF, null, 0);
|
||||
var sb = new System.Text.StringBuilder(1024);
|
||||
|
||||
List<string> result = new List<string>();
|
||||
for (uint i = 0; i < n; i++)
|
||||
{
|
||||
int len = (int)WinAPI.DragQueryFile(lParam.wParam, i, sb, 1024);
|
||||
result.Add(sb.ToString(0, len));
|
||||
sb.Length = 0;
|
||||
}
|
||||
WinAPI.DragFinish(lParam.wParam);
|
||||
if (OnDroppedFiles != null)
|
||||
OnDroppedFiles(result, pos);
|
||||
}
|
||||
return WinAPI.CallNextHookEx(m_Hook, code, wParam, ref lParam);
|
||||
}
|
||||
#else
|
||||
public static void InstallHook()
|
||||
{
|
||||
}
|
||||
public static void UninstallHook()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/DragAndDrop/B83.Win32.cs.meta
Normal file
11
Assets/Scripts/DragAndDrop/B83.Win32.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5182a63499ffa6c449a1c6f4bb475410
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
50
Assets/Scripts/DragAndDrop/FileDragAndDrop.cs
Normal file
50
Assets/Scripts/DragAndDrop/FileDragAndDrop.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using B83.Win32;
|
||||
|
||||
|
||||
public class FileDragAndDrop : MonoBehaviour
|
||||
{
|
||||
List<string> log = new List<string>();
|
||||
void OnEnable ()
|
||||
{
|
||||
// must be installed on the main thread to get the right thread id.
|
||||
UnityDragAndDropHook.InstallHook();
|
||||
UnityDragAndDropHook.OnDroppedFiles += OnFiles;
|
||||
}
|
||||
void OnDisable()
|
||||
{
|
||||
UnityDragAndDropHook.UninstallHook();
|
||||
}
|
||||
|
||||
void OnFiles(List<string> aFiles, POINT aPos)
|
||||
{
|
||||
string file = "";
|
||||
// scan through dropped files and filter out supported image types
|
||||
foreach (var f in aFiles)
|
||||
{
|
||||
var fi = new System.IO.FileInfo(f);
|
||||
var ext = fi.Extension.ToLower();
|
||||
if (ext == ".png" || ext == ".jpg" || ext == ".jpeg")
|
||||
{
|
||||
file = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If the user dropped a supported file, create a DropInfo
|
||||
if (file != "")
|
||||
{
|
||||
var data = System.IO.File.ReadAllBytes(file);
|
||||
var tex = new Texture2D(1, 1);
|
||||
tex.LoadImage(data);
|
||||
tex.name = new System.IO.FileInfo(file).Name;
|
||||
Error.Log(Color.green, "Loading file " + tex.name);
|
||||
Error.Log(Color.green, "Not implemented!");
|
||||
//ModelViewerMain.GetInstance().Builder.SpawnReference(tex);
|
||||
}
|
||||
else
|
||||
{
|
||||
Error.Log(Color.yellow, "Dropped file is not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/DragAndDrop/FileDragAndDrop.cs.meta
Normal file
11
Assets/Scripts/DragAndDrop/FileDragAndDrop.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3fe1a8c3947c1343b441d0b26c74dcd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
100
Assets/Scripts/DragAndDrop/ImageExample.cs
Normal file
100
Assets/Scripts/DragAndDrop/ImageExample.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
using B83.Win32;
|
||||
|
||||
|
||||
public class ImageExample : MonoBehaviour
|
||||
{
|
||||
Texture2D[] textures = new Texture2D[6];
|
||||
DropInfo dropInfo = null;
|
||||
class DropInfo
|
||||
{
|
||||
public string file;
|
||||
public Vector2 pos;
|
||||
}
|
||||
void OnEnable ()
|
||||
{
|
||||
UnityDragAndDropHook.InstallHook();
|
||||
UnityDragAndDropHook.OnDroppedFiles += OnFiles;
|
||||
|
||||
}
|
||||
void OnDisable()
|
||||
{
|
||||
UnityDragAndDropHook.UninstallHook();
|
||||
}
|
||||
|
||||
void OnFiles(List<string> aFiles, POINT aPos)
|
||||
{
|
||||
string file = "";
|
||||
// scan through dropped files and filter out supported image types
|
||||
foreach(var f in aFiles)
|
||||
{
|
||||
var fi = new System.IO.FileInfo(f);
|
||||
var ext = fi.Extension.ToLower();
|
||||
if (ext == ".png" || ext == ".jpg" || ext == ".jpeg")
|
||||
{
|
||||
file = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If the user dropped a supported file, create a DropInfo
|
||||
if (file != "")
|
||||
{
|
||||
var info = new DropInfo
|
||||
{
|
||||
file = file,
|
||||
pos = new Vector2(aPos.x, aPos.y)
|
||||
};
|
||||
dropInfo = info;
|
||||
}
|
||||
}
|
||||
|
||||
void LoadImage(int aIndex, DropInfo aInfo)
|
||||
{
|
||||
if (aInfo == null)
|
||||
return;
|
||||
// get the GUI rect of the last Label / box
|
||||
var rect = GUILayoutUtility.GetLastRect();
|
||||
// check if the drop position is inside that rect
|
||||
if (rect.Contains(aInfo.pos))
|
||||
{
|
||||
var data = System.IO.File.ReadAllBytes(aInfo.file);
|
||||
var tex = new Texture2D(1,1);
|
||||
tex.LoadImage(data);
|
||||
if (textures[aIndex] != null)
|
||||
Destroy(textures[aIndex]);
|
||||
textures[aIndex] = tex;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
DropInfo tmp = null;
|
||||
if (Event.current.type == EventType.Repaint && dropInfo!= null)
|
||||
{
|
||||
tmp = dropInfo;
|
||||
dropInfo = null;
|
||||
}
|
||||
GUILayout.BeginHorizontal();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (textures[i] != null)
|
||||
GUILayout.Label(textures[i], GUILayout.Width(200), GUILayout.Height(200));
|
||||
else
|
||||
GUILayout.Box("Drag image here", GUILayout.Width(200), GUILayout.Height(200));
|
||||
LoadImage(i, tmp);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.BeginHorizontal();
|
||||
for (int i = 3; i < 6; i++)
|
||||
{
|
||||
if (textures[i] != null)
|
||||
GUILayout.Label(textures[i], GUILayout.Width(200), GUILayout.Height(200));
|
||||
else
|
||||
GUILayout.Box("Drag image here", GUILayout.Width(200), GUILayout.Height(200));
|
||||
LoadImage(i, tmp);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/DragAndDrop/ImageExample.cs.meta
Normal file
11
Assets/Scripts/DragAndDrop/ImageExample.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: abe7df44ab19a9b46a506ce5cc1efcf4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
32
Assets/Scripts/FestiveMode.cs
Normal file
32
Assets/Scripts/FestiveMode.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class FestiveMode : MonoBehaviour
|
||||
{
|
||||
public Button DefaultButton;
|
||||
bool _birthday = false;
|
||||
public Button BirthdayButton;
|
||||
public AudioClip BirthdaySound;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
var CurrentDate = System.DateTime.Now;
|
||||
|
||||
if (CurrentDate.Day == 24 && CurrentDate.Month == 1)
|
||||
{
|
||||
_birthday = true;
|
||||
DefaultButton.gameObject.SetActive(false);
|
||||
BirthdayButton.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnButtonClick()
|
||||
{
|
||||
if (_birthday)
|
||||
{
|
||||
AudioSource.PlayClipAtPoint(BirthdaySound, GameObject.FindObjectOfType<Camera>().transform.position, 0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/FestiveMode.cs.meta
Normal file
11
Assets/Scripts/FestiveMode.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f40185d2dbc771c449552261f42dc5cd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
7
Assets/Scripts/HSVPicker.meta
Normal file
7
Assets/Scripts/HSVPicker.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23371cc964348c240b759eeeeb4d63aa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
5
Assets/Scripts/HSVPicker/Editor.meta
Normal file
5
Assets/Scripts/HSVPicker/Editor.meta
Normal file
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a9e9df3c14e9034eb587348635c8f09
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
65
Assets/Scripts/HSVPicker/Editor/BoxSliderEditor.cs
Normal file
65
Assets/Scripts/HSVPicker/Editor/BoxSliderEditor.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UI;
|
||||
|
||||
namespace HSVPicker.Editors
|
||||
{
|
||||
[CustomEditor(typeof(BoxSlider), true)]
|
||||
[CanEditMultipleObjects]
|
||||
public class BoxSliderEditor : SelectableEditor
|
||||
{
|
||||
|
||||
SerializedProperty m_HandleRect;
|
||||
SerializedProperty m_MinValue;
|
||||
SerializedProperty m_MaxValue;
|
||||
SerializedProperty m_WholeNumbers;
|
||||
SerializedProperty m_Value;
|
||||
SerializedProperty m_ValueY;
|
||||
SerializedProperty m_OnValueChanged;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
m_HandleRect = serializedObject.FindProperty("m_HandleRect");
|
||||
|
||||
m_MinValue = serializedObject.FindProperty("m_MinValue");
|
||||
m_MaxValue = serializedObject.FindProperty("m_MaxValue");
|
||||
m_WholeNumbers = serializedObject.FindProperty("m_WholeNumbers");
|
||||
m_Value = serializedObject.FindProperty("m_Value");
|
||||
m_ValueY = serializedObject.FindProperty("m_ValueY");
|
||||
m_OnValueChanged = serializedObject.FindProperty("m_OnValueChanged");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
EditorGUILayout.Space();
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.PropertyField(m_HandleRect);
|
||||
|
||||
if (m_HandleRect.objectReferenceValue != null)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
|
||||
EditorGUILayout.PropertyField(m_MinValue);
|
||||
EditorGUILayout.PropertyField(m_MaxValue);
|
||||
EditorGUILayout.PropertyField(m_WholeNumbers);
|
||||
EditorGUILayout.Slider(m_Value, m_MinValue.floatValue, m_MaxValue.floatValue);
|
||||
EditorGUILayout.Slider(m_ValueY, m_MinValue.floatValue, m_MaxValue.floatValue);
|
||||
|
||||
// Draw the event notification options
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.PropertyField(m_OnValueChanged);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox("Specify a RectTransform for the slider fill or the slider handle or both. Each must have a parent RectTransform that it can slide within.", MessageType.Info);
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Scripts/HSVPicker/Editor/BoxSliderEditor.cs.meta
Normal file
12
Assets/Scripts/HSVPicker/Editor/BoxSliderEditor.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8701e045b26e51f4eb345f2ccb3c13f5
|
||||
timeCreated: 1426804458
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
17
Assets/Scripts/HSVPicker/Editor/HSVPicker.Editors.asmdef
Normal file
17
Assets/Scripts/HSVPicker/Editor/HSVPicker.Editors.asmdef
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "HSVPicker.Editors",
|
||||
"references": [
|
||||
"HSVPicker"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 485edc8694d264a8fb6d3a830531425d
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Scripts/HSVPicker/Enums.meta
Normal file
9
Assets/Scripts/HSVPicker/Enums.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d3904d3d18ddd544820bd8518990fee
|
||||
folderAsset: yes
|
||||
timeCreated: 1442586617
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
13
Assets/Scripts/HSVPicker/Enums/ColorValues.cs
Normal file
13
Assets/Scripts/HSVPicker/Enums/ColorValues.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using UnityEngine;
|
||||
|
||||
public enum ColorValues
|
||||
{
|
||||
R,
|
||||
G,
|
||||
B,
|
||||
A,
|
||||
|
||||
Hue,
|
||||
Saturation,
|
||||
Value
|
||||
}
|
||||
12
Assets/Scripts/HSVPicker/Enums/ColorValues.cs.meta
Normal file
12
Assets/Scripts/HSVPicker/Enums/ColorValues.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 859a1720e083e504cb68917f781e87c7
|
||||
timeCreated: 1442586608
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Scripts/HSVPicker/Events.meta
Normal file
9
Assets/Scripts/HSVPicker/Events.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6bb0d49c64210014e9a24ed9345928c2
|
||||
folderAsset: yes
|
||||
timeCreated: 1442747310
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Scripts/HSVPicker/Events/ColorChangedEvent.cs
Normal file
9
Assets/Scripts/HSVPicker/Events/ColorChangedEvent.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using UnityEngine.Events;
|
||||
|
||||
[Serializable]
|
||||
public class ColorChangedEvent : UnityEvent<Color>
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff46fbecea7739f4690e4285c88f53c5
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
6
Assets/Scripts/HSVPicker/Events/HSVChangedEvent.cs
Normal file
6
Assets/Scripts/HSVPicker/Events/HSVChangedEvent.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
using UnityEngine.Events;
|
||||
|
||||
public class HSVChangedEvent : UnityEvent<float, float, float>
|
||||
{
|
||||
|
||||
}
|
||||
12
Assets/Scripts/HSVPicker/Events/HSVChangedEvent.cs.meta
Normal file
12
Assets/Scripts/HSVPicker/Events/HSVChangedEvent.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d95ce8fba3dbbf4eb14411412169b88
|
||||
timeCreated: 1442747317
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
15
Assets/Scripts/HSVPicker/HSVPicker.asmdef
Normal file
15
Assets/Scripts/HSVPicker/HSVPicker.asmdef
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "HSVPicker",
|
||||
"references": [
|
||||
"GUID:6055be8ebefd69e48b49212b09b47b2f"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
7
Assets/Scripts/HSVPicker/HSVPicker.asmdef.meta
Normal file
7
Assets/Scripts/HSVPicker/HSVPicker.asmdef.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 413a95a52ca644b7dac76988ad8915af
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9189
Assets/Scripts/HSVPicker/Picker 2.0.prefab
Normal file
9189
Assets/Scripts/HSVPicker/Picker 2.0.prefab
Normal file
File diff suppressed because it is too large
Load Diff
8
Assets/Scripts/HSVPicker/Picker 2.0.prefab.meta
Normal file
8
Assets/Scripts/HSVPicker/Picker 2.0.prefab.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 916ee089a0d7b63419075f91e1c657ec
|
||||
timeCreated: 1442747914
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
28
Assets/Scripts/HSVPicker/README.txt
Normal file
28
Assets/Scripts/HSVPicker/README.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
HSV color picker using Unity UI.
|
||||
Github https://github.com/judah4/HSV-Color-Picker-Unity
|
||||
|
||||
Usage:
|
||||
Drag picker prefab onto a UI canvas.
|
||||
|
||||
Setup:
|
||||
On the color picker setup section.
|
||||
|
||||
Show Rgb: Show RGB sliders.
|
||||
|
||||
Show Hsv: Show HSV sliders.
|
||||
|
||||
Show Alpha: Show the alpha slider.
|
||||
|
||||
Show Color Box: Show the larger color selection box and color column.
|
||||
|
||||
Show Color Slider Toggle: Show the button to toggle the HSV and RGB sliders.
|
||||
|
||||
Show Header: Options to show the top header with color preview and hex code.
|
||||
* Hide: Hide the top header.
|
||||
* Show Color: Show only the color preview in the header.
|
||||
* Show Color Code: Show only the color code in the header.
|
||||
* Show All: Show the entire top header.
|
||||
|
||||
Color Presets:
|
||||
The prefabs starts with 4 colors in the color presets. This can be updated in the Setup section of the picker prefab.
|
||||
Set the Preset Colors Id for different shared list between color pickers.
|
||||
7
Assets/Scripts/HSVPicker/README.txt.meta
Normal file
7
Assets/Scripts/HSVPicker/README.txt.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 78aa9aa1471451045b0f2f552ad0c361
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Scripts/HSVPicker/UI.meta
Normal file
9
Assets/Scripts/HSVPicker/UI.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b5fe4e314cbd9944bcaa93e814e9bd5
|
||||
folderAsset: yes
|
||||
timeCreated: 1442586536
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
30
Assets/Scripts/HSVPicker/UI/ColorImage.cs
Normal file
30
Assets/Scripts/HSVPicker/UI/ColorImage.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace HSVPicker
|
||||
{
|
||||
[RequireComponent(typeof(Image))]
|
||||
public class ColorImage : MonoBehaviour
|
||||
{
|
||||
public ColorPicker picker;
|
||||
|
||||
private Image image;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
image = GetComponent<Image>();
|
||||
picker.onValueChanged.AddListener(ColorChanged);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
picker.onValueChanged.RemoveListener(ColorChanged);
|
||||
}
|
||||
|
||||
private void ColorChanged(Color newColor)
|
||||
{
|
||||
image.color = newColor;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
12
Assets/Scripts/HSVPicker/UI/ColorImage.cs.meta
Normal file
12
Assets/Scripts/HSVPicker/UI/ColorImage.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6bca58eb07ad66b498a2f158bcb13225
|
||||
timeCreated: 1442675622
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
92
Assets/Scripts/HSVPicker/UI/ColorLabel.cs
Normal file
92
Assets/Scripts/HSVPicker/UI/ColorLabel.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
|
||||
namespace HSVPicker
|
||||
{
|
||||
|
||||
[RequireComponent(typeof(TMP_Text))]
|
||||
public class ColorLabel : MonoBehaviour
|
||||
{
|
||||
public ColorPicker picker;
|
||||
|
||||
public ColorValues type;
|
||||
|
||||
public string prefix = "R: ";
|
||||
public float minValue = 0;
|
||||
public float maxValue = 255;
|
||||
|
||||
public int precision = 0;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private TMP_Text label;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
label = GetComponent<TMP_Text>();
|
||||
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (Application.isPlaying && picker != null)
|
||||
{
|
||||
picker.onValueChanged.AddListener(ColorChanged);
|
||||
picker.onHSVChanged.AddListener(HSVChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (picker != null)
|
||||
{
|
||||
picker.onValueChanged.RemoveListener(ColorChanged);
|
||||
picker.onHSVChanged.RemoveListener(HSVChanged);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnValidate()
|
||||
{
|
||||
label = GetComponent<TMP_Text>();
|
||||
UpdateValue();
|
||||
}
|
||||
#endif
|
||||
|
||||
private void ColorChanged(Color color)
|
||||
{
|
||||
UpdateValue();
|
||||
}
|
||||
|
||||
private void HSVChanged(float hue, float sateration, float value)
|
||||
{
|
||||
UpdateValue();
|
||||
}
|
||||
|
||||
private void UpdateValue()
|
||||
{
|
||||
if(label == null)
|
||||
return;
|
||||
|
||||
if (picker == null)
|
||||
{
|
||||
label.text = prefix + "-";
|
||||
}
|
||||
else
|
||||
{
|
||||
float value = minValue + (picker.GetValue(type) * (maxValue - minValue));
|
||||
|
||||
label.text = prefix + ConvertToDisplayString(value);
|
||||
}
|
||||
}
|
||||
|
||||
private string ConvertToDisplayString(float value)
|
||||
{
|
||||
if (precision > 0)
|
||||
return value.ToString("f " + precision);
|
||||
else
|
||||
return Mathf.FloorToInt(value).ToString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
12
Assets/Scripts/HSVPicker/UI/ColorLabel.cs.meta
Normal file
12
Assets/Scripts/HSVPicker/UI/ColorLabel.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b10e832a32d2d14facd8a3f489ee8d6
|
||||
timeCreated: 1442587803
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
306
Assets/Scripts/HSVPicker/UI/ColorPicker.cs
Normal file
306
Assets/Scripts/HSVPicker/UI/ColorPicker.cs
Normal file
@@ -0,0 +1,306 @@
|
||||
using UnityEngine;
|
||||
namespace HSVPicker
|
||||
{
|
||||
public class ColorPicker : MonoBehaviour
|
||||
{
|
||||
|
||||
private float _hue = 0;
|
||||
private float _saturation = 0;
|
||||
private float _brightness = 0;
|
||||
|
||||
[SerializeField]
|
||||
private Color _color = Color.red;
|
||||
|
||||
[Header("Setup")]
|
||||
public ColorPickerSetup Setup;
|
||||
|
||||
[Header("Event")]
|
||||
public ColorChangedEvent onValueChanged = new ColorChangedEvent();
|
||||
public HSVChangedEvent onHSVChanged = new HSVChangedEvent();
|
||||
|
||||
public Color CurrentColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return _color;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (CurrentColor == value)
|
||||
return;
|
||||
|
||||
_color = value;
|
||||
|
||||
RGBChanged();
|
||||
|
||||
SendChangedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Setup.AlphaSlidiers.Toggle(Setup.ShowAlpha);
|
||||
Setup.ColorToggleElement.Toggle(Setup.ShowColorSliderToggle);
|
||||
Setup.RgbSliders.Toggle(Setup.ShowRgb);
|
||||
Setup.HsvSliders.Toggle(Setup.ShowHsv);
|
||||
Setup.ColorBox.Toggle(Setup.ShowColorBox);
|
||||
|
||||
HandleHeaderSetting(Setup.ShowHeader);
|
||||
UpdateColorToggleText();
|
||||
|
||||
RGBChanged();
|
||||
SendChangedEvent();
|
||||
}
|
||||
|
||||
public float H
|
||||
{
|
||||
get
|
||||
{
|
||||
return _hue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_hue == value)
|
||||
return;
|
||||
|
||||
_hue = value;
|
||||
|
||||
HSVChanged();
|
||||
|
||||
SendChangedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
public float S
|
||||
{
|
||||
get
|
||||
{
|
||||
return _saturation;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_saturation == value)
|
||||
return;
|
||||
|
||||
_saturation = value;
|
||||
|
||||
HSVChanged();
|
||||
|
||||
SendChangedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
public float V
|
||||
{
|
||||
get
|
||||
{
|
||||
return _brightness;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_brightness == value)
|
||||
return;
|
||||
|
||||
_brightness = value;
|
||||
|
||||
HSVChanged();
|
||||
|
||||
SendChangedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
public float R
|
||||
{
|
||||
get
|
||||
{
|
||||
return _color.r;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_color.r == value)
|
||||
return;
|
||||
|
||||
_color.r = value;
|
||||
|
||||
RGBChanged();
|
||||
|
||||
SendChangedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
public float G
|
||||
{
|
||||
get
|
||||
{
|
||||
return _color.g;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_color.g == value)
|
||||
return;
|
||||
|
||||
_color.g = value;
|
||||
|
||||
RGBChanged();
|
||||
|
||||
SendChangedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
public float B
|
||||
{
|
||||
get
|
||||
{
|
||||
return _color.b;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_color.b == value)
|
||||
return;
|
||||
|
||||
_color.b = value;
|
||||
|
||||
RGBChanged();
|
||||
|
||||
SendChangedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
private float A
|
||||
{
|
||||
get
|
||||
{
|
||||
return _color.a;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_color.a == value)
|
||||
return;
|
||||
|
||||
_color.a = value;
|
||||
|
||||
SendChangedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
private void RGBChanged()
|
||||
{
|
||||
HsvColor color = HSVUtil.ConvertRgbToHsv(CurrentColor);
|
||||
|
||||
_hue = color.normalizedH;
|
||||
_saturation = color.normalizedS;
|
||||
_brightness = color.normalizedV;
|
||||
}
|
||||
|
||||
private void HSVChanged()
|
||||
{
|
||||
Color color = HSVUtil.ConvertHsvToRgb(_hue * 360, _saturation, _brightness, _color.a);
|
||||
|
||||
_color = color;
|
||||
}
|
||||
|
||||
private void SendChangedEvent()
|
||||
{
|
||||
onValueChanged.Invoke(CurrentColor);
|
||||
onHSVChanged.Invoke(_hue, _saturation, _brightness);
|
||||
}
|
||||
|
||||
public void AssignColor(ColorValues type, float value)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ColorValues.R:
|
||||
R = value;
|
||||
break;
|
||||
case ColorValues.G:
|
||||
G = value;
|
||||
break;
|
||||
case ColorValues.B:
|
||||
B = value;
|
||||
break;
|
||||
case ColorValues.A:
|
||||
A = value;
|
||||
break;
|
||||
case ColorValues.Hue:
|
||||
H = value;
|
||||
break;
|
||||
case ColorValues.Saturation:
|
||||
S = value;
|
||||
break;
|
||||
case ColorValues.Value:
|
||||
V = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void AssignColor(Color color)
|
||||
{
|
||||
CurrentColor = color;
|
||||
}
|
||||
|
||||
public float GetValue(ColorValues type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ColorValues.R:
|
||||
return R;
|
||||
case ColorValues.G:
|
||||
return G;
|
||||
case ColorValues.B:
|
||||
return B;
|
||||
case ColorValues.A:
|
||||
return A;
|
||||
case ColorValues.Hue:
|
||||
return H;
|
||||
case ColorValues.Saturation:
|
||||
return S;
|
||||
case ColorValues.Value:
|
||||
return V;
|
||||
default:
|
||||
throw new System.NotImplementedException("");
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleColorSliders()
|
||||
{
|
||||
Setup.ShowHsv = !Setup.ShowHsv;
|
||||
Setup.ShowRgb = !Setup.ShowRgb;
|
||||
Setup.HsvSliders.Toggle(Setup.ShowHsv);
|
||||
Setup.RgbSliders.Toggle(Setup.ShowRgb);
|
||||
|
||||
|
||||
UpdateColorToggleText();
|
||||
}
|
||||
|
||||
void UpdateColorToggleText()
|
||||
{
|
||||
if (Setup.ShowRgb)
|
||||
{
|
||||
Setup.SliderToggleButtonText.text = "RGB";
|
||||
}
|
||||
|
||||
if (Setup.ShowHsv)
|
||||
{
|
||||
Setup.SliderToggleButtonText.text = "HSV";
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleHeaderSetting(ColorPickerSetup.ColorHeaderShowing setupShowHeader)
|
||||
{
|
||||
if (setupShowHeader == ColorPickerSetup.ColorHeaderShowing.Hide)
|
||||
{
|
||||
Setup.ColorHeader.Toggle(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Setup.ColorHeader.Toggle(true);
|
||||
|
||||
Setup.ColorPreview.Toggle(setupShowHeader != ColorPickerSetup.ColorHeaderShowing.ShowColorCode);
|
||||
Setup.ColorCode.Toggle(setupShowHeader != ColorPickerSetup.ColorHeaderShowing.ShowColor);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
8
Assets/Scripts/HSVPicker/UI/ColorPicker.cs.meta
Normal file
8
Assets/Scripts/HSVPicker/UI/ColorPicker.cs.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8262e4a8322117f4da079921eaa72834
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
58
Assets/Scripts/HSVPicker/UI/ColorPickerSetup.cs
Normal file
58
Assets/Scripts/HSVPicker/UI/ColorPickerSetup.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
|
||||
namespace HSVPicker
|
||||
{
|
||||
[System.Serializable]
|
||||
public class ColorPickerSetup
|
||||
{
|
||||
public enum ColorHeaderShowing
|
||||
{
|
||||
Hide,
|
||||
ShowColor,
|
||||
ShowColorCode,
|
||||
ShowAll,
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class UiElements
|
||||
{
|
||||
public RectTransform[] Elements;
|
||||
|
||||
|
||||
public void Toggle(bool active)
|
||||
{
|
||||
for (int cnt = 0; cnt < Elements.Length; cnt++)
|
||||
{
|
||||
Elements[cnt].gameObject.SetActive(active);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public bool ShowRgb = true;
|
||||
public bool ShowHsv;
|
||||
public bool ShowAlpha = true;
|
||||
public bool ShowColorBox = true;
|
||||
public bool ShowColorSliderToggle = true;
|
||||
|
||||
public ColorHeaderShowing ShowHeader = ColorHeaderShowing.ShowAll;
|
||||
|
||||
public UiElements RgbSliders;
|
||||
public UiElements HsvSliders;
|
||||
public UiElements ColorToggleElement;
|
||||
public UiElements AlphaSlidiers;
|
||||
|
||||
|
||||
public UiElements ColorHeader;
|
||||
public UiElements ColorCode;
|
||||
public UiElements ColorPreview;
|
||||
|
||||
public UiElements ColorBox;
|
||||
public TMP_Text SliderToggleButtonText;
|
||||
|
||||
public string PresetColorsId = "default";
|
||||
public Color[] DefaultPresetColors;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/HSVPicker/UI/ColorPickerSetup.cs.meta
Normal file
11
Assets/Scripts/HSVPicker/UI/ColorPickerSetup.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f1e0a31fe4cdb5458d5a88aa1268434
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
67
Assets/Scripts/HSVPicker/UI/ColorPresetManager.cs
Normal file
67
Assets/Scripts/HSVPicker/UI/ColorPresetManager.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace HSVPicker
|
||||
{
|
||||
public static class ColorPresetManager
|
||||
{
|
||||
private static Dictionary<string, ColorPresetList> _presets = new Dictionary<string, ColorPresetList>();
|
||||
|
||||
public static ColorPresetList Get(string listId = "default")
|
||||
{
|
||||
ColorPresetList preset;
|
||||
if (!_presets.TryGetValue(listId, out preset))
|
||||
{
|
||||
preset = new ColorPresetList(listId);
|
||||
_presets.Add(listId, preset);
|
||||
}
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class ColorPresetList
|
||||
{
|
||||
public string ListId { get; private set; }
|
||||
public List<Color> Colors { get; private set; }
|
||||
|
||||
public event UnityAction<List<Color>> OnColorsUpdated;
|
||||
|
||||
public ColorPresetList(string listId, List<Color> colors = null)
|
||||
{
|
||||
if (colors == null)
|
||||
{
|
||||
colors = new List<Color>();
|
||||
}
|
||||
|
||||
Colors = colors;
|
||||
ListId = listId;
|
||||
}
|
||||
|
||||
public void AddColor(Color color)
|
||||
{
|
||||
Colors.Add(color);
|
||||
if (OnColorsUpdated != null)
|
||||
{
|
||||
OnColorsUpdated.Invoke(Colors);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateList(IEnumerable<Color> colors)
|
||||
{
|
||||
Colors.Clear();
|
||||
Colors.AddRange(colors);
|
||||
|
||||
if (OnColorsUpdated != null)
|
||||
{
|
||||
OnColorsUpdated.Invoke(Colors);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/HSVPicker/UI/ColorPresetManager.cs.meta
Normal file
11
Assets/Scripts/HSVPicker/UI/ColorPresetManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 55b59bed8e892614e9397d8a20e36e0c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
86
Assets/Scripts/HSVPicker/UI/ColorPresets.cs
Normal file
86
Assets/Scripts/HSVPicker/UI/ColorPresets.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace HSVPicker
|
||||
{
|
||||
public class ColorPresets : MonoBehaviour
|
||||
{
|
||||
public ColorPicker picker;
|
||||
public GameObject[] presets;
|
||||
public Image createPresetImage;
|
||||
|
||||
private ColorPresetList _colors;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
// picker.onHSVChanged.AddListener(HSVChanged);
|
||||
picker.onValueChanged.AddListener(ColorChanged);
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
_colors = ColorPresetManager.Get(picker.Setup.PresetColorsId);
|
||||
|
||||
if (_colors.Colors.Count < picker.Setup.DefaultPresetColors.Length)
|
||||
{
|
||||
_colors.UpdateList(picker.Setup.DefaultPresetColors);
|
||||
}
|
||||
|
||||
_colors.OnColorsUpdated += OnColorsUpdate;
|
||||
OnColorsUpdate(_colors.Colors);
|
||||
}
|
||||
|
||||
private void OnColorsUpdate(List<Color> colors)
|
||||
{
|
||||
for (int cnt = 0; cnt < presets.Length; cnt++)
|
||||
{
|
||||
if (colors.Count <= cnt)
|
||||
{
|
||||
presets[cnt].SetActive(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
presets[cnt].SetActive(true);
|
||||
presets[cnt].GetComponent<Image>().color = colors[cnt];
|
||||
|
||||
}
|
||||
|
||||
createPresetImage.gameObject.SetActive(colors.Count < presets.Length);
|
||||
|
||||
}
|
||||
|
||||
public void CreatePresetButton()
|
||||
{
|
||||
_colors.AddColor(picker.CurrentColor);
|
||||
|
||||
// for (var i = 0; i < presets.Length; i++)
|
||||
//{
|
||||
// if (!presets[i].activeSelf)
|
||||
// {
|
||||
// presets[i].SetActive(true);
|
||||
// presets[i].GetComponent<Image>().color = picker.CurrentColor;
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
public void PresetSelect(Image sender)
|
||||
{
|
||||
picker.CurrentColor = sender.color;
|
||||
}
|
||||
|
||||
// Not working, it seems ConvertHsvToRgb() is broken. It doesn't work when fed
|
||||
// input h, s, v as shown below.
|
||||
// private void HSVChanged(float h, float s, float v)
|
||||
// {
|
||||
// createPresetImage.color = HSVUtil.ConvertHsvToRgb(h, s, v, 1);
|
||||
// }
|
||||
private void ColorChanged(Color color)
|
||||
{
|
||||
createPresetImage.color = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Scripts/HSVPicker/UI/ColorPresets.cs.meta
Normal file
12
Assets/Scripts/HSVPicker/UI/ColorPresets.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0923373e76e77402c9c53a2f1250ad3e
|
||||
timeCreated: 1456875791
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
92
Assets/Scripts/HSVPicker/UI/ColorSlider.cs
Normal file
92
Assets/Scripts/HSVPicker/UI/ColorSlider.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
namespace HSVPicker
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays one of the color values of aColorPicker
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Slider))]
|
||||
public class ColorSlider : MonoBehaviour
|
||||
{
|
||||
public ColorPicker hsvpicker;
|
||||
|
||||
/// <summary>
|
||||
/// Which value this slider can edit.
|
||||
/// </summary>
|
||||
public ColorValues type;
|
||||
|
||||
private Slider slider;
|
||||
|
||||
private bool listen = true;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
slider = GetComponent<Slider>();
|
||||
|
||||
hsvpicker.onValueChanged.AddListener(ColorChanged);
|
||||
hsvpicker.onHSVChanged.AddListener(HSVChanged);
|
||||
slider.onValueChanged.AddListener(SliderChanged);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
hsvpicker.onValueChanged.RemoveListener(ColorChanged);
|
||||
hsvpicker.onHSVChanged.RemoveListener(HSVChanged);
|
||||
slider.onValueChanged.RemoveListener(SliderChanged);
|
||||
}
|
||||
|
||||
private void ColorChanged(Color newColor)
|
||||
{
|
||||
listen = false;
|
||||
switch (type)
|
||||
{
|
||||
case ColorValues.R:
|
||||
slider.normalizedValue = newColor.r;
|
||||
break;
|
||||
case ColorValues.G:
|
||||
slider.normalizedValue = newColor.g;
|
||||
break;
|
||||
case ColorValues.B:
|
||||
slider.normalizedValue = newColor.b;
|
||||
break;
|
||||
case ColorValues.A:
|
||||
slider.normalizedValue = newColor.a;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void HSVChanged(float hue, float saturation, float value)
|
||||
{
|
||||
listen = false;
|
||||
switch (type)
|
||||
{
|
||||
case ColorValues.Hue:
|
||||
slider.normalizedValue = hue; //1 - hue;
|
||||
break;
|
||||
case ColorValues.Saturation:
|
||||
slider.normalizedValue = saturation;
|
||||
break;
|
||||
case ColorValues.Value:
|
||||
slider.normalizedValue = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void SliderChanged(float newValue)
|
||||
{
|
||||
if (listen)
|
||||
{
|
||||
newValue = slider.normalizedValue;
|
||||
//if (type == ColorValues.Hue)
|
||||
// newValue = 1 - newValue;
|
||||
|
||||
hsvpicker.AssignColor(type, newValue);
|
||||
}
|
||||
listen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Scripts/HSVPicker/UI/ColorSlider.cs.meta
Normal file
12
Assets/Scripts/HSVPicker/UI/ColorSlider.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c600592efa0cf25479655321bf4fb08a
|
||||
timeCreated: 1442586558
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
206
Assets/Scripts/HSVPicker/UI/ColorSliderImage.cs
Normal file
206
Assets/Scripts/HSVPicker/UI/ColorSliderImage.cs
Normal file
@@ -0,0 +1,206 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
namespace HSVPicker
|
||||
{
|
||||
[RequireComponent(typeof(RawImage)), ExecuteInEditMode()]
|
||||
public class ColorSliderImage : MonoBehaviour
|
||||
{
|
||||
public ColorPicker picker;
|
||||
|
||||
/// <summary>
|
||||
/// Which value this slider can edit.
|
||||
/// </summary>
|
||||
public ColorValues type;
|
||||
|
||||
public Slider.Direction direction;
|
||||
|
||||
private RawImage image;
|
||||
|
||||
private RectTransform rectTransform
|
||||
{
|
||||
get
|
||||
{
|
||||
return transform as RectTransform;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
image = GetComponent<RawImage>();
|
||||
|
||||
if(Application.isPlaying)
|
||||
RegenerateTexture();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (picker != null && Application.isPlaying)
|
||||
{
|
||||
picker.onValueChanged.AddListener(ColorChanged);
|
||||
picker.onHSVChanged.AddListener(HSVChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (picker != null)
|
||||
{
|
||||
picker.onValueChanged.RemoveListener(ColorChanged);
|
||||
picker.onHSVChanged.RemoveListener(HSVChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (image.texture != null)
|
||||
DestroyImmediate(image.texture);
|
||||
}
|
||||
|
||||
private void ColorChanged(Color newColor)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ColorValues.R:
|
||||
case ColorValues.G:
|
||||
case ColorValues.B:
|
||||
case ColorValues.Saturation:
|
||||
case ColorValues.Value:
|
||||
RegenerateTexture();
|
||||
break;
|
||||
case ColorValues.A:
|
||||
case ColorValues.Hue:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void HSVChanged(float hue, float saturation, float value)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ColorValues.R:
|
||||
case ColorValues.G:
|
||||
case ColorValues.B:
|
||||
case ColorValues.Saturation:
|
||||
case ColorValues.Value:
|
||||
RegenerateTexture();
|
||||
break;
|
||||
case ColorValues.A:
|
||||
case ColorValues.Hue:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void RegenerateTexture()
|
||||
{
|
||||
Color32 baseColor = picker != null ? picker.CurrentColor : Color.black;
|
||||
|
||||
float h = picker != null ? picker.H : 0;
|
||||
float s = picker != null ? picker.S : 0;
|
||||
float v = picker != null ? picker.V : 0;
|
||||
|
||||
Texture2D texture;
|
||||
Color32[] colors;
|
||||
|
||||
bool vertical = direction == Slider.Direction.BottomToTop || direction == Slider.Direction.TopToBottom;
|
||||
bool inverted = direction == Slider.Direction.TopToBottom || direction == Slider.Direction.RightToLeft;
|
||||
|
||||
int size;
|
||||
switch (type)
|
||||
{
|
||||
case ColorValues.R:
|
||||
case ColorValues.G:
|
||||
case ColorValues.B:
|
||||
case ColorValues.A:
|
||||
size = 255;
|
||||
break;
|
||||
case ColorValues.Hue:
|
||||
size = 360;
|
||||
break;
|
||||
case ColorValues.Saturation:
|
||||
case ColorValues.Value:
|
||||
size = 100;
|
||||
break;
|
||||
default:
|
||||
throw new System.NotImplementedException("");
|
||||
}
|
||||
if (vertical)
|
||||
texture = new Texture2D(1, size);
|
||||
else
|
||||
texture = new Texture2D(size, 1);
|
||||
|
||||
texture.hideFlags = HideFlags.DontSave;
|
||||
colors = new Color32[size];
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ColorValues.R:
|
||||
for (byte i = 0; i < size; i++)
|
||||
{
|
||||
colors[inverted ? size - 1 - i : i] = new Color32(i, baseColor.g, baseColor.b, 255);
|
||||
}
|
||||
break;
|
||||
case ColorValues.G:
|
||||
for (byte i = 0; i < size; i++)
|
||||
{
|
||||
colors[inverted ? size - 1 - i : i] = new Color32(baseColor.r, i, baseColor.b, 255);
|
||||
}
|
||||
break;
|
||||
case ColorValues.B:
|
||||
for (byte i = 0; i < size; i++)
|
||||
{
|
||||
colors[inverted ? size - 1 - i : i] = new Color32(baseColor.r, baseColor.g, i, 255);
|
||||
}
|
||||
break;
|
||||
case ColorValues.A:
|
||||
for (byte i = 0; i < size; i++)
|
||||
{
|
||||
colors[inverted ? size - 1 - i : i] = new Color32(i, i, i, 255);
|
||||
}
|
||||
break;
|
||||
case ColorValues.Hue:
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
colors[inverted ? size - 1 - i : i] = HSVUtil.ConvertHsvToRgb(i, 1, 1, 1);
|
||||
}
|
||||
break;
|
||||
case ColorValues.Saturation:
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
colors[inverted ? size - 1 - i : i] = HSVUtil.ConvertHsvToRgb(h * 360, (float)i / size, v, 1);
|
||||
}
|
||||
break;
|
||||
case ColorValues.Value:
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
colors[inverted ? size - 1 - i : i] = HSVUtil.ConvertHsvToRgb(h * 360, s, (float)i / size, 1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new System.NotImplementedException("");
|
||||
}
|
||||
texture.SetPixels32(colors);
|
||||
texture.Apply();
|
||||
|
||||
if (image.texture != null)
|
||||
DestroyImmediate(image.texture);
|
||||
image.texture = texture;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case Slider.Direction.BottomToTop:
|
||||
case Slider.Direction.TopToBottom:
|
||||
image.uvRect = new Rect(0, 0, 2, 1);
|
||||
break;
|
||||
case Slider.Direction.LeftToRight:
|
||||
case Slider.Direction.RightToLeft:
|
||||
image.uvRect = new Rect(0, 0, 1, 2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
12
Assets/Scripts/HSVPicker/UI/ColorSliderImage.cs.meta
Normal file
12
Assets/Scripts/HSVPicker/UI/ColorSliderImage.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ca76dd9ad6eb204c9b0481aece34497
|
||||
timeCreated: 1442682013
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
53
Assets/Scripts/HSVPicker/UI/HexColorField.cs
Normal file
53
Assets/Scripts/HSVPicker/UI/HexColorField.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
namespace HSVPicker
|
||||
{
|
||||
[RequireComponent(typeof(TMP_InputField))]
|
||||
public class HexColorField : MonoBehaviour
|
||||
{
|
||||
public ColorPicker hsvpicker;
|
||||
|
||||
public bool displayAlpha;
|
||||
|
||||
private TMP_InputField hexInputField;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
hexInputField = GetComponent<TMP_InputField>();
|
||||
|
||||
// Add listeners to keep text (and color) up to date
|
||||
hexInputField.onEndEdit.AddListener(UpdateColor);
|
||||
hsvpicker.onValueChanged.AddListener(UpdateHex);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
hexInputField.onValueChanged.RemoveListener(UpdateColor);
|
||||
hsvpicker.onValueChanged.RemoveListener(UpdateHex);
|
||||
}
|
||||
|
||||
private void UpdateHex(Color newColor)
|
||||
{
|
||||
hexInputField.text = ColorToHex(newColor);
|
||||
}
|
||||
|
||||
private void UpdateColor(string newHex)
|
||||
{
|
||||
Color color;
|
||||
if (!newHex.StartsWith("#"))
|
||||
newHex = "#"+newHex;
|
||||
if (ColorUtility.TryParseHtmlString(newHex, out color))
|
||||
hsvpicker.CurrentColor = color;
|
||||
else
|
||||
Debug.Log("hex value is in the wrong format, valid formats are: #RGB, #RGBA, #RRGGBB and #RRGGBBAA (# is optional)");
|
||||
}
|
||||
|
||||
private string ColorToHex(Color32 color)
|
||||
{
|
||||
return displayAlpha
|
||||
? string.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", color.r, color.g, color.b, color.a)
|
||||
: string.Format("#{0:X2}{1:X2}{2:X2}", color.r, color.g, color.b);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/Scripts/HSVPicker/UI/HexColorField.cs.meta
Normal file
8
Assets/Scripts/HSVPicker/UI/HexColorField.cs.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d85c534b3c1560544b09d0996dfeba84
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
121
Assets/Scripts/HSVPicker/UI/SVBoxSlider.cs
Normal file
121
Assets/Scripts/HSVPicker/UI/SVBoxSlider.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace HSVPicker
|
||||
{
|
||||
[RequireComponent(typeof(BoxSlider), typeof(RawImage)), ExecuteInEditMode()]
|
||||
public class SVBoxSlider : MonoBehaviour
|
||||
{
|
||||
public ColorPicker picker;
|
||||
|
||||
private BoxSlider slider;
|
||||
private RawImage image;
|
||||
|
||||
private int textureWidth = 128;
|
||||
private int textureHeight = 128;
|
||||
|
||||
private float lastH = -1;
|
||||
private bool listen = true;
|
||||
|
||||
public RectTransform rectTransform
|
||||
{
|
||||
get
|
||||
{
|
||||
return transform as RectTransform;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
slider = GetComponent<BoxSlider>();
|
||||
image = GetComponent<RawImage>();
|
||||
if(Application.isPlaying)
|
||||
{
|
||||
RegenerateSVTexture ();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (Application.isPlaying && picker != null)
|
||||
{
|
||||
slider.onValueChanged.AddListener(SliderChanged);
|
||||
picker.onHSVChanged.AddListener(HSVChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (picker != null)
|
||||
{
|
||||
slider.onValueChanged.RemoveListener(SliderChanged);
|
||||
picker.onHSVChanged.RemoveListener(HSVChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if ( image.texture != null )
|
||||
{
|
||||
DestroyImmediate (image.texture);
|
||||
}
|
||||
}
|
||||
|
||||
private void SliderChanged(float saturation, float value)
|
||||
{
|
||||
if (listen)
|
||||
{
|
||||
picker.AssignColor(ColorValues.Saturation, saturation);
|
||||
picker.AssignColor(ColorValues.Value, value);
|
||||
}
|
||||
listen = true;
|
||||
}
|
||||
|
||||
private void HSVChanged(float h, float s, float v)
|
||||
{
|
||||
if (!lastH.Equals(h))
|
||||
{
|
||||
lastH = h;
|
||||
RegenerateSVTexture();
|
||||
}
|
||||
|
||||
if (!s.Equals(slider.normalizedValue))
|
||||
{
|
||||
listen = false;
|
||||
slider.normalizedValue = s;
|
||||
}
|
||||
|
||||
if (!v.Equals(slider.normalizedValueY))
|
||||
{
|
||||
listen = false;
|
||||
slider.normalizedValueY = v;
|
||||
}
|
||||
}
|
||||
|
||||
private void RegenerateSVTexture()
|
||||
{
|
||||
double h = picker != null ? picker.H * 360 : 0;
|
||||
|
||||
if ( image.texture != null )
|
||||
DestroyImmediate (image.texture);
|
||||
|
||||
var texture = new Texture2D (textureWidth, textureHeight);
|
||||
texture.wrapMode = TextureWrapMode.Clamp;
|
||||
texture.hideFlags = HideFlags.DontSave;
|
||||
|
||||
for ( int s = 0; s < textureWidth; s++ )
|
||||
{
|
||||
Color[] colors = new Color[textureHeight];
|
||||
for ( int v = 0; v < textureHeight; v++ )
|
||||
{
|
||||
colors[v] = HSVUtil.ConvertHsvToRgb (h, (float)s / textureWidth, (float)v / textureHeight, 1);
|
||||
}
|
||||
texture.SetPixels (s, 0, 1, textureHeight, colors);
|
||||
}
|
||||
texture.Apply();
|
||||
|
||||
image.texture = texture;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/Scripts/HSVPicker/UI/SVBoxSlider.cs.meta
Normal file
12
Assets/Scripts/HSVPicker/UI/SVBoxSlider.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e4240873631f724496efec97d7151b3
|
||||
timeCreated: 1442650713
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Scripts/HSVPicker/UtilityScripts.meta
Normal file
9
Assets/Scripts/HSVPicker/UtilityScripts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b33138f525222146865861432dbe845
|
||||
folderAsset: yes
|
||||
timeCreated: 1426051345
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
448
Assets/Scripts/HSVPicker/UtilityScripts/BoxSlider.cs
Normal file
448
Assets/Scripts/HSVPicker/UtilityScripts/BoxSlider.cs
Normal file
@@ -0,0 +1,448 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace HSVPicker
|
||||
{
|
||||
[AddComponentMenu("UI/BoxSlider", 35)]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
public class BoxSlider : Selectable, IDragHandler, IInitializePotentialDragHandler, ICanvasElement
|
||||
{
|
||||
public enum Direction
|
||||
{
|
||||
LeftToRight,
|
||||
RightToLeft,
|
||||
BottomToTop,
|
||||
TopToBottom,
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class BoxSliderEvent : UnityEvent<float, float> { }
|
||||
|
||||
[SerializeField]
|
||||
private RectTransform m_HandleRect;
|
||||
public RectTransform handleRect { get { return m_HandleRect; } set { if (SetClass(ref m_HandleRect, value)) { UpdateCachedReferences(); UpdateVisuals(); } } }
|
||||
|
||||
[Space(6)]
|
||||
|
||||
[SerializeField]
|
||||
private float m_MinValue = 0;
|
||||
public float minValue { get { return m_MinValue; } set { if (SetStruct(ref m_MinValue, value)) { Set(m_Value); SetY (m_ValueY); UpdateVisuals(); } } }
|
||||
|
||||
[SerializeField]
|
||||
private float m_MaxValue = 1;
|
||||
public float maxValue { get { return m_MaxValue; } set { if (SetStruct(ref m_MaxValue, value)) { Set(m_Value); SetY (m_ValueY); UpdateVisuals(); } } }
|
||||
|
||||
[SerializeField]
|
||||
private bool m_WholeNumbers = false;
|
||||
public bool wholeNumbers { get { return m_WholeNumbers; } set { if (SetStruct(ref m_WholeNumbers, value)) { Set(m_Value); SetY (m_ValueY); UpdateVisuals(); } } }
|
||||
|
||||
[SerializeField]
|
||||
private float m_Value = 1f;
|
||||
public float value
|
||||
{
|
||||
get
|
||||
{
|
||||
if (wholeNumbers)
|
||||
return Mathf.Round(m_Value);
|
||||
return m_Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
Set(value);
|
||||
}
|
||||
}
|
||||
|
||||
public float normalizedValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Mathf.Approximately(minValue, maxValue))
|
||||
return 0;
|
||||
return Mathf.InverseLerp(minValue, maxValue, value);
|
||||
}
|
||||
set
|
||||
{
|
||||
this.value = Mathf.Lerp(minValue, maxValue, value);
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private float m_ValueY = 1f;
|
||||
public float valueY
|
||||
{
|
||||
get
|
||||
{
|
||||
if (wholeNumbers)
|
||||
return Mathf.Round(m_ValueY);
|
||||
return m_ValueY;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetY(value);
|
||||
}
|
||||
}
|
||||
|
||||
public float normalizedValueY
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Mathf.Approximately(minValue, maxValue))
|
||||
return 0;
|
||||
return Mathf.InverseLerp(minValue, maxValue, valueY);
|
||||
}
|
||||
set
|
||||
{
|
||||
this.valueY = Mathf.Lerp(minValue, maxValue, value);
|
||||
}
|
||||
}
|
||||
|
||||
[Space(6)]
|
||||
|
||||
// Allow for delegate-based subscriptions for faster events than 'eventReceiver', and allowing for multiple receivers.
|
||||
[SerializeField]
|
||||
private BoxSliderEvent m_OnValueChanged = new BoxSliderEvent();
|
||||
public BoxSliderEvent onValueChanged { get { return m_OnValueChanged; } set { m_OnValueChanged = value; } }
|
||||
|
||||
// Private fields
|
||||
|
||||
//private Image m_FillImage;
|
||||
//private Transform m_FillTransform;
|
||||
//private RectTransform m_FillContainerRect;
|
||||
private Transform m_HandleTransform;
|
||||
private RectTransform m_HandleContainerRect;
|
||||
|
||||
// The offset from handle position to mouse down position
|
||||
private Vector2 m_Offset = Vector2.zero;
|
||||
|
||||
private DrivenRectTransformTracker m_Tracker;
|
||||
|
||||
// Size of each step.
|
||||
float stepSize { get { return wholeNumbers ? 1 : (maxValue - minValue) * 0.1f; } }
|
||||
|
||||
protected BoxSlider()
|
||||
{ }
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate()
|
||||
{
|
||||
base.OnValidate();
|
||||
|
||||
if (wholeNumbers)
|
||||
{
|
||||
m_MinValue = Mathf.Round(m_MinValue);
|
||||
m_MaxValue = Mathf.Round(m_MaxValue);
|
||||
}
|
||||
|
||||
//Onvalidate is called before OnEnabled. We need to make sure not to touch any other objects before OnEnable is run.
|
||||
if (IsActive())
|
||||
{
|
||||
UpdateCachedReferences();
|
||||
Set(m_Value, false);
|
||||
SetY(m_ValueY, false);
|
||||
// Update rects since other things might affect them even if value didn't change.
|
||||
UpdateVisuals();
|
||||
}
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
|
||||
if (!UnityEditor.PrefabUtility.IsPartOfPrefabAsset(this) && !Application.isPlaying)
|
||||
CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this);
|
||||
|
||||
#else
|
||||
|
||||
var prefabType = UnityEditor.PrefabUtility.GetPrefabType(this);
|
||||
if (prefabType != UnityEditor.PrefabType.Prefab && !Application.isPlaying)
|
||||
CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this);
|
||||
#endif
|
||||
}
|
||||
#endif // if UNITY_EDITOR
|
||||
|
||||
public virtual void Rebuild(CanvasUpdate executing)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (executing == CanvasUpdate.Prelayout)
|
||||
onValueChanged.Invoke(value, valueY);
|
||||
#endif
|
||||
}
|
||||
|
||||
public void LayoutComplete()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void GraphicUpdateComplete()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static bool SetClass<T>(ref T currentValue, T newValue) where T: class
|
||||
{
|
||||
if ((currentValue == null && newValue == null) || (currentValue != null && currentValue.Equals(newValue)))
|
||||
return false;
|
||||
|
||||
currentValue = newValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool SetStruct<T>(ref T currentValue, T newValue) where T: struct
|
||||
{
|
||||
if (currentValue.Equals(newValue))
|
||||
return false;
|
||||
|
||||
currentValue = newValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
UpdateCachedReferences();
|
||||
Set(m_Value, false);
|
||||
SetY(m_ValueY, false);
|
||||
// Update rects since they need to be initialized correctly.
|
||||
UpdateVisuals();
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
m_Tracker.Clear();
|
||||
base.OnDisable();
|
||||
}
|
||||
|
||||
void UpdateCachedReferences()
|
||||
{
|
||||
|
||||
if (m_HandleRect)
|
||||
{
|
||||
m_HandleTransform = m_HandleRect.transform;
|
||||
if (m_HandleTransform.parent != null)
|
||||
m_HandleContainerRect = m_HandleTransform.parent.GetComponent<RectTransform>();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_HandleContainerRect = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the valueUpdate the visible Image.
|
||||
void Set(float input)
|
||||
{
|
||||
Set(input, true);
|
||||
}
|
||||
|
||||
void Set(float input, bool sendCallback)
|
||||
{
|
||||
// Clamp the input
|
||||
float newValue = Mathf.Clamp(input, minValue, maxValue);
|
||||
if (wholeNumbers)
|
||||
newValue = Mathf.Round(newValue);
|
||||
|
||||
// If the stepped value doesn't match the last one, it's time to update
|
||||
if (m_Value.Equals(newValue))
|
||||
return;
|
||||
|
||||
m_Value = newValue;
|
||||
UpdateVisuals();
|
||||
if (sendCallback)
|
||||
m_OnValueChanged.Invoke(newValue, valueY);
|
||||
}
|
||||
|
||||
void SetY(float input)
|
||||
{
|
||||
SetY(input, true);
|
||||
}
|
||||
|
||||
void SetY(float input, bool sendCallback)
|
||||
{
|
||||
// Clamp the input
|
||||
float newValue = Mathf.Clamp(input, minValue, maxValue);
|
||||
if (wholeNumbers)
|
||||
newValue = Mathf.Round(newValue);
|
||||
|
||||
// If the stepped value doesn't match the last one, it's time to update
|
||||
if (m_ValueY.Equals(newValue))
|
||||
return;
|
||||
|
||||
m_ValueY = newValue;
|
||||
UpdateVisuals();
|
||||
if (sendCallback)
|
||||
m_OnValueChanged.Invoke(value, newValue);
|
||||
}
|
||||
|
||||
|
||||
protected override void OnRectTransformDimensionsChange()
|
||||
{
|
||||
base.OnRectTransformDimensionsChange();
|
||||
UpdateVisuals();
|
||||
}
|
||||
|
||||
enum Axis
|
||||
{
|
||||
Horizontal = 0,
|
||||
Vertical = 1
|
||||
}
|
||||
|
||||
|
||||
// Force-update the slider. Useful if you've changed the properties and want it to update visually.
|
||||
private void UpdateVisuals()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
UpdateCachedReferences();
|
||||
#endif
|
||||
|
||||
m_Tracker.Clear();
|
||||
|
||||
|
||||
//to business!
|
||||
if (m_HandleContainerRect != null)
|
||||
{
|
||||
m_Tracker.Add(this, m_HandleRect, DrivenTransformProperties.Anchors);
|
||||
Vector2 anchorMin = Vector2.zero;
|
||||
Vector2 anchorMax = Vector2.one;
|
||||
anchorMin[0] = anchorMax[0] = (normalizedValue);
|
||||
anchorMin[1] = anchorMax[1] = ( normalizedValueY);
|
||||
|
||||
m_HandleRect.anchorMin = anchorMin;
|
||||
m_HandleRect.anchorMax = anchorMax;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the slider's position based on the mouse.
|
||||
void UpdateDrag(PointerEventData eventData, Camera cam)
|
||||
{
|
||||
RectTransform clickRect = m_HandleContainerRect;
|
||||
if (clickRect != null && clickRect.rect.size[0] > 0)
|
||||
{
|
||||
Vector2 localCursor;
|
||||
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(clickRect, eventData.position, cam, out localCursor))
|
||||
return;
|
||||
localCursor -= clickRect.rect.position;
|
||||
|
||||
float val = Mathf.Clamp01((localCursor - m_Offset)[0] / clickRect.rect.size[0]);
|
||||
normalizedValue = (val);
|
||||
|
||||
float valY = Mathf.Clamp01((localCursor - m_Offset)[1] / clickRect.rect.size[1]);
|
||||
normalizedValueY = ( valY);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private bool MayDrag(PointerEventData eventData)
|
||||
{
|
||||
return IsActive() && IsInteractable() && eventData.button == PointerEventData.InputButton.Left;
|
||||
}
|
||||
|
||||
public override void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
if (!MayDrag(eventData))
|
||||
return;
|
||||
|
||||
base.OnPointerDown(eventData);
|
||||
|
||||
m_Offset = Vector2.zero;
|
||||
if (m_HandleContainerRect != null && RectTransformUtility.RectangleContainsScreenPoint(m_HandleRect, eventData.position, eventData.enterEventCamera))
|
||||
{
|
||||
Vector2 localMousePos;
|
||||
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(m_HandleRect, eventData.position, eventData.pressEventCamera, out localMousePos))
|
||||
m_Offset = localMousePos;
|
||||
m_Offset.y = -m_Offset.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Outside the slider handle - jump to this point instead
|
||||
UpdateDrag(eventData, eventData.pressEventCamera);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
if (!MayDrag(eventData))
|
||||
return;
|
||||
|
||||
UpdateDrag(eventData, eventData.pressEventCamera);
|
||||
}
|
||||
|
||||
//public override void OnMove(AxisEventData eventData)
|
||||
//{
|
||||
// if (!IsActive() || !IsInteractable())
|
||||
// {
|
||||
// base.OnMove(eventData);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// switch (eventData.moveDir)
|
||||
// {
|
||||
// case MoveDirection.Left:
|
||||
// if (axis == Axis.Horizontal && FindSelectableOnLeft() == null) {
|
||||
// Set(reverseValue ? value + stepSize : value - stepSize);
|
||||
// SetY (reverseValue ? valueY + stepSize : valueY - stepSize);
|
||||
// }
|
||||
// else
|
||||
// base.OnMove(eventData);
|
||||
// break;
|
||||
// case MoveDirection.Right:
|
||||
// if (axis == Axis.Horizontal && FindSelectableOnRight() == null) {
|
||||
// Set(reverseValue ? value - stepSize : value + stepSize);
|
||||
// SetY(reverseValue ? valueY - stepSize : valueY + stepSize);
|
||||
// }
|
||||
// else
|
||||
// base.OnMove(eventData);
|
||||
// break;
|
||||
// case MoveDirection.Up:
|
||||
// if (axis == Axis.Vertical && FindSelectableOnUp() == null) {
|
||||
// Set(reverseValue ? value - stepSize : value + stepSize);
|
||||
// SetY(reverseValue ? valueY - stepSize : valueY + stepSize);
|
||||
// }
|
||||
// else
|
||||
// base.OnMove(eventData);
|
||||
// break;
|
||||
// case MoveDirection.Down:
|
||||
// if (axis == Axis.Vertical && FindSelectableOnDown() == null) {
|
||||
// Set(reverseValue ? value + stepSize : value - stepSize);
|
||||
// SetY(reverseValue ? valueY + stepSize : valueY - stepSize);
|
||||
// }
|
||||
// else
|
||||
// base.OnMove(eventData);
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public override Selectable FindSelectableOnLeft()
|
||||
//{
|
||||
// if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Horizontal)
|
||||
// return null;
|
||||
// return base.FindSelectableOnLeft();
|
||||
//}
|
||||
|
||||
//public override Selectable FindSelectableOnRight()
|
||||
//{
|
||||
// if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Horizontal)
|
||||
// return null;
|
||||
// return base.FindSelectableOnRight();
|
||||
//}
|
||||
|
||||
//public override Selectable FindSelectableOnUp()
|
||||
//{
|
||||
// if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Vertical)
|
||||
// return null;
|
||||
// return base.FindSelectableOnUp();
|
||||
//}
|
||||
|
||||
//public override Selectable FindSelectableOnDown()
|
||||
//{
|
||||
// if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Vertical)
|
||||
// return null;
|
||||
// return base.FindSelectableOnDown();
|
||||
//}
|
||||
|
||||
public virtual void OnInitializePotentialDrag(PointerEventData eventData)
|
||||
{
|
||||
eventData.useDragThreshold = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37c44bc94a9a7f241b5b552f3ff89458
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
210
Assets/Scripts/HSVPicker/UtilityScripts/HSVUtil.cs
Normal file
210
Assets/Scripts/HSVPicker/UtilityScripts/HSVUtil.cs
Normal file
@@ -0,0 +1,210 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace HSVPicker
|
||||
{
|
||||
|
||||
#region ColorUtilities
|
||||
|
||||
public static class HSVUtil
|
||||
{
|
||||
|
||||
public static HsvColor ConvertRgbToHsv(Color color)
|
||||
{
|
||||
return ConvertRgbToHsv((int)(color.r * 255), (int)(color.g * 255), (int)(color.b * 255));
|
||||
}
|
||||
|
||||
//Converts an RGB color to an HSV color.
|
||||
public static HsvColor ConvertRgbToHsv(double r, double b, double g)
|
||||
{
|
||||
double delta, min;
|
||||
double h = 0, s, v;
|
||||
|
||||
min = Math.Min(Math.Min(r, g), b);
|
||||
v = Math.Max(Math.Max(r, g), b);
|
||||
delta = v - min;
|
||||
|
||||
if (v.Equals(0))
|
||||
s = 0;
|
||||
else
|
||||
s = delta / v;
|
||||
|
||||
if (s.Equals(0))
|
||||
h = 360;
|
||||
else
|
||||
{
|
||||
if (r.Equals(v))
|
||||
h = (g - b) / delta;
|
||||
else if (g.Equals(v))
|
||||
h = 2 + (b - r) / delta;
|
||||
else if (b.Equals(v))
|
||||
h = 4 + (r - g) / delta;
|
||||
|
||||
h *= 60;
|
||||
if (h <= 0.0)
|
||||
h += 360;
|
||||
}
|
||||
|
||||
HsvColor hsvColor = new HsvColor();
|
||||
hsvColor.H = 360 - h;
|
||||
hsvColor.S = s;
|
||||
hsvColor.V = v / 255;
|
||||
|
||||
return hsvColor;
|
||||
|
||||
}
|
||||
|
||||
// Converts an HSV color to an RGB color.
|
||||
public static Color ConvertHsvToRgb(double h, double s, double v, float alpha)
|
||||
{
|
||||
|
||||
double r = 0, g = 0, b = 0;
|
||||
|
||||
if (s.Equals(0))
|
||||
{
|
||||
r = v;
|
||||
g = v;
|
||||
b = v;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
int i;
|
||||
double f, p, q, t;
|
||||
|
||||
|
||||
if (h.Equals(360))
|
||||
h = 0;
|
||||
else
|
||||
h = h / 60;
|
||||
|
||||
i = (int)(h);
|
||||
f = h - i;
|
||||
|
||||
p = v * (1.0 - s);
|
||||
q = v * (1.0 - (s * f));
|
||||
t = v * (1.0 - (s * (1.0f - f)));
|
||||
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
r = v;
|
||||
g = t;
|
||||
b = p;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
r = q;
|
||||
g = v;
|
||||
b = p;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
r = p;
|
||||
g = v;
|
||||
b = t;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
r = p;
|
||||
g = q;
|
||||
b = v;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
r = t;
|
||||
g = p;
|
||||
b = v;
|
||||
break;
|
||||
|
||||
default:
|
||||
r = v;
|
||||
g = p;
|
||||
b = q;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return new Color((float)r, (float)g, (float)b, alpha);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion ColorUtilities
|
||||
|
||||
|
||||
// Describes a color in terms of
|
||||
// Hue, Saturation, and Value (brightness)
|
||||
#region HsvColor
|
||||
public struct HsvColor
|
||||
{
|
||||
/// <summary>
|
||||
/// The Hue, ranges between 0 and 360
|
||||
/// </summary>
|
||||
public double H;
|
||||
|
||||
/// <summary>
|
||||
/// The saturation, ranges between 0 and 1
|
||||
/// </summary>
|
||||
public double S;
|
||||
|
||||
// The value (brightness), ranges between 0 and 1
|
||||
public double V;
|
||||
|
||||
public float normalizedH
|
||||
{
|
||||
get
|
||||
{
|
||||
return (float)H / 360f;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
H = (double)value * 360;
|
||||
}
|
||||
}
|
||||
|
||||
public float normalizedS
|
||||
{
|
||||
get
|
||||
{
|
||||
return (float)S;
|
||||
}
|
||||
set
|
||||
{
|
||||
S = (double)value;
|
||||
}
|
||||
}
|
||||
|
||||
public float normalizedV
|
||||
{
|
||||
get
|
||||
{
|
||||
return (float)V;
|
||||
}
|
||||
set
|
||||
{
|
||||
V = (double)value;
|
||||
}
|
||||
}
|
||||
|
||||
public HsvColor(double h, double s, double v)
|
||||
{
|
||||
this.H = h;
|
||||
this.S = s;
|
||||
this.V = v;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "{" + H.ToString("f2") + "," + S.ToString("f2") + "," + V.ToString("f2") + "}";
|
||||
}
|
||||
}
|
||||
#endregion HsvColor
|
||||
|
||||
|
||||
}
|
||||
|
||||
8
Assets/Scripts/HSVPicker/UtilityScripts/HSVUtil.cs.meta
Normal file
8
Assets/Scripts/HSVPicker/UtilityScripts/HSVUtil.cs.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f3189246d7fc204faba7a1e9c08e0af
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
11
Assets/Scripts/HSVPicker/package.json
Normal file
11
Assets/Scripts/HSVPicker/package.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "judah4.hsvcolorpickerunity",
|
||||
"displayName": "HSVPicker",
|
||||
"version": "3.0.1",
|
||||
"unity": "2019.4",
|
||||
"description": "HSV color picker for Unity UI",
|
||||
"keywords": [
|
||||
],
|
||||
"dependencies": {
|
||||
}
|
||||
}
|
||||
7
Assets/Scripts/HSVPicker/package.json.meta
Normal file
7
Assets/Scripts/HSVPicker/package.json.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d46aec3749789425caab28d9edf026cf
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
100
Assets/Scripts/KeyboardShortcuts.cs
Normal file
100
Assets/Scripts/KeyboardShortcuts.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using CommandUndoRedo;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
public class KeyboardShortcuts : MonoBehaviour
|
||||
{
|
||||
public static KeyboardShortcuts Instance;
|
||||
EventSystem eventSystem;
|
||||
public bool KeyboardLocked = false;
|
||||
public List<char> KeyStrokes = new List<char>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null)
|
||||
{
|
||||
Destroy(Instance);
|
||||
}
|
||||
Instance = this;
|
||||
eventSystem = EventSystem.current;
|
||||
}
|
||||
|
||||
public void Undo()
|
||||
{
|
||||
UndoRedoManager.Undo();
|
||||
}
|
||||
|
||||
public void Redo()
|
||||
{
|
||||
UndoRedoManager.Redo();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (eventSystem.currentSelectedGameObject != null) return;
|
||||
KatboiSequence();
|
||||
|
||||
if (Input.anyKeyDown && !string.IsNullOrEmpty(Input.inputString))
|
||||
{
|
||||
switch (Input.inputString.ToUpper()[0])
|
||||
{
|
||||
case 'H':
|
||||
//Settings.Instance.showHints = !Settings.Instance.showHints;
|
||||
//ModelViewerInterface.GetInstance().TooltipLabels[0].transform.parent.gameObject.SetActive(Settings.Instance.showHints);
|
||||
//Settings.Save();
|
||||
break;
|
||||
case 'X':
|
||||
Screenshot.Instance.TakeScreenshot();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.RightArrow))
|
||||
{
|
||||
TimelineController.ChangeCurrentFrame(1, true);
|
||||
}
|
||||
else if (Input.GetKeyDown(KeyCode.LeftArrow))
|
||||
{
|
||||
TimelineController.ChangeCurrentFrame(-1, true);
|
||||
}
|
||||
else if (Input.GetKeyDown(KeyCode.Space))
|
||||
{
|
||||
TimelineController.Instance.Play = !TimelineController.Instance.Play;
|
||||
}
|
||||
}
|
||||
|
||||
private void KatboiSequence()
|
||||
{
|
||||
List<string> sequences = new List<string>()
|
||||
{
|
||||
"KATBOI01"
|
||||
};
|
||||
|
||||
if (Input.anyKeyDown && !string.IsNullOrEmpty(Input.inputString))
|
||||
{
|
||||
if (KeyStrokes.Count >= 10)
|
||||
{
|
||||
KeyStrokes = KeyStrokes.Skip(KeyStrokes.Count - 10).ToList();
|
||||
}
|
||||
KeyStrokes.Add(Input.inputString.ToUpper()[0]);
|
||||
}
|
||||
|
||||
var curString = new string(KeyStrokes.ToArray());
|
||||
|
||||
string passcode = sequences.FirstOrDefault(s => curString.Contains(s));
|
||||
|
||||
if (!string.IsNullOrEmpty(passcode))
|
||||
{
|
||||
switch (passcode)
|
||||
{
|
||||
case "KATBOI01":
|
||||
//secret here
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
KeyStrokes.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/KeyboardShortcuts.cs.meta
Normal file
11
Assets/Scripts/KeyboardShortcuts.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9296f7a775266d6448fa6b138a00d1a3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/ModelViewerBase.meta
Normal file
8
Assets/Scripts/ModelViewerBase.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7528a3be00b5af46aee1dec1474f705
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
77
Assets/Scripts/ModelViewerBase/AssetLibrary.cs
Normal file
77
Assets/Scripts/ModelViewerBase/AssetLibrary.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.AddressableAssets.ResourceLocators;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using UnityEngine.ResourceManagement.ResourceProviders;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class AssetLibrary : MonoBehaviour
|
||||
{
|
||||
protected static AssetLibrary _mainInstance;
|
||||
public ResourceLocationMap AddressableResourceMap;
|
||||
private List<string> _addressableKeys;
|
||||
public string LocalFilesPath;
|
||||
|
||||
public static T GetInstance<T>() where T : AssetLibrary
|
||||
{
|
||||
return _mainInstance as T;
|
||||
}
|
||||
|
||||
public List<string> GetAddressableKeys()
|
||||
{
|
||||
if (_addressableKeys == null)
|
||||
{
|
||||
_addressableKeys = AddressableResourceMap.Keys.Select(k=>k.ToString()).ToList();
|
||||
}
|
||||
return _addressableKeys.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load catalog.json from games that use addressables
|
||||
/// </summary>
|
||||
/// <param name="catalogPath"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerator LoadAddressableCatalog(string catalogPath)
|
||||
{
|
||||
var opHandle = Addressables.LoadContentCatalogAsync(catalogPath);
|
||||
yield return opHandle;
|
||||
|
||||
if (opHandle.Status == AsyncOperationStatus.Succeeded)
|
||||
{
|
||||
Debug.Log(opHandle.Result.GetType());
|
||||
AddressableResourceMap = opHandle.Result as ResourceLocationMap;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw opHandle.OperationException;
|
||||
}
|
||||
|
||||
//var keys = AddressableResourceMap.Keys.Where(k=>k.ToString().Contains("chara_100_0001")).ToList();
|
||||
//for (int i = 0; i < keys.Count; i++)
|
||||
//{
|
||||
// Debug.Log(keys[i].ToString());
|
||||
// Debug.Log(JObject.FromObject(AddressableResourceMap.Locations[keys[i]][0]).ToString());
|
||||
// Debug.Log(AddressableResourceMap.Locations[keys[i]][0].Data.GetType());
|
||||
// //switch (AddressableResourceMap.Locations[keys[i]][0])
|
||||
// //{
|
||||
// // case CompactLocation cl:
|
||||
// // break;
|
||||
// //}
|
||||
//}
|
||||
}
|
||||
|
||||
public string GetResourcePath(string resourceName)
|
||||
{
|
||||
var locator = AddressableResourceMap.Locations[resourceName][0]; // AddressableResourceMap.Locations[resourceName][0].Dependencies[0].Data as AssetBundleRequestOptions;
|
||||
if (locator.HasDependencies)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
var data = locator.Data as AssetBundleRequestOptions;
|
||||
var filePath = data.BundleName + "/" + data.Hash + "/" + "__data";
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/ModelViewerBase/AssetLibrary.cs.meta
Normal file
11
Assets/Scripts/ModelViewerBase/AssetLibrary.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68d09003b62bea04bbedb8a5b21b9aa6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
5
Assets/Scripts/ModelViewerBase/AssetSpawnData.cs
Normal file
5
Assets/Scripts/ModelViewerBase/AssetSpawnData.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
public class AssetSpawnData
|
||||
{
|
||||
public AssetTypes AssetType;
|
||||
public string FilePath;
|
||||
}
|
||||
11
Assets/Scripts/ModelViewerBase/AssetSpawnData.cs.meta
Normal file
11
Assets/Scripts/ModelViewerBase/AssetSpawnData.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a31e5f4826d6b7c42bca99c19497a7f4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
6
Assets/Scripts/ModelViewerBase/AssetTypes.cs
Normal file
6
Assets/Scripts/ModelViewerBase/AssetTypes.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
public enum AssetTypes
|
||||
{
|
||||
Unknown,
|
||||
Character,
|
||||
Object
|
||||
}
|
||||
11
Assets/Scripts/ModelViewerBase/AssetTypes.cs.meta
Normal file
11
Assets/Scripts/ModelViewerBase/AssetTypes.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 547b343c746a81e4dbfc463e6edd4948
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
6
Assets/Scripts/ModelViewerBase/BoneList.cs
Normal file
6
Assets/Scripts/ModelViewerBase/BoneList.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
[System.Serializable]
|
||||
public class BoneList
|
||||
{
|
||||
public string Name;
|
||||
public SerializableBone[] Bones = new SerializableBone[0];
|
||||
}
|
||||
11
Assets/Scripts/ModelViewerBase/BoneList.cs.meta
Normal file
11
Assets/Scripts/ModelViewerBase/BoneList.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 98e7f80672878ce44b33fbf239398d53
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
288
Assets/Scripts/ModelViewerBase/CameraOrbit.cs
Normal file
288
Assets/Scripts/ModelViewerBase/CameraOrbit.cs
Normal file
@@ -0,0 +1,288 @@
|
||||
using CommandUndoRedo;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
public class CameraOrbit : MonoBehaviour
|
||||
{
|
||||
public bool LightLock = false;
|
||||
public Camera Cam;
|
||||
bool controlOn;
|
||||
float controlTime;
|
||||
|
||||
[Header("Light")]
|
||||
public GameObject Light;
|
||||
public GameObject CameraTargetHelper;
|
||||
public Vector3 TargetCenter;
|
||||
|
||||
EventSystem eventSystem;
|
||||
|
||||
[Header("Free Camera")]
|
||||
bool FreeCamLeft = false;
|
||||
bool FreeCamRight = false;
|
||||
public Vector3 lookRotation;
|
||||
|
||||
private CameraSettings _settings => ModelViewerMain.GetInstance().GetCameraHandler().Settings;
|
||||
|
||||
private CameraTransformCommand _tempCommand;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
public CameraOrbit Init()
|
||||
{
|
||||
Cam = GetComponentInChildren<Camera>();
|
||||
eventSystem = EventSystem.current;
|
||||
return this;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (ModelViewerMain.GetInstance() == null) return;
|
||||
UpdateImmediate();
|
||||
}
|
||||
|
||||
public void UpdateImmediate()
|
||||
{
|
||||
if (HandleManager.InteractionInProgress || _settings.CameraLock) return;
|
||||
|
||||
switch (_settings.CameraMode)
|
||||
{
|
||||
case 0:
|
||||
OrbitAround();
|
||||
OrbitLight();
|
||||
break;
|
||||
case 1:
|
||||
OrbitAround(true);
|
||||
OrbitLight();
|
||||
break;
|
||||
case 2: FreeCamera(); break;
|
||||
}
|
||||
}
|
||||
|
||||
#region Camera
|
||||
/// <summary>
|
||||
/// Orbit camera around world center
|
||||
/// </summary>
|
||||
void OrbitAround(bool aroundCharacter = false)
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
var settings = _settings;
|
||||
|
||||
using (var context = new KeyframeToggleContext(settings))
|
||||
{
|
||||
if (eventSystem.currentSelectedGameObject == null)
|
||||
{
|
||||
x = Input.GetAxis("Horizontal");
|
||||
y = Input.GetAxis("Vertical");
|
||||
}
|
||||
|
||||
if (aroundCharacter)
|
||||
{
|
||||
var selectedObject = ModelViewerMain.GetInstance().SelectedObject;
|
||||
TargetCenter = selectedObject != null ? selectedObject.GetCenter() : Vector3.zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
TargetCenter = Vector3.zero;
|
||||
}
|
||||
|
||||
Cam.fieldOfView = settings.Fov;
|
||||
Vector3 position = transform.position;
|
||||
Vector3 rotation = Cam.transform.localEulerAngles;
|
||||
|
||||
if (Input.GetMouseButtonDown(0) && !eventSystem.IsPointerOverGameObject())
|
||||
{
|
||||
StartKeyframe();
|
||||
controlOn = true;
|
||||
controlTime = 0;
|
||||
}
|
||||
if (Input.GetMouseButton(0) && controlOn)
|
||||
{
|
||||
controlTime += Time.deltaTime;
|
||||
position -= Input.GetAxis("Mouse X") * settings.RotSpeed * transform.right;
|
||||
settings.SliderCamDist.value -= Input.mouseScrollDelta.y * settings.ZoomSpeed;
|
||||
settings.SliderCamHeight.value -= Input.GetAxis("Mouse Y") * settings.RotSpeed;
|
||||
}
|
||||
else if (controlOn)
|
||||
{
|
||||
controlOn = false;
|
||||
if (controlTime > 0.2f)
|
||||
{
|
||||
context.ForceSetKeyframe();
|
||||
EndKeyframe();
|
||||
}
|
||||
}
|
||||
|
||||
if (Input.GetMouseButtonDown(2) && !eventSystem.IsPointerOverGameObject())
|
||||
{
|
||||
StartKeyframe();
|
||||
CameraTargetHelper.SetActive(true);
|
||||
controlTime = 0;
|
||||
}
|
||||
if (Input.GetMouseButton(2) && CameraTargetHelper.activeSelf)
|
||||
{
|
||||
controlTime += Time.deltaTime;
|
||||
settings.SliderTargetHeight.value -= Input.GetAxis("Mouse Y");
|
||||
CameraTargetHelper.transform.position = settings.SliderTargetHeight.value * Vector3.up;
|
||||
}
|
||||
if (CameraTargetHelper.activeSelf && Input.GetMouseButtonUp(2))
|
||||
{
|
||||
CameraTargetHelper.SetActive(false);
|
||||
if (controlTime > 0.2f)
|
||||
{
|
||||
context.ForceSetKeyframe();
|
||||
EndKeyframe();
|
||||
}
|
||||
}
|
||||
|
||||
float camDist = settings.CamDist;
|
||||
settings.SliderCamHeight.maxValue = camDist + 1 - camDist * 0.2f;
|
||||
settings.SliderCamHeight.minValue = -camDist + 1 + camDist * 0.2f;
|
||||
settings.SliderCamHeight.value += y * settings.RotSpeed;
|
||||
|
||||
Vector3 target = TargetCenter + settings.TargetHeight * Vector3.up; //set target offsets
|
||||
|
||||
position.y = TargetCenter.y + settings.CamHeight; //set camera height
|
||||
transform.position = position; //set final position of camera at target
|
||||
transform.position += (x * transform.right) * settings.RotSpeed;
|
||||
|
||||
//Debug.Log(rotation);
|
||||
transform.LookAt(target); //look at target position
|
||||
Cam.transform.localEulerAngles = settings.CamAngle * Vector3.forward;
|
||||
transform.position = target - transform.forward * camDist; //move away from target
|
||||
lookRotation = transform.localEulerAngles;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Free Camera, Unity-Style
|
||||
/// </summary>
|
||||
void FreeCamera()
|
||||
{
|
||||
var settings = _settings; ;
|
||||
//Debug.Log("1 " + lookRotation);
|
||||
//Debug.Log("2 " + transform.localEulerAngles);
|
||||
//Debug.Log("3 " + transform.eulerAngles);
|
||||
Cam.fieldOfView = settings.Fov;
|
||||
float moveSpeed = settings.MovSpeed;
|
||||
float rotateSpeed = settings.RotSpeed;
|
||||
|
||||
if (Input.GetMouseButtonDown(0) && !eventSystem.IsPointerOverGameObject())
|
||||
{
|
||||
StartKeyframe();
|
||||
lookRotation = transform.localEulerAngles;
|
||||
FreeCamLeft = true;
|
||||
controlTime = 0;
|
||||
}
|
||||
if (Input.GetMouseButton(0) && FreeCamLeft)
|
||||
{
|
||||
controlTime += Time.deltaTime;
|
||||
transform.position += Input.GetAxis("Vertical") * transform.forward * Time.deltaTime * moveSpeed;
|
||||
transform.position += Input.GetAxis("Horizontal") * transform.right * Time.deltaTime * moveSpeed;
|
||||
|
||||
lookRotation.x -= Input.GetAxis("Mouse Y") * rotateSpeed;
|
||||
lookRotation.y += Input.GetAxis("Mouse X") * rotateSpeed;
|
||||
|
||||
lookRotation.x = Mathf.Clamp(lookRotation.x, -90, 90);
|
||||
if (lookRotation.y >= 360) lookRotation.y -= 360;
|
||||
if (lookRotation.y <= -360) lookRotation.y += 360;
|
||||
//x (up down) y (left right) changes
|
||||
transform.localRotation = Quaternion.Euler(lookRotation.x, lookRotation.y, lookRotation.z);
|
||||
}
|
||||
else if (FreeCamLeft)
|
||||
{
|
||||
FreeCamLeft = false;
|
||||
if (controlTime > 0.2f)
|
||||
{
|
||||
ModelViewerMain.GetInstance().GetCameraHandler().SetKeyframe();
|
||||
EndKeyframe();
|
||||
}
|
||||
}
|
||||
|
||||
if (Input.GetMouseButtonDown(1) && !eventSystem.IsPointerOverGameObject())
|
||||
{
|
||||
StartKeyframe();
|
||||
FreeCamRight = true;
|
||||
controlTime = 0;
|
||||
}
|
||||
if (Input.GetMouseButton(1) && FreeCamRight)
|
||||
{
|
||||
controlTime += Time.deltaTime;
|
||||
transform.position += Input.GetAxis("Mouse X") * transform.right * Time.deltaTime * moveSpeed;
|
||||
transform.position += Input.GetAxis("Mouse Y") * transform.up * Time.deltaTime * moveSpeed;
|
||||
}
|
||||
else if (FreeCamRight)
|
||||
{
|
||||
FreeCamRight = false;
|
||||
if (controlTime > 0.2f)
|
||||
{
|
||||
ModelViewerMain.GetInstance().GetCameraHandler().SetKeyframe();
|
||||
EndKeyframe();
|
||||
}
|
||||
}
|
||||
Cam.transform.localEulerAngles = settings.CamAngle * Vector3.forward;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Light
|
||||
/// <summary>
|
||||
/// Rotate Light Source
|
||||
/// </summary>
|
||||
private void OrbitLight()
|
||||
{
|
||||
if (Input.GetMouseButton(1) && !LightLock)
|
||||
{
|
||||
Light.transform.Rotate(Input.GetAxis("Mouse X") * Vector3.up, Space.Self);
|
||||
Light.transform.Rotate(Input.GetAxis("Mouse Y") * Vector3.right, Space.Self);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetLightColor(Color color)
|
||||
{
|
||||
Light.GetComponent<Light>().color = color;
|
||||
}
|
||||
|
||||
public void SetLightIntensity(float value)
|
||||
{
|
||||
Light.GetComponent<Light>().intensity = value;
|
||||
}
|
||||
|
||||
public void SetLightShadowIntensity(float value)
|
||||
{
|
||||
Light.GetComponent<Light>().shadowStrength = value;
|
||||
}
|
||||
|
||||
public void SetLightShadows(int value)
|
||||
{
|
||||
Light.GetComponent<Light>().shadows = (LightShadows)value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void StartKeyframe()
|
||||
{
|
||||
var cam = ModelViewerMain.GetInstance().GetCameraHandler();
|
||||
if (cam == ModelViewerMain.GetInstance().WorkCameraOrbit)
|
||||
{
|
||||
_tempCommand = null;
|
||||
return;
|
||||
}
|
||||
_tempCommand = new CameraTransformCommand()
|
||||
{
|
||||
Container = cam,
|
||||
OldValues = cam.SerializeFrame() as KeyframeDataCamera,
|
||||
Frame = TimelineController.Instance.CurrentFrame
|
||||
};
|
||||
}
|
||||
|
||||
private void EndKeyframe()
|
||||
{
|
||||
if (_tempCommand != null )
|
||||
{
|
||||
_tempCommand.NewValues = _tempCommand.Container.SerializeFrame() as KeyframeDataCamera;
|
||||
UndoRedoManager.Insert(_tempCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/ModelViewerBase/CameraOrbit.cs.meta
Normal file
11
Assets/Scripts/ModelViewerBase/CameraOrbit.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32a48605970827e4999f4dd7807a5eac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
119
Assets/Scripts/ModelViewerBase/CameraSettings.cs
Normal file
119
Assets/Scripts/ModelViewerBase/CameraSettings.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class CameraSettings : MonoBehaviour, IKeyframeSetter
|
||||
{
|
||||
protected bool _setKeyframe = true;
|
||||
|
||||
[Header("Scene")]
|
||||
public SliderPanel
|
||||
SliderFov;
|
||||
public SliderPanel
|
||||
SliderCamDist,
|
||||
SliderCamHeight,
|
||||
SliderTargetHeight,
|
||||
SliderCamAngle;
|
||||
|
||||
[Header("Unsaved")]
|
||||
public SliderPanel
|
||||
SliderMovSpeed;
|
||||
public SliderPanel
|
||||
SliderRotSpeed,
|
||||
SliderZoomSpeed;
|
||||
|
||||
public Toggle ToggleCameraLock;
|
||||
public Toggle ToggleWorkCamera;
|
||||
|
||||
public ExtendedDropdown BackgroundDropdown;
|
||||
public TMPro.TMP_Dropdown DropdownCameraMode;
|
||||
|
||||
public GameObject ColorPickerPanel;
|
||||
|
||||
public int CameraMode => DropdownCameraMode.value;
|
||||
|
||||
public bool CameraLock => ToggleCameraLock.isOn;
|
||||
|
||||
public float Fov => SliderFov.value;
|
||||
public float CamDist => SliderCamDist.value;
|
||||
public float CamHeight => SliderCamHeight.value;
|
||||
public float TargetHeight => SliderTargetHeight.value;
|
||||
public float CamAngle => SliderCamAngle.value;
|
||||
public float MovSpeed => SliderMovSpeed.value;
|
||||
public float RotSpeed => SliderRotSpeed.value;
|
||||
public float ZoomSpeed => SliderZoomSpeed.value;
|
||||
|
||||
public void SwapCamera(bool workCameraMode)
|
||||
{
|
||||
var mainCamera = ModelViewerMain.GetInstance().MainCameraOrbit;
|
||||
var workCamera = ModelViewerMain.GetInstance().WorkCameraOrbit;
|
||||
|
||||
var camera = mainCamera.Camera;
|
||||
|
||||
if (workCameraMode)
|
||||
{
|
||||
mainCamera.LastPosition = mainCamera.SerializeFrame() as KeyframeDataCamera;
|
||||
mainCamera.transform.SetPositionAndRotation(camera.Cam.transform.position, camera.Cam.transform.rotation);
|
||||
mainCamera.LineRenderer.enabled = true;
|
||||
workCamera.LineRenderer.enabled = false;
|
||||
|
||||
if(workCamera.LastPosition.Root.Position == Vector3.zero)
|
||||
{
|
||||
workCamera.PastePose(mainCamera.LastPosition, new PoseLoadOptions(true));
|
||||
}
|
||||
else
|
||||
{
|
||||
workCamera.PastePose(workCamera.LastPosition, new PoseLoadOptions(true));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
workCamera.LastPosition = workCamera.SerializeFrame() as KeyframeDataCamera;
|
||||
workCamera.transform.SetPositionAndRotation(camera.Cam.transform.position, camera.Cam.transform.rotation);
|
||||
//WorkCameraOrbit.LineRenderer.enabled = true;
|
||||
mainCamera.LineRenderer.enabled = false;
|
||||
|
||||
mainCamera.PastePose(mainCamera.LastPosition, new PoseLoadOptions(true));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetKeyframe(int frameNum = -1)
|
||||
{
|
||||
if (ToggleWorkCamera.isOn || !_setKeyframe) return;
|
||||
|
||||
ModelViewerMain.GetInstance().MainCameraOrbit.SetKeyframe();
|
||||
}
|
||||
|
||||
public void EnableKeyframeSet()
|
||||
{
|
||||
_setKeyframe = true;
|
||||
}
|
||||
|
||||
public void DisableKeyframeSet()
|
||||
{
|
||||
_setKeyframe = false;
|
||||
}
|
||||
|
||||
public void OnBackgroundDropdownSelected(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
Camera.main.clearFlags = CameraClearFlags.Skybox;
|
||||
//ColorPickerPanel.SetActive(false);
|
||||
break;
|
||||
case 1:
|
||||
Camera.main.clearFlags = CameraClearFlags.SolidColor;
|
||||
//ColorPickerPanel.SetActive(true);
|
||||
break;
|
||||
case 2:
|
||||
Camera.main.clearFlags = CameraClearFlags.Nothing;
|
||||
//ColorPickerPanel.SetActive(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBackgroundColor(Color color)
|
||||
{
|
||||
Camera.main.backgroundColor = color;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/ModelViewerBase/CameraSettings.cs.meta
Normal file
11
Assets/Scripts/ModelViewerBase/CameraSettings.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38982c2df9f1d8143ab670461e160feb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/ModelViewerBase/Containers.meta
Normal file
8
Assets/Scripts/ModelViewerBase/Containers.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee079ecd1686a3d43ae7b09d94eb43bb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
137
Assets/Scripts/ModelViewerBase/Containers/CameraContainer.cs
Normal file
137
Assets/Scripts/ModelViewerBase/Containers/CameraContainer.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
|
||||
public class CameraContainer: ObjectContainer
|
||||
{
|
||||
public CameraOrbit Camera;
|
||||
public KeyframeDataCamera LastPosition;
|
||||
public LineRenderer LineRenderer;
|
||||
|
||||
public CameraSettings Settings;
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
//Set default keyframe in custom ModelViewerMain
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!LineRenderer.enabled) return;
|
||||
|
||||
float fov = Settings.Fov;
|
||||
float aspect = Camera.Cam.aspect;
|
||||
float nearPlane = Camera.Cam.nearClipPlane;
|
||||
float farPlane = Camera.Cam.farClipPlane;
|
||||
|
||||
Vector3[] far = CalculateCameraFrustRect(fov, aspect, farPlane, transform);
|
||||
Vector3[] near = CalculateCameraFrustRect(fov, aspect, nearPlane, transform);
|
||||
|
||||
var edges = new Vector3[]
|
||||
{
|
||||
far[0], far[1], far[2], far[3], far[0], near[0], near[1], near[2], near[3], near[0], near[1], far[1], far[2], near[2], near[3], far[3]
|
||||
};
|
||||
|
||||
LineRenderer.positionCount = edges.Length;
|
||||
LineRenderer.SetPositions(edges);
|
||||
}
|
||||
|
||||
private static Vector3[] CalculateCameraFrustRect(float fieldOfView, float aspect, float dist, Transform transform)
|
||||
{
|
||||
dist = Mathf.Clamp(dist, 0.1f, 20f);
|
||||
|
||||
Vector3[] rect = new Vector3[4];
|
||||
float frustumHeight = 2.0F * dist * Mathf.Tan(fieldOfView * 0.5F * Mathf.Deg2Rad);
|
||||
rect[0] = transform.TransformPoint(new Vector3(-frustumHeight * aspect / 2, frustumHeight / 2, dist));
|
||||
rect[1] = transform.TransformPoint(new Vector3(frustumHeight * aspect / 2, frustumHeight / 2, dist));
|
||||
rect[2] = transform.TransformPoint(new Vector3(frustumHeight * aspect / 2, -frustumHeight / 2, dist));
|
||||
rect[3] = transform.TransformPoint(new Vector3(-frustumHeight * aspect / 2, -frustumHeight / 2, dist));
|
||||
|
||||
return (rect);
|
||||
}
|
||||
|
||||
Vector3 TransformPoint(Vector3 transforPos, Quaternion transformRotation, Vector3 transformScale, Vector3 pos)
|
||||
{
|
||||
Matrix4x4 matrix = Matrix4x4.TRS(transforPos, transformRotation, transformScale);
|
||||
return matrix.MultiplyPoint3x4(pos);
|
||||
}
|
||||
|
||||
Vector3 InverseTransformPoint(Vector3 transforPos, Quaternion transformRotation, Vector3 transformScale, Vector3 pos)
|
||||
{
|
||||
Matrix4x4 matrix = Matrix4x4.TRS(transforPos, transformRotation, transformScale);
|
||||
Matrix4x4 inverse = matrix.inverse;
|
||||
return inverse.MultiplyPoint3x4(pos);
|
||||
}
|
||||
|
||||
public override ObjectContainerSerializable Serialize()
|
||||
{
|
||||
var serialized = new CameraContainerSerializable(this);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
public override KeyframeData SerializeFrame()
|
||||
{
|
||||
return new KeyframeDataCamera(this);
|
||||
}
|
||||
|
||||
public override void Deserialize(ObjectContainerSerializable serialized)
|
||||
{
|
||||
DeserializeFrames(serialized);
|
||||
}
|
||||
|
||||
public override void Lerp(KeyframeData frame1, KeyframeData frame2, float amount)
|
||||
{
|
||||
var tsf = frame1 as KeyframeDataCamera;
|
||||
|
||||
if (frame1 != frame2)
|
||||
{
|
||||
tsf = tsf.Lerp(frame2, amount) as KeyframeDataCamera;
|
||||
}
|
||||
|
||||
var orbitLocator = ModelViewerMain.GetInstance().MainCameraOrbit;
|
||||
|
||||
if (ModelViewerMain.GetInstance().GetCameraHandler() == ModelViewerMain.GetInstance().WorkCameraOrbit)
|
||||
{
|
||||
//if in work camera mode, move the camera locator only
|
||||
orbitLocator.transform.position = tsf.Root.Position;
|
||||
orbitLocator.transform.eulerAngles = tsf.Root.Rotation;
|
||||
orbitLocator.LastPosition = tsf;
|
||||
}
|
||||
else
|
||||
{
|
||||
orbitLocator.PastePose(tsf, new PoseLoadOptions(true));
|
||||
}
|
||||
}
|
||||
|
||||
public override void Select()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Deselect()
|
||||
{
|
||||
}
|
||||
|
||||
public override void PastePose(KeyframeData frame, PoseLoadOptions pasteParams = null)
|
||||
{
|
||||
var keyframe = frame as KeyframeDataCamera;
|
||||
Camera.transform.localPosition = keyframe.Root.Position;
|
||||
Camera.transform.localEulerAngles = keyframe.Root.Rotation;
|
||||
Camera.lookRotation = keyframe.Root.Rotation;
|
||||
//if (Camera.lookRotation.x > 90) Camera.lookRotation.x -= 360;
|
||||
//if (Camera.lookRotation.x < -90) Camera.lookRotation.x += 360;
|
||||
//lookRotation.x = lookRotation.x - 360;
|
||||
|
||||
using (new KeyframeToggleContext(this))
|
||||
{
|
||||
Settings.DropdownCameraMode.value = keyframe.CameraMode;
|
||||
//Settings.ToggleCameraLock.isOn = keyframe.CameraLock;
|
||||
Settings.SliderFov.value = keyframe.Fov;
|
||||
Settings.SliderCamDist.value = keyframe.CamDist;
|
||||
Settings.SliderCamHeight.value = keyframe.CamHeight;
|
||||
Settings.SliderTargetHeight.value = keyframe.TargetHeigh;
|
||||
Settings.SliderCamAngle.value = keyframe.CamAngle;
|
||||
}
|
||||
|
||||
Camera.UpdateImmediate();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 72e8d74079817324498115876d689669
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
[Serializable]
|
||||
public class CameraContainerSerializable : ObjectContainerSerializable
|
||||
{
|
||||
public CameraContainerSerializable() { }
|
||||
|
||||
public CameraContainerSerializable(CameraContainer container)
|
||||
{
|
||||
GUID = "cameraOrbit";
|
||||
Frames = container.Frames.Select(f => new FrameContent(f)).ToList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a1693bb5411564489cd61fa721c0fd0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
257
Assets/Scripts/ModelViewerBase/Containers/ObjectContainer.cs
Normal file
257
Assets/Scripts/ModelViewerBase/Containers/ObjectContainer.cs
Normal file
@@ -0,0 +1,257 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class ObjectContainer : MonoBehaviour, IKeyframeSetter
|
||||
{
|
||||
[JsonIgnore] public bool DoNotSave;
|
||||
public int ModelId;
|
||||
public string GUID = "";
|
||||
public bool LoadInProgress = false;
|
||||
|
||||
public List<UIHandle> Handles = new List<UIHandle>();
|
||||
public List<Renderer> Renderers = new List<Renderer>();
|
||||
public Dictionary<SkinnedMeshRenderer, List<MorphHelper>> Morphs = new Dictionary<SkinnedMeshRenderer, List<MorphHelper>>();
|
||||
public List<FrameContent> Frames = new List<FrameContent>();
|
||||
public List<GameObject> InstantiatedObjects = new List<GameObject>();
|
||||
protected bool _setKeyframe = true;
|
||||
protected bool _applicationQuitting = false;
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
if (GUID == "")
|
||||
GUID = System.Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
public static T Create<T>(string name = "Container") where T : ObjectContainer
|
||||
{
|
||||
var container = new GameObject(name).AddComponent<T>();
|
||||
return container;
|
||||
}
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
if (ModelViewerMain.GetInstance() == null) return;
|
||||
if (DoNotSave) return;
|
||||
|
||||
if (Frames.Count == 0)
|
||||
{
|
||||
SetKeyframe();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void PasteContainer(ObjectContainerSerializable bones, PoseLoadOptions pasteParams)
|
||||
{
|
||||
GUID = bones.GUID;
|
||||
}
|
||||
|
||||
public virtual Vector3 GetCenter() { return transform.position; }
|
||||
|
||||
public void ToggleVisible(GameObject go, bool value)
|
||||
{
|
||||
go.SetActive(value);
|
||||
}
|
||||
|
||||
public void ToggleRendererVisible(Renderer r, bool value)
|
||||
{
|
||||
r.enabled = value;
|
||||
}
|
||||
|
||||
public virtual ObjectContainerSerializable Serialize()
|
||||
{
|
||||
return new ObjectContainerSerializable(this);
|
||||
}
|
||||
|
||||
public virtual KeyframeData SerializeFrame()
|
||||
{
|
||||
return new KeyframeData(this);
|
||||
}
|
||||
|
||||
public virtual void Deserialize(ObjectContainerSerializable serialized)
|
||||
{
|
||||
throw new NotImplementedException(GetType().FullName);
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
if (_applicationQuitting) return;
|
||||
|
||||
foreach (var rend in Renderers)
|
||||
{
|
||||
for (int i = rend.sharedMaterials.Length - 1; i >= 0; i--)
|
||||
{
|
||||
Destroy(rend.sharedMaterials[i]);
|
||||
}
|
||||
}
|
||||
foreach (var obj in InstantiatedObjects)
|
||||
{
|
||||
Destroy(obj);
|
||||
}
|
||||
ModelViewerMain.UnregisterObject(this);
|
||||
if (gameObject != null)
|
||||
Destroy(gameObject);
|
||||
Resources.UnloadUnusedAssets();
|
||||
System.GC.Collect();
|
||||
}
|
||||
|
||||
#region Timeline
|
||||
public virtual DataType GetDataType()
|
||||
{
|
||||
switch (this)
|
||||
{
|
||||
case SceneContainer _:
|
||||
return DataType.Scene;
|
||||
case CameraContainer _:
|
||||
return DataType.Camera;
|
||||
default:
|
||||
return DataType.Character;
|
||||
}
|
||||
}
|
||||
|
||||
public FrameContent TryGetFrame(int frameNum)
|
||||
{
|
||||
return Frames.FirstOrDefault(f => f.FrameNum == frameNum);
|
||||
}
|
||||
|
||||
public void GetClosestFrames(int frame, out FrameContent previousFrame, out FrameContent nextFrame)
|
||||
{
|
||||
previousFrame = null;
|
||||
nextFrame = null;
|
||||
|
||||
var frames = Frames.OrderBy(f => f.FrameNum).ToArray();
|
||||
|
||||
for (int i = 0; i < Frames.Count; i++)
|
||||
{
|
||||
if (Frames[i].FrameNum < frame)
|
||||
{
|
||||
previousFrame = nextFrame = frames[i];
|
||||
}
|
||||
else if (Frames[i].FrameNum == frame)
|
||||
{
|
||||
previousFrame = nextFrame = frames[i];
|
||||
break;
|
||||
}
|
||||
else if (Frames[i].FrameNum > frame)
|
||||
{
|
||||
if (previousFrame == null) previousFrame = frames[i];
|
||||
nextFrame = frames[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Returns true if frame existed or false if it was created </summary>
|
||||
public bool GetCurrentFrame(int frame, out FrameContent currentFrame)
|
||||
{
|
||||
GetClosestFrames(frame, out var previousFrame, out var nextFrame);
|
||||
|
||||
if (previousFrame.FrameNum == frame)
|
||||
{
|
||||
currentFrame = previousFrame;
|
||||
return true;
|
||||
}
|
||||
else if (nextFrame.FrameNum == frame)
|
||||
{
|
||||
currentFrame = nextFrame;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentFrame = new FrameContent(frame);
|
||||
Frames.Add(currentFrame);
|
||||
Frames = Frames.OrderBy(f => f.FrameNum).ToList();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetKeyframe(int frameNum = -1)
|
||||
{
|
||||
if (DoNotSave || !_setKeyframe) return;
|
||||
Debug.Log("Setting frame for " + name);
|
||||
//if (Frames.Count == 0) SetDefaultFrame();
|
||||
if (frameNum == -1) frameNum = TimelineController.Instance.CurrentFrame;
|
||||
|
||||
GetClosestFrames(frameNum, out var previousFrame, out var nextFrame);
|
||||
|
||||
FrameContent currentFrame = null;
|
||||
if (previousFrame == null || previousFrame.FrameNum != frameNum)
|
||||
{
|
||||
currentFrame = new FrameContent(frameNum);
|
||||
Frames.Add(currentFrame);
|
||||
Frames = Frames.OrderBy(f => f.FrameNum).ToList();
|
||||
}
|
||||
else if (previousFrame.FrameNum == frameNum) currentFrame = previousFrame;
|
||||
else if (nextFrame.FrameNum == frameNum) currentFrame = nextFrame;
|
||||
|
||||
currentFrame.SetObjectData(SerializeFrame());
|
||||
|
||||
TimelineController.UpdateTimeline();
|
||||
}
|
||||
|
||||
public void SetDefaultFrame()
|
||||
{
|
||||
Frames = new List<FrameContent>()
|
||||
{
|
||||
new FrameContent(0).SetObjectData(SerializeFrame())
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public virtual void DeserializeFrames(ObjectContainerSerializable serialized)
|
||||
{
|
||||
Frames = serialized.Frames.Select(f => new FrameContent(f)).ToList();
|
||||
}
|
||||
|
||||
public virtual void Lerp(KeyframeData frame1, KeyframeData frame2, float amount)
|
||||
{
|
||||
if (frame1 == frame2)
|
||||
{
|
||||
PastePose(frame1, new PoseLoadOptions(true));
|
||||
}
|
||||
else
|
||||
{
|
||||
PastePose(frame1.Lerp(frame2, amount), new PoseLoadOptions(true));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void PastePose(KeyframeData frame, PoseLoadOptions pasteParams)
|
||||
{
|
||||
if (pasteParams.Root)
|
||||
{
|
||||
transform.SetTransform(frame.Root);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Deselect()
|
||||
{
|
||||
throw new NotImplementedException(this.GetType().FullName);
|
||||
}
|
||||
|
||||
public virtual void Select()
|
||||
{
|
||||
throw new NotImplementedException(this.GetType().FullName);
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
Destroy(this.gameObject);
|
||||
}
|
||||
|
||||
public void EnableKeyframeSet()
|
||||
{
|
||||
_setKeyframe = true;
|
||||
}
|
||||
|
||||
public void DisableKeyframeSet()
|
||||
{
|
||||
_setKeyframe = false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
_applicationQuitting = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bf6dfe0e5776cd49b8f8923c18704da
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
[System.Serializable]
|
||||
public class ObjectContainerSerializable
|
||||
{
|
||||
public string Filename;
|
||||
public string GUID;
|
||||
public List<FrameContent> Frames;
|
||||
|
||||
public ObjectContainerSerializable() { }
|
||||
|
||||
public ObjectContainerSerializable(ObjectContainer containerBase)
|
||||
{
|
||||
this.Filename = containerBase.name;
|
||||
this.GUID = containerBase.GUID;
|
||||
this.Frames = containerBase.Frames.Select(frame => new FrameContent(frame)).ToList();
|
||||
}
|
||||
|
||||
public ObjectContainerSerializable(ObjectContainerSerializable source)
|
||||
{
|
||||
this.Filename = source.Filename;
|
||||
this.GUID = source.GUID;
|
||||
this.Frames = source.Frames.Select(frame => new FrameContent(frame)).ToList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85c39ae818417104eb7ae9174bd0f708
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
37
Assets/Scripts/ModelViewerBase/Containers/SceneContainer.cs
Normal file
37
Assets/Scripts/ModelViewerBase/Containers/SceneContainer.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public class SceneContainer : ObjectContainer
|
||||
{
|
||||
public CameraContainer MainCameraOrbit;
|
||||
public CameraContainer WorkCameraOrbit;
|
||||
|
||||
public List<ObjectContainer> AllObjects = new List<ObjectContainer>();
|
||||
|
||||
public List<T> Objects<T>() where T : ObjectContainer
|
||||
{
|
||||
return AllObjects.Cast<T>().ToList();
|
||||
}
|
||||
|
||||
public static SceneContainer Create<T>(ModelViewerMain main) where T : SceneContainer
|
||||
{
|
||||
var container = new GameObject("Scene").AddComponent<T>();
|
||||
container.Init(main);
|
||||
return container;
|
||||
}
|
||||
|
||||
public virtual void Init(ModelViewerMain main)
|
||||
{
|
||||
GUID = "scene";
|
||||
MainCameraOrbit = main.MainCameraOrbit;
|
||||
WorkCameraOrbit = main.WorkCameraOrbit;
|
||||
SetDefaultFrame();
|
||||
AllObjects.Add(MainCameraOrbit);
|
||||
}
|
||||
|
||||
public override ObjectContainerSerializable Serialize()
|
||||
{
|
||||
return new SceneSerializable(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 520e0b69d9f17e2488c1eb19d9a50940
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
[Serializable]
|
||||
public class SceneSerializable : ObjectContainerSerializable
|
||||
{
|
||||
public string Version;
|
||||
public string Date;
|
||||
public TimelineControllerSerializable Timeline;
|
||||
public List<ObjectContainerSerializable> Objects = new List<ObjectContainerSerializable>();
|
||||
|
||||
public SceneSerializable() { }
|
||||
|
||||
public SceneSerializable(SceneContainer scene)
|
||||
{
|
||||
this.Version = Application.version;
|
||||
this.Date = DateTime.Now.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture); ;
|
||||
this.Timeline = new TimelineControllerSerializable(TimelineController.Instance);
|
||||
this.Frames = scene.Frames.Select(f => new FrameContent(f)).ToList();
|
||||
foreach (var obj in scene.AllObjects)
|
||||
{
|
||||
if (obj != scene)
|
||||
Objects.Add(obj.Serialize());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7592143342b8b0741831e85e6a2f88b1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/ModelViewerBase/Inverse Kinematics.meta
Normal file
8
Assets/Scripts/ModelViewerBase/Inverse Kinematics.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d421e7c2f2db7e4c90eed5665505326
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,156 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class InverseKinematics : MonoBehaviour {
|
||||
private Material lineMaterial;
|
||||
private Dictionary<GameObject, Transform[]> linePoints = new Dictionary<GameObject, Transform[]>();
|
||||
public bool SoftEnabled = true;
|
||||
|
||||
public Transform upperArm;
|
||||
public Transform forearm;
|
||||
public Transform hand;
|
||||
public Transform elbow;
|
||||
public Transform target;
|
||||
[Space(20)]
|
||||
public Vector3 uppperArm_OffsetRotation;
|
||||
public Vector3 forearm_OffsetRotation;
|
||||
public Vector3 hand_OffsetRotation;
|
||||
[Space(20)]
|
||||
public bool handMatchesTargetRotation = true;
|
||||
[Space(20)]
|
||||
public bool linesVisible = true;
|
||||
public bool forceLinesInvisible = true;
|
||||
|
||||
float angle;
|
||||
float upperArm_Length;
|
||||
float forearm_Length;
|
||||
float arm_Length;
|
||||
float targetDistance;
|
||||
float adyacent;
|
||||
|
||||
public void SpawnLines(Color specialColor) {
|
||||
lineMaterial = new Material(Shader.Find("Legacy Shaders/Particles/Alpha Blended Premultiply"));
|
||||
NewLine(upperArm, elbow, 0.005f, Color.yellow);
|
||||
NewLine(elbow, target, 0.005f, Color.yellow);
|
||||
NewLine(upperArm, target, 0.005f, Color.white);
|
||||
NewLine(forearm, elbow, 0.01f, specialColor);
|
||||
}
|
||||
|
||||
void NewLine(Transform point1, Transform point2, float width, Color color)
|
||||
{
|
||||
GameObject go = new GameObject("line");
|
||||
go.layer = 5;
|
||||
go.transform.SetParent(this.transform);
|
||||
var lr = go.AddComponent<LineRenderer>();
|
||||
lr.startWidth = lr.endWidth = width;
|
||||
lr.startColor = lr.endColor = color;
|
||||
lr.sharedMaterial = lineMaterial;
|
||||
|
||||
linePoints.Add(go, new Transform[] { point1, point2 });
|
||||
}
|
||||
|
||||
void UpdateLines()
|
||||
{
|
||||
foreach(var kv in linePoints)
|
||||
{
|
||||
var lr = kv.Key.GetComponent<LineRenderer>();
|
||||
if (!SoftEnabled)
|
||||
{
|
||||
if(lr.enabled != SoftEnabled)
|
||||
{
|
||||
lr.enabled = SoftEnabled;
|
||||
}
|
||||
}
|
||||
else if((lr.enabled != linesVisible) || (lr.enabled && forceLinesInvisible))
|
||||
{
|
||||
if(forceLinesInvisible)
|
||||
{
|
||||
lr.enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
lr.enabled = linesVisible;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < kv.Value.Length; i++)
|
||||
{
|
||||
lr.SetPosition(i, kv.Value[i].position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void LateUpdate () {
|
||||
if(upperArm != null && forearm != null && hand != null && elbow != null && target != null)
|
||||
{
|
||||
if (SoftEnabled)
|
||||
{
|
||||
upperArm_Length = Vector3.Distance(upperArm.position, forearm.position);
|
||||
forearm_Length = Vector3.Distance(forearm.position, hand.position);
|
||||
arm_Length = upperArm_Length + forearm_Length;
|
||||
targetDistance = Vector3.Distance(upperArm.position, target.position);
|
||||
targetDistance = Mathf.Min(targetDistance, arm_Length - arm_Length * 0.001f);
|
||||
|
||||
upperArm.LookAt(target, elbow.position - upperArm.position);
|
||||
upperArm.Rotate(uppperArm_OffsetRotation);
|
||||
|
||||
Vector3 cross = Vector3.Cross(elbow.position - upperArm.position, forearm.position - upperArm.position);
|
||||
|
||||
adyacent = ((upperArm_Length * upperArm_Length) - (forearm_Length * forearm_Length) + (targetDistance * targetDistance)) / (2 * targetDistance);
|
||||
|
||||
angle = Mathf.Acos(adyacent / upperArm_Length) * Mathf.Rad2Deg;
|
||||
|
||||
if (float.IsNaN(angle))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Vector3 oldPosition = upperArm.localPosition;
|
||||
upperArm.RotateAround(upperArm.position, cross, -angle);
|
||||
upperArm.localPosition = oldPosition;
|
||||
|
||||
forearm.LookAt(target, cross);
|
||||
forearm.Rotate(forearm_OffsetRotation);
|
||||
|
||||
if (handMatchesTargetRotation)
|
||||
{
|
||||
hand.rotation = target.rotation;
|
||||
hand.Rotate(hand_OffsetRotation);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//target.position = hand.position;
|
||||
//target.rotation = hand.rotation;
|
||||
//target.Rotate(-hand_OffsetRotation);
|
||||
//elbow.position = forearm.position;
|
||||
}
|
||||
UpdateLines();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
Destroy(lineMaterial);
|
||||
foreach(var i in linePoints)
|
||||
{
|
||||
Destroy(i.Key);
|
||||
}
|
||||
Destroy(elbow.gameObject);
|
||||
Destroy(target.gameObject);
|
||||
}
|
||||
|
||||
void OnDrawGizmos(){
|
||||
if (linesVisible) {
|
||||
if(upperArm != null && elbow != null && hand != null && target != null && elbow != null){
|
||||
Gizmos.color = Color.gray;
|
||||
Gizmos.DrawLine (upperArm.position, forearm.position);
|
||||
Gizmos.DrawLine (forearm.position, hand.position);
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawLine (upperArm.position, target.position);
|
||||
Gizmos.color = Color.blue;
|
||||
Gizmos.DrawLine (forearm.position, elbow.position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30d20bcf9ec4ed24b97a6e8ab136c34f
|
||||
timeCreated: 1499795966
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
38
Assets/Scripts/ModelViewerBase/ModelBuilder.cs
Normal file
38
Assets/Scripts/ModelViewerBase/ModelBuilder.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
public class ModelBuilder : MonoBehaviour
|
||||
{
|
||||
public static ModelBuilder _mainInstance;
|
||||
|
||||
public static ModelBuilder GetInstance()
|
||||
{
|
||||
return _mainInstance;
|
||||
}
|
||||
|
||||
public static T GetInstance<T>() where T : ModelBuilder
|
||||
{
|
||||
return _mainInstance as T;
|
||||
}
|
||||
|
||||
public virtual IEnumerator SpawnSerialized(ObjectContainerSerializable oc, Action<GameObject> callback = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerator SpawnAsset(string assetPath, Action<ObjectContainer> callback = null)
|
||||
{
|
||||
yield return SpawnAsset(AssetTypes.Unknown, assetPath, callback);
|
||||
}
|
||||
|
||||
public virtual IEnumerator SpawnAsset(Enum assetType, string assetPath, Action<ObjectContainer> callback = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual IEnumerator SpawnAsset(AssetSpawnData data, Action<ObjectContainer> callback = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/ModelViewerBase/ModelBuilder.cs.meta
Normal file
11
Assets/Scripts/ModelViewerBase/ModelBuilder.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3553f9c3dfc57b14d95850ae26fc05e7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
21
Assets/Scripts/ModelViewerBase/ModelViewerBase.asmdef
Normal file
21
Assets/Scripts/ModelViewerBase/ModelViewerBase.asmdef
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "ModelViewerBase",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:6055be8ebefd69e48b49212b09b47b2f",
|
||||
"GUID:24ad1c085c49dc34dbe16c3d92c6f299",
|
||||
"GUID:aee7fa92e14bf364ebccdd24623e1764",
|
||||
"GUID:ee695b84b4c90104b9367eebc6b0d70d",
|
||||
"GUID:9e24947de15b9834991c9d8411ea37cf",
|
||||
"GUID:84651a3751eca9349aac36a66bba901b"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f135e4ce2898524aa1e81c5cd7f1242
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
197
Assets/Scripts/ModelViewerBase/ModelViewerDownloader.cs
Normal file
197
Assets/Scripts/ModelViewerBase/ModelViewerDownloader.cs
Normal file
@@ -0,0 +1,197 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
public class ModelViewerDownloader
|
||||
{
|
||||
public static string UrlBase = "";
|
||||
public static string SaveLocation = "/idbfs/ModelViewer/";
|
||||
|
||||
public static ModelViewerDownloader Instance;
|
||||
public bool SyncRequired;
|
||||
|
||||
public ModelViewerDownloader() : this(UrlBase, "/idbfs/ModelViewer/") { }
|
||||
|
||||
public ModelViewerDownloader(string baseUrl, string saveLocation)
|
||||
{
|
||||
UrlBase = baseUrl;
|
||||
SaveLocation = saveLocation;
|
||||
ModelViewerMain.GetInstance().StartCoroutine(Loop());
|
||||
}
|
||||
|
||||
public class DownloadTask
|
||||
{
|
||||
public string Name;
|
||||
public bool Redownload = false;
|
||||
public bool Finished = false;
|
||||
public bool Success = false;
|
||||
public int Priority = 0;
|
||||
public string ResultText;
|
||||
public byte[] ResultBytes;
|
||||
public System.Action OnDownloadSuccess;
|
||||
|
||||
public DownloadTask(string name, int priority, bool redownload)
|
||||
{
|
||||
Name = name;
|
||||
Priority = priority;
|
||||
Redownload = redownload;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<DownloadTask> _downloadRunning = new List<DownloadTask>();
|
||||
private static List<DownloadTask> _downloadQueue = new List<DownloadTask>();
|
||||
|
||||
public IEnumerator Loop()
|
||||
{
|
||||
float lastSync = 5;
|
||||
while (true)
|
||||
{
|
||||
if(_downloadQueue.Count > 0)
|
||||
{
|
||||
_downloadRunning.AddRange(_downloadQueue);
|
||||
_downloadRunning = _downloadRunning.OrderByDescending(d=>d.Priority).ToList();
|
||||
_downloadQueue.Clear();
|
||||
}
|
||||
if(_downloadRunning.Count > 0)
|
||||
{
|
||||
var fileToDownload = _downloadRunning[0];
|
||||
_downloadRunning.RemoveAt(0);
|
||||
yield return DownloadFile(fileToDownload);
|
||||
if(!_downloadRunning.Any() && !_downloadQueue.Any())
|
||||
{
|
||||
SyncRequired = true;
|
||||
lastSync = 0;
|
||||
}
|
||||
}
|
||||
if(SyncRequired)
|
||||
{
|
||||
lastSync += Time.deltaTime;
|
||||
if(lastSync >= 5)
|
||||
{
|
||||
CommitChanges();
|
||||
}
|
||||
}
|
||||
yield return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerator WaitForDownload(string name, int priority = 0, bool redownload = false, System.Action<string[]> lines = null, System.Action<byte[]> bytes = null, System.Action<string> text = null, System.Action onDownloadSuccess = null)
|
||||
{
|
||||
var task = _downloadQueue.Concat(_downloadRunning).FirstOrDefault(t => t.Name == name);
|
||||
|
||||
if(task == null)
|
||||
{
|
||||
task = new DownloadTask(name, priority, redownload);
|
||||
task.OnDownloadSuccess = onDownloadSuccess;
|
||||
_downloadQueue.Add(task);
|
||||
}
|
||||
|
||||
while (!task.Finished)
|
||||
{
|
||||
yield return 0;
|
||||
}
|
||||
|
||||
lines?.Invoke(task.ResultText.Split('\n').Select(s => s.Trim()).ToArray());
|
||||
bytes?.Invoke(task.ResultBytes);
|
||||
text?.Invoke(task.ResultText);
|
||||
}
|
||||
|
||||
private IEnumerator DownloadFile(DownloadTask task)
|
||||
{
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
string fileSavePath = $"{SaveLocation}{task.Name}";
|
||||
#else
|
||||
string fileSavePath = Application.persistentDataPath + " /" + task.Name;
|
||||
#endif
|
||||
|
||||
if (!task.Redownload && LoadFromIdbfs(fileSavePath, out var data))
|
||||
{
|
||||
//Debug.Log("Loaded from " + fileSavePath);
|
||||
task.Success = true;
|
||||
task.ResultText = Encoding.UTF8.GetString(data);
|
||||
task.ResultBytes = data;
|
||||
task.Finished = true;
|
||||
yield break;
|
||||
}
|
||||
|
||||
string url = UrlBase + task.Name + (task.Redownload ? "?time=" + DateTime.Now.Ticks.ToString() : "");
|
||||
//var downloadPanel = KFKViewerUI.Instance.DownloadPanel;
|
||||
|
||||
//Msg.Log(url);
|
||||
|
||||
using (var www = UnityWebRequest.Get(url))
|
||||
{
|
||||
//downloadPanel.gameObject.SetActive(true);
|
||||
|
||||
var operation = www.SendWebRequest();
|
||||
|
||||
do
|
||||
{
|
||||
//downloadPanel.SetStatus(task.Name, www.downloadProgress);
|
||||
yield return null;
|
||||
}
|
||||
while (!operation.isDone);
|
||||
|
||||
if (www.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
Error.Log(Color.red, www.error);
|
||||
task.Success = false;
|
||||
task.ResultText = "";
|
||||
task.ResultBytes = new byte[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveToIdbfs(fileSavePath, www.downloadHandler.data);
|
||||
task.OnDownloadSuccess?.Invoke();
|
||||
task.Success = true;
|
||||
task.ResultText = www.downloadHandler.text;
|
||||
task.ResultBytes = www.downloadHandler.data;
|
||||
}
|
||||
}
|
||||
|
||||
//downloadPanel.SetStatus(task.Name, 0);
|
||||
//downloadPanel.gameObject.SetActive(false);
|
||||
|
||||
task.Finished = true;
|
||||
}
|
||||
|
||||
public static bool LoadFromIdbfs(string name, out byte[] data)
|
||||
{
|
||||
if(File.Exists(name))
|
||||
{
|
||||
data = File.ReadAllBytes(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SaveToIdbfs(string path, byte[] data)
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
File.WriteAllBytes(path, data);
|
||||
//Debug.Log("Saved " + path);
|
||||
}
|
||||
|
||||
private static void CommitChanges()
|
||||
{
|
||||
Instance.SyncRequired = false;
|
||||
Debug.Log("Database Updated");
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
SyncFiles();
|
||||
#endif
|
||||
}
|
||||
|
||||
[DllImport("__Internal")]
|
||||
private static extern void SyncFiles();
|
||||
}
|
||||
11
Assets/Scripts/ModelViewerBase/ModelViewerDownloader.cs.meta
Normal file
11
Assets/Scripts/ModelViewerBase/ModelViewerDownloader.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 413260822fc499146b2e2bfdc91a5a21
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
93
Assets/Scripts/ModelViewerBase/ModelViewerInterface.cs
Normal file
93
Assets/Scripts/ModelViewerBase/ModelViewerInterface.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UIPanels;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
public class ModelViewerInterface : MonoBehaviour
|
||||
{
|
||||
public static ModelViewerInterface _mainInstance;
|
||||
|
||||
public Transform DynamicPanels;
|
||||
public TMPro.TMP_Text[] TooltipLabels;
|
||||
|
||||
public ScrollRect ScenePresetToggle;
|
||||
public ScrollRect PosePresetToggle;
|
||||
|
||||
public List<UIToolbarPanel> TopbarPanels;
|
||||
|
||||
public UIPanels.UIToolbarPanel TogglesContent;
|
||||
public UIPanels.UISaveLoadPanel SaveLoadPanel;
|
||||
public UIPanels.UICameraSettingsPanel CameraSettingsPanel;
|
||||
|
||||
public Canvas MainCanvas;
|
||||
|
||||
public RectTransform Tooltip;
|
||||
public TMPro.TextMeshProUGUI TooltipText;
|
||||
|
||||
public static ModelViewerInterface GetInstance()
|
||||
{
|
||||
return _mainInstance;
|
||||
}
|
||||
|
||||
public static T GetInstance<T>() where T : ModelViewerInterface
|
||||
{
|
||||
return _mainInstance as T;
|
||||
}
|
||||
|
||||
public static void SetTooltip(int index, string tooltip)
|
||||
{
|
||||
var tooltips = GetInstance().TooltipLabels;
|
||||
if(tooltips.Length > index)
|
||||
{
|
||||
tooltips[index].SetText(tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void ToggleVisible(GameObject go)
|
||||
{
|
||||
ToggleVisible(go, false);
|
||||
}
|
||||
|
||||
public static void ToggleVisible(GameObject go, bool force = false, bool forceValue = false)
|
||||
{
|
||||
if (force)
|
||||
{
|
||||
go.SetActive(forceValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
go.SetActive(!go.activeSelf);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetDropdownData(TMPro.TMP_Dropdown dd, List<string> values, bool nullValue = false, bool sortValues = false)
|
||||
{
|
||||
dd.ClearOptions();
|
||||
if (nullValue)
|
||||
dd.AddOptions(new List<string>() { Strings.NoValueSelectedString });
|
||||
if (values != null)
|
||||
{
|
||||
if (sortValues)
|
||||
{
|
||||
values = new List<string>(values);
|
||||
values.Sort();
|
||||
}
|
||||
dd.AddOptions(values);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DropdownPrevious(TMPro.TMP_Dropdown dropdown)
|
||||
{
|
||||
Error.Log(Color.red, "Remove this");
|
||||
dropdown.value = dropdown.value - 1 < 0 ? dropdown.options.Count - 1 : dropdown.value - 1;
|
||||
}
|
||||
|
||||
public static void DropdownNext(TMPro.TMP_Dropdown dropdown)
|
||||
{
|
||||
Error.Log(Color.red, "Remove this");
|
||||
dropdown.value = dropdown.value + 1 >= dropdown.options.Count ? 0 : dropdown.value + 1;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/ModelViewerBase/ModelViewerInterface.cs.meta
Normal file
11
Assets/Scripts/ModelViewerBase/ModelViewerInterface.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b1090dfa84b72140b13b27e73e267f2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
178
Assets/Scripts/ModelViewerBase/ModelViewerMain.cs
Normal file
178
Assets/Scripts/ModelViewerBase/ModelViewerMain.cs
Normal file
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class ModelViewerMain : MonoBehaviour
|
||||
{
|
||||
protected static ModelViewerMain _mainInstance;
|
||||
|
||||
[SerializeField]
|
||||
public CameraContainer
|
||||
MainCameraOrbit,
|
||||
WorkCameraOrbit;
|
||||
|
||||
public OperationMode Mode;
|
||||
public SceneContainer CurrentScene;
|
||||
public ObjectContainer SelectedObject;
|
||||
public List<ObjectContainer> SelectedObjects = new List<ObjectContainer>();
|
||||
|
||||
protected float[] _backupTimes = new float[] { 15 * 60, 5 * 60, 60 };
|
||||
protected float[] _backupTimers;
|
||||
|
||||
public enum OperationMode
|
||||
{
|
||||
Single,
|
||||
Multiple
|
||||
}
|
||||
|
||||
public static ModelViewerMain GetInstance()
|
||||
{
|
||||
return _mainInstance;
|
||||
}
|
||||
|
||||
public static T GetInstance<T>() where T : ModelViewerMain
|
||||
{
|
||||
return _mainInstance as T;
|
||||
}
|
||||
|
||||
public CameraOrbit GetCamera()
|
||||
{
|
||||
return CurrentScene.MainCameraOrbit.Camera;
|
||||
}
|
||||
|
||||
public CameraContainer GetCameraHandler()
|
||||
{
|
||||
if (!CurrentScene.MainCameraOrbit.LineRenderer.enabled)
|
||||
return CurrentScene.MainCameraOrbit;
|
||||
else
|
||||
return CurrentScene.WorkCameraOrbit;
|
||||
}
|
||||
|
||||
public static void RegisterObject(ObjectContainer container)
|
||||
{
|
||||
GetInstance().CurrentScene.AllObjects.Add(container);
|
||||
}
|
||||
|
||||
public static void UnregisterObject(ObjectContainer container)
|
||||
{
|
||||
GetInstance().CurrentScene.AllObjects.Remove(container);
|
||||
GetInstance().SelectionRemove(container);
|
||||
}
|
||||
|
||||
public T GetSelectedObject<T>() where T: ObjectContainer
|
||||
{
|
||||
return SelectedObject as T;
|
||||
}
|
||||
|
||||
public T GetCurrentScene<T>() where T : SceneContainer
|
||||
{
|
||||
return CurrentScene as T;
|
||||
}
|
||||
|
||||
public void SelectObject(ObjectContainer container)
|
||||
{
|
||||
if (SelectedObject == container) return;
|
||||
|
||||
Debug.Log(SelectedObject);
|
||||
|
||||
if(Mode == OperationMode.Single)
|
||||
{
|
||||
SelectedObject?.Destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedObject?.Deselect();
|
||||
}
|
||||
|
||||
SelectedObject = container;
|
||||
SelectedObject?.Select();
|
||||
|
||||
TimelineController.UpdateTimeline();
|
||||
}
|
||||
|
||||
public void SelectionAdd(ObjectContainer container)
|
||||
{
|
||||
if (container == null) return;
|
||||
|
||||
if (SelectedObjects.Count == 0)
|
||||
{
|
||||
SelectedObjects.Add(container);
|
||||
SelectObject(container);
|
||||
}
|
||||
else if(container != null && !SelectedObjects.Contains(container))
|
||||
{
|
||||
SelectedObjects.Add(container);
|
||||
}
|
||||
}
|
||||
|
||||
public void SelectionRemove(ObjectContainer container)
|
||||
{
|
||||
if (container == null) return;
|
||||
|
||||
bool wasSelected = container == SelectedObject;
|
||||
|
||||
if (container != null && SelectedObjects.Contains(container))
|
||||
{
|
||||
SelectedObjects.Remove(container);
|
||||
if (wasSelected)
|
||||
{
|
||||
if(SelectedObjects.Count > 0)
|
||||
{
|
||||
SelectObject(SelectedObjects[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectObject(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SelectionClear()
|
||||
{
|
||||
SelectedObjects.Clear();
|
||||
}
|
||||
|
||||
public void EmptyScene<T>() where T : SceneContainer
|
||||
{
|
||||
DestroyImmediate(CurrentScene);
|
||||
CurrentScene = SceneContainer.Create<T>(this);
|
||||
|
||||
ModelViewerMain.GetInstance().SelectionClear();
|
||||
TimelineController.UpdateTimeline();
|
||||
}
|
||||
|
||||
public SceneSerializable SaveScene()
|
||||
{
|
||||
return CurrentScene.Serialize() as SceneSerializable;
|
||||
}
|
||||
|
||||
public virtual IEnumerator LoadScene(SceneSerializable bc)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected void AutoSaveUpdate()
|
||||
{
|
||||
bool skip = false;
|
||||
for (int i = 0; i < _backupTimes.Length; i++)
|
||||
{
|
||||
_backupTimers[i] -= Time.deltaTime;
|
||||
if (skip)
|
||||
{
|
||||
_backupTimers[i] = _backupTimes[i];
|
||||
}
|
||||
else if (_backupTimers[i] <= 0)
|
||||
{
|
||||
_backupTimers[i] = _backupTimes[i];
|
||||
|
||||
var scene = SaveScene();
|
||||
scene.Filename = $"AutoBackup_{_backupTimes[i]}";
|
||||
UISceneContainer.CreateNew(scene, true).Save(true);
|
||||
|
||||
skip = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/ModelViewerBase/ModelViewerMain.cs.meta
Normal file
11
Assets/Scripts/ModelViewerBase/ModelViewerMain.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b829d711d6087b41a841693e6a48c1b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user