├── .editorconfig
├── .github
└── workflows
│ └── package.yml
├── .gitignore
├── CHANGELOG
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LFE.KeyboardShortcuts.csproj
├── LICENSE.md
├── README.md
├── images
├── demo.gif
├── demo.mp4
└── logo.png
├── src
├── Commands
│ ├── AnimationPatternCommand.cs
│ ├── AnimationSpeedChange.cs
│ ├── AtomAdd.cs
│ ├── AtomCommandBase.cs
│ ├── AtomDelete.cs
│ ├── AtomDump.cs
│ ├── AtomHiddenToggle.cs
│ ├── AtomPositionChange.cs
│ ├── AtomPositionSetLerp.cs
│ ├── AtomRotationChange.cs
│ ├── AtomSelect.cs
│ ├── AtomSelectNext.cs
│ ├── AtomSelectPrev.cs
│ ├── AtomSelectTab.cs
│ ├── CameraPositionChange.cs
│ ├── CameraRotationChange.cs
│ ├── Command.cs
│ ├── CommandConst.cs
│ ├── CommandExecuteEventArgs.cs
│ ├── ControllerCommandBase.cs
│ ├── ControllerPositionChange.cs
│ ├── ControllerPositionSetLerp.cs
│ ├── ControllerRotationChange.cs
│ ├── ErrorLogToggle.cs
│ ├── FreezeAnimationSet.cs
│ ├── FreezeAnimationToggle.cs
│ ├── HardReset.cs
│ ├── MessageLogToggle.cs
│ ├── MirrorReflectionsToggle.cs
│ ├── MonitorFieldOfViewChange.cs
│ ├── MouseRightClickDrag.cs
│ ├── MouseWheelScroll.cs
│ ├── MsaaChange.cs
│ ├── PerformanceMonitorToggle.cs
│ ├── PixelLightCountChange.cs
│ ├── PlayEditModeSet.cs
│ ├── PlayEditModeToggle.cs
│ ├── PluginActionCall.cs
│ ├── PluginAdd.cs
│ ├── PluginBoolSet.cs
│ ├── PluginBoolToggle.cs
│ ├── PluginFloatChange.cs
│ ├── PluginShowUI.cs
│ ├── PluginStringChooserChange.cs
│ ├── RescanPackages.cs
│ ├── SceneLoad.cs
│ ├── SceneNew.cs
│ ├── SceneSave.cs
│ ├── ScreenShotModeOn.cs
│ ├── SoftBodyPhysicsToggle.cs
│ ├── TimeScaleChange.cs
│ ├── UIButtonTriggerCommand.cs
│ └── WorldScaleChange.cs
├── Extensions
│ ├── AtomExtensions.cs
│ ├── EnumerableExtensions.cs
│ ├── InputWrapper.cs
│ ├── JSONStorableExtensions.cs
│ ├── SuperControllerExtensions.cs
│ ├── TransformExtensions.cs
│ └── UITabSelectorExtensions.cs
├── KeyboardShortcuts.cslist
├── Main
│ └── Plugin.cs
├── Models
│ ├── BindingEvent.cs
│ ├── CommandFactory.cs
│ ├── KeyBinding.cs
│ ├── KeyChord.cs
│ ├── KeyRecorder.cs
│ └── ViewModel.cs
└── Utils
│ ├── MathUtilities.cs
│ └── TimingLogger.cs
└── vam
└── meta.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*.cs]
4 | indent_style = space
5 | indent_size = 4
6 | insert_final_newline = true
7 | trim_trailing_whitespace = true
8 |
9 | # Styles
10 |
11 | dotnet_naming_style.pascal_case.capitalization = pascal_case
12 |
13 | dotnet_naming_style.prefix_underscore.capitalization = camel_case
14 | dotnet_naming_style.prefix_underscore.required_prefix = _
15 |
16 | # Const
17 |
18 | dotnet_naming_symbols.constant_fields.applicable_kinds = field
19 | dotnet_naming_symbols.constant_fields.applicable_accessibilities = public, internal, protected_internal, protected, private_protected, private
20 | dotnet_naming_symbols.constant_fields.required_modifiers = const
21 |
22 | dotnet_naming_rule.const_pascal_case.symbols = constant_fields
23 | dotnet_naming_rule.const_pascal_case.capitalization = pascal_case
24 | dotnet_naming_rule.const_pascal_case.severity = suggestion
25 |
26 | # Private
27 |
28 | dotnet_naming_symbols.private_fields.applicable_kinds = field
29 | dotnet_naming_symbols.private_fields.applicable_accessibilities = private
30 |
31 | dotnet_naming_rule.private_members_with_underscore.symbols = private_fields
32 | dotnet_naming_rule.private_members_with_underscore.style = prefix_underscore
33 | dotnet_naming_rule.private_members_with_underscore.severity = suggestion
--------------------------------------------------------------------------------
/.github/workflows/package.yml:
--------------------------------------------------------------------------------
1 | name: KeyboardShortcutsPackage
2 |
3 | on:
4 | push:
5 | tags:
6 | - v*
7 |
8 | jobs:
9 | build:
10 |
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - uses: actions/checkout@v1
15 | - name: Get the version
16 | id: get_version
17 | run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
18 | - name: Zip the release package
19 | id: zip
20 | run: |
21 | mkdir -p publish/Custom/Scripts/LFE/KeyboardShortcuts
22 | cp -r src publish/Custom/Scripts/LFE/KeyboardShortcuts/
23 | cp vam/meta.json publish/
24 | sed -i 's/v0.0.0/${{ steps.get_version.outputs.VERSION }}/' publish/meta.json
25 | cd publish
26 | zip -r "LFE.KeyboardShortcuts.${{ github.run_number }}.var" *
27 | - name: GitHub release
28 | uses: softprops/action-gh-release@v1
29 | if: startsWith(github.ref, 'refs/tags/')
30 | with:
31 | draft: true
32 | files: publish/LFE.KeyboardShortcuts.${{ github.run_number }}.var
33 | env:
34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | settings.json
2 |
3 | ## Ignore Visual Studio temporary files, build results, and
4 | ## files generated by popular Visual Studio add-ons.
5 | ##
6 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
7 |
8 | # User-specific files
9 | *.rsuser
10 | *.suo
11 | *.user
12 | *.userosscache
13 | *.sln.docstates
14 |
15 | # User-specific files (MonoDevelop/Xamarin Studio)
16 | *.userprefs
17 |
18 | # Mono auto generated files
19 | mono_crash.*
20 |
21 | # Build results
22 | [Dd]ebug/
23 | [Dd]ebugPublic/
24 | [Rr]elease/
25 | [Rr]eleases/
26 | x64/
27 | x86/
28 | [Aa][Rr][Mm]/
29 | [Aa][Rr][Mm]64/
30 | bld/
31 | [Bb]in/
32 | [Oo]bj/
33 | [Ll]og/
34 | [Ll]ogs/
35 |
36 | # Visual Studio 2015/2017 cache/options directory
37 | .vs/
38 | # Uncomment if you have tasks that create the project's static files in wwwroot
39 | #wwwroot/
40 |
41 | # Visual Studio 2017 auto generated files
42 | Generated\ Files/
43 |
44 | # MSTest test Results
45 | [Tt]est[Rr]esult*/
46 | [Bb]uild[Ll]og.*
47 |
48 | # NUnit
49 | *.VisualState.xml
50 | TestResult.xml
51 | nunit-*.xml
52 |
53 | # Build Results of an ATL Project
54 | [Dd]ebugPS/
55 | [Rr]eleasePS/
56 | dlldata.c
57 |
58 | # Benchmark Results
59 | BenchmarkDotNet.Artifacts/
60 |
61 | # .NET Core
62 | project.lock.json
63 | project.fragment.lock.json
64 | artifacts/
65 |
66 | # StyleCop
67 | StyleCopReport.xml
68 |
69 | # Files built by Visual Studio
70 | *_i.c
71 | *_p.c
72 | *_h.h
73 | *.ilk
74 | *.meta
75 | *.obj
76 | *.iobj
77 | *.pch
78 | *.pdb
79 | *.ipdb
80 | *.pgc
81 | *.pgd
82 | *.rsp
83 | *.sbr
84 | *.tlb
85 | *.tli
86 | *.tlh
87 | *.tmp
88 | *.tmp_proj
89 | *_wpftmp.csproj
90 | *.log
91 | *.vspscc
92 | *.vssscc
93 | .builds
94 | *.pidb
95 | *.svclog
96 | *.scc
97 |
98 | # Chutzpah Test files
99 | _Chutzpah*
100 |
101 | # Visual C++ cache files
102 | ipch/
103 | *.aps
104 | *.ncb
105 | *.opendb
106 | *.opensdf
107 | *.sdf
108 | *.cachefile
109 | *.VC.db
110 | *.VC.VC.opendb
111 |
112 | # Visual Studio profiler
113 | *.psess
114 | *.vsp
115 | *.vspx
116 | *.sap
117 |
118 | # Visual Studio Trace Files
119 | *.e2e
120 |
121 | # TFS 2012 Local Workspace
122 | $tf/
123 |
124 | # Guidance Automation Toolkit
125 | *.gpState
126 |
127 | # ReSharper is a .NET coding add-in
128 | _ReSharper*/
129 | *.[Rr]e[Ss]harper
130 | *.DotSettings.user
131 |
132 | # TeamCity is a build add-in
133 | _TeamCity*
134 |
135 | # DotCover is a Code Coverage Tool
136 | *.dotCover
137 |
138 | # AxoCover is a Code Coverage Tool
139 | .axoCover/*
140 | !.axoCover/settings.json
141 |
142 | # Coverlet is a free, cross platform Code Coverage Tool
143 | coverage*[.json, .xml, .info]
144 |
145 | # Visual Studio code coverage results
146 | *.coverage
147 | *.coveragexml
148 |
149 | # NCrunch
150 | _NCrunch_*
151 | .*crunch*.local.xml
152 | nCrunchTemp_*
153 |
154 | # MightyMoose
155 | *.mm.*
156 | AutoTest.Net/
157 |
158 | # Web workbench (sass)
159 | .sass-cache/
160 |
161 | # Installshield output folder
162 | [Ee]xpress/
163 |
164 | # DocProject is a documentation generator add-in
165 | DocProject/buildhelp/
166 | DocProject/Help/*.HxT
167 | DocProject/Help/*.HxC
168 | DocProject/Help/*.hhc
169 | DocProject/Help/*.hhk
170 | DocProject/Help/*.hhp
171 | DocProject/Help/Html2
172 | DocProject/Help/html
173 |
174 | # Click-Once directory
175 | publish/
176 |
177 | # Publish Web Output
178 | *.[Pp]ublish.xml
179 | *.azurePubxml
180 | # Note: Comment the next line if you want to checkin your web deploy settings,
181 | # but database connection strings (with potential passwords) will be unencrypted
182 | *.pubxml
183 | *.publishproj
184 |
185 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
186 | # checkin your Azure Web App publish settings, but sensitive information contained
187 | # in these scripts will be unencrypted
188 | PublishScripts/
189 |
190 | # NuGet Packages
191 | *.nupkg
192 | # NuGet Symbol Packages
193 | *.snupkg
194 | # The packages folder can be ignored because of Package Restore
195 | **/[Pp]ackages/*
196 | # except build/, which is used as an MSBuild target.
197 | !**/[Pp]ackages/build/
198 | # Uncomment if necessary however generally it will be regenerated when needed
199 | #!**/[Pp]ackages/repositories.config
200 | # NuGet v3's project.json files produces more ignorable files
201 | *.nuget.props
202 | *.nuget.targets
203 |
204 | # Microsoft Azure Build Output
205 | csx/
206 | *.build.csdef
207 |
208 | # Microsoft Azure Emulator
209 | ecf/
210 | rcf/
211 |
212 | # Windows Store app package directories and files
213 | AppPackages/
214 | BundleArtifacts/
215 | Package.StoreAssociation.xml
216 | _pkginfo.txt
217 | *.appx
218 | *.appxbundle
219 | *.appxupload
220 |
221 | # Visual Studio cache files
222 | # files ending in .cache can be ignored
223 | *.[Cc]ache
224 | # but keep track of directories ending in .cache
225 | !?*.[Cc]ache/
226 |
227 | # Others
228 | ClientBin/
229 | ~$*
230 | *~
231 | *.dbmdl
232 | *.dbproj.schemaview
233 | *.jfm
234 | *.pfx
235 | *.publishsettings
236 | orleans.codegen.cs
237 |
238 | # Including strong name files can present a security risk
239 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
240 | #*.snk
241 |
242 | # Since there are multiple workflows, uncomment next line to ignore bower_components
243 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
244 | #bower_components/
245 |
246 | # RIA/Silverlight projects
247 | Generated_Code/
248 |
249 | # Backup & report files from converting an old project file
250 | # to a newer Visual Studio version. Backup files are not needed,
251 | # because we have git ;-)
252 | _UpgradeReport_Files/
253 | Backup*/
254 | UpgradeLog*.XML
255 | UpgradeLog*.htm
256 | ServiceFabricBackup/
257 | *.rptproj.bak
258 |
259 | # SQL Server files
260 | *.mdf
261 | *.ldf
262 | *.ndf
263 |
264 | # Business Intelligence projects
265 | *.rdl.data
266 | *.bim.layout
267 | *.bim_*.settings
268 | *.rptproj.rsuser
269 | *- [Bb]ackup.rdl
270 | *- [Bb]ackup ([0-9]).rdl
271 | *- [Bb]ackup ([0-9][0-9]).rdl
272 |
273 | # Microsoft Fakes
274 | FakesAssemblies/
275 |
276 | # GhostDoc plugin setting file
277 | *.GhostDoc.xml
278 |
279 | # Node.js Tools for Visual Studio
280 | .ntvs_analysis.dat
281 | node_modules/
282 |
283 | # Visual Studio 6 build log
284 | *.plg
285 |
286 | # Visual Studio 6 workspace options file
287 | *.opt
288 |
289 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
290 | *.vbw
291 |
292 | # Visual Studio LightSwitch build output
293 | **/*.HTMLClient/GeneratedArtifacts
294 | **/*.DesktopClient/GeneratedArtifacts
295 | **/*.DesktopClient/ModelManifest.xml
296 | **/*.Server/GeneratedArtifacts
297 | **/*.Server/ModelManifest.xml
298 | _Pvt_Extensions
299 |
300 | # Paket dependency manager
301 | .paket/paket.exe
302 | paket-files/
303 |
304 | # FAKE - F# Make
305 | .fake/
306 |
307 | # CodeRush personal settings
308 | .cr/personal
309 |
310 | # Python Tools for Visual Studio (PTVS)
311 | __pycache__/
312 | *.pyc
313 |
314 | # Cake - Uncomment if you are using it
315 | # tools/**
316 | # !tools/packages.config
317 |
318 | # Tabs Studio
319 | *.tss
320 |
321 | # Telerik's JustMock configuration file
322 | *.jmconfig
323 |
324 | # BizTalk build output
325 | *.btp.cs
326 | *.btm.cs
327 | *.odx.cs
328 | *.xsd.cs
329 |
330 | # OpenCover UI analysis results
331 | OpenCover/
332 |
333 | # Azure Stream Analytics local run output
334 | ASALocalRun/
335 |
336 | # MSBuild Binary and Structured Log
337 | *.binlog
338 |
339 | # NVidia Nsight GPU debugger configuration file
340 | *.nvuser
341 |
342 | # MFractors (Xamarin productivity tool) working folder
343 | .mfractor/
344 |
345 | # Local History for Visual Studio
346 | .localhistory/
347 |
348 | # BeatPulse healthcheck temp database
349 | healthchecksdb
350 |
351 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
352 | MigrationBackup/
353 |
354 | # Ionide (cross platform F# VS Code tools) working folder
355 | .ionide/
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | Version 0.18 2020-07-30
2 | New: Move or Rotate the selected Free Controller for babul
3 |
4 | Version 0.17 2020-06-19
5 | New: Commands to control Animation patterns
6 | Play, Pause, Reset, and so on
7 | New: Command to run all triggers on a UIButton
8 | New: Command to dump basic atom information to messages
9 |
10 | Version 0.16 2020-05-26
11 | New: Commands to set or toggle Play/Edit Mode
12 |
13 | Version 0.15 2020-05-22
14 | New: Command to move camera with shortcuts
15 | New: Command to rotate camera with shortcuts
16 | New: For developers, allow commands to run either in 'Update' or 'FixedUpdate'
17 |
18 | Version 0.14 2020-05-13
19 | New: Command for Rescan Packages
20 | New: Command for Hard Reset
21 | Fix: Timescale change increment is now smaller
22 | Fix: Do not hang when running as a session plugin and loading another scene
23 |
24 | Version 0.13 2020-05-13
25 | Fix: VaM 1.19 support - Package in VAR format from here on out
26 |
27 | Version 0.12 2020-02-03
28 | New: Add Plugin to Atom action
29 | Fix: Reloading plugins or atoms in the scene no longer crash shortcuts
30 | Fix: Load Scene action now opens in edit mode
31 |
32 | Version 0.11 2020-01-31
33 | New: Actions can now target any free controller on an atom
34 | Change: Plugin actions now target specific plugin instances instead
35 | of a category of plugin. This gives more flexibility but
36 | sacrifices convenience. Thoughts towards convenience are
37 | being considered.
38 | New: Action to turn on screenshot mode
39 | Fix: Tab selection would sometimes fail. Now it fails less
40 |
41 | Version 0.10 2020-01-30
42 | New: Mirror Reflection Toggle Action
43 | New: Msaa Change Action
44 | New: Pixel Light Count Change Action
45 | New: Scene Load / Save Action
46 | New: Performance Monitor Toggle Action
47 | New: Add Atom Action
48 | New: Delete Selected Atom Action
49 | New: Plugin String Chooser Next / Previous Actions
50 | New: Plugin UI Show Action
51 | New: Specific Atom Show UI Tab Actions
52 | New: Specific Atom Select Action
53 | New: Recording text now guides usage of ESC key
54 | Fix: Action group slider now works
55 |
56 | Version 0.9 2020-01-27
57 | New: Support bindings in MacGruber postmagic plugin
58 | New: Support increasing/decreasing float params exposed in plugins
59 |
60 | Version 0.8 2020-01-27
61 | Fix: Overlapping / conflicting bindings that are shorter will be skipped if a longer
62 | one ran. For example, if SHIFT-CTRL-A and SHIFT-A are defined, then if SHIFT-CTRL-A
63 | triggered, then SHIFT-A will not also run.
64 | Fix: Don't trigger bindings if recording a new one
65 | Fix: Tab ui don't break if tab name isn't there for an atom type
66 | Refactor: One code file per command class
67 |
68 | Version 0.7 2020-01-24
69 | New: Gamepad Axis support
70 | New: Position actions for absolute position control (from 0 - 1)
71 | New: Position and rotation actions now respect timescale
72 | New: Action names are shorter in the UI
73 | Fix: Keybinding in config that are not in scene don't get deleted from config file
74 | Refactor: all command internals refactored - so might have made more bugs
75 |
76 | Version 0.6 2020-01-20
77 | New: Atom rotation and positional change actions
78 | New: Atom hide and delete actions
79 | New: Plugin registered boolean actions
80 | New: Plugin registered action actions
81 | Fix: Watch scene for changes and update actions that are listed
82 |
83 | Version 0.5 2020-01-18
84 | Fix: Stop listening to shortcuts if user is typing somewhere
85 | Fix: Saving/Loading settings now works properly if added as Session plugin
86 | Fix: Lots of other "added as session plugin" related breaking is fixed
87 |
88 | Version 0.4 2020-01-17
89 | New: Save settings
90 | New: Ability to filter shortcuts by category
91 | New: Toggle softbody physics action
92 | New: All UI panels for Person now listed as showable (thanks itsgus)
93 | New: Timescale and Animation speed actions (thanks itsgus)
94 | Fix: Hitting ESC in an empty binding field properly exits recording
95 | Fix: Actions show now for atom that plugin is attached to
96 | Fix: Shortcut that goes to tab now works if curently on main menu
97 |
98 | Add more UI Tab actions available
99 | Reorganize code so I don't have so much scrolling to do
100 |
101 | Version 0.3 2020-01-16
102 | Add more UI Tab actions available
103 | Reorganize code so I don't have so much scrolling to do
104 |
105 | Version 0.2 2020-01-15
106 | Example shortcuts to select a tab in the UI for an atom
107 |
108 | Version 0.1 2020-01-15
109 | Initial release
110 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at . All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | If you would like make contributions, please:
2 | - fork this repository
3 | - make your changes
4 | - issue a pull request
5 |
--------------------------------------------------------------------------------
/LFE.KeyboardShortcuts.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {86C32DA8-DA52-47FB-AC78-B6BBFC7963F5}
8 | Library
9 | Properties
10 | LFE.KeyboardShortcuts
11 | LFE.KeyboardShortcuts
12 | v4.6.1
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 | ..\..\..\..\VaM_Data\Managed\Assembly-CSharp.dll
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | ..\..\..\..\VaM_Data\Managed\UnityEngine.dll
48 |
49 |
50 | ..\..\..\..\VaM_Data\Managed\UnityEngine.AnimationModule.dll
51 |
52 |
53 | ..\..\..\..\VaM_Data\Managed\UnityEngine.AudioModule.dll
54 |
55 |
56 | ..\..\..\..\VaM_Data\Managed\UnityEngine.BaselibModule.dll
57 |
58 |
59 | ..\..\..\..\VaM_Data\Managed\UnityEngine.ClothModule.dll
60 |
61 |
62 | ..\..\..\..\VaM_Data\Managed\UnityEngine.CoreModule.dll
63 |
64 |
65 | ..\..\..\..\VaM_Data\Managed\UnityEngine.IMGUIModule.dll
66 |
67 |
68 | ..\..\..\..\VaM_Data\Managed\UnityEngine.InputModule.dll
69 |
70 |
71 | ..\..\..\..\VaM_Data\Managed\UnityEngine.Networking.dll
72 |
73 |
74 | False
75 | ..\..\..\..\VaM_Data\Managed\UnityEngine.PhysicsModule.dll
76 |
77 |
78 | ..\..\..\..\VaM_Data\Managed\UnityEngine.TextRenderingModule.dll
79 |
80 |
81 | ..\..\..\..\VaM_Data\Managed\UnityEngine.UI.dll
82 |
83 |
84 | ..\..\..\..\VaM_Data\Managed\UnityEngine.UIElementsModule.dll
85 |
86 |
87 | ..\..\..\..\VaM_Data\Managed\UnityEngine.UIModule.dll
88 |
89 |
90 | ..\..\..\..\VaM_Data\Managed\UnityEngine.VRModule.dll
91 |
92 |
93 | ..\..\..\..\VaM_Data\Managed\UnityEngine.XRModule.dll
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lfe999/KeyboardShortcuts/411a818b6e56c1a81212f57cbd196c5189f1da66/LICENSE.md
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Virt-A-Mate Keyboard Shortcuts
2 |
3 | Lets you bind keyboard / joystick bindings to many commands in Virt-A-Mate
4 |
5 | ## Installing
6 |
7 | Requires VaM 1.19 or newer.
8 |
9 | Download `LFE.KeyboardShortcuts.(version).var` from [Releases](https://github.com/lfe999/KeyboardShortcuts/releases)
10 |
11 | Save the `.var` file in the `(VAM_ROOT)\AddonPackages`.
12 |
13 | If you have VaM running already, click on the *Main UI > File (Open/Save) > Rescan Add-on Packages* button so that this plugin shows up.
14 |
15 | ## Demo
16 |
17 | 
18 |
19 | ## Quickstart
20 |
21 | ### Add the plugin to your scene
22 |
23 | - Click `Add Plugin` on either an atom or the `Session Plugins` tag from within VaM.
24 | - Click `Select File...` and choose `LFE.KeyboardShortcuts.(version)` on the left.
25 | - Choose the `ADDME.cslist` file
26 |
27 | ### Configure your keyboard shortcuts
28 |
29 | Click `Open Custom UI` on the KeyboardShortcuts plugin.
30 |
31 | The dropdowns at the top will let you filter the keyboard shortcuts by category and subcategory.
32 |
33 | ### Recording a shortcut
34 |
35 | To record a new keyboard shortcut, find the command you would like to modify and click the grey button to the right of the description.
36 |
37 | Then press the key combination that you would like to use to trigger that command.
38 |
39 | Some joypad axis will work but it is limited by the setup of the Unity engine itself. If it works for you then horray! If a command has some sort of "Increase" or "Decrease", then this program tries its best to map one direction of an axis to the increase side and one to the decrease side based on the context.
40 |
41 | ### Clearing a shortcut
42 |
43 | Click the selected shortcut grey button.
44 |
45 | Hit the `ESC` key
46 |
47 | ### Saving your shortcuts
48 |
49 | Anytime you record or clear a shortcut, the settings are automatically saved in the `(VAM_ROOT)\Saves\lfe_keyboardshortcuts.json` file
50 |
51 | ### Resetting all shortcuts
52 |
53 | Delete the file `(VAM_ROOT)\Saves\lfe_keyboardshortcuts.json` in order to set all shortcuts to their default.
54 |
55 | ## Command List
56 |
57 | ### Global Actions
58 |
59 | These are commands that will likely apply no matter what atoms are in the scene.
60 |
61 | | Command | Notes |
62 | | ------- | ----------- |
63 | Animation Speed > Increase |
64 | Animation Speed > Decrease |
65 | Atom > Select Next | Select the next atom alphabetically even if it is hidden
66 | Atom > Select Prev | Select the previous atom alphabetically even if it is hidden
67 | Atom > Select Next Visible | Select the next visible atom alphabetically
68 | Atom > Select Prev Visible | Select the previous visible atom alphabetically
69 | Camera > Move > `Direction` | Move the main camera in the direction that you want
70 | Camera > Look > `Direction` | Rotater the main camera in the direction that you want
71 | Error Log > Toggle |
72 | Message Log > Toggle |
73 | Field of View > Increase | Increase the FOV by 10
74 | Field of View > Decrease | Decrease the FOV by 10
75 | Freeze Animation > Toggle |
76 | Freeze Animation > On |
77 | Freeze Animation > Off |
78 | Mirror Reflections > Toggle |
79 | MSAA Level > Increase | Choose the next highest MSAA level. Does nothing if already at the lowest.
80 | MSAA Level > Decrease | Choose the next lowest MSAA level. Does nothing if already at the lowest.
81 | Performance Monitor > Toggle |
82 | Pixel Light Count > Increase |
83 | Pixel Light Count > Decrease |
84 | Play/Edit > Set To Edit | Turn on Edit Mode
85 | Play/Edit > Set To Play | Turn on Play Mode
86 | Play/Edit > Toggle | Toggle Edit/Play Mode
87 | Rescan Add-on Packages |
88 | Hard Reset |
89 | Scene > New Scene |
90 | Scene > Open Scene |
91 | Scene > Save Scene |
92 | Screen Shot > Mode > Enable |
93 | Soft Body Physics > Toggle |
94 | Time Scale > Increase | Increase time scale by 0.10 - holding `SHIFT` makes this 0.5
95 | Time Scale > Decrease | Decrease time scale by 0.10 - holding `SHIFT` makes this 0.5
96 | World Scale > Increase | Increase world scale by 0.00025 - holding `SHIFT` makes this 0.001
97 | World Scale > Decrease | Decrease world scale by 0.00025 - holding `SHIFT` makes this 0.001
98 | Add > `Atom Type` > `Atom Name` | Add the atom of the given type to the scene
99 |
100 | ### Selected Controller Actions
101 |
102 | These are commands that will be run against the selected controller. They do nothing if no controller is selected.
103 |
104 | !!!!! Be careful of overlap between setting these and setting selected atom actions.
105 |
106 | Position > `[XYZ]` > Interpolate 0 - 1 | Set the `AXIS` of the atom to something between 0 and 1. Probably only useful when assigning a joypad axis.
107 | Position > `[XYZ]` > Increase / Decrease Small | Increase or decrease the given `AXIS` position by a maximum of 0.5 units per second
108 | Position > `[XYZ]` > Increase / Decrease Medium | Increase or decrease the given `AXIS` position by a maximum of 2.0 units per second
109 | Position > `[XYZ]` > Increase / Decrease Large | Increase or decrease the given `AXIS` position by a maximum of 5.0 units per second
110 | Rotation > `[XYZ]` > Increase / Decrease Small | Increase or decrease the given `AXIS` rotation by a maximum of 0.25 rotations per second
111 | Rotation > `[XYZ]` > Increase / Decrease Medium | Increase or decrease the given `AXIS` rotation by a maximum of 0.5 rotations per second
112 | Rotation > `[XYZ]` > Increase / Decrease Large | Increase or decrease the given `AXIS` rotation by a maximum of 2.0 rotations per second
113 |
114 | ### Selected Atom Actions
115 |
116 | These are commands that will be run against a selected atom. They do nothing if no atom is selected.
117 |
118 | !!!!! Be careful of overlap between setting these and setting selected controller actions.
119 |
120 | | Command | Notes |
121 | | ------- | ----------- |
122 | Delete | Delete the selected atom
123 | Hide > Toggle | Toggle the atom hidden or shown
124 | Show UI > `Tab Name` | Show the selected `Tab Name`. If that tab name does not exist on the selected atom, this does nothing.
125 | Position > `[XYZ]` > Interpolate 0 - 1 | Set the `AXIS` of the atom to something between 0 and 1. Probably only useful when assigning a joypad axis.
126 | Position > `[XYZ]` > Increase / Decrease Small | Increase or decrease the given `AXIS` position by a maximum of 0.5 units per second
127 | Position > `[XYZ]` > Increase / Decrease Medium | Increase or decrease the given `AXIS` position by a maximum of 2.0 units per second
128 | Position > `[XYZ]` > Increase / Decrease Large | Increase or decrease the given `AXIS` position by a maximum of 5.0 units per second
129 | Rotation > `[XYZ]` > Increase / Decrease Small | Increase or decrease the given `AXIS` rotation by a maximum of 0.25 rotations per second
130 | Rotation > `[XYZ]` > Increase / Decrease Medium | Increase or decrease the given `AXIS` rotation by a maximum of 0.5 rotations per second
131 | Rotation > `[XYZ]` > Increase / Decrease Large | Increase or decrease the given `AXIS` rotation by a maximum of 2.0 rotations per second
132 |
133 | ### Specific Atom Actions
134 |
135 | These are commands that will be run against the atom with the selected `ID`, EVEN IF IT IS NOT SELECTED.
136 |
137 | This means that a command to `ShowUI > Plugins` will first, select the atom, and then run your selected command.
138 |
139 | Additionally, commands to target specific **free controllers** and **plugins** can be
140 |
141 | | Command | Notes |
142 | | ------- | ----------- |
143 | see "Selected Atom Commands" |
144 |
145 | ### Targeting Plugin Commands
146 |
147 | Any `Params` that a plugin exposes can be targeted.
148 |
149 | In order to trigger a plugin `Params` with a keybinding:
150 | - select the specific atom that has the plugin installed in the left hand dropdown
151 | - select the specific plugin in the right hand dropdown
152 | - set keybinding for the dynamically generated commands available
153 |
154 | | Commands | Notes |
155 | | ------- | ----------- |
156 | `Plugin` > Show UI | open the plugins configuration UI
157 | `Boolean Param` > Toggle | Toggle the `Boolean Param` on or off for the plugin
158 | `Boolean Param` > On | Set the `Boolean Param` On for the plugin
159 | `Boolean Param` > Off | Set the `Boolean Param` Off for the plugin
160 | `Action Param` > Call | Trigger the custom `Action Param` for the plugin
161 | `Float Param` > +0.01 | Increase the float param by a maximum of 0.01 (if joypad axis is bound, increased/decreased amount is interpolated)
162 | `Float Param` > -0.01 |
163 | `Float Param` > +0.10 |
164 | `Float Param` > -0.10 |
165 | `Float Param` > +1.00 |
166 | `Float Param` > -1.00 |
167 | `String Chooser Param` > Next | Select the next item in for the given `String Chooser Param` of the plugin
168 | `String Chooser Param` > Prev | Select the previous item in for the given `String Chooser Param` of the plugin
169 |
--------------------------------------------------------------------------------
/images/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lfe999/KeyboardShortcuts/411a818b6e56c1a81212f57cbd196c5189f1da66/images/demo.gif
--------------------------------------------------------------------------------
/images/demo.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lfe999/KeyboardShortcuts/411a818b6e56c1a81212f57cbd196c5189f1da66/images/demo.mp4
--------------------------------------------------------------------------------
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lfe999/KeyboardShortcuts/411a818b6e56c1a81212f57cbd196c5189f1da66/images/logo.png
--------------------------------------------------------------------------------
/src/Commands/AnimationPatternCommand.cs:
--------------------------------------------------------------------------------
1 |
2 | using System;
3 |
4 | namespace LFE.KeyboardShortcuts.Commands
5 | {
6 | public class AnimationPatternCommand : AtomCommandBase
7 | {
8 | public const int NOTHING = 0;
9 | public const int PLAY = 1;
10 | public const int PAUSE = 2;
11 | public const int UNPAUSE = 3;
12 | public const int TOGGLE_PAUSE = 4;
13 | public const int RESET_AND_PLAY = 5;
14 | public const int RESET = 6;
15 |
16 |
17 | private int _action;
18 |
19 | public AnimationPatternCommand() : this((Func)null, NOTHING) { }
20 | public AnimationPatternCommand(Atom atom, int action) : this((a) => a.uid.Equals(atom.uid), action) { }
21 | public AnimationPatternCommand(Func predicate, int action) : base(predicate) {
22 | _action = action;
23 | }
24 |
25 | public override bool Execute(CommandExecuteEventArgs args)
26 | {
27 | var selected = TargetAtom(args);
28 | if (selected != null) {
29 | var pattern = selected.GetComponentInChildren();
30 | if(pattern != null) {
31 | switch(_action) {
32 | case PLAY:
33 | pattern.Play();
34 | break;
35 | case RESET_AND_PLAY:
36 | pattern.ResetAndPlay();
37 | break;
38 | case PAUSE:
39 | pattern.Pause();
40 | break;
41 | case UNPAUSE:
42 | pattern.UnPause();
43 | break;
44 | case TOGGLE_PAUSE:
45 | pattern.TogglePause();
46 | break;
47 | case RESET:
48 | pattern.ResetAnimation();
49 | break;
50 | }
51 | }
52 | }
53 | return true;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Commands/AnimationSpeedChange.cs:
--------------------------------------------------------------------------------
1 | using LFE.KeyboardShortcuts.Extensions;
2 | using UnityEngine;
3 |
4 | namespace LFE.KeyboardShortcuts.Commands
5 | {
6 | public class AnimationSpeedChange : Command
7 | {
8 | private const float _multiplier = 1.0f;
9 | private const float _min = -3.0f;
10 | private const float _max = 5.0f;
11 |
12 | private float _amount;
13 |
14 | public AnimationSpeedChange(float amount)
15 | {
16 | _amount = amount;
17 | }
18 |
19 | public override bool Execute(CommandExecuteEventArgs args)
20 | {
21 | if (args.KeyBinding.KeyChord.HasAxis)
22 | {
23 | // make sure the keybinding and value change are going the
24 | // same "direction" (for the case where the axis is involved)
25 | if (!MathUtilities.SameSign(args.Data, _amount)) { return false; }
26 | }
27 |
28 | SuperController sc = SuperController.singleton;
29 | var multiplier = _multiplier * Mathf.Abs(args.Data);
30 |
31 | if (InputWrapper.GetKey(KeyCode.LeftShift) || InputWrapper.GetKey(KeyCode.RightShift))
32 | {
33 | multiplier *= 5.0f;
34 | }
35 |
36 | var scale = sc.motionAnimationMaster.playbackSpeed + (_amount * multiplier);
37 | sc.motionAnimationMaster.playbackSpeed = Mathf.Clamp(scale, _min, _max);
38 | return true;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Commands/AtomAdd.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 |
4 | namespace LFE.KeyboardShortcuts.Commands
5 | {
6 | public class AtomAdd : Command
7 | {
8 | private string _type;
9 | public AtomAdd(string type)
10 | {
11 | _type = type;
12 | }
13 |
14 | public override bool Execute(CommandExecuteEventArgs args)
15 | {
16 | SuperController.singleton.StartCoroutine(SuperController.singleton.AddAtomByType(_type, useuid: null, userInvoked: false));
17 | return true;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Commands/AtomCommandBase.cs:
--------------------------------------------------------------------------------
1 | using LFE.KeyboardShortcuts.Extensions;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 |
6 | namespace LFE.KeyboardShortcuts.Commands
7 | {
8 | public abstract class AtomCommandBase : Command {
9 | protected Func _predicate;
10 | protected AtomCommandBase(Func predicate)
11 | {
12 | _predicate = predicate;
13 | }
14 |
15 | public virtual Atom TargetAtom(CommandExecuteEventArgs args)
16 | {
17 | if(_predicate == null)
18 | {
19 | return SuperController.singleton.GetSelectedAtom();
20 | }
21 | else
22 | {
23 | return SelectableAtoms().Where(_predicate).FirstOrDefault();
24 | }
25 | }
26 |
27 | protected IEnumerable SelectableAtoms()
28 | {
29 | return SuperController.singleton.GetSelectableAtoms().OrderBy((a) => a.uid);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Commands/AtomDelete.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 |
4 | namespace LFE.KeyboardShortcuts.Commands
5 | {
6 | public class AtomDelete : AtomCommandBase
7 | {
8 | public AtomDelete() : this(null) { }
9 | public AtomDelete(Func predicate) : base(predicate) { }
10 | public override bool Execute(CommandExecuteEventArgs args)
11 | {
12 | var selected = TargetAtom(args);
13 | if (selected != null) {
14 | SuperController.singleton.StartCoroutine(DeleteAtom(selected));
15 | }
16 | return true;
17 | }
18 |
19 | private IEnumerator DeleteAtom(Atom atom)
20 | {
21 | SuperController.singleton.RemoveAtom(atom);
22 | yield return null;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Commands/AtomDump.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using LFE.KeyboardShortcuts.Extensions;
4 |
5 | namespace LFE.KeyboardShortcuts.Commands
6 | {
7 | public class AtomDump : AtomCommandBase
8 | {
9 | public AtomDump() : this((Func)null) { }
10 | public AtomDump(Atom atom) : this((a) => a.uid.Equals(atom.uid)) { }
11 | public AtomDump(Func predicate) : base(predicate) { }
12 |
13 | // TODO: consider integrating with acidbubbles debug plugin
14 | public override bool Execute(CommandExecuteEventArgs args)
15 | {
16 | var selected = TargetAtom(args);
17 | if (selected != null) {
18 | DumpObject(selected);
19 | }
20 | return true;
21 | }
22 |
23 | private void DumpObject(object thing) {
24 | if(thing is Atom) {
25 | DumpAtom(thing as Atom);
26 |
27 | }
28 | else {
29 | Log($"{thing}");
30 | }
31 | }
32 |
33 | private void DumpAtom(Atom atom) {
34 | Log($"atom.name = \"{atom.name}\"");
35 | Log($"atom.uid = \"{atom.uid}\"");
36 | Log($"atom.type = \"{atom.type}\"");
37 |
38 | var paramNames = string.Join(", ", atom.GetAllParamAndActionNames().ToArray());
39 | Log($"atom.params = [{paramNames}]");
40 |
41 | Log("atom.components = [");
42 | foreach(var c in atom.GetComponentsInChildren