├── .gitignore ├── Editor.meta ├── Editor ├── Jacky's Editor Helpers.meta ├── Jacky's Editor Helpers │ ├── EditorExtensions.cs │ ├── EditorExtensions.cs.meta │ ├── EditorHelper.cs │ ├── EditorHelper.cs.meta │ ├── JackysStyles.cs │ ├── JackysStyles.cs.meta │ ├── LICENSE.txt │ └── LICENSE.txt.meta ├── MultiMouseConstants.cs ├── MultiMouseConstants.cs.meta ├── MultiMouseInputDebugger.cs ├── MultiMouseInputDebugger.cs.meta ├── MultiMouseSettingsEditor.cs ├── MultiMouseSettingsEditor.cs.meta ├── MultiMouseSettingsProvider.cs └── MultiMouseSettingsProvider.cs.meta ├── Examples.meta ├── Examples ├── Lightgun Example.meta └── Lightgun Example │ ├── Animations.meta │ ├── Animations │ ├── MuzzleFlash.anim │ ├── MuzzleFlash.anim.meta │ ├── PistolFire.anim │ ├── PistolFire.anim.meta │ ├── Target.controller │ ├── Target.controller.meta │ ├── TargetFlip.anim │ └── TargetFlip.anim.meta │ ├── Audio.meta │ ├── Audio │ ├── 392229__morganpurkis__single-pistol-gunshot-3-3.wav │ └── 392229__morganpurkis__single-pistol-gunshot-3-3.wav.meta │ ├── Fonts.meta │ ├── Fonts │ ├── FugazOne.meta │ └── FugazOne │ │ ├── FugazOne-Regular.ttf │ │ ├── FugazOne-Regular.ttf.meta │ │ ├── OFL.txt │ │ └── OFL.txt.meta │ ├── Kenney Crosshairs.meta │ ├── Kenney Crosshairs │ ├── Kenney.url │ ├── Kenney.url.meta │ ├── License.txt │ ├── License.txt.meta │ ├── Patreon.url │ ├── Patreon.url.meta │ ├── Size.txt │ ├── Size.txt.meta │ ├── crosshair037.png │ ├── crosshair037.png.meta │ ├── crosshair042.png │ └── crosshair042.png.meta │ ├── Kenney Weapon Pack.meta │ ├── Kenney Weapon Pack │ ├── pistol.mat │ ├── pistol.mat.meta │ ├── pistol.obj │ ├── pistol.obj.meta │ ├── pistol_slide.mat │ └── pistol_slide.mat.meta │ ├── Materials.meta │ ├── Materials │ ├── Ground.mat │ ├── Ground.mat.meta │ ├── Target.mat │ └── Target.mat.meta │ ├── Prefabs.meta │ ├── Prefabs │ ├── Crosshair.prefab │ ├── Crosshair.prefab.meta │ ├── MuzzleFlash.prefab │ ├── MuzzleFlash.prefab.meta │ ├── Player.prefab │ ├── Player.prefab.meta │ ├── PlayerSlot.prefab │ ├── PlayerSlot.prefab.meta │ ├── Target.prefab │ └── Target.prefab.meta │ ├── Scenes.meta │ ├── Scenes │ ├── Lightgun00.unity │ ├── Lightgun00.unity.meta │ ├── Lightgun01.unity │ └── Lightgun01.unity.meta │ ├── Scripts.meta │ ├── Scripts │ ├── Crosshair.cs │ ├── Crosshair.cs.meta │ ├── IShootable.cs │ ├── IShootable.cs.meta │ ├── Lightgun.cs │ ├── Lightgun.cs.meta │ ├── PlayerBehaviour.cs │ ├── PlayerBehaviour.cs.meta │ ├── SceneLoader.cs │ ├── SceneLoader.cs.meta │ ├── TargetBehaviour.cs │ ├── TargetBehaviour.cs.meta │ ├── UI.meta │ ├── UI │ │ ├── MainMenuUI.cs │ │ ├── MainMenuUI.cs.meta │ │ ├── MultiMouseInputModule.cs │ │ ├── MultiMouseInputModule.cs.meta │ │ ├── PlayerSlot.cs │ │ ├── PlayerSlot.cs.meta │ │ ├── UILightgun.cs │ │ └── UILightgun.cs.meta │ ├── ViewModelRotator.cs │ ├── ViewModelRotator.cs.meta │ ├── WeaponObject.cs │ └── WeaponObject.cs.meta │ ├── Sprites.meta │ ├── Sprites │ ├── Title Graphic.psd │ ├── Title Graphic.psd.meta │ ├── target.jpg │ ├── target.jpg.meta │ ├── whitepixel.png │ └── whitepixel.png.meta │ ├── Weapon Data.meta │ └── Weapon Data │ ├── Machine Gun.asset │ ├── Machine Gun.asset.meta │ ├── Pistol.asset │ ├── Pistol.asset.meta │ ├── Shotgun.asset │ └── Shotgun.asset.meta ├── LICENSE ├── LICENSE.meta ├── PlayerLoopUtils.meta ├── PlayerLoopUtils ├── PlayerLoopUtils.cs └── PlayerLoopUtils.cs.meta ├── Plugins.meta ├── Plugins ├── MultiMouseLib.dll └── MultiMouseLib.dll.meta ├── Prefabs.meta ├── Prefabs ├── MultiMouseInterface.prefab └── MultiMouseInterface.prefab.meta ├── README.md ├── README.md.meta ├── Scripts.meta ├── Scripts ├── MultiMouse.cs ├── MultiMouse.cs.meta ├── MultiMouseSettings.cs ├── MultiMouseSettings.cs.meta ├── MultiMouseWrapper.cs └── MultiMouseWrapper.cs.meta └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # This .gitignore file should be placed at the root of your Unity project directory 2 | # 3 | # Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore 4 | # 5 | /[Ll]ibrary/ 6 | /[Tt]emp/ 7 | /[Oo]bj/ 8 | /[Bb]uild/ 9 | /[Bb]uilds/ 10 | /[Ll]ogs/ 11 | /[Mm]emoryCaptures/ 12 | 13 | # Asset meta data should only be ignored when the corresponding asset is also ignored 14 | !/[Aa]ssets/**/*.meta 15 | 16 | # Uncomment this line if you wish to ignore the asset store tools plugin 17 | # /[Aa]ssets/AssetStoreTools* 18 | 19 | # Autogenerated Jetbrains Rider plugin 20 | [Aa]ssets/Plugins/Editor/JetBrains* 21 | 22 | # Visual Studio cache directory 23 | .vs/ 24 | 25 | # Gradle cache directory 26 | .gradle/ 27 | 28 | # Autogenerated VS/MD/Consulo solution and project files 29 | ExportedObj/ 30 | .consulo/ 31 | *.csproj 32 | *.unityproj 33 | *.sln 34 | *.suo 35 | *.tmp 36 | *.user 37 | *.userprefs 38 | *.pidb 39 | *.booproj 40 | *.svd 41 | *.pdb 42 | *.mdb 43 | *.opendb 44 | *.VC.db 45 | 46 | # Unity3D generated meta files 47 | *.pidb.meta 48 | *.pdb.meta 49 | *.mdb.meta 50 | 51 | # Unity3D generated file on crash reports 52 | sysinfo.txt 53 | 54 | # Builds 55 | *.apk 56 | *.unitypackage 57 | 58 | # Crashlytics generated file 59 | crashlytics-build.properties 60 | 61 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 94e85ce8f42f16441a83fce8ed853840 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Jacky's Editor Helpers.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aa441529cab85c644ac8264b65953fb5 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Jacky's Editor Helpers/EditorExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | 6 | namespace JackysEditorHelpers 7 | { 8 | public static class EditorExtensions 9 | { 10 | /// 11 | /// Adds a new element to the end of the array and returns the new element 12 | /// 13 | /// 14 | /// 15 | public static SerializedProperty AddAndReturnNewArrayElement(this SerializedProperty prop) 16 | { 17 | int index = prop.arraySize; 18 | prop.InsertArrayElementAtIndex(index); 19 | return prop.GetArrayElementAtIndex(index); 20 | } 21 | 22 | /// 23 | /// Removes all null or missing elements from an array. 24 | /// For missing elements, invoke this method in Update or OnGUI 25 | /// 26 | /// 27 | /// 28 | public static SerializedProperty RemoveNullElementsFromArray(this SerializedProperty prop) 29 | { 30 | for (int i = prop.arraySize - 1; i > -1; i--) 31 | { 32 | if (prop.GetArrayElementAtIndex(i).objectReferenceValue == null) 33 | { 34 | // A dirty hack, but Unity serialization is real messy 35 | // https://answers.unity.com/questions/555724/serializedpropertydeletearrayelementatindex-leaves.html 36 | prop.DeleteArrayElementAtIndex(i); 37 | prop.DeleteArrayElementAtIndex(i); 38 | } 39 | } 40 | return prop; 41 | } 42 | 43 | public static GUIContent GUIContent(this SerializedProperty property) 44 | { 45 | return new GUIContent(property.displayName, property.tooltip); 46 | } 47 | 48 | public static string TimeToString(this float time) 49 | { 50 | time *= 1000; 51 | int minutes = (int)time / 60000; 52 | int seconds = (int)time / 1000 - 60 * minutes; 53 | int milliseconds = (int)time - minutes * 60000 - 1000 * seconds; 54 | return string.Format("{0:00}:{1:00}:{2:000}", minutes, seconds, milliseconds); 55 | } 56 | 57 | public static GUIStyle ApplyRichText(this GUIStyle referenceStyle) 58 | { 59 | var style = new GUIStyle(referenceStyle); 60 | style.richText = true; 61 | return style; 62 | } 63 | 64 | public static GUIStyle SetTextColor(this GUIStyle referenceStyle, Color color) 65 | { 66 | var style = new GUIStyle(referenceStyle); 67 | style.normal.textColor = color; 68 | return style; 69 | } 70 | 71 | public static GUIStyle ApplyTextAnchor(this GUIStyle referenceStyle, TextAnchor anchor) 72 | { 73 | var style = new GUIStyle(referenceStyle); 74 | style.alignment = anchor; 75 | return style; 76 | } 77 | 78 | public static GUIStyle SetFontSize(this GUIStyle referenceStyle, int fontSize) 79 | { 80 | var style = new GUIStyle(referenceStyle); 81 | style.fontSize = fontSize; 82 | return style; 83 | } 84 | 85 | public static GUIStyle ApplyBoldText(this GUIStyle referenceStyle) 86 | { 87 | var style = new GUIStyle(referenceStyle); 88 | style.fontStyle = FontStyle.Bold; 89 | return style; 90 | } 91 | 92 | public static GUIStyle ApplyWordWrap(this GUIStyle referenceStyle) 93 | { 94 | var style = new GUIStyle(referenceStyle); 95 | style.wordWrap = true; 96 | return style; 97 | } 98 | } 99 | 100 | public static class Extensions 101 | { 102 | public static T[] GetKeysCached(this Dictionary d) 103 | { 104 | T[] keys = new T[d.Keys.Count]; 105 | d.Keys.CopyTo(keys, 0); 106 | return keys; 107 | } 108 | 109 | public static Color Add(this Color thisColor, Color otherColor) 110 | { 111 | return new Color 112 | { 113 | r = Mathf.Clamp01(thisColor.r + otherColor.r), 114 | g = Mathf.Clamp01(thisColor.g + otherColor.g), 115 | b = Mathf.Clamp01(thisColor.b + otherColor.g), 116 | a = Mathf.Clamp01(thisColor.a + otherColor.a) 117 | }; 118 | } 119 | 120 | public static Color Subtract(this Color thisColor, Color otherColor) 121 | { 122 | return new Color 123 | { 124 | r = Mathf.Clamp01(thisColor.r - otherColor.r), 125 | g = Mathf.Clamp01(thisColor.g - otherColor.g), 126 | b = Mathf.Clamp01(thisColor.b - otherColor.g), 127 | a = Mathf.Clamp01(thisColor.a - otherColor.a) 128 | }; 129 | } 130 | 131 | /// 132 | /// Helpful method by Stack Overflow user ata 133 | /// https://stackoverflow.com/questions/3210393/how-do-i-remove-all-non-alphanumeric-characters-from-a-string-except-dash 134 | /// 135 | /// 136 | /// 137 | public static string ConvertToAlphanumeric(this string input) 138 | { 139 | char[] arr = input.ToCharArray(); 140 | 141 | arr = System.Array.FindAll(arr, c => char.IsLetterOrDigit(c)); 142 | 143 | if (arr.Length > 0) 144 | { 145 | // If the first index is a number 146 | while (char.IsDigit(arr[0]) || arr[0] == '.') 147 | { 148 | List newArray = new List(); 149 | newArray = new List(arr); 150 | newArray.RemoveAt(0); 151 | arr = newArray.ToArray(); 152 | if (arr.Length == 0) break; // No valid characters to use, returning empty 153 | } 154 | 155 | if (arr.Length != 0) 156 | { 157 | // If the last index is a period 158 | while (arr[arr.Length - 1] == '.') 159 | { 160 | List newArray = new List(); 161 | newArray = new List(arr); 162 | newArray.RemoveAt(newArray.Count - 1); 163 | arr = newArray.ToArray(); 164 | if (arr.Length == 0) break; // No valid characters to use, returning empty 165 | } 166 | } 167 | } 168 | 169 | return new string(arr); 170 | } 171 | } 172 | } -------------------------------------------------------------------------------- /Editor/Jacky's Editor Helpers/EditorExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3eaa289f3e726135e9cb24f672557bf7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/Jacky's Editor Helpers/EditorHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | 6 | namespace JackysEditorHelpers 7 | { 8 | public class EditorHelper : Editor 9 | { 10 | public static Color ButtonPressedColor => GUI.color.Add(new Color(0.2f, 0.2f, 0.2f, 0)); 11 | public static Color ButtonColor => GUI.color.Subtract(new Color(0.2f, 0.2f, 0.2f, 0)); 12 | 13 | public static string OpenSmartSaveFileDialog(out T asset, string defaultName = "New Object", string startingPath = "Assets") where T : ScriptableObject 14 | { 15 | string savePath = EditorUtility.SaveFilePanel("Designate Save Path", startingPath, defaultName, "asset"); 16 | asset = null; 17 | if (savePath != "") // Make sure user didn't press "Cancel" 18 | { 19 | asset = CreateInstance(); 20 | savePath = savePath.Remove(0, savePath.IndexOf("Assets/")); 21 | CreateAssetSafe(asset, savePath); 22 | EditorUtility.FocusProjectWindow(); 23 | Selection.activeObject = asset; 24 | } 25 | return savePath; 26 | } 27 | 28 | public static string OpenSmartSaveFileDialogInProject(out T asset, string defaultName = "New Object") where T : ScriptableObject 29 | { 30 | string savePath = EditorUtility.SaveFilePanelInProject("Designate Save Path", defaultName, "asset", "Choose where to save your file"); 31 | asset = null; 32 | if (savePath != "") // Make sure user didn't press "Cancel" 33 | { 34 | asset = CreateInstance(); 35 | savePath = savePath.Remove(0, savePath.IndexOf("Assets/")); 36 | CreateAssetSafe(asset, savePath); 37 | EditorUtility.FocusProjectWindow(); 38 | Selection.activeObject = asset; 39 | } 40 | return savePath; 41 | } 42 | 43 | /// 44 | /// 45 | /// 46 | /// 47 | /// False if the operation was unsuccessful or was cancelled, 48 | /// True if an asset was created. 49 | public static bool CreateAssetSafe(Object asset, string path) 50 | { 51 | if (AssetDatabase.IsValidFolder(path)) 52 | { 53 | Debug.LogError("Error! Attempted to write an asset over a folder!"); 54 | return false; 55 | } 56 | string folderPath = path.Substring(0, path.LastIndexOf("/")); 57 | if (GenerateFolderStructureAt(folderPath)) 58 | { 59 | AssetDatabase.CreateAsset(asset, path); 60 | return true; 61 | } 62 | return false; 63 | } 64 | 65 | /// 66 | /// Generates the folder structure to a specified path if it doesn't already exist. 67 | /// Will perform the check itself first 68 | /// 69 | /// The FOLDER path, this should NOT include any file names 70 | /// Asks if you want to generate the folder structure 71 | /// False if the user cancels the operation, 72 | /// True if there was no need to generate anything or if the operation was successful 73 | public static bool GenerateFolderStructureAt(string folderPath, bool ask = true) 74 | { 75 | // Convert slashes so we can use the Equals operator together with other file-system operations 76 | folderPath = folderPath.Replace("/", "\\"); 77 | if (!AssetDatabase.IsValidFolder(folderPath)) 78 | { 79 | string existingPath = "Assets"; 80 | string unknownPath = folderPath.Remove(0, existingPath.Length + 1); 81 | // Remove the "Assets/" at the start of the path name 82 | string folderName = (unknownPath.Contains("\\")) ? unknownPath.Substring(0, (unknownPath.IndexOf("\\"))) : unknownPath; 83 | do 84 | { 85 | string newPath = System.IO.Path.Combine(existingPath, folderName); 86 | // Begin checking down the file path to see if it's valid 87 | if (!AssetDatabase.IsValidFolder(newPath)) 88 | { 89 | bool createFolder = true; 90 | if (ask) 91 | { 92 | createFolder = EditorUtility.DisplayDialog("Path does not exist!", "The folder " + 93 | "\"" + 94 | newPath + 95 | "\" does not exist! Would you like to create this folder?", "Yes", "No"); 96 | } 97 | 98 | if (createFolder) 99 | { 100 | AssetDatabase.CreateFolder(existingPath, folderName); 101 | } 102 | else return false; 103 | } 104 | existingPath = newPath; 105 | // Full path still doesn't exist 106 | if (!existingPath.Equals(folderPath)) 107 | { 108 | unknownPath = unknownPath.Remove(0, folderName.Length + 1); 109 | folderName = (unknownPath.Contains("\\")) ? unknownPath.Substring(0, (unknownPath.IndexOf("\\"))) : unknownPath; 110 | } 111 | } 112 | while (!AssetDatabase.IsValidFolder(folderPath)); 113 | } 114 | return true; 115 | } 116 | 117 | public static void RenderSmartFolderProperty(GUIContent content, SerializedProperty folderProp, bool limitToAssetFolder = true, string panelTitle = "Specify a New Folder") 118 | { 119 | EditorGUILayout.BeginHorizontal(); 120 | SmartAssetField(content, folderProp, limitToAssetFolder); 121 | SmartBrowseButton(folderProp, limitToAssetFolder, panelTitle); 122 | EditorGUILayout.EndHorizontal(); 123 | } 124 | 125 | public static void RenderSmartFileProperty(GUIContent content, SerializedProperty folderProp, string extension, bool limitToAssetFolder = true, string panelTitle = "Specify a New Folder") 126 | { 127 | EditorGUILayout.BeginHorizontal(); 128 | SmartAssetField(content, folderProp, limitToAssetFolder); 129 | if (!limitToAssetFolder) 130 | SmartBrowseButton(folderProp, extension, limitToAssetFolder, panelTitle); 131 | EditorGUILayout.EndHorizontal(); 132 | } 133 | 134 | public static void SmartAssetField(GUIContent content, SerializedProperty folderProp, bool limitToAssetsFolder = true) 135 | { 136 | string folderPath = folderProp.stringValue; 137 | //if (folderPath == string.Empty) folderPath = Application.dataPath; 138 | bool touchedFolder = false; 139 | bool touchedString = false; 140 | 141 | Rect rect = EditorGUILayout.GetControlRect(); 142 | if (DragAndDropRegion(rect, "", "")) 143 | { 144 | DefaultAsset da = DragAndDrop.objectReferences[0] as DefaultAsset; 145 | if (da) folderProp.stringValue = AssetDatabase.GetAssetPath(da); 146 | return; 147 | } 148 | if (limitToAssetsFolder) rect.width *= 2f / 3f; 149 | EditorGUI.BeginChangeCheck(); 150 | folderPath = EditorGUI.TextField(rect, content, folderPath); 151 | touchedString = EditorGUI.EndChangeCheck(); 152 | 153 | rect.position += new Vector2(rect.width + 5, 0); 154 | rect.width = rect.width / 2f - 5; 155 | 156 | if (limitToAssetsFolder) 157 | { 158 | DefaultAsset folderAsset = AssetDatabase.LoadAssetAtPath(folderPath); 159 | EditorGUI.BeginChangeCheck(); 160 | folderAsset = (DefaultAsset)EditorGUI.ObjectField(rect, GUIContent.none, folderAsset, typeof(DefaultAsset), false); 161 | if (EditorGUI.EndChangeCheck()) 162 | { 163 | touchedFolder = true; 164 | folderPath = AssetDatabase.GetAssetPath(folderAsset); 165 | } 166 | } 167 | 168 | if (touchedString || touchedFolder) 169 | { 170 | // If the user presses "cancel" 171 | if (folderPath.Equals(string.Empty)) 172 | { 173 | return; 174 | } 175 | // or specifies something outside of this folder, reset filePath and don't proceed 176 | else if (limitToAssetsFolder) 177 | { 178 | if (!folderPath.Contains("Assets")) 179 | { 180 | EditorUtility.DisplayDialog("Folder Browsing Error!", "Please choose a different folder inside the project's Assets folder.", "OK"); 181 | return; 182 | } 183 | else 184 | { 185 | // Fix path to be usable for AssetDatabase.FindAssets 186 | if (folderPath[folderPath.Length - 1] == '/') folderPath = folderPath.Remove(folderPath.Length - 1, 1); 187 | } 188 | } 189 | } 190 | folderProp.stringValue = folderPath; 191 | } 192 | 193 | public static void SmartBrowseButton(SerializedProperty pathProp, string extension = "", bool limitToAssetsFolder = true, string panelTitle = "Specify a New File") 194 | { 195 | GUIContent buttonContent = new GUIContent(" Browse ", "Designate a New Folder"); 196 | if (GUILayout.Button(buttonContent, new GUILayoutOption[] { GUILayout.ExpandWidth(false) })) 197 | { 198 | // Stop editing any fields 199 | EditorGUI.FocusTextInControl(""); 200 | 201 | string filePath = pathProp.stringValue; 202 | filePath = EditorUtility.OpenFilePanel(panelTitle, filePath, extension); 203 | 204 | // If the user presses "cancel" 205 | if (filePath.Equals(string.Empty)) 206 | { 207 | return; 208 | } 209 | if (limitToAssetsFolder) 210 | { 211 | // or specifies something outside of this folder, reset filePath and don't proceed 212 | if (!filePath.Contains("Assets")) 213 | { 214 | EditorUtility.DisplayDialog("Folder Browsing Error!", "Please choose a different folder from" + 215 | "inside the project's Assets folder. ", "OK"); 216 | return; 217 | } 218 | else if (filePath.Contains(Application.dataPath)) 219 | { 220 | // Fix path to be usable for AssetDatabase.FindAssets 221 | filePath = filePath.Remove(0, filePath.IndexOf("Assets")); 222 | } 223 | } 224 | 225 | pathProp.stringValue = filePath; 226 | } 227 | } 228 | 229 | public static void SmartBrowseButton(SerializedProperty folderProp, bool limitToAssetFolder = true, string panelTitle = "Specify a New Folder") 230 | { 231 | GUIContent buttonContent = new GUIContent(" Browse ", "Designate a New Folder"); 232 | if (GUILayout.Button(buttonContent, new GUILayoutOption[] { GUILayout.ExpandWidth(false) })) 233 | { 234 | string filePath = folderProp.stringValue; 235 | filePath = EditorUtility.OpenFolderPanel(panelTitle, filePath, string.Empty); 236 | 237 | // If the user presses "cancel" 238 | if (filePath.Equals(string.Empty)) 239 | { 240 | return; 241 | } 242 | if (limitToAssetFolder) 243 | { 244 | // or specifies something outside of this folder, reset filePath and don't proceed 245 | if (!filePath.Contains("Assets")) 246 | { 247 | EditorUtility.DisplayDialog("Folder Browsing Error!", "AudioManager is a Unity editor tool and can only " + 248 | "function inside the project's Assets folder. Please choose a different folder.", "OK"); 249 | return; 250 | } 251 | else if (filePath.Contains(Application.dataPath)) 252 | { 253 | // Fix path to be usable for AssetDatabase.FindAssets 254 | filePath = filePath.Remove(0, filePath.IndexOf("Assets")); 255 | } 256 | } 257 | 258 | folderProp.stringValue = filePath; 259 | } 260 | } 261 | 262 | public static List ImportAssetsAtPath(string filePath) where T : Object 263 | { 264 | List imports = new List(); 265 | List importTargets = new List(System.IO.Directory.GetFiles(filePath)); 266 | for (int i = 0; i < importTargets.Count; i++) 267 | { 268 | var asset = AssetDatabase.LoadAssetAtPath(importTargets[i]); 269 | if (!AssetDatabase.IsValidFolder(importTargets[i])) 270 | { 271 | if (asset != null) 272 | { 273 | imports.Add(asset); 274 | } 275 | } 276 | } 277 | return imports; 278 | } 279 | 280 | public static List ImportAssetsOrFoldersAtPath(string filePath) where T : Object 281 | { 282 | var asset = AssetDatabase.LoadAssetAtPath(filePath); 283 | if (!AssetDatabase.IsValidFolder(filePath)) 284 | { 285 | if (asset != null) 286 | { 287 | return new List { asset }; 288 | } 289 | } 290 | else 291 | { 292 | List imports = new List(); 293 | List importTarget = new List(System.IO.Directory.GetDirectories(filePath)); 294 | importTarget.AddRange(System.IO.Directory.GetFiles(filePath)); 295 | for (int i = 0; i < importTarget.Count; i++) 296 | { 297 | imports.AddRange(ImportAssetsOrFoldersAtPath(importTarget[i])); 298 | } 299 | return imports; 300 | } 301 | 302 | return new List(); 303 | } 304 | 305 | public static List ImportSubAssetsAtPath(string filePath) where T : Object 306 | { 307 | var assets = AssetDatabase.LoadAllAssetsAtPath(filePath); 308 | 309 | var loadedAssets = new List(); 310 | for (int i = 0; i < assets.Length; i++) 311 | { 312 | var a = assets[i] as T; 313 | if (a) // Was cast successful? 314 | { 315 | loadedAssets.Add(a); 316 | } 317 | } 318 | 319 | return loadedAssets; 320 | } 321 | 322 | public static bool IsDragging(Rect dragRect) => dragRect.Contains(Event.current.mousePosition) && DragAndDrop.objectReferences.Length > 0; 323 | 324 | const int DAD_FONTSIZE = 40; 325 | const int DAD_BUFFER = 60; 326 | public static bool DragAndDropRegion(Rect dragRect, string normalLabel, string dragLabel, GUIStyle style = null) 327 | { 328 | switch (Event.current.type) 329 | { 330 | case EventType.Repaint: 331 | case EventType.Layout: 332 | string label; 333 | 334 | if (IsDragging(dragRect)) 335 | { 336 | if (style == null) style = GUI.skin.box.SetFontSize(DAD_FONTSIZE); 337 | label = dragLabel; 338 | } 339 | else 340 | { 341 | if (style == null) style = EditorStyles.label.SetFontSize(DAD_FONTSIZE); 342 | label = normalLabel; 343 | } 344 | 345 | style = style 346 | .ApplyTextAnchor(TextAnchor.MiddleCenter) 347 | .SetFontSize((int)Mathf.Lerp(1f, (float)style.fontSize, dragRect.height / (float)(DAD_BUFFER))) 348 | .ApplyBoldText(); 349 | 350 | GUI.Box(dragRect, label, style); 351 | 352 | return false; 353 | } 354 | 355 | if (dragRect.Contains(Event.current.mousePosition)) 356 | { 357 | if (Event.current.type == EventType.DragUpdated) 358 | { 359 | DragAndDrop.visualMode = DragAndDropVisualMode.Copy; 360 | Event.current.Use(); 361 | } 362 | else if (Event.current.type == EventType.DragPerform) 363 | { 364 | Event.current.Use(); 365 | return true; 366 | } 367 | } 368 | return false; 369 | } 370 | 371 | public static bool CondensedButton(string label) 372 | { 373 | return GUILayout.Button(" " + label + " ", new GUILayoutOption[] { GUILayout.ExpandWidth(false) }); 374 | } 375 | 376 | public static void RenderSequentialIntPopup(SerializedProperty property, int firstValue, int lastValue) 377 | { 378 | int size = (lastValue + 1) - firstValue; 379 | var displayOptions = new GUIContent[size]; 380 | var optionValues = new int[size]; 381 | for (int i = 0; i < size; i++) 382 | { 383 | displayOptions[i] = new GUIContent(i.ToString()); 384 | optionValues[i] = i; 385 | } 386 | 387 | EditorGUILayout.IntPopup(property, displayOptions, optionValues); 388 | } 389 | 390 | /// 391 | /// Equivalent to the FileUtil version, but works with backslashes 392 | /// 393 | /// 394 | public static string GetProjectRelativePath(string path) 395 | { 396 | return FileUtil.GetProjectRelativePath(path.Replace('\\', '/')); 397 | } 398 | 399 | static Color guiColor; 400 | public static void BeginColourChange(Color color) 401 | { 402 | guiColor = GUI.color; 403 | GUI.color = color; 404 | } 405 | 406 | public static void EndColourChange() => GUI.color = guiColor; 407 | 408 | static Color guiBackgroundColor; 409 | public static void BeginBackgroundColourChange(Color color) 410 | { 411 | guiBackgroundColor = GUI.backgroundColor; 412 | GUI.backgroundColor = color; 413 | } 414 | 415 | public static void EndBackgroundColourChange() => GUI.backgroundColor = guiBackgroundColor; 416 | } 417 | } -------------------------------------------------------------------------------- /Editor/Jacky's Editor Helpers/EditorHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a99a3e986e601494b8a870c4887dc326 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/Jacky's Editor Helpers/JackysStyles.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | namespace JackysEditorHelpers 5 | { 6 | public class JackysStyles : Editor 7 | { 8 | public static GUIStyle CenteredTitle => 9 | EditorStyles.boldLabel 10 | .ApplyBoldText() 11 | .ApplyTextAnchor(TextAnchor.MiddleCenter) 12 | .SetFontSize(20); 13 | 14 | public static GUIStyle CenteredLabel => 15 | EditorStyles.label 16 | .ApplyTextAnchor(TextAnchor.MiddleCenter); 17 | 18 | public static GUIStyle CenteredBoldHeader => 19 | new GUIStyle(EditorStyles.boldLabel) 20 | .ApplyTextAnchor(TextAnchor.UpperCenter) 21 | .SetFontSize(14); 22 | 23 | public static GUIStyle CenteredHeader => 24 | EditorStyles.largeLabel.ApplyTextAnchor(TextAnchor.MiddleCenter); 25 | 26 | public static GUIStyle UpCenteredHeader => 27 | EditorStyles.largeLabel.ApplyTextAnchor(TextAnchor.UpperCenter); 28 | } 29 | } -------------------------------------------------------------------------------- /Editor/Jacky's Editor Helpers/JackysStyles.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3243e618a7b0abb4497b093ac63990ba 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/Jacky's Editor Helpers/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright © 2021 Jacky Yang 3 | 4 | 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: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | 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. -------------------------------------------------------------------------------- /Editor/Jacky's Editor Helpers/LICENSE.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b883a6f316de59d449f1c0b179183fd5 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/MultiMouseConstants.cs: -------------------------------------------------------------------------------- 1 | namespace MultiMouseUnity.Editor 2 | { 3 | public class MultiMouseConstants 4 | { 5 | public const string PACKAGE_NAME = "Multi Mouse"; 6 | public const string MENU_TITLE = PACKAGE_NAME + "/"; 7 | public const string MENU_SETTINGS = "Project/" + PACKAGE_NAME; 8 | } 9 | } -------------------------------------------------------------------------------- /Editor/MultiMouseConstants.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ed5a1dd27884e144aa4f44c84f585403 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/MultiMouseInputDebugger.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | using JackysEditorHelpers; 6 | 7 | namespace MultiMouseUnity.Editor 8 | { 9 | public class MultiMouseInputDebugger : EditorWindow 10 | { 11 | static MultiMouseInputDebugger window; 12 | public static MultiMouseInputDebugger Window 13 | { 14 | get 15 | { 16 | if (window == null) window = GetWindow(); 17 | return window; 18 | } 19 | } 20 | 21 | [MenuItem("MultiMouse/Input Debugger")] 22 | private static void ShowWindow() 23 | { 24 | window = GetWindow(); 25 | window.titleContent = new GUIContent("MultiMouse Input Debugger"); 26 | window.Show(); 27 | } 28 | 29 | private void OnInspectorUpdate() 30 | { 31 | if (!Application.isPlaying) 32 | { 33 | 34 | return; 35 | } 36 | 37 | if (!MultiMouseWrapper.Initialized) 38 | { 39 | 40 | return; 41 | } 42 | 43 | Repaint(); 44 | } 45 | 46 | private void OnGUI() 47 | { 48 | if (!Application.isPlaying) 49 | { 50 | EditorGUILayout.HelpBox("Please enter Play Mode to begin receiving input!", MessageType.Info); 51 | return; 52 | } 53 | 54 | if (!MultiMouseWrapper.Initialized) 55 | { 56 | EditorGUILayout.HelpBox("MultiMouse not Initialized.", MessageType.Warning); 57 | return; 58 | } 59 | 60 | EditorGUILayout.BeginVertical(EditorStyles.helpBox); 61 | for (int i = 0; i < 14; i++) 62 | { 63 | var device = MultiMouseWrapper.Instance.TryGetDeviceAtIndex(i); 64 | if (device != null) 65 | { 66 | EditorGUILayout.LabelField("Device ID", i.ToString()); 67 | EditorGUILayout.LabelField("Name", device.DeviceID); 68 | var pos = MultiMouseWrapper.Instance.GetMousePosition(i); 69 | EditorGUILayout.LabelField("Position", pos.ToString()); 70 | EditorGUILayout.LabelField("Is Lightgun?", device.IsLightgun.ToString()); 71 | 72 | EditorGUILayout.BeginHorizontal(); 73 | EditorGUILayout.PrefixLabel("Buttons"); 74 | var rect = EditorGUILayout.GetControlRect(); 75 | EditorGUILayout.EndHorizontal(); 76 | 77 | float width = 1 / 3f; 78 | 79 | for (int j = 0; j < 3; j++) 80 | { 81 | var boxRect = new Rect(rect); 82 | boxRect.xMin = Mathf.Lerp(rect.xMin, rect.xMax, width * j) + 5; 83 | boxRect.xMax = Mathf.Lerp(rect.xMin, rect.xMax, width * (j + 1)) - 5; 84 | 85 | var down = MultiMouseWrapper.Instance.GetMouseButton(i, j); 86 | 87 | if (down) EditorHelper.BeginColourChange(Color.green); 88 | GUI.Box(boxRect, j.ToString()); 89 | if (down) EditorHelper.EndColourChange(); 90 | } 91 | } 92 | } 93 | EditorGUILayout.EndVertical(); 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /Editor/MultiMouseInputDebugger.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5676ebbcbf868374286d2a315069a82b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/MultiMouseSettingsEditor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | 6 | namespace MultiMouseUnity.Editor 7 | { 8 | #if UNITY_EDITOR 9 | [CustomEditor(typeof(MultiMouseSettings))] 10 | public class MultiMouseSettingsEditor : UnityEditor.Editor 11 | { 12 | public override void OnInspectorGUI() 13 | { 14 | if (GUILayout.Button("Open Settings")) 15 | { 16 | SettingsService.OpenProjectSettings(MultiMouseConstants.MENU_SETTINGS); 17 | } 18 | } 19 | } 20 | #endif 21 | } -------------------------------------------------------------------------------- /Editor/MultiMouseSettingsEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 887b6601c97cbc447b6e6ea0c763fa20 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/MultiMouseSettingsProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | 6 | namespace MultiMouseUnity.Editor 7 | { 8 | public class MultiMouseSettingsProvider : SettingsProvider 9 | { 10 | public MultiMouseSettingsProvider(string path, SettingsScope scope = SettingsScope.Project) : base(path, scope) 11 | { 12 | } 13 | 14 | SerializedProperty 15 | maxDevices, 16 | keepDetectingUntilFull, 17 | maxMouseButtons; 18 | 19 | protected MultiMouseSettings Settings => MultiMouseSettings.Settings; 20 | protected SerializedObject SerializedObject => MultiMouseSettings.SerializedObject; 21 | 22 | protected SerializedProperty FindProp(string prop) => SerializedObject.FindProperty(prop); 23 | void FindSerializedProperties() 24 | { 25 | maxDevices = FindProp(nameof(maxDevices)); 26 | keepDetectingUntilFull = FindProp(nameof(keepDetectingUntilFull)); 27 | maxMouseButtons = FindProp(nameof(maxMouseButtons)); 28 | } 29 | 30 | public override void OnActivate(string searchContext, UnityEngine.UIElements.VisualElement rootElement) 31 | { 32 | base.OnActivate(searchContext, rootElement); 33 | FindSerializedProperties(); 34 | } 35 | 36 | public override void OnGUI(string searchContext) 37 | { 38 | // This makes prefix labels larger 39 | EditorGUIUtility.labelWidth += 50; 40 | 41 | EditorGUILayout.PropertyField(maxDevices); 42 | EditorGUILayout.PropertyField(keepDetectingUntilFull); 43 | EditorGUILayout.PropertyField(maxMouseButtons); 44 | 45 | if (GUILayout.Button("Reset to Default", new GUILayoutOption[] { GUILayout.ExpandWidth(false) })) 46 | { 47 | Settings.Reset(); 48 | } 49 | 50 | SerializedObject.ApplyModifiedProperties(); 51 | 52 | EditorGUIUtility.labelWidth -= 50; 53 | } 54 | 55 | [SettingsProvider] 56 | public static SettingsProvider CreateMyCustomSettingsProvider() 57 | { 58 | // First parameter is the path in the Settings window. 59 | // Second parameter is the scope of this setting: it only appears in the Project Settings window. 60 | var provider = new MultiMouseSettingsProvider(MultiMouseConstants.MENU_SETTINGS, SettingsScope.Project); 61 | provider.keywords = GetSearchKeywordsFromSerializedObject(MultiMouseSettings.SerializedObject); 62 | 63 | return provider; 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /Editor/MultiMouseSettingsProvider.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b3d1a0764e9802b45bd707f2ac698407 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Examples.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0acc7946a7871814ea01f10e54305a8e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 13f0439e277a93c4b9a37e550f8885f0 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Animations.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8b479876b02d7c74bbfb9330260dc8c7 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Animations/MuzzleFlash.anim: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!74 &7400000 4 | AnimationClip: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: MuzzleFlash 10 | serializedVersion: 6 11 | m_Legacy: 1 12 | m_Compressed: 0 13 | m_UseHighQualityCurve: 1 14 | m_RotationCurves: [] 15 | m_CompressedRotationCurves: [] 16 | m_EulerCurves: [] 17 | m_PositionCurves: [] 18 | m_ScaleCurves: [] 19 | m_FloatCurves: 20 | - curve: 21 | serializedVersion: 2 22 | m_Curve: 23 | - serializedVersion: 3 24 | time: 0 25 | value: 50 26 | inSlope: 0 27 | outSlope: 0 28 | tangentMode: 136 29 | weightedMode: 0 30 | inWeight: 0.33333334 31 | outWeight: 0.33333334 32 | - serializedVersion: 3 33 | time: 0.033333335 34 | value: 29.16 35 | inSlope: -600 36 | outSlope: -600 37 | tangentMode: 136 38 | weightedMode: 0 39 | inWeight: 0.33333334 40 | outWeight: 0.33333334 41 | - serializedVersion: 3 42 | time: 0.083333336 43 | value: 0 44 | inSlope: 0 45 | outSlope: 0 46 | tangentMode: 136 47 | weightedMode: 0 48 | inWeight: 0.33333334 49 | outWeight: 0.33333334 50 | m_PreInfinity: 2 51 | m_PostInfinity: 2 52 | m_RotationOrder: 4 53 | attribute: m_SizeDelta.x 54 | path: 55 | classID: 224 56 | script: {fileID: 0} 57 | - curve: 58 | serializedVersion: 2 59 | m_Curve: 60 | - serializedVersion: 3 61 | time: 0 62 | value: 50 63 | inSlope: 0 64 | outSlope: 0 65 | tangentMode: 136 66 | weightedMode: 0 67 | inWeight: 0.33333334 68 | outWeight: 0.33333334 69 | - serializedVersion: 3 70 | time: 0.033333335 71 | value: 29.16 72 | inSlope: -600 73 | outSlope: -600 74 | tangentMode: 136 75 | weightedMode: 0 76 | inWeight: 0.33333334 77 | outWeight: 0.33333334 78 | - serializedVersion: 3 79 | time: 0.083333336 80 | value: 0 81 | inSlope: 0 82 | outSlope: 0 83 | tangentMode: 136 84 | weightedMode: 0 85 | inWeight: 0.33333334 86 | outWeight: 0.33333334 87 | m_PreInfinity: 2 88 | m_PostInfinity: 2 89 | m_RotationOrder: 4 90 | attribute: m_SizeDelta.y 91 | path: 92 | classID: 224 93 | script: {fileID: 0} 94 | - curve: 95 | serializedVersion: 2 96 | m_Curve: 97 | - serializedVersion: 3 98 | time: 0 99 | value: 1 100 | inSlope: 0 101 | outSlope: 0 102 | tangentMode: 136 103 | weightedMode: 0 104 | inWeight: 0.33333334 105 | outWeight: 0.33333334 106 | - serializedVersion: 3 107 | time: 0.033333335 108 | value: 1 109 | inSlope: 0 110 | outSlope: 0 111 | tangentMode: 136 112 | weightedMode: 0 113 | inWeight: 0.33333334 114 | outWeight: 0.33333334 115 | m_PreInfinity: 2 116 | m_PostInfinity: 2 117 | m_RotationOrder: 4 118 | attribute: m_Color.r 119 | path: 120 | classID: 114 121 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 122 | - curve: 123 | serializedVersion: 2 124 | m_Curve: 125 | - serializedVersion: 3 126 | time: 0 127 | value: 0.7170844 128 | inSlope: 0 129 | outSlope: 0 130 | tangentMode: 136 131 | weightedMode: 0 132 | inWeight: 0.33333334 133 | outWeight: 0.33333334 134 | - serializedVersion: 3 135 | time: 0.033333335 136 | value: 0.7170844 137 | inSlope: 0 138 | outSlope: 0 139 | tangentMode: 136 140 | weightedMode: 0 141 | inWeight: 0.33333334 142 | outWeight: 0.33333334 143 | m_PreInfinity: 2 144 | m_PostInfinity: 2 145 | m_RotationOrder: 4 146 | attribute: m_Color.g 147 | path: 148 | classID: 114 149 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 150 | - curve: 151 | serializedVersion: 2 152 | m_Curve: 153 | - serializedVersion: 3 154 | time: 0 155 | value: 0 156 | inSlope: 0 157 | outSlope: 0 158 | tangentMode: 136 159 | weightedMode: 0 160 | inWeight: 0.33333334 161 | outWeight: 0.33333334 162 | - serializedVersion: 3 163 | time: 0.033333335 164 | value: 0 165 | inSlope: 0 166 | outSlope: 0 167 | tangentMode: 136 168 | weightedMode: 0 169 | inWeight: 0.33333334 170 | outWeight: 0.33333334 171 | m_PreInfinity: 2 172 | m_PostInfinity: 2 173 | m_RotationOrder: 4 174 | attribute: m_Color.b 175 | path: 176 | classID: 114 177 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 178 | - curve: 179 | serializedVersion: 2 180 | m_Curve: 181 | - serializedVersion: 3 182 | time: 0 183 | value: 1 184 | inSlope: 0 185 | outSlope: 0 186 | tangentMode: 136 187 | weightedMode: 0 188 | inWeight: 0.33333334 189 | outWeight: 0.33333334 190 | - serializedVersion: 3 191 | time: 0.033333335 192 | value: 0.972 193 | inSlope: -1.3439999 194 | outSlope: -1.3439999 195 | tangentMode: 136 196 | weightedMode: 0 197 | inWeight: 0.33333334 198 | outWeight: 0.33333334 199 | - serializedVersion: 3 200 | time: 0.083333336 201 | value: 0 202 | inSlope: 0 203 | outSlope: 0 204 | tangentMode: 136 205 | weightedMode: 0 206 | inWeight: 0.33333334 207 | outWeight: 0.33333334 208 | m_PreInfinity: 2 209 | m_PostInfinity: 2 210 | m_RotationOrder: 4 211 | attribute: m_Color.a 212 | path: 213 | classID: 114 214 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 215 | m_PPtrCurves: [] 216 | m_SampleRate: 60 217 | m_WrapMode: 0 218 | m_Bounds: 219 | m_Center: {x: 0, y: 0, z: 0} 220 | m_Extent: {x: 0, y: 0, z: 0} 221 | m_ClipBindingConstant: 222 | genericBindings: [] 223 | pptrCurveMapping: [] 224 | m_AnimationClipSettings: 225 | serializedVersion: 2 226 | m_AdditiveReferencePoseClip: {fileID: 0} 227 | m_AdditiveReferencePoseTime: 0 228 | m_StartTime: 0 229 | m_StopTime: 0.083333336 230 | m_OrientationOffsetY: 0 231 | m_Level: 0 232 | m_CycleOffset: 0 233 | m_HasAdditiveReferencePose: 0 234 | m_LoopTime: 0 235 | m_LoopBlend: 0 236 | m_LoopBlendOrientation: 0 237 | m_LoopBlendPositionY: 0 238 | m_LoopBlendPositionXZ: 0 239 | m_KeepOriginalOrientation: 0 240 | m_KeepOriginalPositionY: 1 241 | m_KeepOriginalPositionXZ: 0 242 | m_HeightFromFeet: 0 243 | m_Mirror: 0 244 | m_EditorCurves: 245 | - curve: 246 | serializedVersion: 2 247 | m_Curve: 248 | - serializedVersion: 3 249 | time: 0 250 | value: 50 251 | inSlope: 0 252 | outSlope: 0 253 | tangentMode: 136 254 | weightedMode: 0 255 | inWeight: 0.33333334 256 | outWeight: 0.33333334 257 | - serializedVersion: 3 258 | time: 0.033333335 259 | value: 29.16 260 | inSlope: -600 261 | outSlope: -600 262 | tangentMode: 136 263 | weightedMode: 0 264 | inWeight: 0.33333334 265 | outWeight: 0.33333334 266 | - serializedVersion: 3 267 | time: 0.083333336 268 | value: 0 269 | inSlope: 0 270 | outSlope: 0 271 | tangentMode: 136 272 | weightedMode: 0 273 | inWeight: 0.33333334 274 | outWeight: 0.33333334 275 | m_PreInfinity: 2 276 | m_PostInfinity: 2 277 | m_RotationOrder: 4 278 | attribute: m_SizeDelta.x 279 | path: 280 | classID: 224 281 | script: {fileID: 0} 282 | - curve: 283 | serializedVersion: 2 284 | m_Curve: 285 | - serializedVersion: 3 286 | time: 0 287 | value: 50 288 | inSlope: 0 289 | outSlope: 0 290 | tangentMode: 136 291 | weightedMode: 0 292 | inWeight: 0.33333334 293 | outWeight: 0.33333334 294 | - serializedVersion: 3 295 | time: 0.033333335 296 | value: 29.16 297 | inSlope: -600 298 | outSlope: -600 299 | tangentMode: 136 300 | weightedMode: 0 301 | inWeight: 0.33333334 302 | outWeight: 0.33333334 303 | - serializedVersion: 3 304 | time: 0.083333336 305 | value: 0 306 | inSlope: 0 307 | outSlope: 0 308 | tangentMode: 136 309 | weightedMode: 0 310 | inWeight: 0.33333334 311 | outWeight: 0.33333334 312 | m_PreInfinity: 2 313 | m_PostInfinity: 2 314 | m_RotationOrder: 4 315 | attribute: m_SizeDelta.y 316 | path: 317 | classID: 224 318 | script: {fileID: 0} 319 | - curve: 320 | serializedVersion: 2 321 | m_Curve: 322 | - serializedVersion: 3 323 | time: 0 324 | value: 1 325 | inSlope: 0 326 | outSlope: 0 327 | tangentMode: 136 328 | weightedMode: 0 329 | inWeight: 0.33333334 330 | outWeight: 0.33333334 331 | - serializedVersion: 3 332 | time: 0.033333335 333 | value: 1 334 | inSlope: 0 335 | outSlope: 0 336 | tangentMode: 136 337 | weightedMode: 0 338 | inWeight: 0.33333334 339 | outWeight: 0.33333334 340 | m_PreInfinity: 2 341 | m_PostInfinity: 2 342 | m_RotationOrder: 4 343 | attribute: m_Color.r 344 | path: 345 | classID: 114 346 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 347 | - curve: 348 | serializedVersion: 2 349 | m_Curve: 350 | - serializedVersion: 3 351 | time: 0 352 | value: 0.7170844 353 | inSlope: 0 354 | outSlope: 0 355 | tangentMode: 136 356 | weightedMode: 0 357 | inWeight: 0.33333334 358 | outWeight: 0.33333334 359 | - serializedVersion: 3 360 | time: 0.033333335 361 | value: 0.7170844 362 | inSlope: 0 363 | outSlope: 0 364 | tangentMode: 136 365 | weightedMode: 0 366 | inWeight: 0.33333334 367 | outWeight: 0.33333334 368 | m_PreInfinity: 2 369 | m_PostInfinity: 2 370 | m_RotationOrder: 4 371 | attribute: m_Color.g 372 | path: 373 | classID: 114 374 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 375 | - curve: 376 | serializedVersion: 2 377 | m_Curve: 378 | - serializedVersion: 3 379 | time: 0 380 | value: 0 381 | inSlope: 0 382 | outSlope: 0 383 | tangentMode: 136 384 | weightedMode: 0 385 | inWeight: 0.33333334 386 | outWeight: 0.33333334 387 | - serializedVersion: 3 388 | time: 0.033333335 389 | value: 0 390 | inSlope: 0 391 | outSlope: 0 392 | tangentMode: 136 393 | weightedMode: 0 394 | inWeight: 0.33333334 395 | outWeight: 0.33333334 396 | m_PreInfinity: 2 397 | m_PostInfinity: 2 398 | m_RotationOrder: 4 399 | attribute: m_Color.b 400 | path: 401 | classID: 114 402 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 403 | - curve: 404 | serializedVersion: 2 405 | m_Curve: 406 | - serializedVersion: 3 407 | time: 0 408 | value: 1 409 | inSlope: 0 410 | outSlope: 0 411 | tangentMode: 136 412 | weightedMode: 0 413 | inWeight: 0.33333334 414 | outWeight: 0.33333334 415 | - serializedVersion: 3 416 | time: 0.033333335 417 | value: 0.972 418 | inSlope: -1.3439999 419 | outSlope: -1.3439999 420 | tangentMode: 136 421 | weightedMode: 0 422 | inWeight: 0.33333334 423 | outWeight: 0.33333334 424 | - serializedVersion: 3 425 | time: 0.083333336 426 | value: 0 427 | inSlope: 0 428 | outSlope: 0 429 | tangentMode: 136 430 | weightedMode: 0 431 | inWeight: 0.33333334 432 | outWeight: 0.33333334 433 | m_PreInfinity: 2 434 | m_PostInfinity: 2 435 | m_RotationOrder: 4 436 | attribute: m_Color.a 437 | path: 438 | classID: 114 439 | script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 440 | m_EulerEditorCurves: [] 441 | m_HasGenericRootTransform: 0 442 | m_HasMotionFloatCurves: 0 443 | m_Events: [] 444 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Animations/MuzzleFlash.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ace61bc1c1bae142a8f009f5c4b130d 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 7400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Animations/PistolFire.anim: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!74 &7400000 4 | AnimationClip: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: PistolFire 10 | serializedVersion: 6 11 | m_Legacy: 1 12 | m_Compressed: 0 13 | m_UseHighQualityCurve: 1 14 | m_RotationCurves: [] 15 | m_CompressedRotationCurves: [] 16 | m_EulerCurves: [] 17 | m_PositionCurves: 18 | - curve: 19 | serializedVersion: 2 20 | m_Curve: 21 | - serializedVersion: 3 22 | time: 0 23 | value: {x: 0, y: 0, z: -0.0111} 24 | inSlope: {x: 0, y: 0, z: 0} 25 | outSlope: {x: 0, y: 0, z: 0} 26 | tangentMode: 0 27 | weightedMode: 0 28 | inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} 29 | outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} 30 | - serializedVersion: 3 31 | time: 0.083333336 32 | value: {x: 0, y: 0, z: 0} 33 | inSlope: {x: 0, y: 0, z: 0} 34 | outSlope: {x: 0, y: 0, z: 0} 35 | tangentMode: 0 36 | weightedMode: 0 37 | inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} 38 | outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} 39 | m_PreInfinity: 2 40 | m_PostInfinity: 2 41 | m_RotationOrder: 4 42 | path: Mesh1_Group2_Group1_Model 43 | m_ScaleCurves: [] 44 | m_FloatCurves: [] 45 | m_PPtrCurves: [] 46 | m_SampleRate: 60 47 | m_WrapMode: 0 48 | m_Bounds: 49 | m_Center: {x: 0, y: 0, z: 0} 50 | m_Extent: {x: 0, y: 0, z: 0} 51 | m_ClipBindingConstant: 52 | genericBindings: [] 53 | pptrCurveMapping: [] 54 | m_AnimationClipSettings: 55 | serializedVersion: 2 56 | m_AdditiveReferencePoseClip: {fileID: 0} 57 | m_AdditiveReferencePoseTime: 0 58 | m_StartTime: 0 59 | m_StopTime: 0.083333336 60 | m_OrientationOffsetY: 0 61 | m_Level: 0 62 | m_CycleOffset: 0 63 | m_HasAdditiveReferencePose: 0 64 | m_LoopTime: 0 65 | m_LoopBlend: 0 66 | m_LoopBlendOrientation: 0 67 | m_LoopBlendPositionY: 0 68 | m_LoopBlendPositionXZ: 0 69 | m_KeepOriginalOrientation: 0 70 | m_KeepOriginalPositionY: 1 71 | m_KeepOriginalPositionXZ: 0 72 | m_HeightFromFeet: 0 73 | m_Mirror: 0 74 | m_EditorCurves: 75 | - curve: 76 | serializedVersion: 2 77 | m_Curve: 78 | - serializedVersion: 3 79 | time: 0 80 | value: 0 81 | inSlope: 0 82 | outSlope: 0 83 | tangentMode: 136 84 | weightedMode: 0 85 | inWeight: 0.33333334 86 | outWeight: 0.33333334 87 | - serializedVersion: 3 88 | time: 0.083333336 89 | value: 0 90 | inSlope: 0 91 | outSlope: 0 92 | tangentMode: 136 93 | weightedMode: 0 94 | inWeight: 0.33333334 95 | outWeight: 0.33333334 96 | m_PreInfinity: 2 97 | m_PostInfinity: 2 98 | m_RotationOrder: 4 99 | attribute: m_LocalPosition.x 100 | path: Mesh1_Group2_Group1_Model 101 | classID: 4 102 | script: {fileID: 0} 103 | - curve: 104 | serializedVersion: 2 105 | m_Curve: 106 | - serializedVersion: 3 107 | time: 0 108 | value: 0 109 | inSlope: 0 110 | outSlope: 0 111 | tangentMode: 136 112 | weightedMode: 0 113 | inWeight: 0.33333334 114 | outWeight: 0.33333334 115 | - serializedVersion: 3 116 | time: 0.083333336 117 | value: 0 118 | inSlope: 0 119 | outSlope: 0 120 | tangentMode: 136 121 | weightedMode: 0 122 | inWeight: 0.33333334 123 | outWeight: 0.33333334 124 | m_PreInfinity: 2 125 | m_PostInfinity: 2 126 | m_RotationOrder: 4 127 | attribute: m_LocalPosition.y 128 | path: Mesh1_Group2_Group1_Model 129 | classID: 4 130 | script: {fileID: 0} 131 | - curve: 132 | serializedVersion: 2 133 | m_Curve: 134 | - serializedVersion: 3 135 | time: 0 136 | value: -0.0111 137 | inSlope: 0 138 | outSlope: 0 139 | tangentMode: 136 140 | weightedMode: 0 141 | inWeight: 0.33333334 142 | outWeight: 0.33333334 143 | - serializedVersion: 3 144 | time: 0.083333336 145 | value: 0 146 | inSlope: 0 147 | outSlope: 0 148 | tangentMode: 136 149 | weightedMode: 0 150 | inWeight: 0.33333334 151 | outWeight: 0.33333334 152 | m_PreInfinity: 2 153 | m_PostInfinity: 2 154 | m_RotationOrder: 4 155 | attribute: m_LocalPosition.z 156 | path: Mesh1_Group2_Group1_Model 157 | classID: 4 158 | script: {fileID: 0} 159 | m_EulerEditorCurves: [] 160 | m_HasGenericRootTransform: 0 161 | m_HasMotionFloatCurves: 0 162 | m_Events: [] 163 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Animations/PistolFire.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a89f04882c2e03c478cc1703d7debb69 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 7400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Animations/Target.controller: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1102 &-4259800364720847614 4 | AnimatorState: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 1 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Flip Down 11 | m_Speed: 2 12 | m_CycleOffset: 0 13 | m_Transitions: [] 14 | m_StateMachineBehaviours: [] 15 | m_Position: {x: 50, y: 50, z: 0} 16 | m_IKOnFeet: 0 17 | m_WriteDefaultValues: 1 18 | m_Mirror: 0 19 | m_SpeedParameterActive: 0 20 | m_MirrorParameterActive: 0 21 | m_CycleOffsetParameterActive: 0 22 | m_TimeParameterActive: 0 23 | m_Motion: {fileID: 7400000, guid: 7ae5dccabd769d443aaabd80b6f5474a, type: 2} 24 | m_Tag: 25 | m_SpeedParameter: 26 | m_MirrorParameter: 27 | m_CycleOffsetParameter: 28 | m_TimeParameter: 29 | --- !u!1102 &-2455785141965403627 30 | AnimatorState: 31 | serializedVersion: 6 32 | m_ObjectHideFlags: 1 33 | m_CorrespondingSourceObject: {fileID: 0} 34 | m_PrefabInstance: {fileID: 0} 35 | m_PrefabAsset: {fileID: 0} 36 | m_Name: Idle 37 | m_Speed: 1 38 | m_CycleOffset: 0 39 | m_Transitions: [] 40 | m_StateMachineBehaviours: [] 41 | m_Position: {x: 50, y: 50, z: 0} 42 | m_IKOnFeet: 0 43 | m_WriteDefaultValues: 1 44 | m_Mirror: 0 45 | m_SpeedParameterActive: 0 46 | m_MirrorParameterActive: 0 47 | m_CycleOffsetParameterActive: 0 48 | m_TimeParameterActive: 0 49 | m_Motion: {fileID: 0} 50 | m_Tag: 51 | m_SpeedParameter: 52 | m_MirrorParameter: 53 | m_CycleOffsetParameter: 54 | m_TimeParameter: 55 | --- !u!1107 &-1772705675088902581 56 | AnimatorStateMachine: 57 | serializedVersion: 6 58 | m_ObjectHideFlags: 1 59 | m_CorrespondingSourceObject: {fileID: 0} 60 | m_PrefabInstance: {fileID: 0} 61 | m_PrefabAsset: {fileID: 0} 62 | m_Name: Base Layer 63 | m_ChildStates: 64 | - serializedVersion: 1 65 | m_State: {fileID: -4259800364720847614} 66 | m_Position: {x: 270, y: 10, z: 0} 67 | - serializedVersion: 1 68 | m_State: {fileID: -2455785141965403627} 69 | m_Position: {x: 270, y: 110, z: 0} 70 | - serializedVersion: 1 71 | m_State: {fileID: -483106718277987501} 72 | m_Position: {x: 520, y: 10, z: 0} 73 | m_ChildStateMachines: [] 74 | m_AnyStateTransitions: [] 75 | m_EntryTransitions: [] 76 | m_StateMachineTransitions: {} 77 | m_StateMachineBehaviours: [] 78 | m_AnyStatePosition: {x: 50, y: 20, z: 0} 79 | m_EntryPosition: {x: 50, y: 120, z: 0} 80 | m_ExitPosition: {x: 800, y: 120, z: 0} 81 | m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} 82 | m_DefaultState: {fileID: -2455785141965403627} 83 | --- !u!1102 &-483106718277987501 84 | AnimatorState: 85 | serializedVersion: 6 86 | m_ObjectHideFlags: 1 87 | m_CorrespondingSourceObject: {fileID: 0} 88 | m_PrefabInstance: {fileID: 0} 89 | m_PrefabAsset: {fileID: 0} 90 | m_Name: Flip Up 91 | m_Speed: -0.5 92 | m_CycleOffset: 0 93 | m_Transitions: [] 94 | m_StateMachineBehaviours: [] 95 | m_Position: {x: 50, y: 50, z: 0} 96 | m_IKOnFeet: 0 97 | m_WriteDefaultValues: 1 98 | m_Mirror: 0 99 | m_SpeedParameterActive: 0 100 | m_MirrorParameterActive: 0 101 | m_CycleOffsetParameterActive: 0 102 | m_TimeParameterActive: 0 103 | m_Motion: {fileID: 7400000, guid: 7ae5dccabd769d443aaabd80b6f5474a, type: 2} 104 | m_Tag: 105 | m_SpeedParameter: 106 | m_MirrorParameter: 107 | m_CycleOffsetParameter: 108 | m_TimeParameter: 109 | --- !u!91 &9100000 110 | AnimatorController: 111 | m_ObjectHideFlags: 0 112 | m_CorrespondingSourceObject: {fileID: 0} 113 | m_PrefabInstance: {fileID: 0} 114 | m_PrefabAsset: {fileID: 0} 115 | m_Name: Target 116 | serializedVersion: 5 117 | m_AnimatorParameters: [] 118 | m_AnimatorLayers: 119 | - serializedVersion: 5 120 | m_Name: Base Layer 121 | m_StateMachine: {fileID: -1772705675088902581} 122 | m_Mask: {fileID: 0} 123 | m_Motions: [] 124 | m_Behaviours: [] 125 | m_BlendingMode: 0 126 | m_SyncedLayerIndex: -1 127 | m_DefaultWeight: 0 128 | m_IKPass: 0 129 | m_SyncedLayerAffectsTiming: 0 130 | m_Controller: {fileID: 9100000} 131 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Animations/Target.controller.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 149e92f7aa38f4a4cbd7145f6c5c3432 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 9100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Animations/TargetFlip.anim: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!74 &7400000 4 | AnimationClip: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: TargetFlip 10 | serializedVersion: 6 11 | m_Legacy: 0 12 | m_Compressed: 0 13 | m_UseHighQualityCurve: 1 14 | m_RotationCurves: [] 15 | m_CompressedRotationCurves: [] 16 | m_EulerCurves: 17 | - curve: 18 | serializedVersion: 2 19 | m_Curve: 20 | - serializedVersion: 3 21 | time: 0 22 | value: {x: 0, y: 0, z: 0} 23 | inSlope: {x: 0, y: 0, z: 0} 24 | outSlope: {x: 0, y: 0, z: 0} 25 | tangentMode: 0 26 | weightedMode: 0 27 | inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} 28 | outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} 29 | - serializedVersion: 3 30 | time: 0.25 31 | value: {x: 90, y: 0, z: 0} 32 | inSlope: {x: 0, y: 0, z: 0} 33 | outSlope: {x: 0, y: 0, z: 0} 34 | tangentMode: 0 35 | weightedMode: 0 36 | inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} 37 | outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} 38 | m_PreInfinity: 2 39 | m_PostInfinity: 2 40 | m_RotationOrder: 4 41 | path: Pivot 42 | m_PositionCurves: [] 43 | m_ScaleCurves: [] 44 | m_FloatCurves: [] 45 | m_PPtrCurves: [] 46 | m_SampleRate: 60 47 | m_WrapMode: 0 48 | m_Bounds: 49 | m_Center: {x: 0, y: 0, z: 0} 50 | m_Extent: {x: 0, y: 0, z: 0} 51 | m_ClipBindingConstant: 52 | genericBindings: 53 | - serializedVersion: 2 54 | path: 1567512304 55 | attribute: 4 56 | script: {fileID: 0} 57 | typeID: 4 58 | customType: 4 59 | isPPtrCurve: 0 60 | pptrCurveMapping: [] 61 | m_AnimationClipSettings: 62 | serializedVersion: 2 63 | m_AdditiveReferencePoseClip: {fileID: 0} 64 | m_AdditiveReferencePoseTime: 0 65 | m_StartTime: 0 66 | m_StopTime: 0.25 67 | m_OrientationOffsetY: 0 68 | m_Level: 0 69 | m_CycleOffset: 0 70 | m_HasAdditiveReferencePose: 0 71 | m_LoopTime: 0 72 | m_LoopBlend: 0 73 | m_LoopBlendOrientation: 0 74 | m_LoopBlendPositionY: 0 75 | m_LoopBlendPositionXZ: 0 76 | m_KeepOriginalOrientation: 0 77 | m_KeepOriginalPositionY: 1 78 | m_KeepOriginalPositionXZ: 0 79 | m_HeightFromFeet: 0 80 | m_Mirror: 0 81 | m_EditorCurves: 82 | - curve: 83 | serializedVersion: 2 84 | m_Curve: 85 | - serializedVersion: 3 86 | time: 0 87 | value: 0 88 | inSlope: 0 89 | outSlope: 0 90 | tangentMode: 136 91 | weightedMode: 0 92 | inWeight: 0.33333334 93 | outWeight: 0.33333334 94 | - serializedVersion: 3 95 | time: 0.25 96 | value: 90 97 | inSlope: 0 98 | outSlope: 0 99 | tangentMode: 136 100 | weightedMode: 0 101 | inWeight: 0.33333334 102 | outWeight: 0.33333334 103 | m_PreInfinity: 2 104 | m_PostInfinity: 2 105 | m_RotationOrder: 4 106 | attribute: localEulerAnglesRaw.x 107 | path: Pivot 108 | classID: 4 109 | script: {fileID: 0} 110 | - curve: 111 | serializedVersion: 2 112 | m_Curve: 113 | - serializedVersion: 3 114 | time: 0 115 | value: 0 116 | inSlope: 0 117 | outSlope: 0 118 | tangentMode: 136 119 | weightedMode: 0 120 | inWeight: 0.33333334 121 | outWeight: 0.33333334 122 | - serializedVersion: 3 123 | time: 0.25 124 | value: 0 125 | inSlope: 0 126 | outSlope: 0 127 | tangentMode: 136 128 | weightedMode: 0 129 | inWeight: 0.33333334 130 | outWeight: 0.33333334 131 | m_PreInfinity: 2 132 | m_PostInfinity: 2 133 | m_RotationOrder: 4 134 | attribute: localEulerAnglesRaw.y 135 | path: Pivot 136 | classID: 4 137 | script: {fileID: 0} 138 | - curve: 139 | serializedVersion: 2 140 | m_Curve: 141 | - serializedVersion: 3 142 | time: 0 143 | value: 0 144 | inSlope: 0 145 | outSlope: 0 146 | tangentMode: 136 147 | weightedMode: 0 148 | inWeight: 0.33333334 149 | outWeight: 0.33333334 150 | - serializedVersion: 3 151 | time: 0.25 152 | value: 0 153 | inSlope: 0 154 | outSlope: 0 155 | tangentMode: 136 156 | weightedMode: 0 157 | inWeight: 0.33333334 158 | outWeight: 0.33333334 159 | m_PreInfinity: 2 160 | m_PostInfinity: 2 161 | m_RotationOrder: 4 162 | attribute: localEulerAnglesRaw.z 163 | path: Pivot 164 | classID: 4 165 | script: {fileID: 0} 166 | m_EulerEditorCurves: 167 | - curve: 168 | serializedVersion: 2 169 | m_Curve: [] 170 | m_PreInfinity: 2 171 | m_PostInfinity: 2 172 | m_RotationOrder: 4 173 | attribute: m_LocalEulerAngles.x 174 | path: Pivot 175 | classID: 4 176 | script: {fileID: 0} 177 | - curve: 178 | serializedVersion: 2 179 | m_Curve: [] 180 | m_PreInfinity: 2 181 | m_PostInfinity: 2 182 | m_RotationOrder: 4 183 | attribute: m_LocalEulerAngles.y 184 | path: Pivot 185 | classID: 4 186 | script: {fileID: 0} 187 | - curve: 188 | serializedVersion: 2 189 | m_Curve: [] 190 | m_PreInfinity: 2 191 | m_PostInfinity: 2 192 | m_RotationOrder: 4 193 | attribute: m_LocalEulerAngles.z 194 | path: Pivot 195 | classID: 4 196 | script: {fileID: 0} 197 | m_HasGenericRootTransform: 0 198 | m_HasMotionFloatCurves: 0 199 | m_Events: [] 200 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Animations/TargetFlip.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7ae5dccabd769d443aaabd80b6f5474a 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 7400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Audio.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8c09cae32c687de46ba6719c8129aa43 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Audio/392229__morganpurkis__single-pistol-gunshot-3-3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackyyang09/Multi-Mouse-Unity/ddad073af483dca5d75442fc4d23e5ddb552036b/Examples/Lightgun Example/Audio/392229__morganpurkis__single-pistol-gunshot-3-3.wav -------------------------------------------------------------------------------- /Examples/Lightgun Example/Audio/392229__morganpurkis__single-pistol-gunshot-3-3.wav.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 863f67d126e79ff4fa81c9a0a4c517a7 3 | AudioImporter: 4 | externalObjects: {} 5 | serializedVersion: 6 6 | defaultSettings: 7 | loadType: 0 8 | sampleRateSetting: 0 9 | sampleRateOverride: 44100 10 | compressionFormat: 1 11 | quality: 1 12 | conversionMode: 0 13 | platformSettingOverrides: {} 14 | forceToMono: 0 15 | normalize: 1 16 | preloadAudioData: 1 17 | loadInBackground: 0 18 | ambisonic: 0 19 | 3D: 1 20 | userData: 21 | assetBundleName: 22 | assetBundleVariant: 23 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Fonts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 50eeb97bf999f6c4798be7cfc469ea40 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Fonts/FugazOne.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1421b483f87d4a7438d64667d54dd73a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Fonts/FugazOne/FugazOne-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackyyang09/Multi-Mouse-Unity/ddad073af483dca5d75442fc4d23e5ddb552036b/Examples/Lightgun Example/Fonts/FugazOne/FugazOne-Regular.ttf -------------------------------------------------------------------------------- /Examples/Lightgun Example/Fonts/FugazOne/FugazOne-Regular.ttf.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b8178a78a91ffd74cbff628006128bee 3 | TrueTypeFontImporter: 4 | externalObjects: {} 5 | serializedVersion: 4 6 | fontSize: 16 7 | forceTextureCase: -2 8 | characterSpacing: 0 9 | characterPadding: 1 10 | includeFontData: 1 11 | fontNames: 12 | - Fugaz One 13 | fallbackFontReferences: [] 14 | customCharacters: 15 | fontRenderingMode: 0 16 | ascentCalculationMode: 1 17 | useLegacyBoundsCalculation: 0 18 | shouldRoundAdvanceValue: 1 19 | userData: 20 | assetBundleName: 21 | assetBundleVariant: 22 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Fonts/FugazOne/OFL.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 by LatinoType Limitada (luciano@latinotype.com), 2 | with Reserved Font Names "Fugaz One" 3 | 4 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 5 | This license is copied below, and is also available with a FAQ at: 6 | http://scripts.sil.org/OFL 7 | 8 | 9 | ----------------------------------------------------------- 10 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 11 | ----------------------------------------------------------- 12 | 13 | PREAMBLE 14 | The goals of the Open Font License (OFL) are to stimulate worldwide 15 | development of collaborative font projects, to support the font creation 16 | efforts of academic and linguistic communities, and to provide a free and 17 | open framework in which fonts may be shared and improved in partnership 18 | with others. 19 | 20 | The OFL allows the licensed fonts to be used, studied, modified and 21 | redistributed freely as long as they are not sold by themselves. The 22 | fonts, including any derivative works, can be bundled, embedded, 23 | redistributed and/or sold with any software provided that any reserved 24 | names are not used by derivative works. The fonts and derivatives, 25 | however, cannot be released under any other type of license. The 26 | requirement for fonts to remain under this license does not apply 27 | to any document created using the fonts or their derivatives. 28 | 29 | DEFINITIONS 30 | "Font Software" refers to the set of files released by the Copyright 31 | Holder(s) under this license and clearly marked as such. This may 32 | include source files, build scripts and documentation. 33 | 34 | "Reserved Font Name" refers to any names specified as such after the 35 | copyright statement(s). 36 | 37 | "Original Version" refers to the collection of Font Software components as 38 | distributed by the Copyright Holder(s). 39 | 40 | "Modified Version" refers to any derivative made by adding to, deleting, 41 | or substituting -- in part or in whole -- any of the components of the 42 | Original Version, by changing formats or by porting the Font Software to a 43 | new environment. 44 | 45 | "Author" refers to any designer, engineer, programmer, technical 46 | writer or other person who contributed to the Font Software. 47 | 48 | PERMISSION & CONDITIONS 49 | Permission is hereby granted, free of charge, to any person obtaining 50 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 51 | redistribute, and sell modified and unmodified copies of the Font 52 | Software, subject to the following conditions: 53 | 54 | 1) Neither the Font Software nor any of its individual components, 55 | in Original or Modified Versions, may be sold by itself. 56 | 57 | 2) Original or Modified Versions of the Font Software may be bundled, 58 | redistributed and/or sold with any software, provided that each copy 59 | contains the above copyright notice and this license. These can be 60 | included either as stand-alone text files, human-readable headers or 61 | in the appropriate machine-readable metadata fields within text or 62 | binary files as long as those fields can be easily viewed by the user. 63 | 64 | 3) No Modified Version of the Font Software may use the Reserved Font 65 | Name(s) unless explicit written permission is granted by the corresponding 66 | Copyright Holder. This restriction only applies to the primary font name as 67 | presented to the users. 68 | 69 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 70 | Software shall not be used to promote, endorse or advertise any 71 | Modified Version, except to acknowledge the contribution(s) of the 72 | Copyright Holder(s) and the Author(s) or with their explicit written 73 | permission. 74 | 75 | 5) The Font Software, modified or unmodified, in part or in whole, 76 | must be distributed entirely under this license, and must not be 77 | distributed under any other license. The requirement for fonts to 78 | remain under this license does not apply to any document created 79 | using the Font Software. 80 | 81 | TERMINATION 82 | This license becomes null and void if any of the above conditions are 83 | not met. 84 | 85 | DISCLAIMER 86 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 87 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 88 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 89 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 90 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 91 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 92 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 93 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 94 | OTHER DEALINGS IN THE FONT SOFTWARE. 95 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Fonts/FugazOne/OFL.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 719899c4153530a4c9eee7c8b67af935 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Crosshairs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c9983d7d2d48880479077acce169a953 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Crosshairs/Kenney.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://www.kenney.nl/ -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Crosshairs/Kenney.url.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3ec4b2c0d6499c449a3a4161d772c58c 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Crosshairs/License.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | Crosshair Pack 4 | 5 | by Kenney Vleugels (Kenney.nl) 6 | 7 | ------------------------------ 8 | 9 | License (Creative Commons Zero, CC0) 10 | http://creativecommons.org/publicdomain/zero/1.0/ 11 | 12 | You may use these assets in personal and commercial projects. 13 | Credit (Kenney or www.kenney.nl) would be nice but is not mandatory. 14 | 15 | ------------------------------ 16 | 17 | Donate: http://support.kenney.nl 18 | 19 | Follow on Twitter for updates: @KenneyNL (www.twitter.com/kenneynl) -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Crosshairs/License.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a4b6ba0d767f2b149a9f64063cf2a7bd 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Crosshairs/Patreon.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=https://www.patreon.com/kenney/ -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Crosshairs/Patreon.url.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: df45a6988a6e49443a3ef8849bf0db1d 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Crosshairs/Size.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackyyang09/Multi-Mouse-Unity/ddad073af483dca5d75442fc4d23e5ddb552036b/Examples/Lightgun Example/Kenney Crosshairs/Size.txt -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Crosshairs/Size.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a3977a123780e374fa6b447f61e40583 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Crosshairs/crosshair037.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackyyang09/Multi-Mouse-Unity/ddad073af483dca5d75442fc4d23e5ddb552036b/Examples/Lightgun Example/Kenney Crosshairs/crosshair037.png -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Crosshairs/crosshair037.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 34d287129f1526d40b3644b07330c097 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: -1 36 | aniso: -1 37 | mipBias: -100 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: -1 41 | nPOTScale: 0 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 1 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 1 54 | spriteTessellationDetail: -1 55 | textureType: 8 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | maxTextureSizeSet: 0 59 | compressionQualitySet: 0 60 | textureFormatSet: 0 61 | ignorePngGamma: 0 62 | applyGammaDecoding: 0 63 | platformSettings: 64 | - serializedVersion: 3 65 | buildTarget: DefaultTexturePlatform 66 | maxTextureSize: 2048 67 | resizeAlgorithm: 0 68 | textureFormat: -1 69 | textureCompression: 1 70 | compressionQuality: 50 71 | crunchedCompression: 0 72 | allowsAlphaSplitting: 0 73 | overridden: 0 74 | androidETC2FallbackOverride: 0 75 | forceMaximumCompressionQuality_BC6H_BC7: 0 76 | - serializedVersion: 3 77 | buildTarget: Standalone 78 | maxTextureSize: 2048 79 | resizeAlgorithm: 0 80 | textureFormat: -1 81 | textureCompression: 1 82 | compressionQuality: 50 83 | crunchedCompression: 0 84 | allowsAlphaSplitting: 0 85 | overridden: 0 86 | androidETC2FallbackOverride: 0 87 | forceMaximumCompressionQuality_BC6H_BC7: 0 88 | - serializedVersion: 3 89 | buildTarget: Android 90 | maxTextureSize: 2048 91 | resizeAlgorithm: 0 92 | textureFormat: -1 93 | textureCompression: 1 94 | compressionQuality: 50 95 | crunchedCompression: 0 96 | allowsAlphaSplitting: 0 97 | overridden: 0 98 | androidETC2FallbackOverride: 0 99 | forceMaximumCompressionQuality_BC6H_BC7: 0 100 | - serializedVersion: 3 101 | buildTarget: WebGL 102 | maxTextureSize: 2048 103 | resizeAlgorithm: 0 104 | textureFormat: -1 105 | textureCompression: 1 106 | compressionQuality: 50 107 | crunchedCompression: 0 108 | allowsAlphaSplitting: 0 109 | overridden: 0 110 | androidETC2FallbackOverride: 0 111 | forceMaximumCompressionQuality_BC6H_BC7: 0 112 | spriteSheet: 113 | serializedVersion: 2 114 | sprites: [] 115 | outline: [] 116 | physicsShape: [] 117 | bones: [] 118 | spriteID: 5e97eb03825dee720800000000000000 119 | internalID: 0 120 | vertices: [] 121 | indices: 122 | edges: [] 123 | weights: [] 124 | secondaryTextures: [] 125 | spritePackingTag: 126 | pSDRemoveMatte: 0 127 | pSDShowRemoveMatteOption: 0 128 | userData: 129 | assetBundleName: 130 | assetBundleVariant: 131 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Crosshairs/crosshair042.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackyyang09/Multi-Mouse-Unity/ddad073af483dca5d75442fc4d23e5ddb552036b/Examples/Lightgun Example/Kenney Crosshairs/crosshair042.png -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Crosshairs/crosshair042.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 33cb4e34136a5904fb68208aa711d7d6 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: -1 36 | aniso: -1 37 | mipBias: -100 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: -1 41 | nPOTScale: 0 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 1 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 1 54 | spriteTessellationDetail: -1 55 | textureType: 8 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | maxTextureSizeSet: 0 59 | compressionQualitySet: 0 60 | textureFormatSet: 0 61 | ignorePngGamma: 0 62 | applyGammaDecoding: 0 63 | platformSettings: 64 | - serializedVersion: 3 65 | buildTarget: DefaultTexturePlatform 66 | maxTextureSize: 2048 67 | resizeAlgorithm: 0 68 | textureFormat: -1 69 | textureCompression: 1 70 | compressionQuality: 50 71 | crunchedCompression: 0 72 | allowsAlphaSplitting: 0 73 | overridden: 0 74 | androidETC2FallbackOverride: 0 75 | forceMaximumCompressionQuality_BC6H_BC7: 0 76 | - serializedVersion: 3 77 | buildTarget: Standalone 78 | maxTextureSize: 2048 79 | resizeAlgorithm: 0 80 | textureFormat: -1 81 | textureCompression: 1 82 | compressionQuality: 50 83 | crunchedCompression: 0 84 | allowsAlphaSplitting: 0 85 | overridden: 0 86 | androidETC2FallbackOverride: 0 87 | forceMaximumCompressionQuality_BC6H_BC7: 0 88 | - serializedVersion: 3 89 | buildTarget: Android 90 | maxTextureSize: 2048 91 | resizeAlgorithm: 0 92 | textureFormat: -1 93 | textureCompression: 1 94 | compressionQuality: 50 95 | crunchedCompression: 0 96 | allowsAlphaSplitting: 0 97 | overridden: 0 98 | androidETC2FallbackOverride: 0 99 | forceMaximumCompressionQuality_BC6H_BC7: 0 100 | - serializedVersion: 3 101 | buildTarget: WebGL 102 | maxTextureSize: 2048 103 | resizeAlgorithm: 0 104 | textureFormat: -1 105 | textureCompression: 1 106 | compressionQuality: 50 107 | crunchedCompression: 0 108 | allowsAlphaSplitting: 0 109 | overridden: 0 110 | androidETC2FallbackOverride: 0 111 | forceMaximumCompressionQuality_BC6H_BC7: 0 112 | spriteSheet: 113 | serializedVersion: 2 114 | sprites: [] 115 | outline: [] 116 | physicsShape: [] 117 | bones: [] 118 | spriteID: 5e97eb03825dee720800000000000000 119 | internalID: 0 120 | vertices: [] 121 | indices: 122 | edges: [] 123 | weights: [] 124 | secondaryTextures: [] 125 | spritePackingTag: 126 | pSDRemoveMatte: 0 127 | pSDShowRemoveMatteOption: 0 128 | userData: 129 | assetBundleName: 130 | assetBundleVariant: 131 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Weapon Pack.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3c88c34b97edada4a9b945c0960c33ec 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Weapon Pack/pistol.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 8 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: pistol 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ValidKeywords: [] 13 | m_InvalidKeywords: [] 14 | m_LightmapFlags: 4 15 | m_EnableInstancingVariants: 0 16 | m_DoubleSidedGI: 0 17 | m_CustomRenderQueue: -1 18 | stringTagMap: {} 19 | disabledShaderPasses: [] 20 | m_SavedProperties: 21 | serializedVersion: 3 22 | m_TexEnvs: 23 | - _BumpMap: 24 | m_Texture: {fileID: 0} 25 | m_Scale: {x: 1, y: 1} 26 | m_Offset: {x: 0, y: 0} 27 | - _DetailAlbedoMap: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | - _DetailMask: 32 | m_Texture: {fileID: 0} 33 | m_Scale: {x: 1, y: 1} 34 | m_Offset: {x: 0, y: 0} 35 | - _DetailNormalMap: 36 | m_Texture: {fileID: 0} 37 | m_Scale: {x: 1, y: 1} 38 | m_Offset: {x: 0, y: 0} 39 | - _EmissionMap: 40 | m_Texture: {fileID: 0} 41 | m_Scale: {x: 1, y: 1} 42 | m_Offset: {x: 0, y: 0} 43 | - _MainTex: 44 | m_Texture: {fileID: 0} 45 | m_Scale: {x: 1, y: 1} 46 | m_Offset: {x: 0, y: 0} 47 | - _MetallicGlossMap: 48 | m_Texture: {fileID: 0} 49 | m_Scale: {x: 1, y: 1} 50 | m_Offset: {x: 0, y: 0} 51 | - _OcclusionMap: 52 | m_Texture: {fileID: 0} 53 | m_Scale: {x: 1, y: 1} 54 | m_Offset: {x: 0, y: 0} 55 | - _ParallaxMap: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | m_Ints: [] 60 | m_Floats: 61 | - _BumpScale: 1 62 | - _Cutoff: 0.5 63 | - _DetailNormalMapScale: 1 64 | - _DstBlend: 0 65 | - _GlossMapScale: 1 66 | - _Glossiness: 0.5 67 | - _GlossyReflections: 1 68 | - _Metallic: 0 69 | - _Mode: 0 70 | - _OcclusionStrength: 1 71 | - _Parallax: 0.02 72 | - _SmoothnessTextureChannel: 0 73 | - _SpecularHighlights: 1 74 | - _SrcBlend: 1 75 | - _UVSec: 0 76 | - _ZWrite: 1 77 | m_Colors: 78 | - _Color: {r: 0.05660379, g: 0.05660379, b: 0.05660379, a: 1} 79 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 80 | m_BuildTextureStacks: [] 81 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Weapon Pack/pistol.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6ab2825ab16f47248b94e8aa68ec142c 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Weapon Pack/pistol.obj.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e438cfd6b3e59ec419334c3af87d8f5f 3 | ModelImporter: 4 | serializedVersion: 21300 5 | internalIDToNameTable: [] 6 | externalObjects: 7 | - first: 8 | type: UnityEngine:Material 9 | assembly: UnityEngine.CoreModule 10 | name: Mesh1_Group2_Group1_ModelMat 11 | second: {fileID: 2100000, guid: 04bf992c605b19d4781551a216b2e645, type: 2} 12 | - first: 13 | type: UnityEngine:Material 14 | assembly: UnityEngine.CoreModule 15 | name: Mesh2_Group3_Group1_ModelMat 16 | second: {fileID: 2100000, guid: 6ab2825ab16f47248b94e8aa68ec142c, type: 2} 17 | materials: 18 | materialImportMode: 2 19 | materialName: 0 20 | materialSearch: 1 21 | materialLocation: 1 22 | animations: 23 | legacyGenerateAnimations: 4 24 | bakeSimulation: 0 25 | resampleCurves: 1 26 | optimizeGameObjects: 0 27 | removeConstantScaleCurves: 1 28 | motionNodeName: 29 | rigImportErrors: 30 | rigImportWarnings: 31 | animationImportErrors: 32 | animationImportWarnings: 33 | animationRetargetingWarnings: 34 | animationDoRetargetingWarnings: 0 35 | importAnimatedCustomProperties: 0 36 | importConstraints: 0 37 | animationCompression: 1 38 | animationRotationError: 0.5 39 | animationPositionError: 0.5 40 | animationScaleError: 0.5 41 | animationWrapMode: 0 42 | extraExposedTransformPaths: [] 43 | extraUserProperties: [] 44 | clipAnimations: [] 45 | isReadable: 0 46 | meshes: 47 | lODScreenPercentages: [] 48 | globalScale: 1 49 | meshCompression: 0 50 | addColliders: 0 51 | useSRGBMaterialColor: 1 52 | sortHierarchyByName: 1 53 | importVisibility: 1 54 | importBlendShapes: 1 55 | importCameras: 1 56 | importLights: 1 57 | nodeNameCollisionStrategy: 1 58 | fileIdsGeneration: 2 59 | swapUVChannels: 0 60 | generateSecondaryUV: 0 61 | useFileUnits: 1 62 | keepQuads: 0 63 | weldVertices: 1 64 | bakeAxisConversion: 0 65 | preserveHierarchy: 0 66 | skinWeightsMode: 0 67 | maxBonesPerVertex: 4 68 | minBoneWeight: 0.001 69 | optimizeBones: 1 70 | meshOptimizationFlags: -1 71 | indexFormat: 0 72 | secondaryUVAngleDistortion: 8 73 | secondaryUVAreaDistortion: 15.000001 74 | secondaryUVHardAngle: 88 75 | secondaryUVMarginMethod: 1 76 | secondaryUVMinLightmapResolution: 40 77 | secondaryUVMinObjectScale: 1 78 | secondaryUVPackMargin: 4 79 | useFileScale: 1 80 | tangentSpace: 81 | normalSmoothAngle: 60 82 | normalImportMode: 0 83 | tangentImportMode: 3 84 | normalCalculationMode: 4 85 | legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 86 | blendShapeNormalImportMode: 1 87 | normalSmoothingSource: 0 88 | referencedClips: [] 89 | importAnimation: 1 90 | humanDescription: 91 | serializedVersion: 3 92 | human: [] 93 | skeleton: [] 94 | armTwist: 0.5 95 | foreArmTwist: 0.5 96 | upperLegTwist: 0.5 97 | legTwist: 0.5 98 | armStretch: 0.05 99 | legStretch: 0.05 100 | feetSpacing: 0 101 | globalScale: 1 102 | rootMotionBoneName: 103 | hasTranslationDoF: 0 104 | hasExtraRoot: 0 105 | skeletonHasParents: 1 106 | lastHumanDescriptionAvatarSource: {instanceID: 0} 107 | autoGenerateAvatarMappingIfUnspecified: 1 108 | animationType: 2 109 | humanoidOversampling: 1 110 | avatarSetup: 0 111 | addHumanoidExtraRootOnlyWhenUsingAvatar: 1 112 | remapMaterialsIfMaterialImportModeIsNone: 0 113 | additionalBone: 0 114 | userData: 115 | assetBundleName: 116 | assetBundleVariant: 117 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Weapon Pack/pistol_slide.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 8 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: pistol_slide 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ValidKeywords: [] 13 | m_InvalidKeywords: [] 14 | m_LightmapFlags: 4 15 | m_EnableInstancingVariants: 0 16 | m_DoubleSidedGI: 0 17 | m_CustomRenderQueue: -1 18 | stringTagMap: {} 19 | disabledShaderPasses: [] 20 | m_SavedProperties: 21 | serializedVersion: 3 22 | m_TexEnvs: 23 | - _BumpMap: 24 | m_Texture: {fileID: 0} 25 | m_Scale: {x: 1, y: 1} 26 | m_Offset: {x: 0, y: 0} 27 | - _DetailAlbedoMap: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | - _DetailMask: 32 | m_Texture: {fileID: 0} 33 | m_Scale: {x: 1, y: 1} 34 | m_Offset: {x: 0, y: 0} 35 | - _DetailNormalMap: 36 | m_Texture: {fileID: 0} 37 | m_Scale: {x: 1, y: 1} 38 | m_Offset: {x: 0, y: 0} 39 | - _EmissionMap: 40 | m_Texture: {fileID: 0} 41 | m_Scale: {x: 1, y: 1} 42 | m_Offset: {x: 0, y: 0} 43 | - _MainTex: 44 | m_Texture: {fileID: 0} 45 | m_Scale: {x: 1, y: 1} 46 | m_Offset: {x: 0, y: 0} 47 | - _MetallicGlossMap: 48 | m_Texture: {fileID: 0} 49 | m_Scale: {x: 1, y: 1} 50 | m_Offset: {x: 0, y: 0} 51 | - _OcclusionMap: 52 | m_Texture: {fileID: 0} 53 | m_Scale: {x: 1, y: 1} 54 | m_Offset: {x: 0, y: 0} 55 | - _ParallaxMap: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | m_Ints: [] 60 | m_Floats: 61 | - _BumpScale: 1 62 | - _Cutoff: 0.5 63 | - _DetailNormalMapScale: 1 64 | - _DstBlend: 0 65 | - _GlossMapScale: 1 66 | - _Glossiness: 0.5 67 | - _GlossyReflections: 1 68 | - _Metallic: 0 69 | - _Mode: 0 70 | - _OcclusionStrength: 1 71 | - _Parallax: 0.02 72 | - _SmoothnessTextureChannel: 0 73 | - _SpecularHighlights: 1 74 | - _SrcBlend: 1 75 | - _UVSec: 0 76 | - _ZWrite: 1 77 | m_Colors: 78 | - _Color: {r: 0.5283019, g: 0.5283019, b: 0.5283019, a: 1} 79 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 80 | m_BuildTextureStacks: [] 81 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Kenney Weapon Pack/pistol_slide.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 04bf992c605b19d4781551a216b2e645 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5123cd860396a6b448842215c1f0ea59 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Materials/Ground.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 8 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Ground 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ValidKeywords: [] 13 | m_InvalidKeywords: [] 14 | m_LightmapFlags: 4 15 | m_EnableInstancingVariants: 0 16 | m_DoubleSidedGI: 0 17 | m_CustomRenderQueue: -1 18 | stringTagMap: {} 19 | disabledShaderPasses: [] 20 | m_SavedProperties: 21 | serializedVersion: 3 22 | m_TexEnvs: 23 | - _BumpMap: 24 | m_Texture: {fileID: 0} 25 | m_Scale: {x: 1, y: 1} 26 | m_Offset: {x: 0, y: 0} 27 | - _DetailAlbedoMap: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | - _DetailMask: 32 | m_Texture: {fileID: 0} 33 | m_Scale: {x: 1, y: 1} 34 | m_Offset: {x: 0, y: 0} 35 | - _DetailNormalMap: 36 | m_Texture: {fileID: 0} 37 | m_Scale: {x: 1, y: 1} 38 | m_Offset: {x: 0, y: 0} 39 | - _EmissionMap: 40 | m_Texture: {fileID: 0} 41 | m_Scale: {x: 1, y: 1} 42 | m_Offset: {x: 0, y: 0} 43 | - _MainTex: 44 | m_Texture: {fileID: 0} 45 | m_Scale: {x: 1, y: 1} 46 | m_Offset: {x: 0, y: 0} 47 | - _MetallicGlossMap: 48 | m_Texture: {fileID: 0} 49 | m_Scale: {x: 1, y: 1} 50 | m_Offset: {x: 0, y: 0} 51 | - _OcclusionMap: 52 | m_Texture: {fileID: 0} 53 | m_Scale: {x: 1, y: 1} 54 | m_Offset: {x: 0, y: 0} 55 | - _ParallaxMap: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | m_Ints: [] 60 | m_Floats: 61 | - _BumpScale: 1 62 | - _Cutoff: 0.5 63 | - _DetailNormalMapScale: 1 64 | - _DstBlend: 0 65 | - _GlossMapScale: 1 66 | - _Glossiness: 0.5 67 | - _GlossyReflections: 1 68 | - _Metallic: 0 69 | - _Mode: 0 70 | - _OcclusionStrength: 1 71 | - _Parallax: 0.02 72 | - _SmoothnessTextureChannel: 0 73 | - _SpecularHighlights: 1 74 | - _SrcBlend: 1 75 | - _UVSec: 0 76 | - _ZWrite: 1 77 | m_Colors: 78 | - _Color: {r: 1, g: 1, b: 1, a: 1} 79 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 80 | m_BuildTextureStacks: [] 81 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Materials/Ground.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 63a704acdcdbf1548965ae5c28a025d0 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Materials/Target.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 8 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Target 11 | m_Shader: {fileID: 10752, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ValidKeywords: [] 13 | m_InvalidKeywords: [] 14 | m_LightmapFlags: 0 15 | m_EnableInstancingVariants: 0 16 | m_DoubleSidedGI: 0 17 | m_CustomRenderQueue: -1 18 | stringTagMap: {} 19 | disabledShaderPasses: [] 20 | m_SavedProperties: 21 | serializedVersion: 3 22 | m_TexEnvs: 23 | - _BumpMap: 24 | m_Texture: {fileID: 0} 25 | m_Scale: {x: 1, y: 1} 26 | m_Offset: {x: 0, y: 0} 27 | - _DetailAlbedoMap: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | - _DetailMask: 32 | m_Texture: {fileID: 0} 33 | m_Scale: {x: 1, y: 1} 34 | m_Offset: {x: 0, y: 0} 35 | - _DetailNormalMap: 36 | m_Texture: {fileID: 0} 37 | m_Scale: {x: 1, y: 1} 38 | m_Offset: {x: 0, y: 0} 39 | - _EmissionMap: 40 | m_Texture: {fileID: 0} 41 | m_Scale: {x: 1, y: 1} 42 | m_Offset: {x: 0, y: 0} 43 | - _MainTex: 44 | m_Texture: {fileID: 2800000, guid: d247ef2b7ddbdaa4bb0d6afac71177ef, type: 3} 45 | m_Scale: {x: 1, y: 1} 46 | m_Offset: {x: 0, y: 0} 47 | - _MetallicGlossMap: 48 | m_Texture: {fileID: 0} 49 | m_Scale: {x: 1, y: 1} 50 | m_Offset: {x: 0, y: 0} 51 | - _OcclusionMap: 52 | m_Texture: {fileID: 0} 53 | m_Scale: {x: 1, y: 1} 54 | m_Offset: {x: 0, y: 0} 55 | - _ParallaxMap: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | m_Ints: [] 60 | m_Floats: 61 | - _BlendOp: 0 62 | - _BumpScale: 1 63 | - _CameraFadingEnabled: 0 64 | - _CameraFarFadeDistance: 2 65 | - _CameraNearFadeDistance: 1 66 | - _ColorMode: 0 67 | - _Cull: 2 68 | - _Cutoff: 0.5 69 | - _DetailNormalMapScale: 1 70 | - _DistortionBlend: 0.5 71 | - _DistortionEnabled: 0 72 | - _DistortionStrength: 1 73 | - _DistortionStrengthScaled: 0 74 | - _DstBlend: 0 75 | - _EmissionEnabled: 0 76 | - _FlipbookMode: 0 77 | - _GlossMapScale: 1 78 | - _Glossiness: 0 79 | - _GlossyReflections: 1 80 | - _LightingEnabled: 0 81 | - _Metallic: 0 82 | - _Mode: 0 83 | - _OcclusionStrength: 1 84 | - _Parallax: 0.02 85 | - _SmoothnessTextureChannel: 0 86 | - _SoftParticlesEnabled: 0 87 | - _SoftParticlesFarFadeDistance: 1 88 | - _SoftParticlesNearFadeDistance: 0 89 | - _SpecularHighlights: 1 90 | - _SrcBlend: 1 91 | - _UVSec: 0 92 | - _ZWrite: 1 93 | m_Colors: 94 | - _CameraFadeParams: {r: 0, g: Infinity, b: 0, a: 0} 95 | - _Color: {r: 1, g: 1, b: 1, a: 1} 96 | - _ColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0} 97 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 98 | - _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0} 99 | m_BuildTextureStacks: [] 100 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Materials/Target.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 302321b8b1874ee48af00a732aece090 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 38a5b17e34413c144abb26f73a02d607 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Prefabs/Crosshair.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &5052824327147330254 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 5052824327147330249} 12 | - component: {fileID: 5052824327147330251} 13 | - component: {fileID: 8039368011212355987} 14 | m_Layer: 5 15 | m_Name: Crosshair 16 | m_TagString: Untagged 17 | m_Icon: {fileID: 0} 18 | m_NavMeshLayer: 0 19 | m_StaticEditorFlags: 0 20 | m_IsActive: 1 21 | --- !u!224 &5052824327147330249 22 | RectTransform: 23 | m_ObjectHideFlags: 0 24 | m_CorrespondingSourceObject: {fileID: 0} 25 | m_PrefabInstance: {fileID: 0} 26 | m_PrefabAsset: {fileID: 0} 27 | m_GameObject: {fileID: 5052824327147330254} 28 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 29 | m_LocalPosition: {x: 0, y: 0, z: 0} 30 | m_LocalScale: {x: 1, y: 1, z: 1} 31 | m_ConstrainProportionsScale: 0 32 | m_Children: 33 | - {fileID: 4958444353995746495} 34 | - {fileID: 5872867847793391518} 35 | m_Father: {fileID: 0} 36 | m_RootOrder: 0 37 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 38 | m_AnchorMin: {x: 0, y: 1} 39 | m_AnchorMax: {x: 0, y: 1} 40 | m_AnchoredPosition: {x: 0, y: 0} 41 | m_SizeDelta: {x: 100, y: 100} 42 | m_Pivot: {x: 0.5, y: 0.5} 43 | --- !u!222 &5052824327147330251 44 | CanvasRenderer: 45 | m_ObjectHideFlags: 0 46 | m_CorrespondingSourceObject: {fileID: 0} 47 | m_PrefabInstance: {fileID: 0} 48 | m_PrefabAsset: {fileID: 0} 49 | m_GameObject: {fileID: 5052824327147330254} 50 | m_CullTransparentMesh: 0 51 | --- !u!114 &8039368011212355987 52 | MonoBehaviour: 53 | m_ObjectHideFlags: 0 54 | m_CorrespondingSourceObject: {fileID: 0} 55 | m_PrefabInstance: {fileID: 0} 56 | m_PrefabAsset: {fileID: 0} 57 | m_GameObject: {fileID: 5052824327147330254} 58 | m_Enabled: 1 59 | m_EditorHideFlags: 0 60 | m_Script: {fileID: 11500000, guid: dcc079ccf19704a4493a6d8fea3b2ae2, type: 3} 61 | m_Name: 62 | m_EditorClassIdentifier: 63 | deviceID: 0 64 | --- !u!1 &8568213464256251540 65 | GameObject: 66 | m_ObjectHideFlags: 0 67 | m_CorrespondingSourceObject: {fileID: 0} 68 | m_PrefabInstance: {fileID: 0} 69 | m_PrefabAsset: {fileID: 0} 70 | serializedVersion: 6 71 | m_Component: 72 | - component: {fileID: 5872867847793391518} 73 | - component: {fileID: 3283556926863915168} 74 | - component: {fileID: 1502873688641058794} 75 | m_Layer: 5 76 | m_Name: Highlight 77 | m_TagString: Untagged 78 | m_Icon: {fileID: 0} 79 | m_NavMeshLayer: 0 80 | m_StaticEditorFlags: 0 81 | m_IsActive: 1 82 | --- !u!224 &5872867847793391518 83 | RectTransform: 84 | m_ObjectHideFlags: 0 85 | m_CorrespondingSourceObject: {fileID: 0} 86 | m_PrefabInstance: {fileID: 0} 87 | m_PrefabAsset: {fileID: 0} 88 | m_GameObject: {fileID: 8568213464256251540} 89 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 90 | m_LocalPosition: {x: 0, y: 0, z: 0} 91 | m_LocalScale: {x: 1, y: 1, z: 1} 92 | m_ConstrainProportionsScale: 0 93 | m_Children: [] 94 | m_Father: {fileID: 5052824327147330249} 95 | m_RootOrder: 1 96 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 97 | m_AnchorMin: {x: 0.5, y: 0.5} 98 | m_AnchorMax: {x: 0.5, y: 0.5} 99 | m_AnchoredPosition: {x: 0, y: 0} 100 | m_SizeDelta: {x: 100, y: 100} 101 | m_Pivot: {x: 0.5, y: 0.5} 102 | --- !u!222 &3283556926863915168 103 | CanvasRenderer: 104 | m_ObjectHideFlags: 0 105 | m_CorrespondingSourceObject: {fileID: 0} 106 | m_PrefabInstance: {fileID: 0} 107 | m_PrefabAsset: {fileID: 0} 108 | m_GameObject: {fileID: 8568213464256251540} 109 | m_CullTransparentMesh: 0 110 | --- !u!114 &1502873688641058794 111 | MonoBehaviour: 112 | m_ObjectHideFlags: 0 113 | m_CorrespondingSourceObject: {fileID: 0} 114 | m_PrefabInstance: {fileID: 0} 115 | m_PrefabAsset: {fileID: 0} 116 | m_GameObject: {fileID: 8568213464256251540} 117 | m_Enabled: 1 118 | m_EditorHideFlags: 0 119 | m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 120 | m_Name: 121 | m_EditorClassIdentifier: 122 | m_Material: {fileID: 0} 123 | m_Color: {r: 1, g: 0, b: 0, a: 1} 124 | m_RaycastTarget: 1 125 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} 126 | m_Maskable: 1 127 | m_OnCullStateChanged: 128 | m_PersistentCalls: 129 | m_Calls: [] 130 | m_Sprite: {fileID: 21300000, guid: fb3b1c424ed97934fae631f70952cd54, type: 3} 131 | m_Type: 0 132 | m_PreserveAspect: 0 133 | m_FillCenter: 1 134 | m_FillMethod: 4 135 | m_FillAmount: 1 136 | m_FillClockwise: 1 137 | m_FillOrigin: 0 138 | m_UseSpriteMesh: 0 139 | m_PixelsPerUnitMultiplier: 1 140 | --- !u!1 &9168062729023126979 141 | GameObject: 142 | m_ObjectHideFlags: 0 143 | m_CorrespondingSourceObject: {fileID: 0} 144 | m_PrefabInstance: {fileID: 0} 145 | m_PrefabAsset: {fileID: 0} 146 | serializedVersion: 6 147 | m_Component: 148 | - component: {fileID: 4958444353995746495} 149 | - component: {fileID: 6191968295805366464} 150 | - component: {fileID: 8103961989605807131} 151 | m_Layer: 5 152 | m_Name: Center 153 | m_TagString: Untagged 154 | m_Icon: {fileID: 0} 155 | m_NavMeshLayer: 0 156 | m_StaticEditorFlags: 0 157 | m_IsActive: 1 158 | --- !u!224 &4958444353995746495 159 | RectTransform: 160 | m_ObjectHideFlags: 0 161 | m_CorrespondingSourceObject: {fileID: 0} 162 | m_PrefabInstance: {fileID: 0} 163 | m_PrefabAsset: {fileID: 0} 164 | m_GameObject: {fileID: 9168062729023126979} 165 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 166 | m_LocalPosition: {x: 0, y: 0, z: 0} 167 | m_LocalScale: {x: 1, y: 1, z: 1} 168 | m_ConstrainProportionsScale: 0 169 | m_Children: [] 170 | m_Father: {fileID: 5052824327147330249} 171 | m_RootOrder: 0 172 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 173 | m_AnchorMin: {x: 0.5, y: 0.5} 174 | m_AnchorMax: {x: 0.5, y: 0.5} 175 | m_AnchoredPosition: {x: 0, y: 0} 176 | m_SizeDelta: {x: 100, y: 100} 177 | m_Pivot: {x: 0.5, y: 0.5} 178 | --- !u!222 &6191968295805366464 179 | CanvasRenderer: 180 | m_ObjectHideFlags: 0 181 | m_CorrespondingSourceObject: {fileID: 0} 182 | m_PrefabInstance: {fileID: 0} 183 | m_PrefabAsset: {fileID: 0} 184 | m_GameObject: {fileID: 9168062729023126979} 185 | m_CullTransparentMesh: 0 186 | --- !u!114 &8103961989605807131 187 | MonoBehaviour: 188 | m_ObjectHideFlags: 0 189 | m_CorrespondingSourceObject: {fileID: 0} 190 | m_PrefabInstance: {fileID: 0} 191 | m_PrefabAsset: {fileID: 0} 192 | m_GameObject: {fileID: 9168062729023126979} 193 | m_Enabled: 1 194 | m_EditorHideFlags: 0 195 | m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 196 | m_Name: 197 | m_EditorClassIdentifier: 198 | m_Material: {fileID: 0} 199 | m_Color: {r: 1, g: 1, b: 1, a: 1} 200 | m_RaycastTarget: 1 201 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} 202 | m_Maskable: 1 203 | m_OnCullStateChanged: 204 | m_PersistentCalls: 205 | m_Calls: [] 206 | m_Sprite: {fileID: 21300000, guid: b7512c5583c280a4a84c14a6767c3093, type: 3} 207 | m_Type: 0 208 | m_PreserveAspect: 0 209 | m_FillCenter: 1 210 | m_FillMethod: 4 211 | m_FillAmount: 1 212 | m_FillClockwise: 1 213 | m_FillOrigin: 0 214 | m_UseSpriteMesh: 0 215 | m_PixelsPerUnitMultiplier: 1 216 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Prefabs/Crosshair.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cd0b0dc7ea5789f4cbfcf80f67d44245 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Prefabs/MuzzleFlash.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &1071529151986673640 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 2373108308630068930} 12 | - component: {fileID: 1007196764826416431} 13 | - component: {fileID: 6743041498546821050} 14 | - component: {fileID: 1584374568893334555} 15 | m_Layer: 5 16 | m_Name: MuzzleFlash 17 | m_TagString: Untagged 18 | m_Icon: {fileID: 0} 19 | m_NavMeshLayer: 0 20 | m_StaticEditorFlags: 0 21 | m_IsActive: 1 22 | --- !u!224 &2373108308630068930 23 | RectTransform: 24 | m_ObjectHideFlags: 0 25 | m_CorrespondingSourceObject: {fileID: 0} 26 | m_PrefabInstance: {fileID: 0} 27 | m_PrefabAsset: {fileID: 0} 28 | m_GameObject: {fileID: 1071529151986673640} 29 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 30 | m_LocalPosition: {x: 0, y: 0, z: 0} 31 | m_LocalScale: {x: 1, y: 1, z: 1} 32 | m_ConstrainProportionsScale: 0 33 | m_Children: 34 | - {fileID: 2354309953881900159} 35 | m_Father: {fileID: 0} 36 | m_RootOrder: 0 37 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 38 | m_AnchorMin: {x: 0.5, y: 0.5} 39 | m_AnchorMax: {x: 0.5, y: 0.5} 40 | m_AnchoredPosition: {x: 0, y: 0} 41 | m_SizeDelta: {x: 0, y: 0} 42 | m_Pivot: {x: 0.5, y: 0.5} 43 | --- !u!222 &1007196764826416431 44 | CanvasRenderer: 45 | m_ObjectHideFlags: 0 46 | m_CorrespondingSourceObject: {fileID: 0} 47 | m_PrefabInstance: {fileID: 0} 48 | m_PrefabAsset: {fileID: 0} 49 | m_GameObject: {fileID: 1071529151986673640} 50 | m_CullTransparentMesh: 1 51 | --- !u!114 &6743041498546821050 52 | MonoBehaviour: 53 | m_ObjectHideFlags: 0 54 | m_CorrespondingSourceObject: {fileID: 0} 55 | m_PrefabInstance: {fileID: 0} 56 | m_PrefabAsset: {fileID: 0} 57 | m_GameObject: {fileID: 1071529151986673640} 58 | m_Enabled: 1 59 | m_EditorHideFlags: 0 60 | m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 61 | m_Name: 62 | m_EditorClassIdentifier: 63 | m_Material: {fileID: 0} 64 | m_Color: {r: 1, g: 0.7170844, b: 0, a: 1} 65 | m_RaycastTarget: 0 66 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} 67 | m_Maskable: 1 68 | m_OnCullStateChanged: 69 | m_PersistentCalls: 70 | m_Calls: [] 71 | m_Sprite: {fileID: 10913, guid: 0000000000000000f000000000000000, type: 0} 72 | m_Type: 0 73 | m_PreserveAspect: 0 74 | m_FillCenter: 1 75 | m_FillMethod: 4 76 | m_FillAmount: 1 77 | m_FillClockwise: 1 78 | m_FillOrigin: 0 79 | m_UseSpriteMesh: 0 80 | m_PixelsPerUnitMultiplier: 1 81 | --- !u!111 &1584374568893334555 82 | Animation: 83 | m_ObjectHideFlags: 0 84 | m_CorrespondingSourceObject: {fileID: 0} 85 | m_PrefabInstance: {fileID: 0} 86 | m_PrefabAsset: {fileID: 0} 87 | m_GameObject: {fileID: 1071529151986673640} 88 | m_Enabled: 1 89 | serializedVersion: 3 90 | m_Animation: {fileID: 7400000, guid: 5ace61bc1c1bae142a8f009f5c4b130d, type: 2} 91 | m_Animations: 92 | - {fileID: 7400000, guid: 5ace61bc1c1bae142a8f009f5c4b130d, type: 2} 93 | m_WrapMode: 0 94 | m_PlayAutomatically: 1 95 | m_AnimatePhysics: 0 96 | m_CullingType: 0 97 | --- !u!1 &6278503754425794751 98 | GameObject: 99 | m_ObjectHideFlags: 0 100 | m_CorrespondingSourceObject: {fileID: 0} 101 | m_PrefabInstance: {fileID: 0} 102 | m_PrefabAsset: {fileID: 0} 103 | serializedVersion: 6 104 | m_Component: 105 | - component: {fileID: 2354309953881900159} 106 | - component: {fileID: 3925026272620807313} 107 | m_Layer: 5 108 | m_Name: Gunshot Sound 109 | m_TagString: Untagged 110 | m_Icon: {fileID: 0} 111 | m_NavMeshLayer: 0 112 | m_StaticEditorFlags: 0 113 | m_IsActive: 1 114 | --- !u!4 &2354309953881900159 115 | Transform: 116 | m_ObjectHideFlags: 0 117 | m_CorrespondingSourceObject: {fileID: 0} 118 | m_PrefabInstance: {fileID: 0} 119 | m_PrefabAsset: {fileID: 0} 120 | m_GameObject: {fileID: 6278503754425794751} 121 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 122 | m_LocalPosition: {x: -960, y: -540, z: 0} 123 | m_LocalScale: {x: 1, y: 1, z: 1} 124 | m_ConstrainProportionsScale: 0 125 | m_Children: [] 126 | m_Father: {fileID: 2373108308630068930} 127 | m_RootOrder: 0 128 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 129 | --- !u!82 &3925026272620807313 130 | AudioSource: 131 | m_ObjectHideFlags: 0 132 | m_CorrespondingSourceObject: {fileID: 0} 133 | m_PrefabInstance: {fileID: 0} 134 | m_PrefabAsset: {fileID: 0} 135 | m_GameObject: {fileID: 6278503754425794751} 136 | m_Enabled: 1 137 | serializedVersion: 4 138 | OutputAudioMixerGroup: {fileID: 0} 139 | m_audioClip: {fileID: 8300000, guid: 863f67d126e79ff4fa81c9a0a4c517a7, type: 3} 140 | m_PlayOnAwake: 1 141 | m_Volume: 0.15 142 | m_Pitch: 1 143 | Loop: 0 144 | Mute: 0 145 | Spatialize: 0 146 | SpatializePostEffects: 0 147 | Priority: 128 148 | DopplerLevel: 1 149 | MinDistance: 1 150 | MaxDistance: 500 151 | Pan2D: 0 152 | rolloffMode: 0 153 | BypassEffects: 0 154 | BypassListenerEffects: 0 155 | BypassReverbZones: 0 156 | rolloffCustomCurve: 157 | serializedVersion: 2 158 | m_Curve: 159 | - serializedVersion: 3 160 | time: 0 161 | value: 1 162 | inSlope: 0 163 | outSlope: 0 164 | tangentMode: 0 165 | weightedMode: 0 166 | inWeight: 0.33333334 167 | outWeight: 0.33333334 168 | - serializedVersion: 3 169 | time: 1 170 | value: 0 171 | inSlope: 0 172 | outSlope: 0 173 | tangentMode: 0 174 | weightedMode: 0 175 | inWeight: 0.33333334 176 | outWeight: 0.33333334 177 | m_PreInfinity: 2 178 | m_PostInfinity: 2 179 | m_RotationOrder: 4 180 | panLevelCustomCurve: 181 | serializedVersion: 2 182 | m_Curve: 183 | - serializedVersion: 3 184 | time: 0 185 | value: 0 186 | inSlope: 0 187 | outSlope: 0 188 | tangentMode: 0 189 | weightedMode: 0 190 | inWeight: 0.33333334 191 | outWeight: 0.33333334 192 | m_PreInfinity: 2 193 | m_PostInfinity: 2 194 | m_RotationOrder: 4 195 | spreadCustomCurve: 196 | serializedVersion: 2 197 | m_Curve: 198 | - serializedVersion: 3 199 | time: 0 200 | value: 0 201 | inSlope: 0 202 | outSlope: 0 203 | tangentMode: 0 204 | weightedMode: 0 205 | inWeight: 0.33333334 206 | outWeight: 0.33333334 207 | m_PreInfinity: 2 208 | m_PostInfinity: 2 209 | m_RotationOrder: 4 210 | reverbZoneMixCustomCurve: 211 | serializedVersion: 2 212 | m_Curve: 213 | - serializedVersion: 3 214 | time: 0 215 | value: 1 216 | inSlope: 0 217 | outSlope: 0 218 | tangentMode: 0 219 | weightedMode: 0 220 | inWeight: 0.33333334 221 | outWeight: 0.33333334 222 | m_PreInfinity: 2 223 | m_PostInfinity: 2 224 | m_RotationOrder: 4 225 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Prefabs/MuzzleFlash.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3fa75804dc25f0342ad7dffa6b8d4b79 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Prefabs/Player.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9220252b783dcbf4cbaae733aefafdb6 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Prefabs/PlayerSlot.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5d4b17ad0e95d644ca71373f7b571f66 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Prefabs/Target.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &2375210115839505329 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 2375210115839347790} 12 | m_Layer: 0 13 | m_Name: Pivot 14 | m_TagString: Untagged 15 | m_Icon: {fileID: 0} 16 | m_NavMeshLayer: 0 17 | m_StaticEditorFlags: 0 18 | m_IsActive: 1 19 | --- !u!4 &2375210115839347790 20 | Transform: 21 | m_ObjectHideFlags: 0 22 | m_CorrespondingSourceObject: {fileID: 0} 23 | m_PrefabInstance: {fileID: 0} 24 | m_PrefabAsset: {fileID: 0} 25 | m_GameObject: {fileID: 2375210115839505329} 26 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 27 | m_LocalPosition: {x: 0, y: 0, z: 0} 28 | m_LocalScale: {x: 1, y: 1, z: 1} 29 | m_ConstrainProportionsScale: 0 30 | m_Children: 31 | - {fileID: 2375210117362608912} 32 | m_Father: {fileID: 2375210116637417975} 33 | m_RootOrder: 0 34 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 35 | --- !u!1 &2375210116637417974 36 | GameObject: 37 | m_ObjectHideFlags: 0 38 | m_CorrespondingSourceObject: {fileID: 0} 39 | m_PrefabInstance: {fileID: 0} 40 | m_PrefabAsset: {fileID: 0} 41 | serializedVersion: 6 42 | m_Component: 43 | - component: {fileID: 2375210116637417975} 44 | - component: {fileID: 2345133176955609067} 45 | - component: {fileID: 1281548584389672044} 46 | - component: {fileID: 1476315211533130931} 47 | m_Layer: 0 48 | m_Name: Target 49 | m_TagString: Untagged 50 | m_Icon: {fileID: 0} 51 | m_NavMeshLayer: 0 52 | m_StaticEditorFlags: 0 53 | m_IsActive: 1 54 | --- !u!4 &2375210116637417975 55 | Transform: 56 | m_ObjectHideFlags: 0 57 | m_CorrespondingSourceObject: {fileID: 0} 58 | m_PrefabInstance: {fileID: 0} 59 | m_PrefabAsset: {fileID: 0} 60 | m_GameObject: {fileID: 2375210116637417974} 61 | m_LocalRotation: {x: -0, y: -0.13195929, z: -0, w: 0.9912552} 62 | m_LocalPosition: {x: -3.75, y: 0, z: -4.26} 63 | m_LocalScale: {x: 1, y: 1, z: 1} 64 | m_ConstrainProportionsScale: 0 65 | m_Children: 66 | - {fileID: 2375210115839347790} 67 | m_Father: {fileID: 0} 68 | m_RootOrder: 0 69 | m_LocalEulerAnglesHint: {x: 0, y: -15.166, z: 0} 70 | --- !u!114 &2345133176955609067 71 | MonoBehaviour: 72 | m_ObjectHideFlags: 0 73 | m_CorrespondingSourceObject: {fileID: 0} 74 | m_PrefabInstance: {fileID: 0} 75 | m_PrefabAsset: {fileID: 0} 76 | m_GameObject: {fileID: 2375210116637417974} 77 | m_Enabled: 1 78 | m_EditorHideFlags: 0 79 | m_Script: {fileID: 11500000, guid: 0a1768e13811e4541bb3ae2b63485e5d, type: 3} 80 | m_Name: 81 | m_EditorClassIdentifier: 82 | resetTime: 3 83 | collider: {fileID: 2375210117362608913} 84 | anim: {fileID: 1281548584389672044} 85 | --- !u!95 &1281548584389672044 86 | Animator: 87 | serializedVersion: 4 88 | m_ObjectHideFlags: 0 89 | m_CorrespondingSourceObject: {fileID: 0} 90 | m_PrefabInstance: {fileID: 0} 91 | m_PrefabAsset: {fileID: 0} 92 | m_GameObject: {fileID: 2375210116637417974} 93 | m_Enabled: 1 94 | m_Avatar: {fileID: 0} 95 | m_Controller: {fileID: 9100000, guid: 149e92f7aa38f4a4cbd7145f6c5c3432, type: 2} 96 | m_CullingMode: 0 97 | m_UpdateMode: 0 98 | m_ApplyRootMotion: 0 99 | m_LinearVelocityBlending: 0 100 | m_StabilizeFeet: 0 101 | m_WarningMessage: 102 | m_HasTransformHierarchy: 1 103 | m_AllowConstantClipSamplingOptimization: 1 104 | m_KeepAnimatorControllerStateOnDisable: 0 105 | --- !u!54 &1476315211533130931 106 | Rigidbody: 107 | m_ObjectHideFlags: 0 108 | m_CorrespondingSourceObject: {fileID: 0} 109 | m_PrefabInstance: {fileID: 0} 110 | m_PrefabAsset: {fileID: 0} 111 | m_GameObject: {fileID: 2375210116637417974} 112 | serializedVersion: 2 113 | m_Mass: 1 114 | m_Drag: 0 115 | m_AngularDrag: 0.05 116 | m_UseGravity: 0 117 | m_IsKinematic: 0 118 | m_Interpolate: 0 119 | m_Constraints: 0 120 | m_CollisionDetection: 0 121 | --- !u!1 &2375210117045290520 122 | GameObject: 123 | m_ObjectHideFlags: 0 124 | m_CorrespondingSourceObject: {fileID: 0} 125 | m_PrefabInstance: {fileID: 0} 126 | m_PrefabAsset: {fileID: 0} 127 | serializedVersion: 6 128 | m_Component: 129 | - component: {fileID: 2375210117045290521} 130 | - component: {fileID: 2375210117045290516} 131 | - component: {fileID: 2375210117045290519} 132 | m_Layer: 0 133 | m_Name: Quad 134 | m_TagString: Untagged 135 | m_Icon: {fileID: 0} 136 | m_NavMeshLayer: 0 137 | m_StaticEditorFlags: 0 138 | m_IsActive: 0 139 | --- !u!4 &2375210117045290521 140 | Transform: 141 | m_ObjectHideFlags: 0 142 | m_CorrespondingSourceObject: {fileID: 0} 143 | m_PrefabInstance: {fileID: 0} 144 | m_PrefabAsset: {fileID: 0} 145 | m_GameObject: {fileID: 2375210117045290520} 146 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 147 | m_LocalPosition: {x: 0, y: 0, z: -0.59} 148 | m_LocalScale: {x: 1, y: 1, z: 1} 149 | m_ConstrainProportionsScale: 0 150 | m_Children: [] 151 | m_Father: {fileID: 2375210117362608912} 152 | m_RootOrder: 0 153 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 154 | --- !u!33 &2375210117045290516 155 | MeshFilter: 156 | m_ObjectHideFlags: 0 157 | m_CorrespondingSourceObject: {fileID: 0} 158 | m_PrefabInstance: {fileID: 0} 159 | m_PrefabAsset: {fileID: 0} 160 | m_GameObject: {fileID: 2375210117045290520} 161 | m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} 162 | --- !u!23 &2375210117045290519 163 | MeshRenderer: 164 | m_ObjectHideFlags: 0 165 | m_CorrespondingSourceObject: {fileID: 0} 166 | m_PrefabInstance: {fileID: 0} 167 | m_PrefabAsset: {fileID: 0} 168 | m_GameObject: {fileID: 2375210117045290520} 169 | m_Enabled: 1 170 | m_CastShadows: 1 171 | m_ReceiveShadows: 1 172 | m_DynamicOccludee: 1 173 | m_StaticShadowCaster: 0 174 | m_MotionVectors: 1 175 | m_LightProbeUsage: 1 176 | m_ReflectionProbeUsage: 1 177 | m_RayTracingMode: 2 178 | m_RayTraceProcedural: 0 179 | m_RenderingLayerMask: 1 180 | m_RendererPriority: 0 181 | m_Materials: 182 | - {fileID: 2100000, guid: 302321b8b1874ee48af00a732aece090, type: 2} 183 | m_StaticBatchInfo: 184 | firstSubMesh: 0 185 | subMeshCount: 0 186 | m_StaticBatchRoot: {fileID: 0} 187 | m_ProbeAnchor: {fileID: 0} 188 | m_LightProbeVolumeOverride: {fileID: 0} 189 | m_ScaleInLightmap: 1 190 | m_ReceiveGI: 1 191 | m_PreserveUVs: 0 192 | m_IgnoreNormalsForChartDetection: 0 193 | m_ImportantGI: 0 194 | m_StitchLightmapSeams: 1 195 | m_SelectedEditorRenderState: 3 196 | m_MinimumChartSize: 4 197 | m_AutoUVMaxDistance: 0.5 198 | m_AutoUVMaxAngle: 89 199 | m_LightmapParameters: {fileID: 0} 200 | m_SortingLayerID: 0 201 | m_SortingLayer: 0 202 | m_SortingOrder: 0 203 | m_AdditionalVertexStreams: {fileID: 0} 204 | --- !u!1 &2375210117362608915 205 | GameObject: 206 | m_ObjectHideFlags: 0 207 | m_CorrespondingSourceObject: {fileID: 0} 208 | m_PrefabInstance: {fileID: 0} 209 | m_PrefabAsset: {fileID: 0} 210 | serializedVersion: 6 211 | m_Component: 212 | - component: {fileID: 2375210117362608912} 213 | - component: {fileID: 2375210117362608943} 214 | - component: {fileID: 2375210117362608942} 215 | - component: {fileID: 2375210117362608913} 216 | m_Layer: 0 217 | m_Name: Cube 218 | m_TagString: Untagged 219 | m_Icon: {fileID: 0} 220 | m_NavMeshLayer: 0 221 | m_StaticEditorFlags: 0 222 | m_IsActive: 1 223 | --- !u!4 &2375210117362608912 224 | Transform: 225 | m_ObjectHideFlags: 0 226 | m_CorrespondingSourceObject: {fileID: 0} 227 | m_PrefabInstance: {fileID: 0} 228 | m_PrefabAsset: {fileID: 0} 229 | m_GameObject: {fileID: 2375210117362608915} 230 | m_LocalRotation: {x: 0, y: 1, z: 0, w: 0} 231 | m_LocalPosition: {x: 0, y: 1, z: -0.04999999} 232 | m_LocalScale: {x: 1, y: 2, z: 0.099999994} 233 | m_ConstrainProportionsScale: 0 234 | m_Children: 235 | - {fileID: 2375210117045290521} 236 | m_Father: {fileID: 2375210115839347790} 237 | m_RootOrder: 0 238 | m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0} 239 | --- !u!33 &2375210117362608943 240 | MeshFilter: 241 | m_ObjectHideFlags: 0 242 | m_CorrespondingSourceObject: {fileID: 0} 243 | m_PrefabInstance: {fileID: 0} 244 | m_PrefabAsset: {fileID: 0} 245 | m_GameObject: {fileID: 2375210117362608915} 246 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 247 | --- !u!23 &2375210117362608942 248 | MeshRenderer: 249 | m_ObjectHideFlags: 0 250 | m_CorrespondingSourceObject: {fileID: 0} 251 | m_PrefabInstance: {fileID: 0} 252 | m_PrefabAsset: {fileID: 0} 253 | m_GameObject: {fileID: 2375210117362608915} 254 | m_Enabled: 1 255 | m_CastShadows: 1 256 | m_ReceiveShadows: 1 257 | m_DynamicOccludee: 1 258 | m_StaticShadowCaster: 0 259 | m_MotionVectors: 1 260 | m_LightProbeUsage: 1 261 | m_ReflectionProbeUsage: 1 262 | m_RayTracingMode: 2 263 | m_RayTraceProcedural: 0 264 | m_RenderingLayerMask: 1 265 | m_RendererPriority: 0 266 | m_Materials: 267 | - {fileID: 2100000, guid: 302321b8b1874ee48af00a732aece090, type: 2} 268 | m_StaticBatchInfo: 269 | firstSubMesh: 0 270 | subMeshCount: 0 271 | m_StaticBatchRoot: {fileID: 0} 272 | m_ProbeAnchor: {fileID: 0} 273 | m_LightProbeVolumeOverride: {fileID: 0} 274 | m_ScaleInLightmap: 1 275 | m_ReceiveGI: 1 276 | m_PreserveUVs: 0 277 | m_IgnoreNormalsForChartDetection: 0 278 | m_ImportantGI: 0 279 | m_StitchLightmapSeams: 1 280 | m_SelectedEditorRenderState: 3 281 | m_MinimumChartSize: 4 282 | m_AutoUVMaxDistance: 0.5 283 | m_AutoUVMaxAngle: 89 284 | m_LightmapParameters: {fileID: 0} 285 | m_SortingLayerID: 0 286 | m_SortingLayer: 0 287 | m_SortingOrder: 0 288 | m_AdditionalVertexStreams: {fileID: 0} 289 | --- !u!65 &2375210117362608913 290 | BoxCollider: 291 | m_ObjectHideFlags: 0 292 | m_CorrespondingSourceObject: {fileID: 0} 293 | m_PrefabInstance: {fileID: 0} 294 | m_PrefabAsset: {fileID: 0} 295 | m_GameObject: {fileID: 2375210117362608915} 296 | m_Material: {fileID: 0} 297 | m_IsTrigger: 1 298 | m_Enabled: 1 299 | serializedVersion: 2 300 | m_Size: {x: 1, y: 1, z: 1} 301 | m_Center: {x: 0, y: 0, z: 0} 302 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Prefabs/Target.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3f7e010614894f84d883b9411a809b2f 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 263c58c95d2ce694eaee657fed28aab4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scenes/Lightgun00.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a14afa81d88c76a48b6a669eb85f3886 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scenes/Lightgun01.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b8b7ab39b0baa954fb322638a884e103 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 30b2fe0e2c48f63448fd74bc800cb39a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/Crosshair.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace MultiMouseUnity.Example 7 | { 8 | public class Crosshair : MonoBehaviour 9 | { 10 | [SerializeField] int deviceID; 11 | 12 | private void OnEnable() 13 | { 14 | MultiMouseWrapper.OnLeftMouseButtonDown[deviceID] += HideCursor; 15 | } 16 | 17 | private void OnDisable() 18 | { 19 | MultiMouseWrapper.OnLeftMouseButtonDown[deviceID] -= HideCursor; 20 | } 21 | 22 | public void SetDeviceID(int id) => deviceID = id; 23 | 24 | private void HideCursor() 25 | { 26 | Cursor.visible = false; 27 | Cursor.lockState = CursorLockMode.Locked; 28 | } 29 | 30 | // Update is called once per frame 31 | void Update() 32 | { 33 | if (!MultiMouseWrapper.Instance.IsMouseActive(deviceID)) return; 34 | transform.position = MultiMouseWrapper.Instance.GetMousePosition(deviceID); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/Crosshair.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dcc079ccf19704a4493a6d8fea3b2ae2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/IShootable.cs: -------------------------------------------------------------------------------- 1 | public interface IShootable 2 | { 3 | void InvokeOnShotBehaviour(); 4 | } -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/IShootable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 786a41b5645f36d41b9adaeeddf29d34 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/Lightgun.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | namespace MultiMouseUnity.Example 5 | { 6 | public class Lightgun : MonoBehaviour 7 | { 8 | [SerializeField] Transform uiTransform; 9 | [SerializeField] Image highlight; 10 | [SerializeField] Crosshair crosshair; 11 | 12 | Camera cam; 13 | 14 | public System.Action OnShoot; 15 | 16 | // Start is called before the first frame update 17 | void Start() 18 | { 19 | cam = Camera.main; 20 | highlight.CrossFadeAlpha(0, 0, false); 21 | } 22 | 23 | public void Shoot(WeaponObject weapon) 24 | { 25 | if (weapon.pellets == 0) // This weapon is not a shotgun 26 | { 27 | FireShotAt(crosshair.transform.position, weapon); 28 | } 29 | else // This weapon is a shotgun 30 | { 31 | for (int i = 0; i < weapon.pellets; i++) 32 | { 33 | var offset = (Vector3)Random.insideUnitCircle * weapon.bulletSpread; 34 | FireShotAt(crosshair.transform.position + offset, weapon); 35 | } 36 | } 37 | } 38 | 39 | void FireShotAt(Vector2 pos, WeaponObject weapon) 40 | { 41 | Ray ray = cam.ScreenPointToRay(pos); 42 | RaycastHit hit; 43 | IShootable shootable; 44 | 45 | if (Physics.Raycast(ray, out hit, Mathf.Infinity)) 46 | { 47 | if (hit.transform.TryGetComponent(out shootable)) 48 | { 49 | shootable.InvokeOnShotBehaviour(); 50 | 51 | highlight.CrossFadeAlpha(1, 0, false); 52 | highlight.CrossFadeAlpha(0, 0.5f, false); 53 | } 54 | } 55 | 56 | // Instantiating and destroying muzzle flash effects can be computationally expensive! 57 | // In a real game project, you should consider other methods of creating these effects 58 | var muzzleFlash = Instantiate(weapon.muzzleFlashPrefab, uiTransform); 59 | muzzleFlash.transform.position = pos; 60 | Destroy(muzzleFlash, 1); 61 | 62 | OnShoot?.Invoke(); 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/Lightgun.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ad78fb877beb94148968dcd64698e75d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/PlayerBehaviour.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace MultiMouseUnity.Example 7 | { 8 | public class PlayerBehaviour : MonoBehaviour 9 | { 10 | [SerializeField] WeaponObject weapon; 11 | int ammo; 12 | 13 | [SerializeField] int playerIndex; 14 | [SerializeField] int fireButton = 0; 15 | [SerializeField] int reloadButton = 1; 16 | int deviceID = -1; 17 | 18 | [Header("Object References")] 19 | [SerializeField] Canvas canvas; 20 | [SerializeField] Lightgun lightgun; 21 | [SerializeField] Crosshair crossHair; 22 | [SerializeField] ViewModelRotator viewModel; 23 | 24 | [Header("UI")] 25 | [SerializeField] CanvasGroup waitingUI; 26 | [SerializeField] CanvasGroup gameUI; 27 | [SerializeField] UnityEngine.UI.Text weaponLabel; 28 | [SerializeField] UnityEngine.UI.Text ammoCount; 29 | [SerializeField] UnityEngine.UI.Image ammoFill; 30 | 31 | float lastFireTime; 32 | 33 | private void Start() 34 | { 35 | ammo = weapon.ammoCapacity; 36 | UpdateAmmoUI(); 37 | 38 | if (MainMenuUI.PlayData == null) 39 | { 40 | deviceID = playerIndex; 41 | } 42 | else 43 | { 44 | if (MultiMouseWrapper.Instance.ActiveDeviceCount > 0) 45 | { 46 | deviceID = MainMenuUI.PlayData.playerIDs[playerIndex]; 47 | if (deviceID > -1) 48 | { 49 | OnDeviceFound(deviceID); 50 | } 51 | } 52 | } 53 | } 54 | 55 | private void OnEnable() 56 | { 57 | MultiMouseWrapper.OnDeviceFound += OnDeviceFound; 58 | } 59 | 60 | private void OnDisable() 61 | { 62 | MultiMouseWrapper.OnDeviceFound -= OnDeviceFound; 63 | if (deviceID > -1) 64 | { 65 | MultiMouseWrapper.OnLeftMouseButtonDown[deviceID] -= HideCursor; 66 | MultiMouseWrapper.OnRightMouseButtonDown[deviceID] -= Reload; 67 | } 68 | } 69 | 70 | private void Update() 71 | { 72 | if (Time.time < lastFireTime + weapon.fireDelay) return; 73 | if (!MultiMouseWrapper.Instance.IsMouseActive(deviceID)) return; 74 | 75 | switch (weapon.weaponType) 76 | { 77 | case FireType.SemiAuto: 78 | if (MultiMouseWrapper.Instance.GetMouseButtonDown(deviceID, fireButton)) 79 | { 80 | PullTrigger(); 81 | } 82 | break; 83 | case FireType.FullAuto: 84 | if (MultiMouseWrapper.Instance.GetMouseButton(deviceID, fireButton)) 85 | { 86 | PullTrigger(); 87 | } 88 | break; 89 | } 90 | } 91 | 92 | void PullTrigger() 93 | { 94 | if (ammo == 0) return; 95 | 96 | lightgun.Shoot(weapon); 97 | ammo--; 98 | UpdateAmmoUI(); 99 | lastFireTime = Time.time; 100 | } 101 | 102 | private void OnDeviceFound(int mouseID) 103 | { 104 | if (mouseID == deviceID) 105 | { 106 | waitingUI.alpha = 0; 107 | gameUI.alpha = 1; 108 | crossHair.SetDeviceID(deviceID); 109 | viewModel.Initialize(deviceID, lightgun); 110 | MultiMouseWrapper.OnLeftMouseButtonDown[deviceID] += HideCursor; 111 | MultiMouseWrapper.OnRightMouseButtonDown[deviceID] += Reload; 112 | } 113 | } 114 | 115 | private void Reload() 116 | { 117 | ammo = weapon.ammoCapacity; 118 | UpdateAmmoUI(); 119 | } 120 | 121 | private void HideCursor() 122 | { 123 | Cursor.visible = false; 124 | Cursor.lockState = CursorLockMode.Locked; 125 | } 126 | 127 | void UpdateAmmoUI() 128 | { 129 | weaponLabel.text = weapon.name; 130 | 131 | ammoCount.text = ammo.ToString(); 132 | ammoFill.fillAmount = (float)ammo / (float)weapon.ammoCapacity; 133 | 134 | ammoCount.color = ammoFill.fillAmount <= 0.2f ? Color.red : Color.white; 135 | ammoFill.color = ammoFill.fillAmount <= 0.2f ? Color.red : Color.white; 136 | } 137 | } 138 | } -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/PlayerBehaviour.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 556df1802d4cc164bb67e1ca604c7fab 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/SceneLoader.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | #if UNITY_EDITOR 5 | using UnityEditor; 6 | #endif 7 | 8 | public class SceneLoader : MonoBehaviour 9 | { 10 | #if UNITY_EDITOR 11 | [SerializeField] SceneAsset[] sceneAssets; 12 | 13 | // Start is called before the first frame update 14 | void Start() 15 | { 16 | var scenes = new List(); 17 | var paths = new List(); 18 | for (int i = 0; i < EditorBuildSettings.scenes.Length; i++) 19 | { 20 | scenes.Add(EditorBuildSettings.scenes[i]); 21 | paths.Add(EditorBuildSettings.scenes[i].path); 22 | } 23 | 24 | foreach (var sceneAsset in sceneAssets) 25 | { 26 | string scenePath = AssetDatabase.GetAssetPath(sceneAsset); 27 | if (!string.IsNullOrEmpty(scenePath) && !paths.Contains(scenePath)) 28 | { 29 | paths.Add(scenePath); 30 | scenes.Add(new EditorBuildSettingsScene(scenePath, true)); 31 | } 32 | } 33 | 34 | // Set the Build Settings window Scene list 35 | EditorBuildSettings.scenes = scenes.ToArray(); 36 | } 37 | #endif 38 | } -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/SceneLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 22ce5bd943c22c34b976631794dded74 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/TargetBehaviour.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class TargetBehaviour : MonoBehaviour, IShootable 6 | { 7 | [SerializeField] float resetTime = 3; 8 | [SerializeField] new Collider collider; 9 | [SerializeField] Animator anim; 10 | 11 | // Start is called before the first frame update 12 | void Start() 13 | { 14 | ResetTarget(); 15 | } 16 | 17 | public void InvokeOnShotBehaviour() 18 | { 19 | anim.Play("Flip Down"); 20 | collider.enabled = false; 21 | Invoke(nameof(ResetTarget), resetTime); 22 | } 23 | 24 | void ResetTarget() 25 | { 26 | anim.Play("Flip Up"); 27 | collider.enabled = true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/TargetBehaviour.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0a1768e13811e4541bb3ae2b63485e5d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/UI.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d70a39ec345e7bc489554dedf3faa824 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/UI/MainMenuUI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using UnityEngine.UI; 6 | 7 | namespace MultiMouseUnity.Example 8 | { 9 | public class PlayData 10 | { 11 | public int[] playerIDs = new int[] { -1, -1, }; 12 | } 13 | 14 | public class MainMenuUI : MonoBehaviour 15 | { 16 | [SerializeField] string gameSceneName = "Lightgun01"; 17 | 18 | [SerializeField] Text clickStartLabel; 19 | [SerializeField] CanvasGroup playerMenu; 20 | [SerializeField] CanvasGroup playButton; 21 | 22 | [SerializeField] PlayerSlot[] slots; 23 | [SerializeField] AudioSource gunShotSound; 24 | 25 | public static PlayData PlayData; 26 | 27 | // Start is called before the first frame update 28 | void Start() 29 | { 30 | PlayData = new PlayData(); 31 | 32 | // Just in case these were toyed with 33 | clickStartLabel.enabled = true; 34 | playerMenu.alpha = 0; 35 | slots[0].UpdateStateForDevice(-1); 36 | slots[1].UpdateStateForDevice(-1); 37 | } 38 | 39 | private void OnEnable() 40 | { 41 | MultiMouseWrapper.OnDeviceFound += OnDeviceFound; 42 | } 43 | 44 | private void OnDisable() 45 | { 46 | MultiMouseWrapper.OnDeviceFound -= OnDeviceFound; 47 | } 48 | 49 | private void OnDeviceFound(int obj) 50 | { 51 | clickStartLabel.enabled = false; 52 | playerMenu.alpha = 1; 53 | gunShotSound.Play(); 54 | } 55 | 56 | public void SamButtonClicked() 57 | { 58 | for (int i = 0; i < MultiMouseWrapper.Instance.ActiveDeviceCount; i++) 59 | { 60 | if (MultiMouseWrapper.Instance.GetMouseButtonUp(i, 0)) 61 | { 62 | if (PlayData.playerIDs[0] == -1) 63 | { 64 | if (PlayData.playerIDs[1] == i) 65 | { 66 | PlayData.playerIDs[1] = -1; 67 | slots[1].UpdateStateForDevice(-1); 68 | } 69 | PlayData.playerIDs[0] = i; 70 | slots[0].UpdateStateForDevice(i); 71 | } 72 | else if (PlayData.playerIDs[0] == i) 73 | { 74 | PlayData.playerIDs[0] = -1; 75 | slots[0].UpdateStateForDevice(-1); 76 | } 77 | } 78 | } 79 | UpdatePlayButton(); 80 | } 81 | 82 | public void JimButtonClicked() 83 | { 84 | for (int i = 0; i < MultiMouseWrapper.Instance.ActiveDeviceCount; i++) 85 | { 86 | if (MultiMouseWrapper.Instance.GetMouseButtonUp(i, 0)) 87 | { 88 | if (PlayData.playerIDs[1] == -1) 89 | { 90 | if (PlayData.playerIDs[0] == i) 91 | { 92 | PlayData.playerIDs[0] = -1; 93 | slots[0].UpdateStateForDevice(-1); 94 | } 95 | PlayData.playerIDs[1] = i; 96 | slots[1].UpdateStateForDevice(i); 97 | } 98 | else if (PlayData.playerIDs[1] == i) 99 | { 100 | PlayData.playerIDs[1] = -1; 101 | slots[1].UpdateStateForDevice(-1); 102 | } 103 | } 104 | } 105 | UpdatePlayButton(); 106 | } 107 | 108 | public void UpdatePlayButton() 109 | { 110 | bool hasPlayers = false; 111 | for (int i = 0; i < 2; i++) 112 | { 113 | if (PlayData.playerIDs[i] != -1) 114 | { 115 | hasPlayers = true; 116 | break; 117 | } 118 | } 119 | 120 | playButton.alpha = (float)System.Convert.ToDouble(hasPlayers); 121 | } 122 | 123 | public void Play() 124 | { 125 | playerMenu.alpha = 0; 126 | Invoke(nameof(ChangeScene), 1); 127 | } 128 | 129 | public void ChangeScene() 130 | { 131 | UnityEngine.SceneManagement.SceneManager.LoadScene(gameSceneName); 132 | } 133 | } 134 | } -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/UI/MainMenuUI.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e04dd577d49bcfd4b917db79265a4df3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/UI/MultiMouseInputModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.EventSystems; 5 | 6 | namespace MultiMouseUnity.Example 7 | { 8 | public class MultiMouseInputModule : BaseInputModule 9 | { 10 | public int submitButton; 11 | 12 | List pointerData = new List(); 13 | 14 | MultiMouseWrapper multiMouse => MultiMouseWrapper.Instance; 15 | 16 | protected override void Awake() 17 | { 18 | base.Awake(); 19 | } 20 | 21 | protected override void OnEnable() 22 | { 23 | while (pointerData.Count < multiMouse.ActiveDeviceCount) 24 | { 25 | pointerData.Add(new PointerEventData(eventSystem)); 26 | } 27 | MultiMouseWrapper.OnDeviceFound += OnDeviceFound; 28 | base.OnEnable(); 29 | } 30 | 31 | protected override void OnDisable() 32 | { 33 | MultiMouseWrapper.OnDeviceFound -= OnDeviceFound; 34 | base.OnDisable(); 35 | } 36 | 37 | private void OnDeviceFound(int obj) 38 | { 39 | pointerData.Add(new PointerEventData(eventSystem)); 40 | } 41 | 42 | public override void Process() 43 | { 44 | for (int i = 0; i < multiMouse.ActiveDeviceCount; i++) 45 | { 46 | // Reset data, set camera 47 | pointerData[i].Reset(); 48 | 49 | pointerData[i].position = multiMouse.GetMousePosition(i); 50 | 51 | // Raycast 52 | eventSystem.RaycastAll(pointerData[i], m_RaycastResultCache); 53 | pointerData[i].pointerCurrentRaycast = FindFirstRaycast(m_RaycastResultCache); 54 | var selectedObject = pointerData[i].pointerCurrentRaycast.gameObject; 55 | 56 | m_RaycastResultCache.Clear(); 57 | 58 | HandlePointerExitAndEnter(pointerData[i], selectedObject); 59 | 60 | if (multiMouse.GetMouseButtonDown(i, submitButton)) 61 | { 62 | ProcessPress(pointerData[i], selectedObject); 63 | } 64 | else if (multiMouse.GetMouseButtonUp(i, submitButton)) 65 | { 66 | ProcessRelease(pointerData[i], selectedObject); 67 | } 68 | } 69 | } 70 | 71 | void ProcessPress(PointerEventData data, GameObject selectedObject) 72 | { 73 | // Set raycast 74 | data.pointerPressRaycast = data.pointerCurrentRaycast; 75 | 76 | // Check for object hit, get the down handler, call 77 | GameObject newPointerPress = ExecuteEvents.ExecuteHierarchy(selectedObject, data, ExecuteEvents.pointerDownHandler); 78 | 79 | // If no down handler, try and get click handler 80 | if (newPointerPress == null) 81 | { 82 | newPointerPress = ExecuteEvents.GetEventHandler(selectedObject); 83 | } 84 | 85 | // Set data 86 | data.pressPosition = data.position; 87 | data.pointerPress = newPointerPress; 88 | data.rawPointerPress = selectedObject; 89 | } 90 | 91 | private void ProcessRelease(PointerEventData data, GameObject selectedObject) 92 | { 93 | // Execute pointer up 94 | ExecuteEvents.Execute(data.pointerPress, data, ExecuteEvents.pointerUpHandler); 95 | 96 | // Check click handler 97 | GameObject pointerUpHandler = ExecuteEvents.GetEventHandler(selectedObject); 98 | 99 | // Check if actual 100 | if (data.pointerPress == pointerUpHandler) 101 | { 102 | ExecuteEvents.Execute(data.pointerPress, data, ExecuteEvents.pointerClickHandler); 103 | } 104 | 105 | // Reset data 106 | data.pressPosition = Vector2.zero; 107 | data.pointerPress = null; 108 | data.rawPointerPress = null; 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/UI/MultiMouseInputModule.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 51c2a70f0b74dcc40800299abb7ba27c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/UI/PlayerSlot.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.UI; 5 | 6 | public class PlayerSlot : MonoBehaviour 7 | { 8 | [SerializeField] Text numberLabel; 9 | [SerializeField] Image darkMask; 10 | 11 | public void UpdateStateForDevice(int i) 12 | { 13 | numberLabel.enabled = i != -1; 14 | numberLabel.text = "P" + (i + 1); 15 | numberLabel.color = i == 0 ? Color.red : Color.blue; 16 | darkMask.enabled = i == -1; 17 | } 18 | } -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/UI/PlayerSlot.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f1f39c5148325534ba07d194138c0f0c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/UI/UILightgun.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace MultiMouseUnity.Example 7 | { 8 | /// 9 | /// Component that binds itself to a specific device to give gunshot feedback in Menus. 10 | /// Works in conjunction with the Crosshair class, so that 11 | /// every time the Mouse clicks, create a gunshot effect at the Crosshair position. 12 | /// Unlike the Lightgun class, there is no weapon system, so we don't need to consider ammo etc. 13 | /// 14 | public class UILightgun : MonoBehaviour 15 | { 16 | [SerializeField] int deviceID; 17 | [SerializeField] Crosshair crosshair; 18 | [SerializeField] GameObject muzzleFlashPrefab; 19 | [SerializeField] Transform uiTransform; 20 | 21 | private void OnEnable() 22 | { 23 | MultiMouseWrapper.OnLeftMouseButtonDown[deviceID] += OnLeftClick; 24 | } 25 | 26 | private void OnDisable() 27 | { 28 | MultiMouseWrapper.OnLeftMouseButtonDown[deviceID] -= OnLeftClick; 29 | } 30 | 31 | private void OnLeftClick() 32 | { 33 | // Instantiating and destroying muzzle flash effects can be computationally expensive! 34 | // In a real game project, you should consider other methods of creating these effects 35 | var muzzleFlash = Instantiate(muzzleFlashPrefab, uiTransform); 36 | muzzleFlash.transform.position = crosshair.transform.position; 37 | Destroy(muzzleFlash, 1); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/UI/UILightgun.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 733d1d39e4229d5459df2c1df0cae829 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/ViewModelRotator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace MultiMouseUnity.Example 6 | { 7 | public class ViewModelRotator : MonoBehaviour 8 | { 9 | [SerializeField] int deviceID; 10 | 11 | [SerializeField] float gunYAxisMin, gunYAxisMax; 12 | [SerializeField] float gunXAxisMin, gunXAxisMax; 13 | 14 | [SerializeField] Renderer[] viewModelMeshes; 15 | [SerializeField] Animation anim; 16 | Lightgun lightgun; 17 | 18 | private void Start() 19 | { 20 | SetViewModelVisible(false); 21 | } 22 | 23 | public void Initialize(int id, Lightgun l) 24 | { 25 | deviceID = id; 26 | lightgun = l; 27 | lightgun.OnShoot += OnShoot; 28 | SetViewModelVisible(true); 29 | } 30 | 31 | private void OnDisable() 32 | { 33 | if (lightgun) 34 | { 35 | lightgun.OnShoot -= OnShoot; 36 | } 37 | } 38 | 39 | void SetViewModelVisible(bool visible) 40 | { 41 | foreach (var item in viewModelMeshes) 42 | { 43 | item.enabled = visible; 44 | } 45 | } 46 | 47 | private void Update() 48 | { 49 | if (!MultiMouseWrapper.Instance.IsMouseActive(deviceID)) return; 50 | 51 | var mousePos = MultiMouseWrapper.Instance.GetMousePosition(deviceID); 52 | var eulerAngles = transform.localEulerAngles; 53 | 54 | // Due to how rotation works, we set X to Y and Y to X 55 | var screenWidth = Screen.width; 56 | var lerpY = Mathf.InverseLerp(0, screenWidth, mousePos.x); 57 | eulerAngles.y = Mathf.Lerp(gunYAxisMin, gunYAxisMax, lerpY); 58 | 59 | var screenHeight = Screen.width; 60 | var lerpX = Mathf.InverseLerp(screenHeight, 0, mousePos.y); 61 | eulerAngles.x = Mathf.Lerp(gunYAxisMin, gunYAxisMax, lerpX); 62 | 63 | transform.localEulerAngles = eulerAngles; 64 | } 65 | 66 | private void OnShoot() 67 | { 68 | if (anim.isPlaying) anim.Stop(); 69 | anim.Play(); 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/ViewModelRotator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b1c469fa4687d5343b7fdb8994777a4b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/WeaponObject.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace MultiMouseUnity.Example 6 | { 7 | public enum FireType 8 | { 9 | SemiAuto, 10 | FullAuto 11 | } 12 | 13 | [CreateAssetMenu(fileName = "New Weapon", menuName = "ScriptableObjects/New Weapon", order = 1)] 14 | public class WeaponObject : ScriptableObject 15 | { 16 | [Header("Weapon Stats")] 17 | public FireType weaponType; 18 | public int bulletDamage = 1; 19 | public int ammoCapacity = 30; 20 | 21 | [Header("Full Auto-Specific Properties")] 22 | public float fireDelay = 0.1f; 23 | 24 | [Header("Shell-Specific Properties")] 25 | public int pellets = 0; 26 | /// 27 | /// Only applies if number of pellets is greater than 0. 28 | /// Measured in pixels 29 | /// 30 | public float bulletSpread = 0; 31 | 32 | [Header("Object References")] 33 | public GameObject muzzleFlashPrefab = null; 34 | } 35 | } -------------------------------------------------------------------------------- /Examples/Lightgun Example/Scripts/WeaponObject.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba327a042efef7b4dab8fe59c81a1b1d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Sprites.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 768670ac66738a64b85d62ce7f4756e8 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Sprites/Title Graphic.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackyyang09/Multi-Mouse-Unity/ddad073af483dca5d75442fc4d23e5ddb552036b/Examples/Lightgun Example/Sprites/Title Graphic.psd -------------------------------------------------------------------------------- /Examples/Lightgun Example/Sprites/Title Graphic.psd.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e5813b8597a69934eb6898e131722faf 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 1 40 | wrapV: 1 41 | wrapW: 0 42 | nPOTScale: 0 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 1 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 1 55 | spriteTessellationDetail: -1 56 | textureType: 8 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | cookieLightType: 0 67 | platformSettings: 68 | - serializedVersion: 3 69 | buildTarget: DefaultTexturePlatform 70 | maxTextureSize: 2048 71 | resizeAlgorithm: 0 72 | textureFormat: -1 73 | textureCompression: 1 74 | compressionQuality: 50 75 | crunchedCompression: 0 76 | allowsAlphaSplitting: 0 77 | overridden: 0 78 | androidETC2FallbackOverride: 0 79 | forceMaximumCompressionQuality_BC6H_BC7: 0 80 | - serializedVersion: 3 81 | buildTarget: Standalone 82 | maxTextureSize: 2048 83 | resizeAlgorithm: 0 84 | textureFormat: -1 85 | textureCompression: 1 86 | compressionQuality: 50 87 | crunchedCompression: 0 88 | allowsAlphaSplitting: 0 89 | overridden: 0 90 | androidETC2FallbackOverride: 0 91 | forceMaximumCompressionQuality_BC6H_BC7: 0 92 | - serializedVersion: 3 93 | buildTarget: Server 94 | maxTextureSize: 2048 95 | resizeAlgorithm: 0 96 | textureFormat: -1 97 | textureCompression: 1 98 | compressionQuality: 50 99 | crunchedCompression: 0 100 | allowsAlphaSplitting: 0 101 | overridden: 0 102 | androidETC2FallbackOverride: 0 103 | forceMaximumCompressionQuality_BC6H_BC7: 0 104 | spriteSheet: 105 | serializedVersion: 2 106 | sprites: [] 107 | outline: [] 108 | physicsShape: [] 109 | bones: [] 110 | spriteID: 5e97eb03825dee720800000000000000 111 | internalID: 0 112 | vertices: [] 113 | indices: 114 | edges: [] 115 | weights: [] 116 | secondaryTextures: [] 117 | nameFileIdTable: {} 118 | spritePackingTag: 119 | pSDRemoveMatte: 0 120 | pSDShowRemoveMatteOption: 1 121 | userData: 122 | assetBundleName: 123 | assetBundleVariant: 124 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Sprites/target.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackyyang09/Multi-Mouse-Unity/ddad073af483dca5d75442fc4d23e5ddb552036b/Examples/Lightgun Example/Sprites/target.jpg -------------------------------------------------------------------------------- /Examples/Lightgun Example/Sprites/target.jpg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d247ef2b7ddbdaa4bb0d6afac71177ef 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 0 40 | wrapV: 0 41 | wrapW: 0 42 | nPOTScale: 0 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 1 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 0 55 | spriteTessellationDetail: -1 56 | textureType: 0 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | platformSettings: 67 | - serializedVersion: 3 68 | buildTarget: DefaultTexturePlatform 69 | maxTextureSize: 2048 70 | resizeAlgorithm: 0 71 | textureFormat: -1 72 | textureCompression: 1 73 | compressionQuality: 50 74 | crunchedCompression: 0 75 | allowsAlphaSplitting: 0 76 | overridden: 0 77 | androidETC2FallbackOverride: 0 78 | forceMaximumCompressionQuality_BC6H_BC7: 0 79 | - serializedVersion: 3 80 | buildTarget: Standalone 81 | maxTextureSize: 2048 82 | resizeAlgorithm: 0 83 | textureFormat: -1 84 | textureCompression: 1 85 | compressionQuality: 50 86 | crunchedCompression: 0 87 | allowsAlphaSplitting: 0 88 | overridden: 0 89 | androidETC2FallbackOverride: 0 90 | forceMaximumCompressionQuality_BC6H_BC7: 0 91 | - serializedVersion: 3 92 | buildTarget: Server 93 | maxTextureSize: 2048 94 | resizeAlgorithm: 0 95 | textureFormat: -1 96 | textureCompression: 1 97 | compressionQuality: 50 98 | crunchedCompression: 0 99 | allowsAlphaSplitting: 0 100 | overridden: 0 101 | androidETC2FallbackOverride: 0 102 | forceMaximumCompressionQuality_BC6H_BC7: 0 103 | - serializedVersion: 3 104 | buildTarget: Android 105 | maxTextureSize: 2048 106 | resizeAlgorithm: 0 107 | textureFormat: -1 108 | textureCompression: 1 109 | compressionQuality: 50 110 | crunchedCompression: 0 111 | allowsAlphaSplitting: 0 112 | overridden: 0 113 | androidETC2FallbackOverride: 0 114 | forceMaximumCompressionQuality_BC6H_BC7: 0 115 | - serializedVersion: 3 116 | buildTarget: iPhone 117 | maxTextureSize: 2048 118 | resizeAlgorithm: 0 119 | textureFormat: -1 120 | textureCompression: 1 121 | compressionQuality: 50 122 | crunchedCompression: 0 123 | allowsAlphaSplitting: 0 124 | overridden: 0 125 | androidETC2FallbackOverride: 0 126 | forceMaximumCompressionQuality_BC6H_BC7: 0 127 | spriteSheet: 128 | serializedVersion: 2 129 | sprites: [] 130 | outline: [] 131 | physicsShape: [] 132 | bones: [] 133 | spriteID: 5e97eb03825dee720800000000000000 134 | internalID: 0 135 | vertices: [] 136 | indices: 137 | edges: [] 138 | weights: [] 139 | secondaryTextures: [] 140 | nameFileIdTable: {} 141 | spritePackingTag: 142 | pSDRemoveMatte: 0 143 | pSDShowRemoveMatteOption: 0 144 | userData: 145 | assetBundleName: 146 | assetBundleVariant: 147 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Sprites/whitepixel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackyyang09/Multi-Mouse-Unity/ddad073af483dca5d75442fc4d23e5ddb552036b/Examples/Lightgun Example/Sprites/whitepixel.png -------------------------------------------------------------------------------- /Examples/Lightgun Example/Sprites/whitepixel.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 210be13a6d1c4f44d8a5bce56a4d5cd2 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 1 40 | wrapV: 1 41 | wrapW: 0 42 | nPOTScale: 0 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 1 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 1 55 | spriteTessellationDetail: -1 56 | textureType: 8 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | platformSettings: 67 | - serializedVersion: 3 68 | buildTarget: DefaultTexturePlatform 69 | maxTextureSize: 2048 70 | resizeAlgorithm: 0 71 | textureFormat: -1 72 | textureCompression: 1 73 | compressionQuality: 50 74 | crunchedCompression: 0 75 | allowsAlphaSplitting: 0 76 | overridden: 0 77 | androidETC2FallbackOverride: 0 78 | forceMaximumCompressionQuality_BC6H_BC7: 0 79 | - serializedVersion: 3 80 | buildTarget: Standalone 81 | maxTextureSize: 2048 82 | resizeAlgorithm: 0 83 | textureFormat: -1 84 | textureCompression: 1 85 | compressionQuality: 50 86 | crunchedCompression: 0 87 | allowsAlphaSplitting: 0 88 | overridden: 0 89 | androidETC2FallbackOverride: 0 90 | forceMaximumCompressionQuality_BC6H_BC7: 0 91 | - serializedVersion: 3 92 | buildTarget: Server 93 | maxTextureSize: 2048 94 | resizeAlgorithm: 0 95 | textureFormat: -1 96 | textureCompression: 1 97 | compressionQuality: 50 98 | crunchedCompression: 0 99 | allowsAlphaSplitting: 0 100 | overridden: 0 101 | androidETC2FallbackOverride: 0 102 | forceMaximumCompressionQuality_BC6H_BC7: 0 103 | - serializedVersion: 3 104 | buildTarget: Android 105 | maxTextureSize: 2048 106 | resizeAlgorithm: 0 107 | textureFormat: -1 108 | textureCompression: 1 109 | compressionQuality: 50 110 | crunchedCompression: 0 111 | allowsAlphaSplitting: 0 112 | overridden: 0 113 | androidETC2FallbackOverride: 0 114 | forceMaximumCompressionQuality_BC6H_BC7: 0 115 | - serializedVersion: 3 116 | buildTarget: iPhone 117 | maxTextureSize: 2048 118 | resizeAlgorithm: 0 119 | textureFormat: -1 120 | textureCompression: 1 121 | compressionQuality: 50 122 | crunchedCompression: 0 123 | allowsAlphaSplitting: 0 124 | overridden: 0 125 | androidETC2FallbackOverride: 0 126 | forceMaximumCompressionQuality_BC6H_BC7: 0 127 | spriteSheet: 128 | serializedVersion: 2 129 | sprites: [] 130 | outline: [] 131 | physicsShape: [] 132 | bones: [] 133 | spriteID: 5e97eb03825dee720800000000000000 134 | internalID: 0 135 | vertices: [] 136 | indices: 137 | edges: [] 138 | weights: [] 139 | secondaryTextures: [] 140 | nameFileIdTable: {} 141 | spritePackingTag: 142 | pSDRemoveMatte: 0 143 | pSDShowRemoveMatteOption: 0 144 | userData: 145 | assetBundleName: 146 | assetBundleVariant: 147 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Weapon Data.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dcd38a4cb18a09743a859c08fc8905ff 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Weapon Data/Machine Gun.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 11500000, guid: ba327a042efef7b4dab8fe59c81a1b1d, type: 3} 13 | m_Name: Machine Gun 14 | m_EditorClassIdentifier: 15 | weaponType: 1 16 | bulletDamage: 1 17 | ammoCapacity: 30 18 | fireDelay: 0.075 19 | pellets: 0 20 | bulletSpread: 0 21 | muzzleFlashPrefab: {fileID: 1071529151986673640, guid: 3fa75804dc25f0342ad7dffa6b8d4b79, 22 | type: 3} 23 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Weapon Data/Machine Gun.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d4e372967c54fd642bacf5efb481c428 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Weapon Data/Pistol.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 11500000, guid: ba327a042efef7b4dab8fe59c81a1b1d, type: 3} 13 | m_Name: Pistol 14 | m_EditorClassIdentifier: 15 | weaponType: 0 16 | bulletDamage: 1 17 | ammoCapacity: 9 18 | fireDelay: 0.1 19 | pellets: 0 20 | bulletSpread: 0 21 | muzzleFlashPrefab: {fileID: 1071529151986673640, guid: 3fa75804dc25f0342ad7dffa6b8d4b79, 22 | type: 3} 23 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Weapon Data/Pistol.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 233fba0db9fdf984abde0ab73dd818b8 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Weapon Data/Shotgun.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 11500000, guid: ba327a042efef7b4dab8fe59c81a1b1d, type: 3} 13 | m_Name: Shotgun 14 | m_EditorClassIdentifier: 15 | weaponType: 0 16 | bulletDamage: 1 17 | ammoCapacity: 6 18 | fireDelay: 0.1 19 | pellets: 8 20 | bulletSpread: 175 21 | muzzleFlashPrefab: {fileID: 1071529151986673640, guid: 3fa75804dc25f0342ad7dffa6b8d4b79, 22 | type: 3} 23 | -------------------------------------------------------------------------------- /Examples/Lightgun Example/Weapon Data/Shotgun.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7ba741716e47f2c458c95008804a9dde 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Brogrammist 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3520c7d435327294ebbd02acfab6c5e5 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /PlayerLoopUtils.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7f8f5234af2a3a147828378d80acb493 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /PlayerLoopUtils/PlayerLoopUtils.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.LowLevel; 3 | using UnityEngine.PlayerLoop; 4 | using System; 5 | using System.Text; 6 | 7 | /// 8 | /// Written by tomkail 9 | /// 10 | public static class PlayerLoopUtils 11 | { 12 | public static void PrintPlayerLoop(PlayerLoopSystem def) 13 | { 14 | var sb = new StringBuilder(); 15 | RecursivePlayerLoopPrint(def, sb, 0); 16 | Debug.Log(sb.ToString()); 17 | } 18 | 19 | private static void RecursivePlayerLoopPrint(PlayerLoopSystem def, StringBuilder sb, int depth) 20 | { 21 | if (depth == 0) 22 | sb.AppendLine("ROOT NODE"); 23 | else if (def.type != null) 24 | { 25 | for (int i = 0; i < depth; i++) 26 | sb.Append("\t"); 27 | sb.AppendLine(def.type.Name); 28 | } 29 | if (def.subSystemList != null) 30 | { 31 | depth++; 32 | foreach (var s in def.subSystemList) 33 | RecursivePlayerLoopPrint(s, sb, depth); 34 | depth--; 35 | } 36 | } 37 | 38 | public enum AddMode 39 | { 40 | Beginning, 41 | End 42 | } 43 | 44 | // Add a new PlayerLoopSystem to the PlayerLoop. Example: 45 | // PlayerLoopSystem playerLoop = PlayerLoop.GetDefaultPlayerLoop(); 46 | // Debug.Assert(PlayerLoopUtils.AddToPlayerLoop(CustomUpdate, typeof(LightgunInput), ref playerLoop, typeof(PreUpdate.NewInputUpdate), PlayerLoopUtils.AddMode.End)); 47 | // PlayerLoop.SetPlayerLoop(playerLoop); 48 | public static bool AddToPlayerLoop(PlayerLoopSystem.UpdateFunction function, Type ownerType, ref PlayerLoopSystem playerLoop, Type playerLoopSystemType, AddMode addMode) 49 | { 50 | // did we find the type? e.g. EarlyUpdate/PreLateUpdate/etc. 51 | if (playerLoop.type == playerLoopSystemType) 52 | { 53 | // debugging 54 | //Debug.Log($"Found playerLoop of type {playerLoop.type} with {playerLoop.subSystemList.Length} Functions:"); 55 | //foreach (PlayerLoopSystem sys in playerLoop.subSystemList) 56 | // Debug.Log($" ->{sys.type}"); 57 | 58 | // resize & expand subSystemList to fit one more entry 59 | int oldListLength = (playerLoop.subSystemList != null) ? playerLoop.subSystemList.Length : 0; 60 | Array.Resize(ref playerLoop.subSystemList, oldListLength + 1); 61 | 62 | // prepend our custom loop to the beginning 63 | if (addMode == AddMode.Beginning) 64 | { 65 | // shift to the right, write into first array element 66 | Array.Copy(playerLoop.subSystemList, 0, playerLoop.subSystemList, 1, playerLoop.subSystemList.Length - 1); 67 | playerLoop.subSystemList[0].type = ownerType; 68 | playerLoop.subSystemList[0].updateDelegate = function; 69 | 70 | } 71 | // append our custom loop to the end 72 | else if (addMode == AddMode.End) 73 | { 74 | // simply write into last array element 75 | playerLoop.subSystemList[oldListLength].type = ownerType; 76 | playerLoop.subSystemList[oldListLength].updateDelegate = function; 77 | } 78 | 79 | // debugging 80 | //Debug.Log($"New playerLoop of type {playerLoop.type} with {playerLoop.subSystemList.Length} Functions:"); 81 | //foreach (PlayerLoopSystem sys in playerLoop.subSystemList) 82 | // Debug.Log($" ->{sys.type}"); 83 | 84 | return true; 85 | } 86 | 87 | // recursively keep looking 88 | if (playerLoop.subSystemList != null) 89 | { 90 | for (int i = 0; i < playerLoop.subSystemList.Length; ++i) 91 | { 92 | if (AddToPlayerLoop(function, ownerType, ref playerLoop.subSystemList[i], playerLoopSystemType, addMode)) 93 | return true; 94 | } 95 | } 96 | return false; 97 | } 98 | } -------------------------------------------------------------------------------- /PlayerLoopUtils/PlayerLoopUtils.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3ad89e88b0a41034ebf7349b515b834d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5af4b8a93efb18b44988e68bc1ef776a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Plugins/MultiMouseLib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackyyang09/Multi-Mouse-Unity/ddad073af483dca5d75442fc4d23e5ddb552036b/Plugins/MultiMouseLib.dll -------------------------------------------------------------------------------- /Plugins/MultiMouseLib.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4e2ef93c988c0c74f96f013390986bbf 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 1 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 0 23 | settings: 24 | DefaultValueInitialized: true 25 | userData: 26 | assetBundleName: 27 | assetBundleVariant: 28 | -------------------------------------------------------------------------------- /Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fc8fab1b61469ba4f9754a3b7687e4f7 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Prefabs/MultiMouseInterface.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &258193687855429242 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 258193687855429236} 12 | - component: {fileID: 258193687855429237} 13 | m_Layer: 0 14 | m_Name: MultiMouseInterface 15 | m_TagString: Untagged 16 | m_Icon: {fileID: 0} 17 | m_NavMeshLayer: 0 18 | m_StaticEditorFlags: 0 19 | m_IsActive: 1 20 | --- !u!4 &258193687855429236 21 | Transform: 22 | m_ObjectHideFlags: 0 23 | m_CorrespondingSourceObject: {fileID: 0} 24 | m_PrefabInstance: {fileID: 0} 25 | m_PrefabAsset: {fileID: 0} 26 | m_GameObject: {fileID: 258193687855429242} 27 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 28 | m_LocalPosition: {x: 0, y: 0, z: 0} 29 | m_LocalScale: {x: 1, y: 1, z: 1} 30 | m_ConstrainProportionsScale: 0 31 | m_Children: [] 32 | m_Father: {fileID: 0} 33 | m_RootOrder: 0 34 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 35 | --- !u!114 &258193687855429237 36 | MonoBehaviour: 37 | m_ObjectHideFlags: 0 38 | m_CorrespondingSourceObject: {fileID: 0} 39 | m_PrefabInstance: {fileID: 0} 40 | m_PrefabAsset: {fileID: 0} 41 | m_GameObject: {fileID: 258193687855429242} 42 | m_Enabled: 1 43 | m_EditorHideFlags: 0 44 | m_Script: {fileID: 11500000, guid: 2ea876aa5f0eff94ea45de4663e3691a, type: 3} 45 | m_Name: 46 | m_EditorClassIdentifier: 47 | unclampMousePosition: 0 48 | detectDevicesOnStart: 1 49 | maxDevices: 4 50 | keepDetectingUntilFull: 1 51 | -------------------------------------------------------------------------------- /Prefabs/MultiMouseInterface.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ccf6577210759734c9993dec6a985d21 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | MultiMouseUnity is a Unity implementation and wrapper of Mystery Wizard's [MultiMouse](https://www.sindenwiki.org/wiki/The_House_of_the_Dead_Remake) plugin to get multiple mouse devices working and usable within Unity applications. 3 | 4 | This early version is meant for experienced Unity developers for the purpose of jumping into lightgun game development and helping test for usability issues/bugs. 5 | 6 | Please check out the ExampleGame scene to learn all the ways you can use ManyMouseUnity in your project 7 | 8 | https://user-images.githubusercontent.com/11392541/211867078-4d05bcbd-1ad4-47e1-98d7-daee6032b642.mp4 9 | 10 | # Requirements 11 | You must use Unity 2021.3 or newer to use MultiMouse, otherwise it will crash in-editor. It should also work in 2021.2, but we haven't tested/confirmed that yet. 12 | 13 | # Getting Started 14 | 1. Download the latest release package from [here](https://github.com/jackyyang09/Multi-Mouse-Unity/releases). 15 | 2. Import the package contents into your Unity project 16 | 3. Check out the ExampleGame scene to learn how to integrate MultiMouse in your project 17 | 18 | # Credits 19 | Brogrammist - MultiMouseUnity 20 | 21 | Mystery Wizard - The original MultiMouse plugin 22 | 23 | tomkail - PlayerLoopUtils and some lightgun logic 24 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bd7be0ca381456c46afcc4be7dbdf381 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 060d5e0625889e743842695fe1462532 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Scripts/MultiMouse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | using UnityEngine; 6 | 7 | namespace MultiMouseUnity 8 | { 9 | /// 10 | /// MultiMouseLib created by Mystery Wizard 11 | /// 12 | class MultiMouse 13 | { 14 | #region External Methods 15 | private static IntPtr _currentWindowHandle = IntPtr.Zero; 16 | 17 | static IntPtr UnityWindowHandle 18 | { 19 | get 20 | { 21 | if (_currentWindowHandle == IntPtr.Zero) 22 | #if UNITY_EDITOR 23 | _currentWindowHandle = GetActiveWindow(); 24 | #else 25 | _currentWindowHandle = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle; 26 | #endif 27 | return _currentWindowHandle; 28 | } 29 | } 30 | 31 | [DllImport("user32.dll")] 32 | private static extern IntPtr GetActiveWindow(); 33 | 34 | /// 35 | /// In some cases in Unity based games or other games where you do not have control over the window, you may want to set bUseInternalWindow to false or 0. 36 | /// This will cause the library to use the Windows API SetWindowLong() in order to hijack the current window's window input handling. 37 | /// The hWnd handle is that of the Unity window, there is example code for finding the Unity window within this test application. 38 | /// 39 | /// 40 | /// 41 | /// 42 | /// 43 | [DllImport("MultiMouseLib.dll")] 44 | static extern bool MultiMouse_Init(byte bUseInternalWindow, byte bImmediateCapture, IntPtr hWnd); 45 | 46 | /* 47 | * DevId is the PID/VID combination as a string for the device, MultiMouse_DetectDevice facilitates a way to grab this automatically when a button is pressed on any device. 48 | */ 49 | [DllImport("MultiMouseLib.dll")] 50 | static extern void MultiMouse_Poll(string mDevId); 51 | 52 | /// 53 | /// This will only trigger once per Poll event if the button transition state changes, this will not tell you if the button is still down only when it has been pressed. 54 | /// 55 | /// 56 | /// 57 | /// 58 | [DllImport("MultiMouseLib.dll")] 59 | static extern bool MultiMouse_ButtonDown(string mDevId, byte buttonIdx); 60 | 61 | /// 62 | /// After receiving a button down event, this can be listened/polled for in order to determine if a previously pressed button has been lifted. 63 | /// 64 | /// 65 | /// 66 | /// 67 | [DllImport("MultiMouseLib.dll")] 68 | static extern bool MultiMouse_ButtonUp(string mDevId, byte buttonIdx); 69 | 70 | /// 71 | /// Used to facilitate getting the most accurate/most recent and up to date absolute coordinates for the pointer device. 72 | /// This will not take any older values into account, and will return whatever has most recently been received for the specified device. 73 | /// 74 | /// 75 | /// 76 | [DllImport("MultiMouseLib.dll")] 77 | static extern void MultiMouse_GetAbsCords(string mDevId, ref int x, ref int y); 78 | 79 | /// 80 | /// This is for non-pointing devices which return relative coordinates, all coordinates sent since the last poll are automatically summarized in a single delta. 81 | /// 82 | /// 83 | /// 84 | /// 85 | [DllImport("MultiMouseLib.dll")] 86 | static extern void MultiMouse_GetRelativeCords(string mDevId, ref int x, ref int y); 87 | 88 | [DllImport("MultiMouseLib.dll")] 89 | static extern bool MultiMouse_Destroy(IntPtr hWnd); 90 | 91 | /// 92 | /// Warning this will automatically poll for you, you do not need to call MultiMouse_Poll while calling this but, You should still be calling it once per frame. 93 | /// This should be considered a universal "MultiMouse_ButtonDown" utilized for device detection. 94 | /// 95 | /// The string builder object utilized as the second parameter will be filled with the device pressing the specified button at which point you've "Detected" the device and can stop calling this method. 96 | /// The string builder object specified should be pre-allocated before being sent to the method like so; StringBuilder sb = new StringBuilder(18); 97 | /// The 18 characters is a hard limit, it can be no less than this. 98 | /// 99 | /// 100 | /// 101 | [DllImport("MultiMouseLib.dll")] 102 | static extern void MultiMouse_DetectDevice(byte buttonIdx, StringBuilder devId); 103 | #endregion 104 | 105 | const byte bUseInternalWindow = 1; 106 | const byte bImmediateCapture = 1; 107 | 108 | static bool initialized; 109 | public static bool Initialized => initialized; 110 | 111 | static bool Init_MultiMouse() 112 | { 113 | bool success = MultiMouse_Init(bUseInternalWindow, bImmediateCapture, UnityWindowHandle); 114 | if (success) Debug.Log("MultiMouse initialized successfully"); 115 | else Debug.LogWarning("MultiMouse failed to initialize!"); 116 | return success; 117 | } 118 | 119 | public static void Initialize() 120 | { 121 | initialized = Init_MultiMouse(); 122 | } 123 | 124 | public static void MultiMousePoll(string mDevId) 125 | { 126 | MultiMouse_Poll(mDevId); 127 | } 128 | 129 | public static string GetAnyMousePressingButton(int mouseButton) 130 | { 131 | StringBuilder sb = new StringBuilder(18); 132 | 133 | MultiMouse_DetectDevice((byte)mouseButton, sb); 134 | 135 | return sb.ToString(); 136 | } 137 | 138 | public static bool GetMouseButtonDown(string deviceID, int button) 139 | { 140 | return MultiMouse_ButtonDown(deviceID, (byte)button); 141 | } 142 | 143 | public static bool GetMouseButtonUp(string deviceID, int button) 144 | { 145 | return MultiMouse_ButtonUp(deviceID, (byte)button); 146 | } 147 | 148 | public static Vector2 GetAbsoluteMousePosition(string deviceID) 149 | { 150 | int x = 0, y = 0; 151 | MultiMouse_GetAbsCords(deviceID, ref x, ref y); 152 | return new Vector2(x, y); 153 | } 154 | 155 | public static Vector2 GetRelativeMousePosition(string deviceID) 156 | { 157 | int x = 0, y = 0; 158 | MultiMouse_GetRelativeCords(deviceID, ref x, ref y); 159 | return new Vector2(x, -y); 160 | } 161 | 162 | public static void Destroy() 163 | { 164 | MultiMouse_Destroy(UnityWindowHandle); 165 | } 166 | } 167 | } -------------------------------------------------------------------------------- /Scripts/MultiMouse.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c4ce1de303d1b474f89a229627652c38 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/MultiMouseSettings.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using UnityEngine; 5 | #if UNITY_EDITOR 6 | using UnityEditor; 7 | #endif 8 | 9 | namespace MultiMouseUnity 10 | { 11 | public class MultiMouseSettings : ScriptableObject 12 | { 13 | public bool detectDevicesOnStart = true; 14 | public bool keepDetectingUntilFull = true; 15 | public bool unclampMousePosition; 16 | public int maxDevices; 17 | public int maxMouseButtons; 18 | 19 | #if UNITY_EDITOR 20 | [SerializeField] protected string packagePath; 21 | public string PackagePath 22 | { 23 | get 24 | { 25 | if (!AssetDatabase.IsValidFolder(packagePath)) 26 | { 27 | CacheProjectPath(); 28 | } 29 | return packagePath; 30 | } 31 | } 32 | 33 | void CacheProjectPath() 34 | { 35 | var guids = AssetDatabase.FindAssets(nameof(MultiMouseSettings)); 36 | var path = AssetDatabase.GUIDToAssetPath(guids[0]); 37 | packagePath = path.Remove(path.IndexOf("/Editor/" + nameof(MultiMouseSettings) + ".cs")); 38 | } 39 | 40 | public void Reset() 41 | { 42 | Undo.RecordObject(this, "Reset MultiMouse Settings"); 43 | detectDevicesOnStart = true; 44 | maxDevices = 4; 45 | keepDetectingUntilFull = true; 46 | maxMouseButtons = 4; 47 | } 48 | #endif 49 | 50 | static MultiMouseSettings settings; 51 | public static MultiMouseSettings Settings 52 | { 53 | get 54 | { 55 | if (settings == null) 56 | { 57 | var asset = Resources.Load("MultiMouseSettings"); 58 | settings = asset as MultiMouseSettings; 59 | #if UNITY_EDITOR 60 | if (settings == null) TryCreateNewSettingsAsset(); 61 | #endif 62 | } 63 | return settings; 64 | } 65 | } 66 | 67 | #if UNITY_EDITOR 68 | static readonly string SETTINGS_PATH = "Assets/Settings/Resources/" + nameof(MultiMouseSettings) + ".asset"; 69 | 70 | public static void TryCreateNewSettingsAsset() 71 | { 72 | if (!EditorUtility.DisplayDialog( 73 | "Multi Mouse First Time Setup", 74 | "In order to function, Multi Mouse needs a place to store settings. By default, a " + 75 | "Settings asset will be created at Assets/Settings/Resources/, but you may move it " + 76 | "elsewhere, so long as it's in a Resources folder.\n " + 77 | "Moving it out of the Resources folder will prompt this message to appear again erroneously!", 78 | "Ok Create It.", "Not Yet!")) return; 79 | 80 | var asset = CreateInstance(); 81 | if (!AssetDatabase.IsValidFolder("Assets/Settings")) AssetDatabase.CreateFolder("Assets", "Settings"); 82 | if (!AssetDatabase.IsValidFolder("Assets/Settings/Resources")) AssetDatabase.CreateFolder("Assets/Settings", "Resources"); 83 | AssetDatabase.CreateAsset(asset, SETTINGS_PATH); 84 | asset.Reset(); 85 | 86 | settings = asset; 87 | } 88 | 89 | static SerializedObject serializedObject; 90 | public static SerializedObject SerializedObject 91 | { 92 | get 93 | { 94 | if (serializedObject == null) 95 | { 96 | serializedObject = new SerializedObject(Settings); 97 | return serializedObject; 98 | } 99 | return serializedObject; 100 | } 101 | } 102 | #endif 103 | } 104 | } -------------------------------------------------------------------------------- /Scripts/MultiMouseSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9b9b840cc1f00ef4f9e91d259b970a14 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/MultiMouseWrapper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | #if UNITY_EDITOR 5 | using UnityEditor; 6 | #endif 7 | 8 | namespace MultiMouseUnity 9 | { 10 | //public enum DeviceDetectionMethod 11 | //{ 12 | // Movement, 13 | // MouseButton, 14 | // MovementOrMouseButton 15 | //} 16 | 17 | [System.Serializable] 18 | public class MultiMouseDevice 19 | { 20 | public string DeviceID; 21 | public Vector2 Position; 22 | public bool IsLightgun; 23 | } 24 | 25 | public class MultiMouseWrapper : MonoBehaviour 26 | { 27 | List activeDevices = new List(); 28 | public int ActiveDeviceCount => activeDevices.Count; 29 | 30 | Dictionary idToDevice = new Dictionary(); 31 | 32 | /// 33 | /// Attempts to get a MultiMouseDevice, returns null if none found 34 | /// 35 | /// 36 | /// 37 | public MultiMouseDevice TryGetDeviceAtIndex(int index) 38 | { 39 | if (!IsMouseActive(index)) return null; 40 | return activeDevices[index]; 41 | } 42 | 43 | public bool IsMouseActive(int index) 44 | { 45 | return Mathf.Abs(index) < activeDevices.Count; 46 | } 47 | 48 | const int MAX_BUTTONS = 4; 49 | /// 50 | /// Only supports up to 4 buttons 51 | /// for performance and practicality 52 | /// 53 | List isButtonDown = new List(); 54 | 55 | bool mouseHeld; 56 | 57 | MultiMouseSettings settings => MultiMouseSettings.Settings; 58 | 59 | static MultiMouseWrapper instance; 60 | public static MultiMouseWrapper Instance 61 | { 62 | get 63 | { 64 | if (instance == null) 65 | { 66 | instance = FindObjectOfType(); 67 | if (instance == null) 68 | { 69 | Debug.LogWarning("MultiMouseWrapper not found in this scene!"); 70 | } 71 | } 72 | return instance; 73 | } 74 | } 75 | 76 | /// 77 | /// Invoked after a device is found with StartDetectingDevice() 78 | /// int mouseID - The ID of the device found 79 | /// 80 | public static System.Action OnDeviceFound; 81 | 82 | public static bool Initialized => MultiMouse.Initialized; 83 | 84 | #region Events 85 | static System.Action[] onLeftMouseButtonDown; 86 | public static System.Action[] OnLeftMouseButtonDown 87 | { 88 | get 89 | { 90 | if (onLeftMouseButtonDown == null) 91 | { 92 | onLeftMouseButtonDown = new System.Action[Instance.settings.maxDevices]; 93 | } 94 | return onLeftMouseButtonDown; 95 | } 96 | } 97 | 98 | static System.Action[] onLeftMouseButtonUp; 99 | public static System.Action[] OnLeftMouseButtonUp 100 | { 101 | get 102 | { 103 | if (onLeftMouseButtonUp == null) 104 | { 105 | onLeftMouseButtonUp = new System.Action[Instance.settings.maxDevices]; 106 | } 107 | return onLeftMouseButtonUp; 108 | } 109 | } 110 | 111 | static System.Action[] onRightMouseButtonDown; 112 | public static System.Action[] OnRightMouseButtonDown 113 | { 114 | get 115 | { 116 | if (onRightMouseButtonDown == null) 117 | { 118 | onRightMouseButtonDown = new System.Action[Instance.settings.maxDevices]; 119 | } 120 | return onRightMouseButtonDown; 121 | } 122 | } 123 | 124 | static System.Action[] onRightMouseButtonUp; 125 | public static System.Action[] OnRightMouseButtonUp 126 | { 127 | get 128 | { 129 | if (onRightMouseButtonUp == null) 130 | { 131 | onRightMouseButtonUp = new System.Action[Instance.settings.maxDevices]; 132 | } 133 | return onRightMouseButtonUp; 134 | } 135 | } 136 | #endregion 137 | 138 | [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] 139 | static void OnRuntimeMethodLoad() 140 | { 141 | UnityEngine.LowLevel.PlayerLoopSystem playerLoop = UnityEngine.LowLevel.PlayerLoop.GetDefaultPlayerLoop(); 142 | // Debug.Assert(PlayerLoopUtils.AddToPlayerLoop(EndOfFrameUpdate, typeof(LightgunInput), ref playerLoop, typeof(PreUpdate.NewInputUpdate), PlayerLoopUtils.AddMode.End)); 143 | Debug.Assert(PlayerLoopUtils.AddToPlayerLoop(StaticUpdate, typeof(MultiMouseWrapper), ref playerLoop, typeof(UnityEngine.PlayerLoop.EarlyUpdate.UpdateInputManager), PlayerLoopUtils.AddMode.Beginning)); 144 | UnityEngine.LowLevel.PlayerLoop.SetPlayerLoop(playerLoop); 145 | } 146 | 147 | bool destroySelf; 148 | private void Awake() 149 | { 150 | if (Instance != null) 151 | { 152 | if (Instance.gameObject.scene.name == "DontDestroyOnLoad") 153 | { 154 | destroySelf = true; 155 | Destroy(gameObject); 156 | } 157 | else if (string.IsNullOrEmpty(Instance.gameObject.scene.name)) 158 | { 159 | instance = null; 160 | } 161 | } 162 | } 163 | 164 | private void OnDestroy() 165 | { 166 | if (Instance == this) 167 | { 168 | instance = null; 169 | if (MultiMouse.Initialized) MultiMouse.Destroy(); 170 | } 171 | } 172 | 173 | private void Start() 174 | { 175 | if (destroySelf) return; 176 | 177 | if (settings == null) 178 | { 179 | enabled = false; 180 | DebugError("Could not find MultiMouse Settings! " + 181 | "If you continue to see this message, you may have to restart the Unity Editor."); 182 | return; 183 | } 184 | 185 | MultiMouse.Initialize(); 186 | 187 | if (transform.parent != null) 188 | { 189 | transform.SetParent(null); 190 | } 191 | DontDestroyOnLoad(this); 192 | 193 | if (settings.detectDevicesOnStart) 194 | { 195 | detectDeviceRoutine = StartCoroutine(DetectDevice()); 196 | } 197 | } 198 | 199 | static void StaticUpdate() 200 | { 201 | if (instance) instance.UpdateDevices(); 202 | } 203 | 204 | private void UpdateDevices() 205 | { 206 | for (int i = 0; i < activeDevices.Count; i++) 207 | { 208 | if (detectDeviceRoutine == null) 209 | { 210 | MultiMouse.MultiMousePoll(activeDevices[i].DeviceID); 211 | } 212 | 213 | for (int j = 1; j <= MAX_BUTTONS; j++) 214 | { 215 | if (MultiMouse.GetMouseButtonDown(activeDevices[i].DeviceID, j)) 216 | { 217 | isButtonDown[i][j] = true; 218 | switch (j) 219 | { 220 | case 1: 221 | OnLeftMouseButtonDown[i]?.Invoke(); 222 | break; 223 | case 2: 224 | OnRightMouseButtonDown[i]?.Invoke(); 225 | break; 226 | } 227 | } 228 | else if (MultiMouse.GetMouseButtonUp(activeDevices[i].DeviceID, j)) 229 | { 230 | isButtonDown[i][j] = false; 231 | switch (j) 232 | { 233 | case 1: 234 | OnLeftMouseButtonUp[i]?.Invoke(); 235 | break; 236 | case 2: 237 | OnRightMouseButtonUp[i]?.Invoke(); 238 | break; 239 | } 240 | } 241 | } 242 | 243 | UpdateMousePosition(activeDevices[i]); 244 | } 245 | } 246 | 247 | [ContextMenu(nameof(StartDetectingDevice))] 248 | public void StartDetectingDevice() 249 | { 250 | if (detectDeviceRoutine != null) StopCoroutine(detectDeviceRoutine); 251 | detectDeviceRoutine = StartCoroutine(DetectDevice()); 252 | } 253 | 254 | Coroutine detectDeviceRoutine; 255 | IEnumerator DetectDevice() 256 | { 257 | do 258 | { 259 | string id = ""; 260 | 261 | while (string.IsNullOrEmpty(id)) 262 | { 263 | id = MultiMouse.GetAnyMousePressingButton(1); 264 | if (!string.IsNullOrEmpty(id)) 265 | { 266 | if (idToDevice.ContainsKey(id)) id = ""; 267 | } 268 | yield return null; 269 | } 270 | 271 | Debug.Log("MultiMouse: Found device of ID " + id); 272 | var newDevice = new MultiMouseDevice(); 273 | newDevice.DeviceID = id; 274 | newDevice.IsLightgun = MultiMouse.GetAbsoluteMousePosition(id) != Vector2.zero; 275 | newDevice.Position = new Vector2( 276 | (float)Screen.width / 2f, 277 | (float)Screen.height / 2f); 278 | activeDevices.Add(newDevice); 279 | idToDevice.Add(id, newDevice); 280 | isButtonDown.Add(new bool[MAX_BUTTONS]); 281 | 282 | OnDeviceFound?.Invoke(activeDevices.Count - 1); 283 | } 284 | while (settings.keepDetectingUntilFull && activeDevices.Count < settings.maxDevices); 285 | 286 | detectDeviceRoutine = null; 287 | } 288 | 289 | /// 290 | /// Returns true if the button is currently held down 291 | /// 292 | /// 293 | /// 294 | /// 295 | public bool GetMouseButton(int deviceID, int buttonIndex) 296 | { 297 | if (!IsMouseActive(deviceID)) 298 | { 299 | DebugWarning("No device found at ID " + deviceID); 300 | return false; 301 | } 302 | return isButtonDown[deviceID][buttonIndex + 1]; 303 | } 304 | 305 | /// 306 | /// Returns true on the frame the button is pressed 307 | /// 308 | /// 309 | /// 310 | /// 311 | public bool GetMouseButtonDown(int deviceID, int buttonIndex) 312 | { 313 | var device = TryGetDeviceAtIndex(deviceID); 314 | if (device == null) 315 | { 316 | DebugWarning("No device found at ID " + deviceID); 317 | return false; 318 | } 319 | 320 | return MultiMouse.GetMouseButtonDown(device.DeviceID, buttonIndex + 1); 321 | } 322 | 323 | /// 324 | /// Returns true on the frame the button is released 325 | /// 326 | /// 327 | /// 328 | /// 329 | public bool GetMouseButtonUp(int deviceID, int buttonIndex) 330 | { 331 | var device = TryGetDeviceAtIndex(deviceID); 332 | if (device == null) 333 | { 334 | DebugWarning("No device found at ID " + deviceID); 335 | return false; 336 | } 337 | 338 | return MultiMouse.GetMouseButtonUp(device.DeviceID, buttonIndex + 1); 339 | } 340 | 341 | void UpdateMousePosition(MultiMouseDevice device) 342 | { 343 | if (device.IsLightgun) 344 | { 345 | var pos = MultiMouse.GetAbsoluteMousePosition(device.DeviceID); 346 | var rect = GetNormalizedUISpaceContainerRect(); 347 | 348 | pos.x = pos.x / (float)ushort.MaxValue; 349 | pos.y = pos.y / (float)ushort.MaxValue; 350 | 351 | var x = Mathf.InverseLerp(rect.xMin, rect.xMax, pos.x); 352 | var y = Mathf.InverseLerp(rect.yMax, rect.yMin, pos.y); 353 | 354 | device.Position = new Vector2(x * Screen.width, y * Screen.height); 355 | //Debug.Log(device.Position + " " + rect); 356 | } 357 | else 358 | { 359 | device.Position += MultiMouse.GetRelativeMousePosition(device.DeviceID); 360 | if (!settings.unclampMousePosition) 361 | { 362 | device.Position = new Vector2( 363 | Mathf.Clamp(device.Position.x, 0, Screen.width), 364 | Mathf.Clamp(device.Position.y, 0, Screen.height)); 365 | } 366 | } 367 | } 368 | 369 | public Vector2 GetMousePosition(int deviceID) 370 | { 371 | var device = TryGetDeviceAtIndex(deviceID); 372 | if (device == null) 373 | { 374 | DebugWarning("No device found at ID " + deviceID); 375 | return Vector2.zero; 376 | } 377 | 378 | return device.Position; 379 | } 380 | 381 | private void OnApplicationFocus(bool focus) 382 | { 383 | if (!MultiMouse.Initialized || !focus) return; 384 | Debug.Log("Application regained focus, re-initializing MultiMouse..."); 385 | MultiMouse.Destroy(); 386 | MultiMouse.Initialize(); 387 | } 388 | 389 | void DebugWarning(string message) 390 | { 391 | Debug.LogWarning("MultiMouse Warning: " + message); 392 | } 393 | 394 | void DebugError(string message) 395 | { 396 | Debug.LogWarning("MultiMouse Error: " + message); 397 | } 398 | 399 | #if UNITY_EDITOR 400 | static EditorWindow gameView; 401 | static EditorWindow GameView 402 | { 403 | get 404 | { 405 | if (gameView == null) 406 | { 407 | gameView = EditorWindow.GetWindow(typeof(EditorWindow).Assembly.GetType("UnityEditor.GameView")); 408 | } 409 | return gameView; 410 | } 411 | } 412 | 413 | const int TAB_HEIGHT = 22; 414 | #endif 415 | 416 | /// 417 | /// Uses top left as 0,0 and bottom right as 1,1, as standard mouse input/unity editor ui does. 418 | /// Thanks tomkail 419 | /// 420 | /// 421 | static Rect GetNormalizedUISpaceContainerRect() 422 | { 423 | var containerRect = new Rect(0, 0, Screen.width, Screen.height); 424 | #if UNITY_EDITOR 425 | containerRect = new Rect(GameView.position.x, GameView.position.y + TAB_HEIGHT, GameView.position.width, GameView.position.height - TAB_HEIGHT); 426 | #elif UNITY_STANDALONE_WIN 427 | containerRect = WindowsUtil.GetWindowPosition(); 428 | #endif 429 | var displayInfo = Screen.mainWindowDisplayInfo; 430 | return new Rect(containerRect.x / displayInfo.width, containerRect.y / displayInfo.height, containerRect.width / displayInfo.width, containerRect.height / displayInfo.height); 431 | } 432 | } 433 | 434 | #if UNITY_EDITOR 435 | [CustomEditor(typeof(MultiMouse))] 436 | class MultiMouseInterfaceEditor : Editor 437 | { 438 | public override void OnInspectorGUI() 439 | { 440 | //base.OnInspectorGUI(); 441 | } 442 | } 443 | #endif 444 | } -------------------------------------------------------------------------------- /Scripts/MultiMouseWrapper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2ea876aa5f0eff94ea45de4663e3691a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.brogrammist.multimouseunity", 3 | "version": "0.0.2", 4 | "displayName": "Multi Mouse Unity", 5 | "description": "Get multiple mouse devices moving in Unity!", 6 | "unity": "2021.3", 7 | "unityRelease": "22f1", 8 | "documentationUrl": "", 9 | "changelogUrl": "https://github.com/jackyyang09/Multi-Mouse-Unity/releases/tag/v.0.0.2s-alpha", 10 | "licensesUrl": "https://raw.githubusercontent.com/jackyyang09/Multi-Mouse-Unity/main/LICENSE", 11 | "keywords": [ 12 | "mouse", 13 | "multi mouse", 14 | "multiple" 15 | ], 16 | "author": { 17 | "name": "Jacky Yang", 18 | "email": "jackyyang267@gmail.com", 19 | "url": "https://github.com/jackyyang09/Multi-Mouse-Unity" 20 | } 21 | } --------------------------------------------------------------------------------