mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2025-04-18 10:28:59 +08:00
Compare commits
1078 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
14c74ae62e | ||
|
186554b3e9 | ||
|
e678ce8a2a | ||
|
ce77fc773c | ||
|
78dca536fb | ||
|
7086b35b3f | ||
|
59c256704b | ||
|
c4f3728d5e | ||
|
dcda15569a | ||
|
8cba3560ce | ||
|
17051419ec | ||
|
1a1cae4e04 | ||
|
e5e4c41b38 | ||
|
c7c9e23acb | ||
|
5be1f13840 | ||
|
420f9b00b1 | ||
|
45b5db46c5 | ||
|
03ee9d6048 | ||
|
897d168137 | ||
|
400960257e | ||
|
f0fcbb66b1 | ||
|
7fd35bb49a | ||
|
bc4c6628ee | ||
|
b733ce2e4d | ||
|
3324d3f71b | ||
|
c3d2cfb29f | ||
|
7610020c3b | ||
|
89de978c77 | ||
|
db9389052c | ||
|
81aed5b798 | ||
|
706ce7aa2f | ||
|
b75e74ef84 | ||
|
8ef4cf6328 | ||
|
c521bd7721 | ||
|
e46e958f39 | ||
|
8a45515af0 | ||
|
36b442f904 | ||
|
124392c422 | ||
|
dff7f03c2f | ||
|
713a0d3b1d | ||
|
e2a02982d5 | ||
|
672dd8b31f | ||
|
6175e20e46 | ||
|
fce938820b | ||
|
34deac5681 | ||
|
b49e5cb460 | ||
|
3165d471b5 | ||
|
2d59c74066 | ||
|
55d744885f | ||
|
318d65f3b5 | ||
|
aac70873c5 | ||
|
5a17d6ea9a | ||
|
62fd986fd0 | ||
|
39b4df8367 | ||
|
fc9b2683c8 | ||
|
98311f11f8 | ||
|
2557972461 | ||
|
9510c56f7a | ||
|
9418b00b54 | ||
|
61f11ff836 | ||
|
2823696af9 | ||
|
45352296e9 | ||
|
4323b40362 | ||
|
57f1851cdd | ||
|
494ad1c4d9 | ||
|
2e79c9b195 | ||
|
7182baca47 | ||
|
71a0d82c66 | ||
|
4c44c576de | ||
|
ec73eb6225 | ||
|
295a46ec12 | ||
|
fa004b2db5 | ||
|
f6362cdbc2 | ||
|
cbf7fa4233 | ||
|
a7906e4fd6 | ||
|
f0a61fe55a | ||
|
7abfb021e3 | ||
|
903f230633 | ||
|
be729c8f53 | ||
|
233521b029 | ||
|
92ebc1c1ac | ||
|
1a20333b58 | ||
|
5f19bad688 | ||
|
fdd3110a98 | ||
|
c7a06e71a0 | ||
|
cd5bb5ff4e | ||
|
e91b8ab6c3 | ||
|
e3a01ff58b | ||
|
5de63b3495 | ||
|
1c8477ba4a | ||
|
cdf8d8400d | ||
|
aaa448bf57 | ||
|
e0f55ddc4f | ||
|
d4543a38c5 | ||
|
e471df8860 | ||
|
70dd38e970 | ||
|
7e5d631b9d | ||
|
3f57e17548 | ||
|
242a108703 | ||
|
07cce41329 | ||
|
53c47bfb0b | ||
|
7cafd314a4 | ||
|
d7e949239a | ||
|
d3ae37c3cf | ||
|
61d4b203ca | ||
|
54f5bd1922 | ||
|
c6199ca183 | ||
|
8a1d2b77dd | ||
|
2849ea9183 | ||
|
eb7793d7c5 | ||
|
de18e77e34 | ||
|
19d8ebee68 | ||
|
54d85a5cef | ||
|
8e2650acdb | ||
|
a6cde1fbe9 | ||
|
428a2cc4a3 | ||
|
5175626b23 | ||
|
8414d203e5 | ||
|
89d38c5371 | ||
|
2f32cb4351 | ||
|
f799af4c03 | ||
|
75d3b5078a | ||
|
18569ab556 | ||
|
129ad4dc35 | ||
|
909d7e66c4 | ||
|
3ceafb8e1f | ||
|
3a94498e45 | ||
|
c1b2351537 | ||
|
71f428d804 | ||
|
be35de2018 | ||
|
cca9e22edd | ||
|
cd0ed0f009 | ||
|
1b8e40c747 | ||
|
e0f9e95df3 | ||
|
7967fcf121 | ||
|
f7dc99be7d | ||
|
9ce8a209d8 | ||
|
6dcd63dde7 | ||
|
d91c69835c | ||
|
5325c809a4 | ||
|
76eca08c22 | ||
|
2c3e24333a | ||
|
f35283db51 | ||
|
d538551fad | ||
|
f3bf07b601 | ||
|
4a65b9f2ac | ||
|
80d17f8284 | ||
|
a7ef0d6635 | ||
|
0606311f51 | ||
|
fd59c3e910 | ||
|
5c084a8b8a | ||
|
2a3da2fec3 | ||
|
ef4304acf1 | ||
|
46f5296528 | ||
|
9f4a7a6304 | ||
|
2c0b6df863 | ||
|
b7373b6584 | ||
|
4b5cf06097 | ||
|
e68e176aa4 | ||
|
d23b9f94a2 | ||
|
30512c26e8 | ||
|
4405d7aa56 | ||
|
a984cf8673 | ||
|
7980d933c2 | ||
|
ef0beec8ed | ||
|
81ad82b765 | ||
|
973e7d2448 | ||
|
59ff119d20 | ||
|
6fd8ac0cd7 | ||
|
29e2041312 | ||
|
a3b9acba39 | ||
|
497d16f89d | ||
|
e752762d21 | ||
|
32ea6678f7 | ||
|
1153abd16e | ||
|
efa263b551 | ||
|
07b648dcc1 | ||
|
131f54a713 | ||
|
1cce15590c | ||
|
e0702c5dcf | ||
|
3b067e4664 | ||
|
26153ea60d | ||
|
5bafb0ba9d | ||
|
11a62c88d4 | ||
|
123523540e | ||
|
ab4d1fd2f4 | ||
|
9dc342e81e | ||
|
ae975506d7 | ||
|
3ba0219430 | ||
|
8bf1d29bf3 | ||
|
55ab65e22d | ||
|
b73feb6b71 | ||
|
662172c2e5 | ||
|
5d399dce4a | ||
|
766f728a8a | ||
|
f40d02ceb9 | ||
|
7ae98d63b0 | ||
|
0b8cd3b3b6 | ||
|
7f9e65bcbc | ||
|
4a376f8723 | ||
|
1024f626e8 | ||
|
828e6b4548 | ||
|
656a401684 | ||
|
394601d4a7 | ||
|
4da4ebc984 | ||
|
30cafb21e4 | ||
|
c379d730ca | ||
|
d9c0a21f0d | ||
|
816d2b28cb | ||
|
4ec36ca489 | ||
|
409592f952 | ||
|
02204c272f | ||
|
36e035c8c7 | ||
|
6c55185895 | ||
|
1c29af20fb | ||
|
4b9d1128c6 | ||
|
2c9939dea8 | ||
|
8150e05dd0 | ||
|
f85d455c8f | ||
|
cb2afcc3d5 | ||
|
838f1dac7e | ||
|
94002e4594 | ||
|
c5e787045a | ||
|
776f08be3f | ||
|
b01b280f79 | ||
|
a71af7ae0a | ||
|
6dafe72c3b | ||
|
848f857728 | ||
|
01d75fb284 | ||
|
cd4cadf23f | ||
|
0f28cf7aba | ||
|
cc93c7e5ed | ||
|
7040e3992b | ||
|
f3f2de3337 | ||
|
b866628b24 | ||
|
7e5c227867 | ||
|
1fe8255f52 | ||
|
3f5d5a2013 | ||
|
4f398d21c3 | ||
|
ee64cafe02 | ||
|
e63a34e2ba | ||
|
a018df9219 | ||
|
13b0ffe0b5 | ||
|
de1744b080 | ||
|
119c56878c | ||
|
d82c41c390 | ||
|
2826c27d63 | ||
|
51fedbd9b0 | ||
|
bf47a4c544 | ||
|
8e49df703f | ||
|
032e7a692e | ||
|
3b86822547 | ||
|
fd3de6e680 | ||
|
2d8f5d764e | ||
|
a5e716cb3e | ||
|
54288ebd44 | ||
|
9dfa0dae23 | ||
|
5090d45cfe | ||
|
7bf5106246 | ||
|
c11a76642c | ||
|
71ddd257a3 | ||
|
9b4e76e053 | ||
|
a98ef213ff | ||
|
c2b6766a40 | ||
|
8ed877c99c | ||
|
56f1b67d31 | ||
|
3648348184 | ||
|
9073ff8c2d | ||
|
48b7d80f7c | ||
|
c80d24ea46 | ||
|
b83b89ce38 | ||
|
3b28ea2b14 | ||
|
65194fbc80 | ||
|
2ea9fb50b6 | ||
|
4e3001ad65 | ||
|
faa8d210f2 | ||
|
f4d80b857d | ||
|
fed6a22d72 | ||
|
a9c2815106 | ||
|
c0582a9961 | ||
|
3eaf8bee6d | ||
|
73755e7664 | ||
|
4f77723906 | ||
|
3be3cfb74a | ||
|
38384a3c70 | ||
|
29177f2c5a | ||
|
106ba8c5ff | ||
|
2735adf55c | ||
|
566a030730 | ||
|
1163fac2e7 | ||
|
4fa0621655 | ||
|
acd6c50543 | ||
|
89b4c8f921 | ||
|
389ae4f2cc | ||
|
422ed5cfb1 | ||
|
0ee291076f | ||
|
c63128095e | ||
|
d403f1b178 | ||
|
e07b18d87e | ||
|
668ab35b46 | ||
|
f9a9f1f1ef | ||
|
22cff4ba3f | ||
|
466017c102 | ||
|
1d58548013 | ||
|
ae950ad938 | ||
|
371809f430 | ||
|
1aa6c03202 | ||
|
db06a6a492 | ||
|
7330cda42a | ||
|
ece8a6837a | ||
|
c309d93bdd | ||
|
d33787a6b0 | ||
|
0a6270bb43 | ||
|
682a0de0e0 | ||
|
b0032a09c0 | ||
|
28ed2e0ed1 | ||
|
c6e863d409 | ||
|
3bc090dc7d | ||
|
2148ab0bfc | ||
|
818f16f839 | ||
|
7f3b0fec3e | ||
|
231feba3a2 | ||
|
13b9bf72e2 | ||
|
802fea09d9 | ||
|
f085ce07b6 | ||
|
6cb249be44 | ||
|
580cb2bfe9 | ||
|
9d48ae4f65 | ||
|
0243b8cc8e | ||
|
369cc010c3 | ||
|
f514a5e904 | ||
|
f9abb5c4fc | ||
|
ea857406ee | ||
|
b853514fea | ||
|
f19a4946bf | ||
|
ca681d6033 | ||
|
ae318b29d8 | ||
|
87a385a43e | ||
|
07660164ba | ||
|
14fd8b81aa | ||
|
46cf066e04 | ||
|
a2b9b817ce | ||
|
f96b2627aa | ||
|
b2ada9fe05 | ||
|
037c450760 | ||
|
f44e070c46 | ||
|
8418f8e047 | ||
|
3b9f0d1838 | ||
|
dd66cd2f7c | ||
|
3b44a0b44f | ||
|
8be802bee5 | ||
|
8ed649f9a4 | ||
|
a42295e0e6 | ||
|
159865e6cd | ||
|
c7df409d70 | ||
|
e7e030f0db | ||
|
9642c845cf | ||
|
436a7dc4dd | ||
|
a75a422cf4 | ||
|
eb5a04511d | ||
|
c2b381c721 | ||
|
3f02a1127f | ||
|
6f95800e41 | ||
|
b732c5268e | ||
|
b70727076c | ||
|
e5af635bd9 | ||
|
7a20eaf57e | ||
|
7384715059 | ||
|
d83c3351d7 | ||
|
1b3b9194c0 | ||
|
467b0d4431 | ||
|
3eea882019 | ||
|
81bcd14bcd | ||
|
c0ee54e8c2 | ||
|
3644ffdb12 | ||
|
622d846b9f | ||
|
3838014517 | ||
|
f4ab86fedc | ||
|
e2e0b88dfa | ||
|
4617575123 | ||
|
13822f33e1 | ||
|
3117275277 | ||
|
ed4f5dfd31 | ||
|
d49f87e754 | ||
|
5a7e02d591 | ||
|
915ddc0d5b | ||
|
a739598d13 | ||
|
a3ce9b2505 | ||
|
4d246fa238 | ||
|
cd366cab2d | ||
|
6b99b763a7 | ||
|
d998763fbe | ||
|
3d1b4f1c76 | ||
|
d4683f99e3 | ||
|
ead026a918 | ||
|
586fb90dca | ||
|
053a0d464b | ||
|
6d89db6a8a | ||
|
7d5860654a | ||
|
87ff50b161 | ||
|
dee5241436 | ||
|
1c766e9fe8 | ||
|
c2f37bb3a1 | ||
|
489d3a7374 | ||
|
3d3aefd4f9 | ||
|
9a974f5f09 | ||
|
098a85af50 | ||
|
2cd996db55 | ||
|
0806c621c5 | ||
|
7a3b782fae | ||
|
8e7526e711 | ||
|
bf9266f054 | ||
|
d999f799fb | ||
|
c50b3526f6 | ||
|
32dc864d8d | ||
|
366ff0832f | ||
|
08b3880d23 | ||
|
7beb5bf09b | ||
|
22555632bf | ||
|
e6af038379 | ||
|
17a85325f8 | ||
|
d8e01234f0 | ||
|
0bc64eb755 | ||
|
50c5bd6001 | ||
|
925d601a1b | ||
|
749d4dac4f | ||
|
8dd4426e64 | ||
|
28de60a31f | ||
|
b9b7677e3a | ||
|
9c96ae2010 | ||
|
57fe84548c | ||
|
746a72f60b | ||
|
f3168253f6 | ||
|
bdb2dc2a42 | ||
|
2efcc670df | ||
|
65d229d338 | ||
|
11ca336ece | ||
|
806d31fd82 | ||
|
4ad38c1229 | ||
|
02ca58a3a9 | ||
|
b3142d7f11 | ||
|
90dfc1822c | ||
|
70aee65472 | ||
|
3937657d35 | ||
|
65dc560429 | ||
|
9adec1e5e7 | ||
|
76d5f882eb | ||
|
ae3e163bd4 | ||
|
6a82c6201f | ||
|
04fc7ac69a | ||
|
14c9da940f | ||
|
fa683e2675 | ||
|
208987df07 | ||
|
7d3eca08f2 | ||
|
7b7af16101 | ||
|
0626cb308c | ||
|
4c20d1e052 | ||
|
628c07a505 | ||
|
72d7a7381a | ||
|
75ebb74924 | ||
|
719c39da6e | ||
|
d725ade36d | ||
|
a0f27ba70f | ||
|
3a3ad4b57c | ||
|
14897926bb | ||
|
66f3e7075c | ||
|
865dae7dfc | ||
|
8d3da50b37 | ||
|
32c538a536 | ||
|
9cd91dd094 | ||
|
445b4990f7 | ||
|
11abeb853b | ||
|
c9db3debcf | ||
|
1c0be75e28 | ||
|
06a53e2e94 | ||
|
bc12e3a985 | ||
|
61a70feed7 | ||
|
2af603e365 | ||
|
e1e313f10b | ||
|
c111b29fbb | ||
|
3ebc4fb2cf | ||
|
926ea255cb | ||
|
0fc9f5d86e | ||
|
2467b5bc28 | ||
|
84ab43b2af | ||
|
a88385a0da | ||
|
edde55d9f2 | ||
|
37ae033248 | ||
|
c37013c840 | ||
|
b25359a14a | ||
|
8d64c63f49 | ||
|
b23c0c1a1c | ||
|
0bae438edd | ||
|
59eb72cb2c | ||
|
c1fbee721f | ||
|
7881aa920e | ||
|
cb2fd75ec6 | ||
|
dffb9f7418 | ||
|
51bedcffef | ||
|
6da55dc08c | ||
|
16642454fc | ||
|
cb3ada9072 | ||
|
0024be06e0 | ||
|
16279e0b65 | ||
|
61e97344ea | ||
|
8a6c1c86c0 | ||
|
a23acc6537 | ||
|
9aa3751e03 | ||
|
f92d10cf50 | ||
|
a630cfc316 | ||
|
a83f1dca7c | ||
|
103deba015 | ||
|
7f7f344963 | ||
|
65797aa012 | ||
|
9516a5eafa | ||
|
88cf2e14b7 | ||
|
12981d1060 | ||
|
2c69bb2b76 | ||
|
aa631f3b01 | ||
|
654aec1aab | ||
|
532e3bc250 | ||
|
f4f26d2f67 | ||
|
2f4e4bce5c | ||
|
8a8b6a355c | ||
|
3f50da35f2 | ||
|
a801f0ee76 | ||
|
fe8eeb1124 | ||
|
902a84ead4 | ||
|
4f05ff1981 | ||
|
4ab0078456 | ||
|
63cf4626e0 | ||
|
68a3f928a4 | ||
|
5e7516a3f8 | ||
|
02952437c0 | ||
|
ea2e1f026d | ||
|
29920d1d91 | ||
|
0294fc16bd | ||
|
81dddabf15 | ||
|
df05929cc2 | ||
|
12de13a947 | ||
|
0ff1da0734 | ||
|
e31a33b82c | ||
|
17e6c22335 | ||
|
01d24f6809 | ||
|
37e7ebcae1 | ||
|
95a686609d | ||
|
d85bbb257c | ||
|
fcc3752bcc | ||
|
f7e574654f | ||
|
eabf6422ec | ||
|
9905da339e | ||
|
76de98e07e | ||
|
fa7eaf916f | ||
|
9bd54a6a78 | ||
|
717e40f7f1 | ||
|
6cc687d1fd | ||
|
c67d28ca1b | ||
|
73c9d7bfff | ||
|
4c28600cce | ||
|
6d48b069c2 | ||
|
57d482aa50 | ||
|
42477aae45 | ||
|
37b0f3c036 | ||
|
d15bbe86a2 | ||
|
f077d24d48 | ||
|
f258c24258 | ||
|
3251dd6cf2 | ||
|
e39a77855a | ||
|
ee7b6f59ac | ||
|
7b21517bac | ||
|
f6ac07e1cd | ||
|
f7b12d7f82 | ||
|
a9141a6cfe | ||
|
962a75f227 | ||
|
b0686f5e46 | ||
|
d60a03a376 | ||
|
15dfc5ad9f | ||
|
598dc110f8 | ||
|
8e6d8302ef | ||
|
6c4c0afb06 | ||
|
97fe8075a6 | ||
|
8ec1d92b6f | ||
|
b7e1c7af34 | ||
|
e0c8061a8d | ||
|
e7b09fd787 | ||
|
e590113a28 | ||
|
e06e83daba | ||
|
b96ed3113b | ||
|
8c435874ac | ||
|
2f67b9509b | ||
|
7a2385352c | ||
|
1666f96d61 | ||
|
0a82c59cd1 | ||
|
e7a317b896 | ||
|
4e61000e57 | ||
|
48e8a53090 | ||
|
f99930999e | ||
|
f253ba0901 | ||
|
401b92cb52 | ||
|
9e5e75676c | ||
|
a86e28a037 | ||
|
b9a5700a7a | ||
|
d26ac60be5 | ||
|
f6a2da8b8d | ||
|
42ca90a6bc | ||
|
d57e211d0b | ||
|
6eab55ae26 | ||
|
56a203c531 | ||
|
197d847514 | ||
|
e01b707916 | ||
|
0d4378764a | ||
|
d6397880e0 | ||
|
c054d48c38 | ||
|
648c9a9608 | ||
|
27f0557367 | ||
|
54d4e974db | ||
|
cc6ecd4f90 | ||
|
befa5e421c | ||
|
e8f7144b6c | ||
|
2cf5967a42 | ||
|
5359e3b006 | ||
|
900c9d2a02 | ||
|
e6bcba718a | ||
|
2751c88fea | ||
|
6b181f3f57 | ||
|
0030012e17 | ||
|
3d2052d8ff | ||
|
6dcea7fa5e | ||
|
c3d71958ea | ||
|
13023d1f24 | ||
|
00e0f8aa9f | ||
|
1b6d06b033 | ||
|
94170179ea | ||
|
1fc9c2d4ac | ||
|
86fc302fa5 | ||
|
07d61b25b2 | ||
|
2d1757a975 | ||
|
a6151de5be | ||
|
c6698f4070 | ||
|
2150d60baa | ||
|
d0b4dd67e5 | ||
|
66d3eee78d | ||
|
1d6a1634db | ||
|
7430996adc | ||
|
85cd118622 | ||
|
6689c15ce9 | ||
|
29e0671cfe | ||
|
2ad324380e | ||
|
de71e1f544 | ||
|
d87d057de9 | ||
|
f0a4db0a06 | ||
|
efdb5dbe8b | ||
|
610ce40270 | ||
|
2650566f9a | ||
|
4d3f49306e | ||
|
a9a0fd648e | ||
|
9e4c876305 | ||
|
93aa4db3e8 | ||
|
e6ffd04110 | ||
|
aa698565ab | ||
|
63043cb4ec | ||
|
d297cf1cad | ||
|
a143b1edf7 | ||
|
ca3633f64d | ||
|
c4b61562b6 | ||
|
b3d5102ae5 | ||
|
b5a698c904 | ||
|
caf627926e | ||
|
9964c024ec | ||
|
f9fa478b77 | ||
|
7c35aa014e | ||
|
0e243aa4c6 | ||
|
409501cb39 | ||
|
1dacdc4b37 | ||
|
7b309f391b | ||
|
95c95f0f90 | ||
|
5369f893ca | ||
|
dd8d04d273 | ||
|
55101797be | ||
|
8321781c67 | ||
|
3a729f48f8 | ||
|
b48555e2e0 | ||
|
e81ce64881 | ||
|
07eedb370d | ||
|
1410503609 | ||
|
f04171ddb4 | ||
|
3107d000a9 | ||
|
e7a7cba16d | ||
|
4589f72bfa | ||
|
ed84e22910 | ||
|
3667dc319a | ||
|
3a34079aef | ||
|
a98b8fb457 | ||
|
892c7d6171 | ||
|
929b92858c | ||
|
bd31cc22f5 | ||
|
17ba11694c | ||
|
178d60a46d | ||
|
1a881e1e46 | ||
|
c86804db1f | ||
|
c17df16652 | ||
|
5f3e1dcf86 | ||
|
0174b71bcc | ||
|
0bab5d1dce | ||
|
344a03d8d6 | ||
|
b4a64f2a4e | ||
|
a5bc6c50ac | ||
|
fc352bed22 | ||
|
e59eda2b3d | ||
|
5949966461 | ||
|
ae7103cf82 | ||
|
939e63c297 | ||
|
907cb57b9e | ||
|
f3dd00b0e5 | ||
|
8dd46c5576 | ||
|
bd1bb55569 | ||
|
8116b96b9e | ||
|
a5b4833713 | ||
|
751618684b | ||
|
9d744710da | ||
|
27bd3496f1 | ||
|
dac642ba6d | ||
|
491cb97fb1 | ||
|
68bc7ece54 | ||
|
f538bf842f | ||
|
b8f786dc4b | ||
|
a647c6a8d6 | ||
|
ccf67ac3f1 | ||
|
65d5af509e | ||
|
dd2f15d533 | ||
|
ddbc3b164b | ||
|
4a89a8738e | ||
|
bc1939f8a2 | ||
|
68cb6c8530 | ||
|
c97a1fa82e | ||
|
2925ecf419 | ||
|
d35723c34d | ||
|
4db96d2538 | ||
|
11bf5e32d0 | ||
|
8b60cdb6fc | ||
|
55e662be66 | ||
|
ef17cbbbf9 | ||
|
3b8a3c3fd9 | ||
|
bf19bc1102 | ||
|
7e8aa3f5f1 | ||
|
56119c0779 | ||
|
02ea485c08 | ||
|
c454bc1ed8 | ||
|
46c1f7ce49 | ||
|
3f681a08de | ||
|
23a8027222 | ||
|
820c2b0b95 | ||
|
af7a9c03ba | ||
|
bef17bbaf8 | ||
|
587084ffb7 | ||
|
7227de11fd | ||
|
c00f4323bb | ||
|
02b7aedb86 | ||
|
6b32b67344 | ||
|
3176dcad76 | ||
|
01ca90fd86 | ||
|
64816e7e3c | ||
|
fc1abcfede | ||
|
11b10a82d5 | ||
|
37309125ea | ||
|
8a770de016 | ||
|
90615dc04e | ||
|
af737379f8 | ||
|
f9e319bf49 | ||
|
f38eb55010 | ||
|
cd6e018d47 | ||
|
38aa88c658 | ||
|
9777a4f235 | ||
|
5feee0a61a | ||
|
c9c9701e1d | ||
|
6332825980 | ||
|
512a7b9995 | ||
|
1f313de484 | ||
|
30112030d4 | ||
|
7edb06279c | ||
|
7ed0179b91 | ||
|
cda95408d5 | ||
|
4dea809502 | ||
|
a837008f3a | ||
|
911dc7bb47 | ||
|
823b1215e7 | ||
|
b6094584f0 | ||
|
c868fe9900 | ||
|
b48fb90ad4 | ||
|
2f27b13dc0 | ||
|
370804a829 | ||
|
a714cd9c14 | ||
|
b55fa356db | ||
|
f0aad41ea7 | ||
|
a5ab271b59 | ||
|
0f338ec353 | ||
|
90806cb300 | ||
|
0669c01a91 | ||
|
685e690d3a | ||
|
ee8b6d3119 | ||
|
6cbcde05f4 | ||
|
ebda9cf7d5 | ||
|
6af61302f0 | ||
|
c8e535cd7e | ||
|
29ca97e0c1 | ||
|
9e7fd463d4 | ||
|
427038904f | ||
|
ed4d30abe4 | ||
|
f169bbf87b | ||
|
b1e763fdb0 | ||
|
5320c474dd | ||
|
eecac2350e | ||
|
f9c19c6d67 | ||
|
b6537da650 | ||
|
75fe74da53 | ||
|
36b13b8192 | ||
|
99386fc756 | ||
|
b155202714 | ||
|
8251f3fcf7 | ||
|
dc0b329626 | ||
|
e3e7bc6e87 | ||
|
8da1c9d3be | ||
|
61de99e01f | ||
|
1c610c8f01 | ||
|
798d38d1ce | ||
|
34b973e9fe | ||
|
39da3b6742 | ||
|
6591f35a78 | ||
|
f3ff0bdb5b | ||
|
0335c31725 | ||
|
5a5142bf62 | ||
|
8471a3134d | ||
|
86aca10ed5 | ||
|
c48ef9be0e | ||
|
06a473eaec | ||
|
5ebc707cf1 | ||
|
4ac4201af0 | ||
|
ef920646c6 | ||
|
897e9915bc | ||
|
978518c385 | ||
|
176e792137 | ||
|
4aa5e32184 | ||
|
16faa4d98a | ||
|
2fe0f45873 | ||
|
fedf07c5c7 | ||
|
f63c2f9a1a | ||
|
3044969454 | ||
|
333d4e8a95 | ||
|
6cb59f5fea | ||
|
abdbecf26f | ||
|
0f2895c14e | ||
|
9138205ace | ||
|
8aba9d4cc7 | ||
|
c0c5848548 | ||
|
c10a2de7de | ||
|
9609328cf0 | ||
|
3f5a52859f | ||
|
4240a4f4cf | ||
|
4b40c5197a | ||
|
6bef069178 | ||
|
7ce6d93083 | ||
|
dec90cb6ca | ||
|
806841481c | ||
|
51b73fec72 | ||
|
5231b75055 | ||
|
21373e13bc | ||
|
05ed734438 | ||
|
98365a5bde | ||
|
78bda4ba59 | ||
|
35bcdf9e45 | ||
|
a97b21498c | ||
|
0e76083643 | ||
|
af9d4d51dd | ||
|
ff1911360a | ||
|
f30fd5a067 | ||
|
76d97cd646 | ||
|
1850945d34 | ||
|
e6e808b2e8 | ||
|
0e2dd7197d | ||
|
483a8abeae | ||
|
69dbab616f | ||
|
c0b4777462 | ||
|
90811f3e55 | ||
|
085c19cf1b | ||
|
5b40a9392c | ||
|
7c2be605e7 | ||
|
94fae18fcc | ||
|
339789c7c2 | ||
|
3bed8b8527 | ||
|
1965389904 | ||
|
cdb5ede7fe | ||
|
73e42169ec | ||
|
3bd862b4ad | ||
|
9a56ff5bb6 | ||
|
5577e4c1bc | ||
|
ed4c1ad5a0 | ||
|
f41719e432 | ||
|
3c7634e4ea | ||
|
095c2667a0 | ||
|
d5c2b98a05 | ||
|
7bc29b2ea5 | ||
|
4e8593845a | ||
|
17589fceb5 | ||
|
5ad6b58c7f | ||
|
f4d8383ced | ||
|
a4c3e1d0f4 | ||
|
023e206d1c | ||
|
bcd4b0f5f1 | ||
|
21795ebfed | ||
|
c87ac92a04 | ||
|
044e2ae704 | ||
|
9f0522b273 | ||
|
f7cec4d435 | ||
|
ce2ba4f312 | ||
|
05f2276aab | ||
|
a7e4c11885 | ||
|
86dd536e6e | ||
|
715105193c | ||
|
81bb1c9833 | ||
|
342039829e | ||
|
0115e3946b | ||
|
2c85f9e0ff | ||
|
bf42cb95c1 | ||
|
ababe2e80a | ||
|
ab529dc936 | ||
|
0d5ae35661 | ||
|
6b5fc80167 | ||
|
ff7c3ff702 | ||
|
e763281966 | ||
|
1e2c821a25 | ||
|
5a36db7b7f | ||
|
1175e43bfd | ||
|
d8cab10a3d | ||
|
5a45c2b04f | ||
|
5cba6f24cb | ||
|
93a0171940 | ||
|
cae4622bfc | ||
|
47a1e8393c | ||
|
f7f9fc773c | ||
|
f12db983c1 | ||
|
1901035fd8 | ||
|
5d11e98956 | ||
|
2ac6c636a8 | ||
|
1e4ed3155f | ||
|
626072ae69 | ||
|
4295767be7 | ||
|
20dae6e5cb | ||
|
c9438ace31 | ||
|
cc1d11a06c | ||
|
a910fa5c05 | ||
|
5b0c57ce7c | ||
|
a300622bb2 | ||
|
9dc44d8ccc | ||
|
ab3b05752a | ||
|
0f07872659 | ||
|
d1288fd335 | ||
|
82d58e52fa | ||
|
deb6bbfe5e | ||
|
bfd1595ad8 | ||
|
00054c1a52 | ||
|
00c683dd23 | ||
|
bd81bafc84 | ||
|
68298e3c97 | ||
|
5bb06e6c65 | ||
|
c7d3cb6fa4 | ||
|
8e76d0225f | ||
|
1dc2f5580f | ||
|
43cd1e3875 | ||
|
169dcdf5ad | ||
|
023e8266ec | ||
|
d301a9dbe0 | ||
|
b6935673d5 | ||
|
0ea207f539 | ||
|
a0d34cb9b8 | ||
|
72f0154cb4 | ||
|
9ab530f8fb | ||
|
488be4417b | ||
|
3e21bc6522 | ||
|
c21e1fe1a6 | ||
|
7e928c6e42 | ||
|
d03ffd882a | ||
|
c7063930bd | ||
|
45945d9f7f | ||
|
af5c6e46a5 | ||
|
ff8cd6b705 | ||
|
38043d3073 | ||
|
8ead8bd8c5 | ||
|
f3a2aa987b | ||
|
7fa4146a91 | ||
|
48c112ddcf | ||
|
6e1c3b65d3 | ||
|
c7e59daf80 | ||
|
a56d8a0ab8 | ||
|
c405ff1089 | ||
|
7d97c75ef8 | ||
|
be654074d9 | ||
|
563b8b9fc7 | ||
|
c8db23e349 | ||
|
f584f38303 | ||
|
e8366cd84a | ||
|
76edc43aca | ||
|
55a2229bc6 | ||
|
2a321612fc | ||
|
99f8052dd9 | ||
|
d39e17a8f6 | ||
|
ce76bb2190 | ||
|
f88f3e6225 | ||
|
319fd9a2ff | ||
|
2f7e6ccd6f | ||
|
d39c098893 | ||
|
db7be7107c | ||
|
887f7d0dff | ||
|
d385eb8800 | ||
|
092274d11c | ||
|
ce6d2c7e79 | ||
|
1af8650ead | ||
|
be04ea608d | ||
|
7d686132de | ||
|
b52e33a517 | ||
|
d4639e2d70 | ||
|
46dd103f55 | ||
|
7192f90e8e | ||
|
dcc1650dbd | ||
|
13e009b6fc | ||
|
c2e6bb53cd | ||
|
2a8c2ec3ce | ||
|
21b45935a2 | ||
|
c1be65032a | ||
|
0dfc7ee2fb | ||
|
81e7904dff | ||
|
52e2398a1d | ||
|
6566fd7b79 | ||
|
85617735e9 | ||
|
08494f840d | ||
|
d6ab6c676f | ||
|
8ac7217c26 | ||
|
0374a9a099 | ||
|
7e9dc20201 | ||
|
91813c54e8 | ||
|
d1e047a3d2 | ||
|
fb19fd6cc0 | ||
|
51b828d318 | ||
|
6d166b3317 | ||
|
26270d5691 | ||
|
1b4b373343 | ||
|
592f469b8b | ||
|
55827868f9 | ||
|
231ae585bb | ||
|
33895a58e8 | ||
|
be32ed55f5 | ||
|
ef1699e4da | ||
|
eb7af61a08 | ||
|
51f7c5936d | ||
|
acdcaa991e | ||
|
305377c1bb | ||
|
9f9c2af1bd | ||
|
df47be245f | ||
|
1b0cb3f75f | ||
|
dd07acda1d | ||
|
b30504c348 | ||
|
c3e0f94448 | ||
|
f64f00e2d3 | ||
|
85676c5fbf | ||
|
76dfa2a6fc | ||
|
0217c0ecf0 | ||
|
250e8be54c | ||
|
b13f60e80f | ||
|
1635b988a9 | ||
|
aba8d45bd8 | ||
|
05523f7a54 | ||
|
986b36a1f1 | ||
|
74dc37d0d7 | ||
|
b9fde37285 | ||
|
435ce7b248 | ||
|
569275dcba | ||
|
a361789c43 | ||
|
549ce8f0d3 | ||
|
db49e2e210 |
.crowdin.yml
.github
CHANGELOG-HEADER.mdFUNDING.ymlcut-changelog.pldependabot.ymlgen-docs-changelog.pl
.gitignore.gitmodulesAssets.metaProjectRoot
Assets
Packages
ProjectSettings
AudioManager.assetBurstAotSettings_Android.jsonBurstAotSettings_StandaloneWindows.jsonClusterInputManager.assetDynamicsManager.assetEditorBuildSettings.assetEditorSettings.assetGraphicsSettings.assetInputManager.assetNavMeshAreas.assetPackageManagerSettings.asset
manifest-2022.jsonmodular-avatar.sln.DotSettingspackages-lock-2022.jsonvpm-manifest-2019.jsonvpm-manifest-2022.jsonPackages
Physics2DSettings.assetPresetManager.assetProjectSettings.assetProjectVersion.txtQualitySettings.assetTagManager.assetTimeManager.assetUnityConnectSettings.assetVFXManager.assetXRSettings.assetlilToonSetting.jsonworkflows
Assets
CHANGELOG-PRERELEASE-jp.mdCHANGELOG-PRERELEASE-jp.md.metaCHANGELOG-PRERELEASE.mdCHANGELOG-PRERELEASE.md.metaCHANGELOG-jp.mdCHANGELOG-jp.md.metaCHANGELOG.mdCHANGELOG.md.metaCOPYING.mdCOPYING.md.metaEditor.metaEditor
ActiveAnimationRetargeter.csActiveAnimationRetargeter.cs.metaAnimation.meta
Animation
FixupAbsolutePlayAudioPass.csFixupAbsolutePlayAudioPass.cs.metaGameObjectDisableDelayPass.csGameObjectDisableDelayPass.cs.metaMMDRelayPass.csMMDRelayPass.cs.metaReadablePropertyExtension.csReadablePropertyExtension.cs.meta
ApplyAnimatorDefaultValuesPass.csApplyAnimatorDefaultValuesPass.cs.metaAvatarProcessor.csAvatarProcessor.cs.metaBlendshapeSyncAnimationProcessor.csBlendshapeSyncAnimationProcessor.cs.metaBoneProxyProcessor.csBoneProxyProcessor.cs.metaBuildContext.csBuildContext.cs.metaCreateBlendTree.csCreateBlendTree.cs.metaErrorReporting.metaErrorReporting
FixupPasses.metaFixupPasses
HarmonyPatches.metaHarmonyPatches
6
.crowdin.yml
Normal file
6
.crowdin.yml
Normal file
@ -0,0 +1,6 @@
|
||||
base_path: .
|
||||
base_url: 'https://api.crowdin.com'
|
||||
preserve_hierarchy: 1
|
||||
files:
|
||||
- source: /Editor/Localization/en-US.json
|
||||
translation: /Editor/Localization/%locale%.json
|
14
.github/CHANGELOG-HEADER.md
vendored
Normal file
14
.github/CHANGELOG-HEADER.md
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
### Fixed
|
||||
|
||||
### Changed
|
||||
|
||||
### Removed
|
||||
|
||||
### Security
|
||||
|
||||
### Deprecated
|
||||
|
14
.github/FUNDING.yml
vendored
Normal file
14
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [bdunderscore]
|
||||
# patreon: # Replace with a single Patreon username
|
||||
# open_collective: # Replace with a single Open Collective username
|
||||
# ko_fi: # Replace with a single Ko-fi username
|
||||
# tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
# community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
# liberapay: # Replace with a single Liberapay username
|
||||
# issuehunt: # Replace with a single IssueHunt username
|
||||
# lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
# polar: # Replace with a single Polar username
|
||||
# buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
|
||||
# custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
@ -2,3 +2,5 @@
|
||||
!com.vrchat.core.*/
|
||||
com.vrchat.*/
|
||||
!nadena.dev.*/
|
||||
nadena.dev.ndmf/
|
||||
*.zip
|
@ -4,12 +4,15 @@
|
||||
"com.unity.ide.rider": "3.0.17",
|
||||
"com.unity.ide.visualstudio": "2.0.17",
|
||||
"com.unity.ide.vscode": "1.2.5",
|
||||
"com.unity.test-framework": "1.1.33",
|
||||
"com.unity.test-framework": "1.3.2",
|
||||
"com.unity.testtools.codecoverage": "1.2.2",
|
||||
"com.unity.textmeshpro": "2.1.6",
|
||||
"com.unity.timeline": "1.2.18",
|
||||
"com.unity.ugui": "1.0.0",
|
||||
"com.unity.xr.oculus.android": "2.38.6",
|
||||
"com.unity.xr.oculus.standalone": "2.38.4",
|
||||
"com.unity.xr.openvr.standalone": "2.0.5",
|
||||
"de.thryrallo.vrc.avatar-performance-tools": "https://github.com/Thryrallo/VRC-Avatar-Performance-Tools.git",
|
||||
"nadena.dev.modular-avatar": "0.0.1",
|
||||
"com.unity.modules.ai": "1.0.0",
|
||||
"com.unity.modules.androidjni": "1.0.0",
|
@ -17,7 +17,7 @@
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.ext.nunit": {
|
||||
"version": "1.0.6",
|
||||
"version": "2.0.3",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
@ -56,23 +56,49 @@
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.nuget.newtonsoft-json": {
|
||||
"version": "2.0.2",
|
||||
"version": "3.0.2",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.postprocessing": {
|
||||
"version": "3.1.1",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.modules.physics": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.settings-manager": {
|
||||
"version": "1.0.1",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.test-framework": {
|
||||
"version": "1.1.33",
|
||||
"version": "1.3.2",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.ext.nunit": "1.0.6",
|
||||
"com.unity.ext.nunit": "2.0.3",
|
||||
"com.unity.modules.imgui": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.testtools.codecoverage": {
|
||||
"version": "1.2.2",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.test-framework": "1.0.16",
|
||||
"com.unity.settings-manager": "1.0.1"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.textmeshpro": {
|
||||
"version": "2.1.6",
|
||||
"depth": 0,
|
||||
@ -103,6 +129,13 @@
|
||||
"com.unity.modules.imgui": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.xr.oculus.android": {
|
||||
"version": "2.38.6",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.xr.oculus.standalone": {
|
||||
"version": "2.38.4",
|
||||
"depth": 0,
|
||||
@ -130,17 +163,42 @@
|
||||
"dependencies": {
|
||||
"com.unity.burst": "1.4.11",
|
||||
"com.unity.mathematics": "1.2.5",
|
||||
"com.unity.nuget.newtonsoft-json": "2.0.2"
|
||||
"com.unity.nuget.newtonsoft-json": "3.0.2"
|
||||
}
|
||||
},
|
||||
"com.vrchat.core.vpm-resolver": {
|
||||
"version": "file:com.vrchat.core.vpm-resolver",
|
||||
"de.thryrallo.vrc.avatar-performance-tools": {
|
||||
"version": "https://github.com/Thryrallo/VRC-Avatar-Performance-Tools.git",
|
||||
"depth": 0,
|
||||
"source": "git",
|
||||
"dependencies": {},
|
||||
"hash": "ba9c16e482e7a376db18e9a85e24fabc04649d37"
|
||||
},
|
||||
"dev.onevr.vrworldtoolkit": {
|
||||
"version": "file:dev.onevr.vrworldtoolkit",
|
||||
"depth": 0,
|
||||
"source": "embedded",
|
||||
"dependencies": {
|
||||
"com.unity.nuget.newtonsoft-json": "2.0.2"
|
||||
"com.unity.postprocessing": "3.1.1"
|
||||
}
|
||||
},
|
||||
"jp.lilxyzw.liltoon": {
|
||||
"version": "file:jp.lilxyzw.liltoon",
|
||||
"depth": 0,
|
||||
"source": "embedded",
|
||||
"dependencies": {}
|
||||
},
|
||||
"jp.suzuryg.face-emo": {
|
||||
"version": "file:jp.suzuryg.face-emo",
|
||||
"depth": 0,
|
||||
"source": "embedded",
|
||||
"dependencies": {}
|
||||
},
|
||||
"lyuma.av3emulator": {
|
||||
"version": "file:lyuma.av3emulator",
|
||||
"depth": 0,
|
||||
"source": "embedded",
|
||||
"dependencies": {}
|
||||
},
|
||||
"nadena.dev.modular-avatar": {
|
||||
"version": "file:nadena.dev.modular-avatar",
|
||||
"depth": 0,
|
||||
@ -149,6 +207,18 @@
|
||||
"com.unity.nuget.newtonsoft-json": "2.0.0"
|
||||
}
|
||||
},
|
||||
"nadena.dev.ndmf": {
|
||||
"version": "file:nadena.dev.ndmf",
|
||||
"depth": 0,
|
||||
"source": "embedded",
|
||||
"dependencies": {}
|
||||
},
|
||||
"vrchat.blackstartx.gesture-manager": {
|
||||
"version": "file:vrchat.blackstartx.gesture-manager",
|
||||
"depth": 0,
|
||||
"source": "embedded",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.ai": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
0
ProjectSettings/AudioManager.asset → .github/ProjectRoot/ProjectSettings/AudioManager.asset
vendored
0
ProjectSettings/AudioManager.asset → .github/ProjectRoot/ProjectSettings/AudioManager.asset
vendored
13
.github/ProjectRoot/ProjectSettings/BurstAotSettings_Android.json
vendored
Normal file
13
.github/ProjectRoot/ProjectSettings/BurstAotSettings_Android.json
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"MonoBehaviour": {
|
||||
"Version": 3,
|
||||
"EnableBurstCompilation": true,
|
||||
"EnableOptimisations": true,
|
||||
"EnableSafetyChecks": false,
|
||||
"EnableDebugInAllBuilds": false,
|
||||
"CpuMinTargetX32": 0,
|
||||
"CpuMaxTargetX32": 0,
|
||||
"CpuMinTargetX64": 0,
|
||||
"CpuMaxTargetX64": 0
|
||||
}
|
||||
}
|
16
.github/ProjectRoot/ProjectSettings/BurstAotSettings_StandaloneWindows.json
vendored
Normal file
16
.github/ProjectRoot/ProjectSettings/BurstAotSettings_StandaloneWindows.json
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"MonoBehaviour": {
|
||||
"Version": 3,
|
||||
"EnableBurstCompilation": true,
|
||||
"EnableOptimisations": true,
|
||||
"EnableSafetyChecks": false,
|
||||
"EnableDebugInAllBuilds": false,
|
||||
"UsePlatformSDKLinker": false,
|
||||
"CpuMinTargetX32": 0,
|
||||
"CpuMaxTargetX32": 0,
|
||||
"CpuMinTargetX64": 0,
|
||||
"CpuMaxTargetX64": 0,
|
||||
"CpuTargetsX32": 6,
|
||||
"CpuTargetsX64": 72
|
||||
}
|
||||
}
|
0
ProjectSettings/DynamicsManager.asset → .github/ProjectRoot/ProjectSettings/DynamicsManager.asset
vendored
0
ProjectSettings/DynamicsManager.asset → .github/ProjectRoot/ProjectSettings/DynamicsManager.asset
vendored
2
ProjectSettings/EditorSettings.asset → .github/ProjectRoot/ProjectSettings/EditorSettings.asset
vendored
2
ProjectSettings/EditorSettings.asset → .github/ProjectRoot/ProjectSettings/EditorSettings.asset
vendored
@ -23,7 +23,7 @@ EditorSettings:
|
||||
m_EnableTextureStreamingInEditMode: 1
|
||||
m_EnableTextureStreamingInPlayMode: 1
|
||||
m_AsyncShaderCompilation: 1
|
||||
m_EnterPlayModeOptionsEnabled: 0
|
||||
m_EnterPlayModeOptionsEnabled: 1
|
||||
m_EnterPlayModeOptions: 3
|
||||
m_ShowLightmapResolutionOverlay: 1
|
||||
m_UseLegacyProbeSampleCount: 0
|
11
ProjectSettings/GraphicsSettings.asset → .github/ProjectRoot/ProjectSettings/GraphicsSettings.asset
vendored
11
ProjectSettings/GraphicsSettings.asset → .github/ProjectRoot/ProjectSettings/GraphicsSettings.asset
vendored
@ -28,16 +28,7 @@ GraphicsSettings:
|
||||
m_LensFlare:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_AlwaysIncludedShaders:
|
||||
- {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 16001, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_AlwaysIncludedShaders: []
|
||||
m_PreloadedShaders: []
|
||||
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
|
||||
type: 0}
|
0
ProjectSettings/InputManager.asset → .github/ProjectRoot/ProjectSettings/InputManager.asset
vendored
0
ProjectSettings/InputManager.asset → .github/ProjectRoot/ProjectSettings/InputManager.asset
vendored
0
ProjectSettings/NavMeshAreas.asset → .github/ProjectRoot/ProjectSettings/NavMeshAreas.asset
vendored
0
ProjectSettings/NavMeshAreas.asset → .github/ProjectRoot/ProjectSettings/NavMeshAreas.asset
vendored
7
.github/ProjectRoot/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json
vendored
Normal file
7
.github/ProjectRoot/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"m_Name": "Settings",
|
||||
"m_Path": "ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json",
|
||||
"m_Dictionary": {
|
||||
"m_DictionaryValues": []
|
||||
}
|
||||
}
|
0
ProjectSettings/PresetManager.asset → .github/ProjectRoot/ProjectSettings/PresetManager.asset
vendored
0
ProjectSettings/PresetManager.asset → .github/ProjectRoot/ProjectSettings/PresetManager.asset
vendored
40
ProjectSettings/ProjectSettings.asset → .github/ProjectRoot/ProjectSettings/ProjectSettings.asset
vendored
40
ProjectSettings/ProjectSettings.asset → .github/ProjectRoot/ProjectSettings/ProjectSettings.asset
vendored
@ -176,7 +176,7 @@ PlayerSettings:
|
||||
applicationIdentifier: {}
|
||||
buildNumber: {}
|
||||
AndroidBundleVersionCode: 1
|
||||
AndroidMinSdkVersion: 19
|
||||
AndroidMinSdkVersion: 25
|
||||
AndroidTargetSdkVersion: 0
|
||||
AndroidPreferredInstallLocation: 1
|
||||
aotOptions:
|
||||
@ -184,7 +184,7 @@ PlayerSettings:
|
||||
iPhoneStrippingLevel: 0
|
||||
iPhoneScriptCallOptimization: 0
|
||||
ForceInternetPermission: 0
|
||||
ForceSDCardPermission: 0
|
||||
ForceSDCardPermission: 1
|
||||
CreateWallpaper: 0
|
||||
APKExpansionFiles: 0
|
||||
keepLoadedShadersAlive: 0
|
||||
@ -250,7 +250,7 @@ PlayerSettings:
|
||||
clonedFromGUID: c0afd0d1d80e3634a9dac47e8a0426ea
|
||||
templatePackageId: com.vrchat.template.base@1.0.0
|
||||
templateDefaultScene: Assets/VRCWelcome.unity
|
||||
AndroidTargetArchitectures: 1
|
||||
AndroidTargetArchitectures: 2
|
||||
AndroidTargetDevices: 0
|
||||
AndroidSplashScreenScale: 0
|
||||
androidSplashScreen: {fileID: 0}
|
||||
@ -313,7 +313,7 @@ PlayerSettings:
|
||||
- m_BuildTarget: LuminSupport
|
||||
m_GraphicsJobs: 0
|
||||
- m_BuildTarget: AndroidPlayer
|
||||
m_GraphicsJobs: 0
|
||||
m_GraphicsJobs: 1
|
||||
- m_BuildTarget: WebGLSupport
|
||||
m_GraphicsJobs: 0
|
||||
m_BuildTargetGraphicsJobMode:
|
||||
@ -327,7 +327,7 @@ PlayerSettings:
|
||||
m_Automatic: 0
|
||||
- m_BuildTarget: iOSSupport
|
||||
m_APIs: 10000000
|
||||
m_Automatic: 1
|
||||
m_Automatic: 0
|
||||
- m_BuildTarget: AppleTVSupport
|
||||
m_APIs: 10000000
|
||||
m_Automatic: 0
|
||||
@ -337,6 +337,9 @@ PlayerSettings:
|
||||
- m_BuildTarget: WindowsStandaloneSupport
|
||||
m_APIs: 02000000
|
||||
m_Automatic: 0
|
||||
- m_BuildTarget: MacStandaloneSupport
|
||||
m_APIs: 10000000
|
||||
m_Automatic: 0
|
||||
m_BuildTargetVRSettings:
|
||||
- m_BuildTarget: Standalone
|
||||
m_Enabled: 1
|
||||
@ -344,6 +347,12 @@ PlayerSettings:
|
||||
- None
|
||||
- OpenVR
|
||||
- Oculus
|
||||
- m_BuildTarget: Android
|
||||
m_Enabled: 1
|
||||
m_Devices:
|
||||
- None
|
||||
- OpenVR
|
||||
- Oculus
|
||||
openGLRequireES31: 0
|
||||
openGLRequireES31AEP: 0
|
||||
openGLRequireES32: 0
|
||||
@ -619,20 +628,35 @@ PlayerSettings:
|
||||
webGLThreadsSupport: 0
|
||||
webGLWasmStreaming: 0
|
||||
scriptingDefineSymbols:
|
||||
1: VRC_SDK_VRCSDK3
|
||||
1: VRC_SDK_VRCSDK3;UNITY_POST_PROCESSING_STACK_V2
|
||||
7: UNITY_POST_PROCESSING_STACK_V2;VRC_SDK_VRCSDK3
|
||||
13: UNITY_POST_PROCESSING_STACK_V2
|
||||
14: UNITY_POST_PROCESSING_STACK_V2
|
||||
19: UNITY_POST_PROCESSING_STACK_V2
|
||||
21: UNITY_POST_PROCESSING_STACK_V2
|
||||
25: UNITY_POST_PROCESSING_STACK_V2
|
||||
27: UNITY_POST_PROCESSING_STACK_V2
|
||||
28: UNITY_POST_PROCESSING_STACK_V2
|
||||
29: UNITY_POST_PROCESSING_STACK_V2
|
||||
30: UNITY_POST_PROCESSING_STACK_V2
|
||||
32: UNITY_POST_PROCESSING_STACK_V2
|
||||
33: UNITY_POST_PROCESSING_STACK_V2
|
||||
platformArchitecture: {}
|
||||
scriptingBackend: {}
|
||||
il2cppCompilerConfiguration: {}
|
||||
il2cppCompilerConfiguration:
|
||||
Android: 1
|
||||
Standalone: 1
|
||||
managedStrippingLevel: {}
|
||||
incrementalIl2cppBuild: {}
|
||||
suppressCommonWarnings: 1
|
||||
allowUnsafeCode: 0
|
||||
additionalIl2CppArgs:
|
||||
additionalIl2CppArgs: --compiler-flags="" --linker-flags=""
|
||||
scriptingRuntimeVersion: 1
|
||||
gcIncremental: 1
|
||||
assemblyVersionValidation: 1
|
||||
gcWBarrierValidation: 0
|
||||
apiCompatibilityLevelPerPlatform:
|
||||
Android: 3
|
||||
Standalone: 3
|
||||
m_RenderingPath: 1
|
||||
m_MobileRenderingPath: 1
|
0
ProjectSettings/ProjectVersion.txt → .github/ProjectRoot/ProjectSettings/ProjectVersion.txt
vendored
0
ProjectSettings/ProjectVersion.txt → .github/ProjectRoot/ProjectSettings/ProjectVersion.txt
vendored
43
ProjectSettings/QualitySettings.asset → .github/ProjectRoot/ProjectSettings/QualitySettings.asset
vendored
43
ProjectSettings/QualitySettings.asset → .github/ProjectRoot/ProjectSettings/QualitySettings.asset
vendored
@ -4,13 +4,13 @@
|
||||
QualitySettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 5
|
||||
m_CurrentQuality: 3
|
||||
m_CurrentQuality: 2
|
||||
m_QualitySettings:
|
||||
- serializedVersion: 2
|
||||
name: VRC Low
|
||||
pixelLightCount: 4
|
||||
shadows: 2
|
||||
shadowResolution: 2
|
||||
shadowResolution: 1
|
||||
shadowProjection: 1
|
||||
shadowCascades: 2
|
||||
shadowDistance: 75
|
||||
@ -58,7 +58,7 @@ QualitySettings:
|
||||
skinWeights: 4
|
||||
textureQuality: 0
|
||||
anisotropicTextures: 2
|
||||
antiAliasing: 4
|
||||
antiAliasing: 2
|
||||
softParticles: 1
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 1
|
||||
@ -86,43 +86,6 @@ QualitySettings:
|
||||
shadows: 2
|
||||
shadowResolution: 3
|
||||
shadowProjection: 1
|
||||
shadowCascades: 2
|
||||
shadowDistance: 75
|
||||
shadowNearPlaneOffset: 2
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 0
|
||||
skinWeights: 4
|
||||
textureQuality: 0
|
||||
anisotropicTextures: 2
|
||||
antiAliasing: 4
|
||||
softParticles: 1
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 1
|
||||
billboardsFaceCameraPosition: 1
|
||||
vSyncCount: 0
|
||||
lodBias: 2
|
||||
maximumLODLevel: 0
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
streamingMipmapsRenderersPerFrame: 512
|
||||
streamingMipmapsMaxLevelReduction: 2
|
||||
streamingMipmapsMaxFileIORequests: 1024
|
||||
particleRaycastBudget: 4096
|
||||
asyncUploadTimeSlice: 2
|
||||
asyncUploadBufferSize: 128
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
excludedTargetPlatforms:
|
||||
- Android
|
||||
- serializedVersion: 2
|
||||
name: VRC Ultra
|
||||
pixelLightCount: 8
|
||||
shadows: 2
|
||||
shadowResolution: 3
|
||||
shadowProjection: 1
|
||||
shadowCascades: 4
|
||||
shadowDistance: 150
|
||||
shadowNearPlaneOffset: 2
|
0
ProjectSettings/TimeManager.asset → .github/ProjectRoot/ProjectSettings/TimeManager.asset
vendored
0
ProjectSettings/TimeManager.asset → .github/ProjectRoot/ProjectSettings/TimeManager.asset
vendored
0
ProjectSettings/lilToonSetting.json → .github/ProjectRoot/ProjectSettings/lilToonSetting.json
vendored
0
ProjectSettings/lilToonSetting.json → .github/ProjectRoot/ProjectSettings/lilToonSetting.json
vendored
44
.github/ProjectRoot/manifest-2022.json
vendored
Normal file
44
.github/ProjectRoot/manifest-2022.json
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"com.unity.ai.navigation": "1.1.4",
|
||||
"com.unity.collab-proxy": "2.0.5",
|
||||
"com.unity.ide.rider": "3.0.24",
|
||||
"com.unity.ide.visualstudio": "2.0.18",
|
||||
"com.unity.ide.vscode": "1.2.5",
|
||||
"com.unity.test-framework": "1.1.33",
|
||||
"com.unity.textmeshpro": "3.0.6",
|
||||
"com.unity.timeline": "1.7.5",
|
||||
"com.unity.ugui": "1.0.0",
|
||||
"com.unity.modules.ai": "1.0.0",
|
||||
"com.unity.modules.androidjni": "1.0.0",
|
||||
"com.unity.modules.animation": "1.0.0",
|
||||
"com.unity.modules.assetbundle": "1.0.0",
|
||||
"com.unity.modules.audio": "1.0.0",
|
||||
"com.unity.modules.cloth": "1.0.0",
|
||||
"com.unity.modules.director": "1.0.0",
|
||||
"com.unity.modules.imageconversion": "1.0.0",
|
||||
"com.unity.modules.imgui": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0",
|
||||
"com.unity.modules.particlesystem": "1.0.0",
|
||||
"com.unity.modules.physics": "1.0.0",
|
||||
"com.unity.modules.physics2d": "1.0.0",
|
||||
"com.unity.modules.screencapture": "1.0.0",
|
||||
"com.unity.modules.terrain": "1.0.0",
|
||||
"com.unity.modules.terrainphysics": "1.0.0",
|
||||
"com.unity.modules.tilemap": "1.0.0",
|
||||
"com.unity.modules.ui": "1.0.0",
|
||||
"com.unity.modules.uielements": "1.0.0",
|
||||
"com.unity.modules.umbra": "1.0.0",
|
||||
"com.unity.modules.unityanalytics": "1.0.0",
|
||||
"com.unity.modules.unitywebrequest": "1.0.0",
|
||||
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
|
||||
"com.unity.modules.unitywebrequestaudio": "1.0.0",
|
||||
"com.unity.modules.unitywebrequesttexture": "1.0.0",
|
||||
"com.unity.modules.unitywebrequestwww": "1.0.0",
|
||||
"com.unity.modules.vehicles": "1.0.0",
|
||||
"com.unity.modules.video": "1.0.0",
|
||||
"com.unity.modules.vr": "1.0.0",
|
||||
"com.unity.modules.wind": "1.0.0",
|
||||
"com.unity.modules.xr": "1.0.0"
|
||||
}
|
||||
}
|
4
.github/ProjectRoot/modular-avatar.sln.DotSettings
vendored
Normal file
4
.github/ProjectRoot/modular-avatar.sln.DotSettings
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=blendshape/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Blendshapes/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=nadena/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
397
.github/ProjectRoot/packages-lock-2022.json
vendored
Normal file
397
.github/ProjectRoot/packages-lock-2022.json
vendored
Normal file
@ -0,0 +1,397 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"com.unity.ai.navigation": {
|
||||
"version": "1.1.4",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.modules.ai": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.burst": {
|
||||
"version": "1.8.7",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.mathematics": "1.2.1"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.collab-proxy": {
|
||||
"version": "2.0.5",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.ext.nunit": {
|
||||
"version": "1.0.6",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.ide.rider": {
|
||||
"version": "3.0.24",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.ext.nunit": "1.0.6"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.ide.visualstudio": {
|
||||
"version": "2.0.18",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.test-framework": "1.1.9"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.ide.vscode": {
|
||||
"version": "1.2.5",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.mathematics": {
|
||||
"version": "1.2.6",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.nuget.newtonsoft-json": {
|
||||
"version": "3.2.1",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.test-framework": {
|
||||
"version": "1.1.33",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.ext.nunit": "1.0.6",
|
||||
"com.unity.modules.imgui": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.textmeshpro": {
|
||||
"version": "3.0.6",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.ugui": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.timeline": {
|
||||
"version": "1.7.5",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.modules.director": "1.0.0",
|
||||
"com.unity.modules.animation": "1.0.0",
|
||||
"com.unity.modules.audio": "1.0.0",
|
||||
"com.unity.modules.particlesystem": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.ugui": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.ui": "1.0.0",
|
||||
"com.unity.modules.imgui": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.vrchat.avatars": {
|
||||
"version": "file:com.vrchat.avatars",
|
||||
"depth": 0,
|
||||
"source": "embedded",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.vrchat.base": {
|
||||
"version": "file:com.vrchat.base",
|
||||
"depth": 0,
|
||||
"source": "embedded",
|
||||
"dependencies": {
|
||||
"com.unity.burst": "1.4.11",
|
||||
"com.unity.mathematics": "1.2.5",
|
||||
"com.unity.nuget.newtonsoft-json": "3.0.2"
|
||||
}
|
||||
},
|
||||
"com.vrchat.core.vpm-resolver": {
|
||||
"version": "file:com.vrchat.core.vpm-resolver",
|
||||
"depth": 0,
|
||||
"source": "embedded",
|
||||
"dependencies": {
|
||||
"com.unity.nuget.newtonsoft-json": "3.0.2"
|
||||
}
|
||||
},
|
||||
"jp.lilxyzw.liltoon": {
|
||||
"version": "file:jp.lilxyzw.liltoon",
|
||||
"depth": 0,
|
||||
"source": "embedded",
|
||||
"dependencies": {}
|
||||
},
|
||||
"nadena.dev.modular-avatar": {
|
||||
"version": "file:nadena.dev.modular-avatar",
|
||||
"depth": 0,
|
||||
"source": "embedded",
|
||||
"dependencies": {
|
||||
"com.unity.nuget.newtonsoft-json": "2.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.ai": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.androidjni": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.animation": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.assetbundle": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.audio": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.cloth": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.physics": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.director": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.audio": "1.0.0",
|
||||
"com.unity.modules.animation": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.imageconversion": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.imgui": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.jsonserialize": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.particlesystem": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.physics": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.physics2d": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.screencapture": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.imageconversion": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.subsystems": {
|
||||
"version": "1.0.0",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.terrain": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.terrainphysics": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.physics": "1.0.0",
|
||||
"com.unity.modules.terrain": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.tilemap": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.physics2d": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.ui": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.uielements": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.ui": "1.0.0",
|
||||
"com.unity.modules.imgui": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.umbra": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.unityanalytics": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.unitywebrequest": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.unitywebrequest": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.unitywebrequestassetbundle": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.assetbundle": "1.0.0",
|
||||
"com.unity.modules.unitywebrequest": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.unitywebrequestaudio": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.unitywebrequest": "1.0.0",
|
||||
"com.unity.modules.audio": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.unitywebrequesttexture": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.unitywebrequest": "1.0.0",
|
||||
"com.unity.modules.imageconversion": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.unitywebrequestwww": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.unitywebrequest": "1.0.0",
|
||||
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
|
||||
"com.unity.modules.unitywebrequestaudio": "1.0.0",
|
||||
"com.unity.modules.audio": "1.0.0",
|
||||
"com.unity.modules.assetbundle": "1.0.0",
|
||||
"com.unity.modules.imageconversion": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.vehicles": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.physics": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.video": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.audio": "1.0.0",
|
||||
"com.unity.modules.ui": "1.0.0",
|
||||
"com.unity.modules.unitywebrequest": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.vr": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.jsonserialize": "1.0.0",
|
||||
"com.unity.modules.physics": "1.0.0",
|
||||
"com.unity.modules.xr": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.modules.wind": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.xr": {
|
||||
"version": "1.0.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.physics": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0",
|
||||
"com.unity.modules.subsystems": "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
.github/ProjectRoot/vpm-manifest-2019.json
vendored
Normal file
25
.github/ProjectRoot/vpm-manifest-2019.json
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"com.vrchat.avatars": {
|
||||
"version": "3.4.2"
|
||||
},
|
||||
"nadena.dev.ndmf": {
|
||||
"version": "1.4.0"
|
||||
}
|
||||
},
|
||||
"locked": {
|
||||
"com.vrchat.avatars": {
|
||||
"version": "3.4.2",
|
||||
"dependencies": {
|
||||
"com.vrchat.base": "3.4.2"
|
||||
}
|
||||
},
|
||||
"com.vrchat.base": {
|
||||
"version": "3.4.2",
|
||||
"dependencies": {}
|
||||
},
|
||||
"nadena.dev.ndmf": {
|
||||
"version": "1.4.0"
|
||||
}
|
||||
}
|
||||
}
|
25
.github/ProjectRoot/vpm-manifest-2022.json
vendored
Normal file
25
.github/ProjectRoot/vpm-manifest-2022.json
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"com.vrchat.avatars": {
|
||||
"version": "3.7.4"
|
||||
},
|
||||
"nadena.dev.ndmf": {
|
||||
"version": "1.8.0-alpha.4"
|
||||
}
|
||||
},
|
||||
"locked": {
|
||||
"com.vrchat.avatars": {
|
||||
"version": "3.7.4",
|
||||
"dependencies": {
|
||||
"com.vrchat.base": "3.7.4"
|
||||
}
|
||||
},
|
||||
"com.vrchat.base": {
|
||||
"version": "3.7.4",
|
||||
"dependencies": {}
|
||||
},
|
||||
"nadena.dev.ndmf": {
|
||||
"version": "1.8.0-alpha.4"
|
||||
}
|
||||
}
|
||||
}
|
71
.github/cut-changelog.pl
vendored
Executable file
71
.github/cut-changelog.pl
vendored
Executable file
@ -0,0 +1,71 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my ($changelog_file, $header_file, $version, $excerpt_file) = @ARGV;
|
||||
|
||||
open my $changelog, '<', $changelog_file or die "Can't open $changelog_file: $!";
|
||||
open my $header, '<', $header_file or die "Can't open $header_file: $!";
|
||||
open my $new_changelog, '>', "$changelog_file.new" or die "Can't open $changelog_file.new: $!";
|
||||
|
||||
if (!$excerpt_file) {
|
||||
$excerpt_file = '/dev/null';
|
||||
}
|
||||
|
||||
open my $excerpt, '>', $excerpt_file or die "Can't open $excerpt_file: $!";
|
||||
|
||||
# Copy all lines before the first "## "
|
||||
while (my $line = <$changelog>) {
|
||||
last if $line =~ /^## /;
|
||||
print $new_changelog $line;
|
||||
}
|
||||
|
||||
# Copy header into the output changelog
|
||||
while (my $line = <$header>) {
|
||||
print $new_changelog $line;
|
||||
}
|
||||
|
||||
# Generate new header: ## [version] - [YYYY-mm-DD]
|
||||
|
||||
my $date = `date +%Y-%m-%d`;
|
||||
chomp $date;
|
||||
|
||||
print $new_changelog "## [$version] - [$date]\n";
|
||||
|
||||
# Copy all lines until the next ## into both the new changelog and $excerpt.
|
||||
# Prune any ###-sections that contain no content
|
||||
|
||||
my @buffered;
|
||||
|
||||
while (my $line = <$changelog>) {
|
||||
if ($line =~ /^### /) {
|
||||
@buffered = ($line);
|
||||
} elsif ($line =~ /^\s*$/) {
|
||||
if (@buffered) {
|
||||
push @buffered, $line;
|
||||
} else {
|
||||
print $new_changelog $line;
|
||||
print $excerpt $line;
|
||||
}
|
||||
} elsif ($line =~ /^## /) {
|
||||
@buffered = ();
|
||||
print $new_changelog $line;
|
||||
last;
|
||||
} else {
|
||||
for my $buffered_line (@buffered){
|
||||
print $new_changelog $buffered_line;
|
||||
print $excerpt $buffered_line;
|
||||
}
|
||||
@buffered = ();
|
||||
print $new_changelog $line;
|
||||
print $excerpt $line;
|
||||
}
|
||||
}
|
||||
|
||||
# Copy remainder of changelog into new changelog
|
||||
while (my $line = <$changelog>) {
|
||||
print $new_changelog $line;
|
||||
}
|
||||
|
||||
rename "$changelog_file.new", $changelog_file or die "Can't rename $changelog_file.new to $changelog_file: $!";
|
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
@ -9,3 +9,7 @@ updates:
|
||||
directory: "/docs" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "github-actions"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
directory: .github/workflows
|
||||
|
22
.github/gen-docs-changelog.pl
vendored
Executable file
22
.github/gen-docs-changelog.pl
vendored
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# We want to skip two sections - the main header, then up to the first version header.
|
||||
# In a prerelease, we only want to skip the first section (not including the unreleased header)
|
||||
|
||||
if ($ENV{PRERELEASE} eq 'false') {
|
||||
while (<>) {
|
||||
if (/^\## /) { last; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while (<>) {
|
||||
if (/^## /) { print; last; }
|
||||
}
|
||||
|
||||
while (<>) {
|
||||
print;
|
||||
}
|
81
.github/workflows/build-release.yml
vendored
81
.github/workflows/build-release.yml
vendored
@ -1,81 +0,0 @@
|
||||
name: Build Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags:
|
||||
- '**'
|
||||
|
||||
env:
|
||||
packageName: "nadena.dev.modular-avatar"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Checkout logo assets
|
||||
uses: actions/checkout@v3
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
repository: bdunderscore/modular-avatar-images
|
||||
path: image-assets
|
||||
- name: Inject logo assets
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
cp -f image-assets/img/logo/ma_logo.png Packages/${{env.packageName}}/Editor/Images/logo.png
|
||||
|
||||
- name: get version
|
||||
id: version
|
||||
uses: notiz-dev/github-action-json-property@7c8cf5cc36eb85d8d287a8086a39dac59628eb31
|
||||
with:
|
||||
path: "Packages/${{env.packageName}}/package.json"
|
||||
prop_path: "version"
|
||||
|
||||
- name: Check tag consistency
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
if [ "${{ steps.version.outputs.prop }}" != "${GITHUB_REF##*/}" ]; then
|
||||
echo "Version in package.json does not match tag name: ${{ steps.version.outputs.prop }} != ${GITHUB_REF##*/}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- run: echo ${{steps.version.outputs.prop}}
|
||||
|
||||
- name: Set Environment Variables
|
||||
run: |
|
||||
echo "zipFile=${{ env.packageName }}-${{ steps.version.outputs.prop }}".zip >> $GITHUB_ENV
|
||||
echo "unityPackage=${{ env.packageName }}-${{ steps.version.outputs.prop }}.unitypackage" >> $GITHUB_ENV
|
||||
|
||||
- name: Create Zip
|
||||
uses: thedoctor0/zip-release@09336613be18a8208dfa66bd57efafd9e2685657
|
||||
with:
|
||||
type: "zip"
|
||||
directory: "Packages/${{env.packageName}}/"
|
||||
filename: "../../${{env.zipFile}}" # make the zip file two directories up, since we start two directories in above
|
||||
|
||||
- run: find "Packages/${{env.packageName}}/" -name \*.meta >> metaList
|
||||
|
||||
- name: Create UnityPackage
|
||||
uses: pCYSl5EDgo/create-unitypackage@e28c7a4616b2754c564b0a959a03b3c89b756fdb
|
||||
with:
|
||||
package-path: ${{ env.unityPackage }}
|
||||
include-files: metaList
|
||||
|
||||
- name: Make Release
|
||||
uses: softprops/action-gh-release@1e07f4398721186383de40550babbdf2b84acfc5
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
draft: true
|
||||
generate_release_notes: true
|
||||
tag_name: ${{ steps.version.outputs.prop }}
|
||||
files: |
|
||||
${{ env.zipFile }}
|
||||
${{ env.unityPackage }}
|
||||
Packages/${{ env.packageName }}/package.json
|
94
.github/workflows/build-test-docs.yml
vendored
94
.github/workflows/build-test-docs.yml
vendored
@ -1,34 +1,108 @@
|
||||
name: Build documentation
|
||||
name: Build documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- refactor-structure
|
||||
pull_request:
|
||||
workflow_call:
|
||||
inputs:
|
||||
ref:
|
||||
description: 'commit to build'
|
||||
type: string
|
||||
required: false
|
||||
path:
|
||||
description: 'path within the docs pages to build to'
|
||||
type: string
|
||||
required: false
|
||||
artifact:
|
||||
description: 'artifact name to write'
|
||||
type: string
|
||||
required: false
|
||||
latest:
|
||||
description: 'build the latest release'
|
||||
type: boolean
|
||||
required: false
|
||||
prerelease:
|
||||
description: 'use prerelease changelog'
|
||||
type: boolean
|
||||
required: false
|
||||
default: true
|
||||
|
||||
jobs:
|
||||
build-docs:
|
||||
name: Build documentation
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
- uses: actions/checkout@v3 # check out this repo
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.ref || github.ref }}
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
repository: bdunderscore/modular-avatar-images
|
||||
path: modular-avatar-images
|
||||
- name: Install logo assets
|
||||
run: |
|
||||
cp -Rv modular-avatar-images/img/* docs/static/img
|
||||
cp -Rv modular-avatar-images/img/* docs~/static/img
|
||||
|
||||
- name: Setup yarn 2.0
|
||||
run: |
|
||||
corepack enable
|
||||
corepack prepare yarn@stable --activate
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "dir=$(cd docs~; yarn config get cacheFolder)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v4
|
||||
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-docs-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-docs-
|
||||
|
||||
- name: Set baseUri
|
||||
if: ${{ inputs.path }}
|
||||
run: |
|
||||
BASEURL="/${{ inputs.path }}/" perl -i -p -e "s{baseUrl: '/'}{baseUrl: '\$ENV{BASEURL}'}" docs~/docusaurus.config.js
|
||||
cat docs~/docusaurus.config.js
|
||||
|
||||
- name: Format changelogs
|
||||
run: |
|
||||
SUFFIX=""
|
||||
export PRERELEASE=${{ inputs.prerelease && 'true' || 'false' }}
|
||||
|
||||
if [ ${{ inputs.prerelease }} == true ]; then
|
||||
SUFFIX="-PRERELEASE"
|
||||
fi
|
||||
|
||||
perl -n .github/gen-docs-changelog.pl < CHANGELOG$SUFFIX.md >> docs~/docs/changelog.md
|
||||
perl -n .github/gen-docs-changelog.pl < CHANGELOG$SUFFIX''-jp.md >> docs~/i18n/ja/docusaurus-plugin-content-docs/current/changelog.md
|
||||
|
||||
- name: Build docs
|
||||
run: |
|
||||
cd docs
|
||||
yarn install
|
||||
cd docs~
|
||||
yarn install --immutable
|
||||
yarn build
|
||||
ls -lR build
|
||||
|
||||
- name: Set robots.txt
|
||||
run: |
|
||||
if [ -e docs~/robots.txt ]; then
|
||||
cp docs~/robots.txt docs~/build/robots.txt
|
||||
fi
|
||||
|
||||
- name: Package documentation
|
||||
run: |
|
||||
tar -cf docs.tar -C docs~/build .
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: docs
|
||||
path: docs/build
|
||||
name: ${{ inputs.artifact || 'docs' }}
|
||||
path: docs.tar
|
58
.github/workflows/changelog-check.yml
vendored
Normal file
58
.github/workflows/changelog-check.yml
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
# From https://github.com/anatawa12/AvatarOptimizer/blob/ccb863243433019f323c23a3a2e24b27e15b2f6c/.github/workflows/changelog-check.yml
|
||||
# Copyright 2022 anatawa12
|
||||
# MIT license.
|
||||
|
||||
# this workflow checks CHANGELOG.md & CHANGELOG-SNAPSHOTS.md is updated correctly
|
||||
# to skip this check, include `NO-CHANGELOG` for CHANGELOG.md
|
||||
# and `NO-CHANGELOG-PRERELEASE` for CHANGELOG-PRERELEASE.md in tags of PR.
|
||||
# also, this action ignores `dependencies` pull requests (expected to be generated by dependabot)
|
||||
|
||||
name: CHANGELOG check
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches: [ main, main-* ]
|
||||
types: [ opened, synchronize, reopened, ready_for_review, labeled, unlabeled ]
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
releasenote-check:
|
||||
if: ${{ ! github.event.pull_request.draft }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
file: [CHANGELOG.md, CHANGELOG-jp.md, CHANGELOG-PRERELEASE.md, CHANGELOG-PRERELEASE-jp.md]
|
||||
|
||||
env:
|
||||
NO_CHANGELOG: ${{
|
||||
contains(github.event.pull_request.labels.*.name, 'NO-CHANGELOG')
|
||||
|| contains(github.event.pull_request.labels.*.name, 'documentation')
|
||||
|| contains(github.event.pull_request.labels.*.name, 'localization')
|
||||
|| contains(github.event.pull_request.labels.*.name, 'ci')
|
||||
|| contains(github.event.pull_request.labels.*.name, 'refactor')
|
||||
|| startsWith(github.event.pull_request.head.label, 'bdunderscore:dependabot/')
|
||||
|| '' }}
|
||||
SNAPSHOT_ONLY: ${{ contains(github.event.pull_request.labels.*.name, 'PRERELEASE-ONLY') || '' }}
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- name: Fetch pull_request info
|
||||
env:
|
||||
GH_REPO: ${{ github.repositoryUrl }}
|
||||
GH_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
PR_NUM: ${{ github.event.number }}
|
||||
run: |
|
||||
gh pr view $PR_NUM --json=files | jq --raw-output '.files[].path' > files.txt
|
||||
- name: Changelog check for ${{ matrix.file }}
|
||||
if: always() && !env.NO_CHANGELOG && (startsWith(matrix.file, 'CHANGELOG-PRERELEASE') || !env.SNAPSHOT_ONLY)
|
||||
run: |
|
||||
if ! grep -e '^${{ matrix.file }}$' < files.txt > /dev/null; then
|
||||
echo "::error::An entry in ${{ matrix.file }} is required for this PR."
|
||||
echo "If this change is only relevant between snapshot versions: Add the label 'PRERELEASE-ONLY' to this PR." >> $GITHUB_STEP_SUMMARY
|
||||
echo "If this change does not warrant any release notes: Add the label 'NO-CHANGELOG' to this PR." >> $GITHUB_STEP_SUMMARY
|
||||
exit 1
|
||||
fi
|
132
.github/workflows/deploy-pages.yml
vendored
132
.github/workflows/deploy-pages.yml
vendored
@ -3,44 +3,130 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
- docs-snapshot
|
||||
- docs-ci-test
|
||||
workflow_dispatch: {}
|
||||
release:
|
||||
types:
|
||||
- released
|
||||
|
||||
concurrency:
|
||||
group: "pages"
|
||||
group: "pages-cf"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
snapshot-docs:
|
||||
name: Snapshot documentation
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
# Run on releases only
|
||||
if: ${{ github.event.release }}
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
- name: Merge with existing branch
|
||||
# Run on releases only
|
||||
if: ${{ github.event.release }}
|
||||
run: |
|
||||
git config --global user.name "GitHub Actions"
|
||||
git config --global user.email "github-actions@nadena.dev"
|
||||
git merge -s ours origin/docs-snapshot
|
||||
git push origin HEAD:docs-snapshot
|
||||
|
||||
build-docs:
|
||||
name: Build documentation
|
||||
name: Build documentation (latest release)
|
||||
# TODO - update to build-docs.yml
|
||||
uses: bdunderscore/modular-avatar/.github/workflows/build-test-docs.yml@main
|
||||
needs:
|
||||
- snapshot-docs
|
||||
with:
|
||||
ref: docs-snapshot
|
||||
prerelease: false
|
||||
|
||||
build-docs-dev:
|
||||
name: Build documentation (main branch)
|
||||
uses: bdunderscore/modular-avatar/.github/workflows/build-test-docs.yml@main
|
||||
with:
|
||||
ref: main
|
||||
path: dev
|
||||
artifact: docs-dev
|
||||
prerelease: true
|
||||
|
||||
deploy-docs:
|
||||
name: Deploy documentation
|
||||
needs: build-docs
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
needs:
|
||||
- build-docs
|
||||
- build-docs-dev
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Download artifact
|
||||
uses: actions/download-artifact@v2
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.ref || github.ref }}
|
||||
|
||||
- name: Download artifact (tagged)
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: docs
|
||||
path: docs/build
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v2
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v1
|
||||
- name: Download artifact (latest)
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: docs/build
|
||||
name: docs-dev
|
||||
path: docs/build/dev
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v1
|
||||
- name: Dump file listing
|
||||
run: |
|
||||
ls -lR docs/build
|
||||
|
||||
- name: Unpack documentation
|
||||
run: |
|
||||
mkdir -p docs-site~/public/dev
|
||||
tar -xf docs/build/docs.tar -C docs-site~/public
|
||||
tar -xf docs/build/dev/docs.tar -C docs-site~/public/dev
|
||||
|
||||
- name: Setup yarn 2.0
|
||||
run: |
|
||||
corepack enable
|
||||
corepack prepare yarn@stable --activate
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "dir=$(cd docs-site~; yarn config get cacheFolder)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v4
|
||||
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-site-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-site-
|
||||
|
||||
- name: Build CF site
|
||||
run: |
|
||||
cd docs-site~
|
||||
YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install
|
||||
|
||||
- name: Deploy to Cloudflare Pages
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
command: deploy --name modular-avatar-docs
|
||||
workingDirectory: docs-site~
|
||||
|
||||
- name: Purge cache
|
||||
uses: nathanvaughn/actions-cloudflare-purge@784d555fc0fc48946a1e34873a43fc8cf634bcfa
|
||||
continue-on-error: true
|
||||
with:
|
||||
cf_zone: ${{ secrets.CF_ZONE_ID }}
|
||||
cf_auth: ${{ secrets.CF_API_TOKEN }}
|
||||
|
56
.github/workflows/export-gameci-license.yml
vendored
Normal file
56
.github/workflows/export-gameci-license.yml
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
name: Export GameCI license
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
|
||||
jobs:
|
||||
export:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Setup
|
||||
run: |
|
||||
sudo apt-get -y install gnupg
|
||||
gpg --import <<EOF
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQGNBGT9rngBDAC92NQAEUXfPlYHESpYjovuSjTwxZBy8R1NR/8czcEnnNUSo09z
|
||||
ygzyRpgvxar5wL00WNY3cF03vXURJCV2FQYrsJEt0zAEQ+hTxwpVFcGjGr4ttI4+
|
||||
HW/kDXeWgH/Fk72eiv6KwmTSVEnjMQAGMOnpPgPxh9Brj0n3wQjp9WinEwRX2gFn
|
||||
gSoOQy6tLWtyLD6rYHDvAZ5FpSuuLqZfc3miHPcrs62IpeE6MaC4FGy7QLCnkL3X
|
||||
JBKYY4Y3/nsiNUv+I2U8laJ1CkUDZfoJ/t6XP35n4PCD/phOxa5E96hrGQqlIrnL
|
||||
vdYWVlZL/Wv+v7v/9taXcQUrqeKudFar2xFkH+LmBs6NRJUf84zRWpJhOTYS7Owo
|
||||
JqJX1GSeZjDbUc/pDX6RIz6iG/cjcCbooLwCtu/oCGJtznVD/bBxnmdmP20UK4Zd
|
||||
JuaG05/FbSM+dtBpAQ68yejloCngPuIYZYcvRi3l/rDl6+IwjsFEzg02yr8Cx6bQ
|
||||
d/gKL3W54Gn4Q5sAEQEAAbQXYmRfYmRfIDxiZF9AbmFkZW5hLmRldj6JAdQEEwEK
|
||||
AD4WIQQgqEPycUKGtLegx/izugd8bgW0LgUCZP2ueAIbAwUJA8JnAAULCQgHAgYV
|
||||
CgkICwIEFgIDAQIeAQIXgAAKCRCzugd8bgW0LnZkDACXHH2lIGemnMvpF+vfUlWt
|
||||
24CYbitrkNyEzFXf+Ya4XssL/9vacXhlPvW04vYRpZAPcqTZxuziLKWTigkymj+k
|
||||
ufRfhK9+XbZQHp10rLiG53o/SM8azXyYFH6PrFJERPD6O1hbTwwfcpfKN3GiNQCM
|
||||
1Oe1Ao/orI/hIViRlMrD8xEjNgZB/5FDzGIYZxsRzjX0Psm+Xmh92DueCf9oVFXe
|
||||
et1wPaxqzP7+YqvrzgTLVksEtieYiauElsEpGcVobVGupKI2K4Du+j2yffPPQJyU
|
||||
fSjw1Xdlpho2ZQu21bMXpl3vQswnkyrfBAIEqd6EsTZFk8B8Xv99U4Jy7fUouf8l
|
||||
8QlCOWIDv0z2mt5OKqGhQuEbKKTmTRIBWnBIfDsE0tZSmInVbChPfefGRTP3Jj2W
|
||||
0Y66yc4rIN560wnwB7yMccgC/hISBb1jsZCW+c87NSDkUz3dgwWVCJQ1sOb5L7Sc
|
||||
ZpfWffOxPewWUjOwTpPXmjoj5YPvGvcC+73gKIgdVn25AY0EZP2ueAEMAMZTMq8X
|
||||
B5I+QsNGkim/bOORflezCPDJYc2ivpdxdiEKSwyj5s9NTJ/huwi/6wnfZ1/EY7L1
|
||||
NOg5MP7V6OXsiQd+i/KNq1pl24UsmAJr4bfVM1D6Kkgg8iC3pBqabFWAQ6Vlh0TK
|
||||
lXAcUGC7VO4BGmdDGp+f9n4tOa7ieDiH0LIsKkj/nVa2chPnvycruNtgOLQ3iusy
|
||||
7DhlacdKFN56n1/somuhfk0t6bIEI3b0d4c2Htu81Xtpm8bkzhwmm9fw6bTBjTjh
|
||||
UtFraj2vmybfujqqofh0FHDz8BJsrZYkQtKmnBGR+9HWGiWuEVx2lQHj4xN/7E8d
|
||||
I+liA+sJtPON3lfBybsEkTx0GwPmwvZ2LnC7dCx8v/aMQMPy7AsnP2SxAkKPKJc7
|
||||
hIeAkobTbQjBHuk+PelimnvUdmdPg+RR4eUDmpCOlRib6x3WKnadOafsO96hAoUg
|
||||
kbcwwlML3TQSauBVbov1ZlLYtXpCQalX0DwdGWvHDHFTXSyvY0IJ36vCFwARAQAB
|
||||
iQG8BBgBCgAmFiEEIKhD8nFChrS3oMf4s7oHfG4FtC4FAmT9rngCGwwFCQPCZwAA
|
||||
CgkQs7oHfG4FtC4cVwv/QHDqWDfJXXRArbsn+n/xofgnt1sB2KwvRaA/DQpI5zk8
|
||||
AFXbqwPClIf+8kvTgGEgDdIBAmLcj5ZEqbu5Y25sbSlNY4Kbk1nYSwan3Jwpakgo
|
||||
04zwPiThLO0kboJ+dsu4TUX8qN1hYRcgomHDe1DocVsvX4Bp+JA809+iCk5FKD95
|
||||
OKeeo++Ulyzigf49qUe70HkqI+LYo4S5nN+EyiqMrcjh4NXDgJkPxt/rCClQVbVi
|
||||
zotM3zo5iqy8sV/GsVzIr6LapxIvfIvrgcchShwLMhl7xy9WhaASdzv/+VnJZrmQ
|
||||
6i6gqZ6fHz/RPeEWdoMU+OojoiQHpjyVsLv8Vj4pilzVKdqofTQ6tyMv6i37C7SJ
|
||||
6OqdaNUCVlM4iFCjm8fg/L+LXIIhmjhdmXtaPDgYwwwcpK2n5IcItp526+6Bu2Wt
|
||||
VhTIRf5zG/qTj/r3P+jrApgbtDpaJST/hrRaqCYiOxkJU2krrrBy9ttq9h4lSiiZ
|
||||
6nL+CD9YfkV6cDH7BWlz
|
||||
=So9v
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
EOF
|
||||
|
||||
echo "foo" | gpg --encrypt -a --recipient bd_@nadena.dev
|
203
.github/workflows/gameci.yml
vendored
Normal file
203
.github/workflows/gameci.yml
vendored
Normal file
@ -0,0 +1,203 @@
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2022 anatawa12
|
||||
# Copyright (c) 2022 bd_
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
|
||||
name: GameCI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, dev, ci, refactor-structure]
|
||||
# This is a bit of a radioactive event; we need to be very careful with what permissions
|
||||
# we assign this action, as we're allowing arbitrary code execution with the context of
|
||||
# whatever permissions we assign.
|
||||
pull_request_target: {}
|
||||
workflow_dispatch: {}
|
||||
workflow_call:
|
||||
secrets:
|
||||
UNITY_LICENSE:
|
||||
required: true
|
||||
|
||||
# pull_request_target grants access to a privileged GITHUB_TOKEN by default, revoke this
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
build-and-test:
|
||||
name: Unit tests
|
||||
strategy:
|
||||
matrix:
|
||||
unity_major_version: [ 2022 ]
|
||||
sdk: [ vrcsdk ]
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
checks: write
|
||||
contents: read
|
||||
steps:
|
||||
- id: configure
|
||||
name: Configure
|
||||
env:
|
||||
unity_major_version: ${{ matrix.unity_major_version }}
|
||||
run: |
|
||||
if [ $unity_major_version == 2019 ]; then
|
||||
echo "unity_version=2019.4.31f1" >> $GITHUB_OUTPUT
|
||||
elif [ $unity_major_version == 2022 ]; then
|
||||
echo "unity_version=2022.3.6f1" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Invalid unity_major_version: $unity_major_version"
|
||||
exit 1
|
||||
fi
|
||||
- id: setup
|
||||
name: Setup
|
||||
env:
|
||||
unity_version: ${{ steps.configure.outputs.unity_version }}
|
||||
sdk: ${{ matrix.sdk }}
|
||||
run: |
|
||||
set -x
|
||||
|
||||
sudo apt-get install xmlstarlet -y
|
||||
|
||||
should_test=true
|
||||
echo should_test=$should_test >> $GITHUB_OUTPUT
|
||||
|
||||
can_fail=false
|
||||
if [ $sdk == standalone ]; then
|
||||
can_fail=$should_test
|
||||
fi
|
||||
echo can_fail=$can_fail >> $GITHUB_OUTPUT
|
||||
|
||||
if $can_fail; then
|
||||
check_name="Unsupported test result ($unity_version, $sdk)"
|
||||
else
|
||||
check_name="Test result ($unity_version, $sdk)"
|
||||
fi
|
||||
echo check_name=$check_name >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
if: ${{ steps.setup.outputs.should_test == 'true' }}
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- id: prepare-project
|
||||
if: ${{ steps.setup.outputs.should_test == 'true' }}
|
||||
name: Prepare project
|
||||
run: |
|
||||
mkdir .github/ProjectRoot/Packages/nadena.dev.modular-avatar -p
|
||||
mv * .github/ProjectRoot/Packages/nadena.dev.modular-avatar
|
||||
mv .github/ProjectRoot/* .
|
||||
mv 'Packages/nadena.dev.modular-avatar/UnitTests~' 'Packages/nadena.dev.modular-avatar/UnitTests'
|
||||
for i in packages-lock manifest vpm-manifest; do
|
||||
if [ -e "$i-${{ matrix.unity_major_version }}.json" ]; then
|
||||
mv "$i-${{ matrix.unity_major_version }}.json" Packages/$i.json -v
|
||||
fi
|
||||
done
|
||||
|
||||
- uses: anatawa12/sh-actions/setup-vrc-get@master
|
||||
|
||||
- name: Resolve packages
|
||||
if: ${{ steps.setup.outputs.should_test == 'true' }}
|
||||
run: |
|
||||
vrc-get repo add -- "https://vpm.nadena.dev/vpm-prerelease.json" || true
|
||||
vrc-get repo add -- "https://vrchat.github.io/packages/index.json?download" || true
|
||||
vrc-get resolve --project .
|
||||
vrc-get info project --project .
|
||||
|
||||
- if: ${{ steps.setup.outputs.should_test == 'true' }}
|
||||
name: "Debug: List project contents"
|
||||
run: |
|
||||
ls -lR
|
||||
ls -lR Packages/nadena*
|
||||
|
||||
- if: ${{ steps.setup.outputs.should_test == 'true' }}
|
||||
name: "Debug: List package versions"
|
||||
run: |
|
||||
for i in Packages/*/package.json; do
|
||||
echo $i
|
||||
cat $i | jq .version
|
||||
done
|
||||
|
||||
- uses: actions/cache@v4
|
||||
if: ${{ steps.setup.outputs.should_test == 'true' }}
|
||||
with:
|
||||
path: Library
|
||||
key: Library-${{ steps.configure.outputs.unity_version }}-${{ matrix.sdk }}
|
||||
restore-keys: Library-
|
||||
|
||||
- uses: game-ci/unity-test-runner@v3
|
||||
id: gameci
|
||||
continue-on-error: ${{ steps.setup.outputs.can_fail == 'true' }}
|
||||
if: ${{ steps.setup.outputs.should_test == 'true' }}
|
||||
env:
|
||||
# meh, just a personal license...
|
||||
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
|
||||
with:
|
||||
testMode: EditMode
|
||||
unityVersion: ${{ steps.configure.outputs.unity_version }}
|
||||
githubToken: ${{ github.token }}
|
||||
coverageOptions: generateAdditionalMetrics;generateHtmlReport;generateBadgeReport;assemblyFilters:+nadena.dev.*
|
||||
customParameters: -nographics -assemblyNames Tests
|
||||
checkName: ${{ steps.setup.outputs.check_name }}
|
||||
|
||||
# For our main "supported" platforms, we report the conclusion of gameci as-is. However, for standalone, we report
|
||||
# neutral if it failed.
|
||||
- id: determine_conclusion
|
||||
name: Determine conclusion
|
||||
if: ${{ steps.setup.outputs.should_test == 'true' }}
|
||||
env:
|
||||
unity_version: ${{ steps.configure.outputs.unity_version }}
|
||||
sdk_platform: ${{ matrix.sdk }}
|
||||
gameci_outcome: ${{ steps.gameci.outcome }}
|
||||
can_fail: ${{ steps.setup.outputs.can_fail }}
|
||||
run: |
|
||||
set -x
|
||||
outcome=$gameci_outcome
|
||||
|
||||
# Check whether any tests actually ran
|
||||
test_count=$(
|
||||
if ! cat ${{ steps.gameci.outputs.artifactsPath }}/editmode-results.xml | \
|
||||
xmlstarlet sel -t -v "/test-run/@total"; then
|
||||
echo 0
|
||||
fi
|
||||
)
|
||||
|
||||
if [ $test_count -eq 0 ] || [ x$test_count == x ]; then
|
||||
outcome=failure
|
||||
output="{ \"summary\": \"No tests ran\" }"
|
||||
|
||||
if ! $can_fail; then
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
output="{ \"summary\": \"Result: $outcome ($test_count tests)\" }"
|
||||
fi
|
||||
|
||||
if [ "$outcome" == "failure" ] && $can_fail; then
|
||||
outcome=neutral
|
||||
fi
|
||||
echo matrix_outcome=$outcome >> $GITHUB_OUTPUT
|
||||
echo matrix_output=$output >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ steps.setup.outputs.should_test == 'true' && matrix.sdk == 'vrcsdk' }}
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: Coverage results ${{ steps.configure.outputs.unity_version }} ${{ matrix.sdk }}
|
||||
path: ${{ steps.gameci.outputs.coveragePath }}
|
39
.github/workflows/gamici-activation.yml
vendored
Normal file
39
.github/workflows/gamici-activation.yml
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2022 anatawa12
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
name: GameCI Acquire activation file
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
jobs:
|
||||
activation:
|
||||
name: Request manual activation file 🔑
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Request manual activation file
|
||||
- name: Request manual activation file
|
||||
id: getManualLicenseFile
|
||||
uses: game-ci/unity-request-activation-file@v2
|
||||
- name: Expose as artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.getManualLicenseFile.outputs.filePath }}
|
||||
path: ${{ steps.getManualLicenseFile.outputs.filePath }}
|
231
.github/workflows/perform-release.yml
vendored
Normal file
231
.github/workflows/perform-release.yml
vendored
Normal file
@ -0,0 +1,231 @@
|
||||
name: Perform Release
|
||||
|
||||
# Portions of this workflow are based on https://github.com/anatawa12/AvatarOptimizer/blob/master/.github/workflows/release.yml
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release_kind:
|
||||
type: choice
|
||||
description: The type of release.
|
||||
default: prerelease
|
||||
required: true
|
||||
options:
|
||||
- prerelease
|
||||
- stable
|
||||
- adhoc
|
||||
publish:
|
||||
description: "True to publish release to git, vpm. if false, this creates release asset only"
|
||||
type: boolean
|
||||
required: false
|
||||
version:
|
||||
description: "Version to release"
|
||||
type: string
|
||||
required: false
|
||||
|
||||
env:
|
||||
PKG_NAME: nadena.dev.modular-avatar
|
||||
RELEASE_TYPE: ${{ github.event.inputs.release_kind }}
|
||||
|
||||
concurrency:
|
||||
group: publish
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: write-all
|
||||
|
||||
jobs:
|
||||
check-gameci:
|
||||
uses: bdunderscore/modular-avatar/.github/workflows/gameci.yml@main
|
||||
permissions:
|
||||
checks: write
|
||||
contents: read
|
||||
secrets: inherit
|
||||
|
||||
check-docs:
|
||||
name: Build documentation (latest release)
|
||||
uses: bdunderscore/modular-avatar/.github/workflows/build-test-docs.yml@main
|
||||
|
||||
create-release:
|
||||
needs: [ check-gameci, check-docs ]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
|
||||
# https://github.com/orgs/community/discussions/13836#discussioncomment-8535364
|
||||
- uses: actions/create-github-app-token@v2
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ vars.RELEASER_APP_ID }}
|
||||
private-key: ${{ secrets.RELEASER_PRIVATE_KEY }}
|
||||
|
||||
- name: Validate prerelease version
|
||||
id: check-version
|
||||
if: ${{ github.event.inputs.release_kind == 'prerelease' && !contains(github.event.inputs.version, '-') }}
|
||||
run:
|
||||
echo "Prerelease version must contain a hyphen"
|
||||
exit 1
|
||||
|
||||
- name: Validate stable version
|
||||
id: check-version-stable
|
||||
if: ${{ github.event.inputs.release_kind == 'stable' && contains(github.event.inputs.version, '-') }}
|
||||
run:
|
||||
echo "Stable version must not contain a hyphen"
|
||||
exit 1
|
||||
|
||||
- name: Validate adhoc
|
||||
id: validate-adhoc
|
||||
if: ${{ github.event.inputs.release_kind == 'adhoc' && github.event.inputs.publish == 'true' }}
|
||||
run:
|
||||
echo "Adhoc release cannot be published"
|
||||
exit 1
|
||||
|
||||
- name: Set Environment Variables
|
||||
run: |
|
||||
echo "zipFile=${{ env.PKG_NAME }}-${{ github.event.inputs.version }}".zip >> $GITHUB_ENV
|
||||
echo "unityPackage=${{ env.PKG_NAME }}-${{ github.event.inputs.version }}.unitypackage" >> $GITHUB_ENV
|
||||
|
||||
echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV
|
||||
|
||||
case "$RELEASE_TYPE" in
|
||||
prerelease)
|
||||
echo "PRERELEASE=true" >> $GITHUB_ENV
|
||||
;;
|
||||
stable)
|
||||
echo "PRERELEASE=false" >> $GITHUB_ENV
|
||||
;;
|
||||
adhoc)
|
||||
echo "PRERELEASE=true" >> $GITHUB_ENV
|
||||
;;
|
||||
esac
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
token: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
- name: Checkout logo assets
|
||||
uses: actions/checkout@v4
|
||||
if: ${{ github.event.inputs.release_kind != 'adhoc' }}
|
||||
with:
|
||||
repository: bdunderscore/modular-avatar-images
|
||||
path: .github/image-assets
|
||||
- name: Inject logo assets
|
||||
if: ${{ github.event.inputs.release_kind != 'adhoc' }}
|
||||
run: |
|
||||
cp -f .github/image-assets/img/logo/ma_logo.png Editor/Images/logo.png
|
||||
cp -f .github/image-assets/img/logo/ma_icon.png Runtime/Icons/Icon_MA_Script.png
|
||||
|
||||
- name: Check semver syntax
|
||||
if: steps.check-tag.outputs.need-new-tag == 'true'
|
||||
id: semver-check
|
||||
run: |
|
||||
chmod +x .github/workflows/*.sh
|
||||
.github/workflows/check-semver-syntax.sh ${{ github.event.inputs.version }}
|
||||
|
||||
- name: Set git user and email
|
||||
id: git-config
|
||||
run: |
|
||||
git config --global user.name "nadena.dev release bot"
|
||||
git config --global user.email "ci@nadena.dev"
|
||||
- name: Update version
|
||||
id: update-version
|
||||
run: |
|
||||
jq '.version = env.VERSION' package.json > package.json.tmp
|
||||
mv package.json.tmp package.json
|
||||
env:
|
||||
VERSION: ${{ github.event.inputs.version }}
|
||||
|
||||
|
||||
- name: Update changelog
|
||||
id: changelog
|
||||
run: |
|
||||
chmod +x .github/*.pl
|
||||
|
||||
if [ "${{ env.PRERELEASE }}" == "true" ]; then
|
||||
./.github/cut-changelog.pl CHANGELOG-PRERELEASE.md .github/CHANGELOG-HEADER.md ${{ env.VERSION }} .github/relnote-en.md
|
||||
./.github/cut-changelog.pl CHANGELOG-PRERELEASE-jp.md .github/CHANGELOG-HEADER.md ${{ env.VERSION }} .github/relnote-jp.md
|
||||
else
|
||||
./.github/cut-changelog.pl CHANGELOG-PRERELEASE.md .github/CHANGELOG-HEADER.md ${{ env.VERSION }}
|
||||
./.github/cut-changelog.pl CHANGELOG-PRERELEASE-jp.md .github/CHANGELOG-HEADER.md ${{ env.VERSION }}
|
||||
./.github/cut-changelog.pl CHANGELOG.md .github/CHANGELOG-HEADER.md ${{ env.VERSION }} .github/relnote-en.md
|
||||
./.github/cut-changelog.pl CHANGELOG-jp.md .github/CHANGELOG-HEADER.md ${{ env.VERSION }} .github/relnote-jp.md
|
||||
fi
|
||||
|
||||
echo Version ${{ env.VERSION }} > release-note.md
|
||||
echo >> release-note.md
|
||||
if [ "${{ env.PRERELEASE }}" == "true" ]; then
|
||||
echo '**This is a prerelease version.** There may be bugs, and API compatibility is not yet guaranteed.' >> release-note.md
|
||||
echo 'Please: **BACK UP YOUR PROJECTS**' >> release-note.md
|
||||
echo >> release-note.md
|
||||
fi
|
||||
echo '## Notable changes' >> release-note.md
|
||||
cat .github/relnote-en.md >> release-note.md
|
||||
echo >> release-note.md
|
||||
echo '## 主な変更点' >> release-note.md
|
||||
cat .github/relnote-jp.md >> release-note.md
|
||||
|
||||
- name: Upload CHANGELOG.md
|
||||
if: ${{ github.event.inputs.release_kind == 'stable' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CHANGELOG
|
||||
path: CHANGELOG.md
|
||||
- name: Upload CHANGELOG-PRERELEASE.md
|
||||
if: ${{ github.event.inputs.release_kind == 'prerelease' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CHANGELOG-PRERELEASE
|
||||
path: CHANGELOG-PRERELEASE.md
|
||||
- name: Upload release note
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: changelog
|
||||
path: release-note.md
|
||||
- run: mv release-note.md .github
|
||||
|
||||
- name: Commit and tag version update
|
||||
run: |
|
||||
git commit -am "Release ${{ github.event.inputs.version }}"
|
||||
git tag -a ${{ github.event.inputs.version }} -m "Release ${{ github.event.inputs.version }}"
|
||||
- name: Publish tag
|
||||
if: ${{ github.event.inputs.publish == 'true' }}
|
||||
run: |
|
||||
BRANCH_NAME=$(git branch --show-current)
|
||||
git push origin $BRANCH_NAME && git push origin ${{ github.event.inputs.version }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
- name: Create Zip
|
||||
run: |
|
||||
zip ".github/${{env.zipFile}}" ./* -r -x .github .git '.git/*' '*~/*' '*.ps1*'
|
||||
|
||||
- name: Move zipfile
|
||||
run: |
|
||||
mv .github/${{env.zipFile}} ${{env.zipFile}}
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: package-zip
|
||||
path: ${{ env.zipFile }}
|
||||
|
||||
- name: Dump release notes
|
||||
run: |
|
||||
cat .github/release-note.md
|
||||
|
||||
- name: Make Release
|
||||
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda
|
||||
if: ${{ github.event.inputs.publish == 'true' }}
|
||||
with:
|
||||
draft: true
|
||||
body_path: .github/release-note.md
|
||||
tag_name: ${{ github.event.inputs.version }}
|
||||
name: ${{ github.event.inputs.version }}
|
||||
make_latest: ${{ github.event.inputs.release_kind == 'stable' }}
|
||||
files: |
|
||||
${{ env.zipFile }}
|
||||
package.json
|
50
.github/workflows/test-docs-site-build.yml
vendored
Normal file
50
.github/workflows/test-docs-site-build.yml
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
name: Test docs-site yarn installation
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- ci
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build-docs:
|
||||
name: Build documentation site
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup yarn 2.0
|
||||
run: |
|
||||
corepack enable
|
||||
corepack prepare yarn@stable --activate
|
||||
yarn --version
|
||||
|
||||
#- name: Get yarn cache directory path
|
||||
# id: yarn-cache-dir-path
|
||||
# run: echo "dir=$(cd docs-site~; yarn config get cacheFolder)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v4
|
||||
if: false
|
||||
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-site-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-site-
|
||||
|
||||
- name: Build CF site
|
||||
run: |
|
||||
cd docs-site~
|
||||
YARN_ENABLE_HARDENED_MODE=0 YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install
|
||||
|
||||
- name: Display diff on failure
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
cd docs-site~
|
||||
env
|
||||
YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install && git diff
|
||||
|
||||
|
4
.github/workflows/trigger-repo-rebuild.yml
vendored
4
.github/workflows/trigger-repo-rebuild.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: Trigger repo listing generator
|
||||
name: Trigger repo listing generator
|
||||
|
||||
on:
|
||||
release:
|
||||
@ -9,7 +9,7 @@ jobs:
|
||||
dispatch:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v6
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.VPM_REPO_TOKEN }}
|
||||
script: |
|
||||
|
76
.gitignore
vendored
76
.gitignore
vendored
@ -1,73 +1,3 @@
|
||||
# This .gitignore file should be placed at the root of your Unity project directory
|
||||
#
|
||||
# Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore
|
||||
#
|
||||
/[Ll]ibrary/
|
||||
/[Tt]emp/
|
||||
/[Oo]bj/
|
||||
/[Bb]uild/
|
||||
/[Bb]uilds/
|
||||
/[Ll]ogs/
|
||||
/[Mm]emoryCaptures/
|
||||
|
||||
# Asset meta data should only be ignored when the corresponding asset is also ignored
|
||||
!/[Aa]ssets/**/*.meta
|
||||
|
||||
# Uncomment this line if you wish to ignore the asset store tools plugin
|
||||
# /[Aa]ssets/AssetStoreTools*
|
||||
|
||||
# Autogenerated Jetbrains Rider plugin
|
||||
[Aa]ssets/Plugins/Editor/JetBrains*
|
||||
|
||||
# Visual Studio cache directory
|
||||
.vs/
|
||||
|
||||
# Gradle cache directory
|
||||
.gradle/
|
||||
|
||||
# Autogenerated VS/MD/Consulo solution and project files
|
||||
ExportedObj/
|
||||
.consulo/
|
||||
*.csproj
|
||||
*.unityproj
|
||||
*.sln
|
||||
*.suo
|
||||
*.tmp
|
||||
*.user
|
||||
*.userprefs
|
||||
*.pidb
|
||||
*.booproj
|
||||
*.svd
|
||||
*.pdb
|
||||
*.mdb
|
||||
*.opendb
|
||||
*.VC.db
|
||||
|
||||
# Unity3D generated meta files
|
||||
*.pidb.meta
|
||||
*.pdb.meta
|
||||
*.mdb.meta
|
||||
|
||||
# Unity3D generated file on crash reports
|
||||
sysinfo.txt
|
||||
|
||||
# Builds
|
||||
*.apk
|
||||
*.unitypackage
|
||||
|
||||
# Crashlytics generated file
|
||||
crashlytics-build.properties
|
||||
|
||||
/UpstreamAssets/
|
||||
/.idea/
|
||||
|
||||
/Assets/**/*
|
||||
|
||||
!/Assets/.gitkeep
|
||||
!/Assets/bd_/
|
||||
!/Assets/bd_/ModularAvatar/
|
||||
!/Assets/bd_/ModularAvatar/.gitkeep
|
||||
!/Assets/bd_/ModularAvatar.meta
|
||||
!/Assets/bd_.meta
|
||||
|
||||
![Mm]odular[Aa]vatar.meta
|
||||
UnitTests
|
||||
UnitTests.meta
|
||||
/UnitTests/
|
||||
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "Packages/nadena.dev.ndmf"]
|
||||
path = Packages/nadena.dev.ndmf
|
||||
url = https://github.com/bdunderscore/ndmf.git
|
3
Assets.meta
Normal file
3
Assets.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45facc2394ac4e6d9c6a8427227dc931
|
||||
timeCreated: 1691906506
|
32
Assets/FixedPrefab.prefab
Normal file
32
Assets/FixedPrefab.prefab
Normal file
@ -0,0 +1,32 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &4316036803263603590
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8830680306940261232}
|
||||
m_Layer: 0
|
||||
m_Name: GameObject
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &8830680306940261232
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4316036803263603590}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
7
Assets/FixedPrefab.prefab.meta
Normal file
7
Assets/FixedPrefab.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 78828bfbcb4cb4ce3b00de044eb2d927
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
138
CHANGELOG-PRERELEASE-jp.md
Normal file
138
CHANGELOG-PRERELEASE-jp.md
Normal file
@ -0,0 +1,138 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
### Fixed
|
||||
|
||||
### Changed
|
||||
|
||||
### Removed
|
||||
|
||||
### Security
|
||||
|
||||
### Deprecated
|
||||
|
||||
## [1.13.0-alpha.2] - [2025-04-14]
|
||||
|
||||
### Fixed
|
||||
- [#1558] Merge AnimatorでベースアバターのArmature内のTransformをアニメーションさせると壊れる問題を修正
|
||||
|
||||
## [1.13.0-alpha.1] - [2025-04-10]
|
||||
|
||||
### Fixed
|
||||
- [#1552] Merge Blend Treeにて、メインアバターFXレイヤーと同じ名前のintやboolパラメーターがBlend Treeに含まれている場合、
|
||||
パラメーター型が修正されない問題を修正
|
||||
- [#1553] リアクティブコンポーネントが生成するステートに、WD設定が正しくない問題を修正
|
||||
- [#1555] VRC Animator Play Audioが、Audio Sourceまでの絶対パスで設定されている場合に、相対パスのMerge Animator
|
||||
コンポーネントとマージされた場合、指定されたオブジェクトが存在しないことを検出し、参照を絶対パスとして扱うように修正
|
||||
- 対象のパスにオブジェクトがある場合は、相対パスとして扱われます。安定性向上のためMerge Animatorコンポーネントと同じ
|
||||
指定方法を使用することをお勧めします。
|
||||
|
||||
### Changed
|
||||
- [#1551] Merge Animatorは、遷移のない単一のstateを持つブレンドツリーのレイヤーに対して常にWDをONに設定します。
|
||||
- 一部、以前の挙動に依存したアセットとの互換性を向上させるための変更です。
|
||||
|
||||
## [1.13.0-alpha.0] - [2025-04-08]
|
||||
|
||||
### Added
|
||||
- (実験的機能) VRC以外のプラットフォームのサポートを有効化
|
||||
|
||||
## [1.12.3] - [2025-04-05]
|
||||
|
||||
### Fixed
|
||||
- Additiveレイヤーの問題を修正(NDMFバージョンアップグレードによって修正)
|
||||
|
||||
### Changed
|
||||
- [#1542] Merge Animatorは、アニメーションクリップを含む単一のstateを持つレイヤーに対してWD設定を一致させるが、
|
||||
ブレンドツリーを含む場合は一致させないように変更されました。
|
||||
- これにより、1.12で導入された互換性の問題が修正されます(1.12.0では、単一のstateアニメーションクリップに対してWD設定
|
||||
と一致しないように変更されました)。
|
||||
|
||||
## [1.12.2] - [2025-04-03]
|
||||
|
||||
### Fixed
|
||||
- [#1537] アニメーターパラメーターをアニメーションさせるカーブが、`Merge Motion` コンポーネントを使用して追加された場合、
|
||||
`Rename Parameters` によって更新されない問題を修正``
|
||||
|
||||
## [1.12.1] - [2025-04-02]
|
||||
|
||||
### Fixed
|
||||
- [#1532] Modular Avatarが新しく作成したプロジェクトでコンパイラエラーを出す問題を修正
|
||||
|
||||
## [1.12.0] - [2025-04-01]
|
||||
|
||||
### Fixed
|
||||
- [#1531] lylicalInventoryとの互換性問題を修正
|
||||
|
||||
### Changed
|
||||
- [#1530] `MA Menu Item`の自動パラメーター機能も、オブジェクトのパスに基づいて名前を割り当てるようになりました。
|
||||
|
||||
## [1.12.0-rc.1] - [2025-03-28]
|
||||
|
||||
### Added
|
||||
- [#1524] MMDワールド対応をアバター全体で無効にする機能を追加
|
||||
|
||||
### Fixed
|
||||
- [#1522] `Convert Constraints` がアニメーション参照を変換できない問題を修正
|
||||
- [#1528] `Merge Animator` が `アバターのWrite Defaults設定に合わせる` 設定を無視し、常に合わせてしまう問題を修正
|
||||
|
||||
### Changed
|
||||
- [#1529] `MA Parameters` の自動リネームは、オブジェクトのパスに基づいて新しい名前を割り当てるように変更されました。これにより、
|
||||
`MA Sync Parameter Sequence` との互換性が向上します。
|
||||
- `MA Sync Parameter Sequence` を使用している場合は、このバージョンに更新した後、SyncedParamsアセットを空にして、
|
||||
すべてのプラットフォームを再アップロードすることをお勧めします。
|
||||
|
||||
## [1.12.0-rc.0] - [2025-03-22]
|
||||
|
||||
### Fixed
|
||||
- [#1508] テクスチャのサイズが4の倍数でない場合に、エクスプレッションメニューアイコンの自動圧縮が失敗する問題を修正
|
||||
- [#1513] iOSビルドでエクスプレッションメニューアイコンの圧縮が壊れる問題を修正
|
||||
|
||||
### Changed
|
||||
- [#1514] `Merge Blend Tree` は `Merge Motion (Blend Tree)` に改名され、アニメーションクリップにも対応するようになりました
|
||||
|
||||
## [1.12.0-beta.0] - [2025-03-17]
|
||||
|
||||
### Added
|
||||
- [#1497] CHANGELOGをドキュメンテーションサイトに追加
|
||||
- [#1482] `Merge Animator` に既存のアニメーターコントローラーを置き換える機能を追加
|
||||
- [#1481] [World Scale Object](https://m-a.nadena.dev/dev/ja/docs/reference/world-scale-object)を追加
|
||||
- [#1489] [`MA MMD Layer Control`](https://modular-avatar.nadena.dev/docs/general-behavior/mmd)を追加
|
||||
|
||||
### Fixed
|
||||
- [#1492] 前回のプレリリースでアイコンとロゴアセットが間違っていた問題を修正
|
||||
- [#1501] MA Parametersコンポーネントのテキスト入力欄を編集する際にUnityのキーボードショートカットが機能しない問題を修正
|
||||
- [#1410] 同期レイヤー内のモーションオーバーライドがBone Proxy/Merge Armatureオブジェクトの移動に対して更新されない問題を修正
|
||||
- [#1504] 一部の状況で内部の`DelayDisable`レイヤーが不要なオブジェクトを参照しないように変更
|
||||
- これにより、オブジェクトがアニメーションされているかどうかを追跡するAAOなどのツールとの互換性が向上します
|
||||
|
||||
### Changed
|
||||
- [#1483] Merge Animator の 「アバターの Write Defaults 設定に合わせる」設定では、Additiveなレイヤー、および単一Stateかつ遷移のないレイヤー
|
||||
に対してはWrite Defaultsを調整しないように変更。
|
||||
- [#1429] Merge Armature は、特定の場合にPhysBoneに指定されたヒューマノイドボーンをマージできるようになりました。
|
||||
- 具体的には、子ヒューマノイドボーンがある場合はPhysBoneから除外される必要があります。
|
||||
- [#1437] Create Toggle for Selectionにおいて、複数選択時時に必要に応じてサブメニューを生成し、子としてトグルを生成するように変更されました。
|
||||
- [#1499] `Object Toggle`で制御される`Audio Source`がアニメーションブロックされたときに常にアクティブにならないように、
|
||||
アニメーションがブロックされたときにオーディオソースを無効にするように変更。
|
||||
- [#1489] `Merge Blend Tree` やリアクティブコンポーネントとMMDワールドの互換性の問題を修正。
|
||||
詳細は[ドキュメント](https://modular-avatar.nadena.dev/docs/general-behavior/mmd)を参照してください。
|
||||
- [#1502] `World Fixed Object` は `VRCParentConstraint` を使用するようになり、Androidビルドで使用可能になりました。
|
||||
|
||||
## [1.12.0-alpha.2] - [2025-03-10]
|
||||
|
||||
### Added
|
||||
- Added CHANGELOG files
|
||||
|
||||
### Changed
|
||||
- [#1476] ModularAvatarMergeAnimator と ModularAvatarMergeParameter を新しい NDMF API (`IVirtualizeMotion` と `IVirtualizeAnimatorController`) を使用するように変更
|
||||
|
||||
## Older versions
|
||||
|
||||
Please see CHANGELOG.md
|
3
CHANGELOG-PRERELEASE-jp.md.meta
Normal file
3
CHANGELOG-PRERELEASE-jp.md.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2f89fef1421c4126b6086156ff536d8f
|
||||
timeCreated: 1741573199
|
140
CHANGELOG-PRERELEASE.md
Normal file
140
CHANGELOG-PRERELEASE.md
Normal file
@ -0,0 +1,140 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
### Fixed
|
||||
|
||||
### Changed
|
||||
|
||||
### Removed
|
||||
|
||||
### Security
|
||||
|
||||
### Deprecated
|
||||
|
||||
## [1.13.0-alpha.2] - [2025-04-14]
|
||||
|
||||
### Fixed
|
||||
- [#1558] Fixed an issue where Merge Animators animating transforms in the base avatar's armature would break.
|
||||
|
||||
## [1.13.0-alpha.1] - [2025-04-10]
|
||||
|
||||
### Fixed
|
||||
- [#1552] Merge Blend Tree failed to correct parameter types when the main avatar FX layer contained an int or bool
|
||||
parameter with the same name as one used in the blend tree.
|
||||
- [#1553] Reactive components might generate states with incorrect write default settings
|
||||
- [#1555] Fixed compatibility regression from 1.11.x: VRC Animator Play Audio, when configured with an absolute path
|
||||
but merged with a relative-path merge animator component, will now detect that the indicated object does not
|
||||
exist, and treat the reference as an absolute path.
|
||||
- Note that if there is an object in the target path, then it will be treated as a relative path. Using
|
||||
addressing for Play Audio behaviors consistent with Merge Animator settings is therefore recommended as it will be
|
||||
more robust.
|
||||
|
||||
### Changed
|
||||
- [#1551] Merge Animator will always set WD ON for single-state blendtree layers with no any state transitions.
|
||||
- This fixes compatibility issues with assets which relied on the prior behavior.
|
||||
|
||||
## [1.13.0-alpha.0] - [2025-04-08]
|
||||
|
||||
### Added
|
||||
- (Experimental feature) Enabled support for non-VRC platforms
|
||||
|
||||
## [1.12.3] - [2025-04-05]
|
||||
|
||||
### Fixed
|
||||
- Fixed issues with additive layers (via NDMF version upgrade)
|
||||
|
||||
### Changed
|
||||
- [#1542] Merge Animator now will match WD settings for layers with a single state containing an animation clip,
|
||||
but not if it contains a blend tree. This fixes some compatibility issues introduced in 1.12 (where the behavior
|
||||
was changed to not match WD settings for single-state animation clips).
|
||||
|
||||
## [1.12.2] - [2025-04-03]
|
||||
|
||||
### Fixed
|
||||
- [#1537] Curves which animated animator parameters, when added using a `Merge Motion` component, would not be updated by
|
||||
`Rename Parameters`
|
||||
|
||||
## [1.12.1] - [2025-04-02]
|
||||
|
||||
### Fixed
|
||||
- [#1532] Modular Avatar has compiler errors in a newly created project
|
||||
|
||||
## [1.12.0] - [2025-04-01]
|
||||
|
||||
### Fixed
|
||||
- [#1531] Fix compatibility issue with lylicalInventory
|
||||
|
||||
### Changed
|
||||
- [#1530] `MA Menu Item` auto parameters now also assign names based on object paths
|
||||
|
||||
## [1.12.0-rc.1] - [2025-03-28]
|
||||
|
||||
### Added
|
||||
- [#1524] Added support for disabling MMD world handling at an avatar level
|
||||
|
||||
### Fixed
|
||||
- [#1522] `Convert Constraints` failed to convert animation references
|
||||
- [#1528] `Merge Animator` ignored the `Match Avatar Write Defaults` setting and always matched
|
||||
|
||||
### Changed
|
||||
- [#1529] `MA Parameters` auto-rename now assigns new names based on the path of the object. This should improve
|
||||
compatibility with `MA Sync Parameter Sequence`
|
||||
- If you are using `MA Sync Parameter Sequence`, it's a good idea to empty your SyncedParams asset and reupload all
|
||||
platforms after updating to this version.
|
||||
|
||||
## [1.12.0-rc.0] - [2025-03-22]
|
||||
|
||||
### Fixed
|
||||
- [#1508] Fix an issue where automatic compression of expressions menu icons would fail when the texture dimensions were
|
||||
not divisible by four.
|
||||
- [#1513] Expression menu icon compression broke on iOS builds
|
||||
|
||||
### Changed
|
||||
- [#1514] `Merge Blend Tree` is now `Merge Motion (Blend Tree)` and supports merging animation clips as well as blend trees
|
||||
|
||||
## [1.12.0-beta.0] - [2025-03-17]
|
||||
|
||||
### Added
|
||||
- [#1497] Added changelog to docs site
|
||||
- [#1482] Added support for replacing pre-existing animator controllers to `Merge Animator`
|
||||
- [#1481] Added [World Scale Object](https://m-a.nadena.dev/dev/docs/reference/world-scale-object)
|
||||
- [#1489] Added [`MA MMD Layer Control`](https://modular-avatar.nadena.dev/docs/general-behavior/mmd)
|
||||
|
||||
### Fixed
|
||||
- [#1492] Fixed incorrect icon and logo assets in prior prerelease
|
||||
- [#1489] Fixed compatibility issues between `Merge Blend Tree` or reactive components and MMD worlds.
|
||||
See [documentation](https://modular-avatar.nadena.dev/docs/general-behavior/mmd) for details on the new handling.
|
||||
- [#1501] Unity keyboard shortcuts don't work when editing text fields on the MA Parameters component
|
||||
- [#1410] Motion overrides on synced layers are not updated for Bone Proxy/Merge Armature object movement
|
||||
- [#1504] The internal `DelayDisable` layer no longer references unnecessary objects in some situations
|
||||
- This helps improve compatibility with AAO and other tools that track whether objects are animated
|
||||
|
||||
### Changed
|
||||
- [#1483] The Merge Animator "Match Avatar Write Defaults" option will no longer adjust write defaults on states in
|
||||
additive layers, or layers with only one state and no transitions.
|
||||
- [#1429] Merge Armature will now allow you to merge humanoid bones with PhysBones attached in certain cases.
|
||||
- Specifically, child humanoid bones (if there are any) must be excluded from all attached Physbones.
|
||||
- [#1437] Create Toggle for Selection now creates submenus as necessary when multiple items are selected, and creates toggles as children.
|
||||
- [#1499] When an audio source is controlled by an Object Toggle, disable the audio source when animations are blocked
|
||||
to avoid it unintentionally being constantly active.
|
||||
- [#1502] `World Fixed Object` now uses `VRCParentConstraint` and is therefore compatible with Android builds
|
||||
|
||||
## [1.12.0-alpha.2] - [2025-03-10]
|
||||
|
||||
### Added
|
||||
- Added CHANGELOG files
|
||||
|
||||
### Changed
|
||||
- [#1476] Switch ModularAvatarMergeAnimator and ModularAvatarMergeParameter to use new NDMF APIs (`IVirtualizeMotion` and `IVirtualizeAnimatorController`)
|
||||
|
||||
## Older versions
|
||||
|
||||
Please see CHANGELOG.md
|
3
CHANGELOG-PRERELEASE.md.meta
Normal file
3
CHANGELOG-PRERELEASE.md.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb586a9c85634b8b81015d16899d797b
|
||||
timeCreated: 1741571222
|
109
CHANGELOG-jp.md
Normal file
109
CHANGELOG-jp.md
Normal file
@ -0,0 +1,109 @@
|
||||
# Changelog
|
||||
|
||||
Modular Avatarの主な変更点をこのファイルで記録しています。
|
||||
なお、プレリリース版の変更点は `CHANGELOG-PRERELEASE.md` に記録されます。
|
||||
|
||||
この形式は [Keep a Changelog](https://keepachangelog.com/ja/1.0.0/) に基づいており、
|
||||
このプロジェクトは [Semantic Versioning](https://semver.org/lang/ja/) に従っています。
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- (実験的機能) VRC以外のプラットフォームのサポートを有効化
|
||||
|
||||
### Fixed
|
||||
|
||||
### Changed
|
||||
|
||||
### Removed
|
||||
|
||||
### Security
|
||||
|
||||
### Deprecated
|
||||
|
||||
## [1.12.5] - [2025-04-14]
|
||||
|
||||
### Fixed
|
||||
- [#1555] VRC Animator Play Audioが、Audio Sourceまでの絶対パスで設定されている場合に、相対パスのMerge Animator
|
||||
コンポーネントとマージされた場合、指定されたオブジェクトが存在しないことを検出し、参照を絶対パスとして扱うように修正
|
||||
- 対象のパスにオブジェクトがある場合は、相対パスとして扱われます。安定性向上のためMerge Animatorコンポーネントと同じ
|
||||
指定方法を使用することをお勧めします。
|
||||
- [#1558] Merge AnimatorでベースアバターのArmature内のTransformをアニメーションさせると壊れる問題を修正
|
||||
- NDMFの依存バージョンを更新
|
||||
- VRChat Avatar Descriptor内のレイヤーが重複している場合、すべてのアニメーターコンテンツが無視される問題を修正
|
||||
- 起動時に発生する `NullReferenceException` を修正
|
||||
- AnimationIndex内の `NullReferenceException` を修正
|
||||
- アニメーションカーブのパスが複数回書き換えられると削除される問題を修正
|
||||
|
||||
## [1.12.4] - [2025-04-10]
|
||||
|
||||
### Fixed
|
||||
- [#1552] Merge Blend Treeにて、メインアバターFXレイヤーと同じ名前のintやboolパラメーターがBlend Treeに含まれている場合、
|
||||
パラメーター型が修正されない問題を修正
|
||||
- [#1553] リアクティブコンポーネントが生成するステートに、WD設定が正しくない問題を修正
|
||||
|
||||
### Changed
|
||||
- [#1551] Merge Animatorは、遷移のない単一のstateを持つブレンドツリーのレイヤーに対して常にWDをONに設定します。
|
||||
- 一部、以前の挙動に依存したアセットとの互換性を向上させるための変更です。
|
||||
|
||||
## [1.12.3] - [2025-04-05]
|
||||
|
||||
### Fixed
|
||||
- Additiveレイヤーの問題を修正(NDMFバージョンアップグレードによって修正)
|
||||
|
||||
### Changed
|
||||
- [#1542] Merge Animatorは、アニメーションクリップを含む単一のstateを持つレイヤーに対してWD設定を一致させるが、
|
||||
ブレンドツリーを含む場合は一致させないように変更されました。
|
||||
- これにより、1.12で導入された互換性の問題が修正されます(1.12.0では、単一のstateアニメーションクリップに対してWD設定
|
||||
と一致しないように変更されました)。
|
||||
|
||||
## [1.12.2] - [2025-04-03]
|
||||
|
||||
### Fixed
|
||||
- [#1537] アニメーターパラメーターをアニメーションさせるカーブが、`Merge Motion` コンポーネントを使用して追加された場合、
|
||||
`Rename Parameters` によって更新されない問題を修正``
|
||||
|
||||
## [1.12.1] - [2025-04-02]
|
||||
|
||||
### Fixed
|
||||
- [#1532] Modular Avatarが新しく作成したプロジェクトでコンパイラエラーを出す問題を修正
|
||||
|
||||
## [1.12.0] - [2025-04-01]
|
||||
|
||||
### Added
|
||||
- CHANGELOGファイルを追加
|
||||
- [#1482] `Merge Animator` に既存のアニメーターコントローラーを置き換える機能を追加
|
||||
- [#1481] [World Scale Object](https://m-a.nadena.dev/ja/docs/reference/world-scale-object)を追加
|
||||
- [#1489] [`MA MMD Layer Control`](https://modular-avatar.nadena.dev/docs/general-behavior/mmd)を追加
|
||||
|
||||
### Fixed
|
||||
- [#1460] パラメーターアセットをMA Parametersにインポートするとき、ローカルのみのパラメーターが間違ってアニメーターのみ扱いになる問題を修正
|
||||
- [#1489] `Merge Blend Tree` やリアクティブコンポーネントとMMDワールドの互換性の問題を修正。
|
||||
- 詳細は[ドキュメント](https://modular-avatar.nadena.dev/docs/general-behavior/mmd)を参照してください。
|
||||
- この動作を無効にするには、新しい `MA VRChat Settings` コンポーネントをアバターの適当なところに追加して、適切な設定を無効にしてください。
|
||||
- [#1501] MA Parametersコンポーネントのテキスト入力欄を編集する際にUnityのキーボードショートカットが機能しない問題を修正
|
||||
- [#1410] 同期レイヤー内のモーションオーバーライドがBone Proxy/Merge Armatureオブジェクトの移動に対して更新されない問題を修正
|
||||
- [#1504] 一部の状況で内部の`DelayDisable`レイヤーが不要なオブジェクトを参照しないように変更
|
||||
- これにより、オブジェクトがアニメーションされているかどうかを追跡するAAOなどのツールとの互換性が向上します
|
||||
- [#1508] テクスチャのサイズが4の倍数でない場合に、エクスプレッションメニューアイコンの自動圧縮が失敗する問題を修正
|
||||
- [#1513] iOSビルドでエクスプレッションメニューアイコンの圧縮処理が壊れる問題を修正
|
||||
|
||||
### Changed
|
||||
- [#1529] `MA Parameters` の自動リネームと `MA Menu Item` の自動パラメーター機能は、オブジェクトのパスに基づいて名前
|
||||
を割り当てるように変更されました。
|
||||
- `MA Sync Parameter Sequence` を使用している場合は、このバージョンに更新した後、SyncedParamsアセットを空にして、
|
||||
すべてのプラットフォームを再アップロードすることをお勧めします。
|
||||
- [#1514] `Merge Blend Tree` は `Merge Motion (Blend Tree)` に改名され、アニメーションクリップにも対応するようになりました
|
||||
- [#1476] ModularAvatarMergeAnimator と ModularAvatarMergeParameter を新しい NDMF API (`IVirtualizeMotion` と `IVirtualizeAnimatorController`) を使用するように変更
|
||||
- [#1483] Merge Animator の 「アバターの Write Defaults 設定に合わせる」設定では、Additiveなレイヤー、および単一Stateかつ遷移のないレイヤー
|
||||
に対してはWrite Defaultsを調整しないように変更。
|
||||
- [#1429] Merge Armature は、特定の場合にPhysBoneに指定されたヒューマノイドボーンをマージできるようになりました。
|
||||
- 具体的には、子ヒューマノイドボーンがある場合はPhysBoneから除外される必要があります。
|
||||
- [#1437] Create Toggle for Selectionにおいて、複数選択時時に必要に応じてサブメニューを生成し、子としてトグルを生成するように変更されました。
|
||||
- [#1499] `Object Toggle`で制御される`Audio Source`がアニメーションブロックされたときに常にアクティブにならないように、
|
||||
アニメーションがブロックされたときにオーディオソースを無効にするように変更。
|
||||
- [#1502] `World Fixed Object` は `VRCParentConstraint` を使用するようになり、Androidビルドで使用可能になりました。
|
||||
|
||||
## それより前
|
||||
|
||||
GitHubのリリースページをご確認ください: https://github.com/bdunderscore/modular-avatar/releases
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1417544c34d9a4f4aacebf76247940a9
|
||||
guid: b27815ff13397374abcf9547a36bfaf4
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
117
CHANGELOG.md
117
CHANGELOG.md
@ -1 +1,116 @@
|
||||
Temporary test release
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
Changes between prerelease versions will be documented in `CHANGELOG-PRERELEASE.md` instead.
|
||||
|
||||
[日本語版はこちらです。](CHANGELOG-jp.md)
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- (Experimental feature) Enabled support for non-VRC platforms
|
||||
|
||||
### Fixed
|
||||
|
||||
### Changed
|
||||
|
||||
### Removed
|
||||
|
||||
### Security
|
||||
|
||||
### Deprecated
|
||||
|
||||
## [1.12.5] - [2025-04-14]
|
||||
|
||||
### Fixed
|
||||
- [#1555] Fixed compatibility regression from 1.11.x: VRC Animator Play Audio, when configured with an absolute path
|
||||
but merged with a relative-path merge animator component, will now detect that the indicated object does not
|
||||
exist, and treat the reference as an absolute path.
|
||||
- Note that if there is an object in the target path, then it will be treated as a relative path. Using
|
||||
addressing for Play Audio behaviors consistent with Merge Animator settings is therefore recommended as it will be
|
||||
more robust.
|
||||
- [#1558] Fixed an issue where Merge Animators animating transforms in the base avatar's armature would break.
|
||||
- Update NDMF dependency
|
||||
- Fixed an issue where duplicate layer entries in the VRChat Avatar Descriptor would cause all animator contents
|
||||
to be ignored.
|
||||
- Fixed a benign `NullReferenceException` at initialization
|
||||
- Fixed a NullReferenceException in AnimationIndex
|
||||
- Fixed an issue where animation curve paths being rewritten multiple times might be deleted
|
||||
|
||||
## [1.12.4] - [2025-04-10]
|
||||
|
||||
### Fixed
|
||||
- [#1552] Merge Blend Tree failed to correct parameter types when the main avatar FX layer contained an int or bool
|
||||
parameter with the same name as one used in the blend tree.
|
||||
- [#1553] Reactive components might generate states with incorrect write default settings
|
||||
|
||||
### Changed
|
||||
- [#1551] Merge Animator will always set WD ON for single-state blendtree layers with no any state transitions.
|
||||
- This fixes compatibility issues with assets which relied on the prior behavior.
|
||||
|
||||
## [1.12.3] - [2025-04-05]
|
||||
|
||||
### Fixed
|
||||
- Fixed issues with additive layers (via NDMF version upgrade)
|
||||
|
||||
### Changed
|
||||
- [#1542] Merge Animator now will match WD settings for layers with a single state containing an animation clip,
|
||||
but not if it contains a blend tree. This fixes some compatibility issues introduced in 1.12 (where the behavior
|
||||
was changed to not match WD settings for single-state animation clips).
|
||||
- [#1551] Merge Animator will always set WD ON for single-state blendtree layers with no any state transitions.
|
||||
|
||||
## [1.12.2] - [2025-04-03]
|
||||
|
||||
### Fixed
|
||||
- [#1537] Curves which animated animator parameters, when added using a `Merge Motion` component, would not be updated by
|
||||
`Rename Parameters`
|
||||
|
||||
## [1.12.1] - [2025-04-02]
|
||||
|
||||
### Fixed
|
||||
- [#1532] Modular Avatar has compiler errors in a newly created project
|
||||
|
||||
## [1.12.0] - [2025-04-01]
|
||||
|
||||
### Added
|
||||
- Added CHANGELOG files
|
||||
- [#1482] Added support for replacing pre-existing animator controllers to `Merge Animator`
|
||||
- [#1481] Added [World Scale Object](https://m-a.nadena.dev/docs/reference/world-scale-object)
|
||||
- [#1489] Added [`MA MMD Layer Control`](https://modular-avatar.nadena.dev/docs/general-behavior/mmd)
|
||||
|
||||
### Fixed
|
||||
- [#1460] When importing parameter assets in MA Parameters, "local only" parameters were incorrectly treated as
|
||||
"animator only"
|
||||
- [#1489] Fixed compatibility issues between `Merge Blend Tree` or reactive components and MMD worlds.
|
||||
- See [documentation](https://modular-avatar.nadena.dev/docs/general-behavior/mmd) for details on the new handling.
|
||||
- To disable this behavior, attach the new `MA VRChat Settings` component to any object on your avatar and disable the appropriate setting.
|
||||
- [#1501] Unity keyboard shortcuts don't work when editing text fields on the MA Parameters component
|
||||
- [#1410] Motion overrides on synced layers are not updated for Bone Proxy/Merge Armature object movement
|
||||
- [#1504] The internal `DelayDisable` layer no longer references unnecessary objects in some situations
|
||||
- This helps improve compatibility with AAO and other tools that track whether objects are animated
|
||||
- [#1508] Fix an issue where automatic compression of expressions menu icons would fail when the texture dimensions were
|
||||
not divisible by four.
|
||||
- [#1513] Expression menu icon compression broke on iOS builds
|
||||
|
||||
### Changed
|
||||
- [#1529] `MA Parameters` auto-rename and `MA Menu Item`'s automatic parameter feature now assign names based on the
|
||||
path of the object. This should improve compatibility with `MA Sync Parameter Sequence`
|
||||
- If you are using `MA Sync Parameter Sequence`, it's a good idea to empty your SyncedParams asset and reupload all
|
||||
platforms after updating to this version.
|
||||
- [#1514] `Merge Blend Tree` is now `Merge Motion (Blend Tree)` and supports merging animation clips as well as blend trees
|
||||
- [#1476] Switch ModularAvatarMergeAnimator and ModularAvatarMergeParameter to use new NDMF APIs (`IVirtualizeMotion` and `IVirtualizeAnimatorController`)
|
||||
- [#1483] The Merge Animator "Match Avatar Write Defaults" option will no longer adjust write defaults on states in
|
||||
additive layers, or layers with only one state and no transitions.
|
||||
- [#1429] Merge Armature will now allow you to merge humanoid bones with PhysBones attached in certain cases.
|
||||
- Specifically, child humanoid bones (if there are any) must be excluded from all attached Physbones.
|
||||
- [#1437] Create Toggle for Selection now creates submenus as necessary when multiple items are selected, and creates toggles as children.
|
||||
- [#1499] When an audio source is controlled by an Object Toggle, disable the audio source when animations are blocked
|
||||
to avoid it unintentionally being constantly active.
|
||||
- [#1502] `World Fixed Object` now uses `VRCParentConstraint` and is therefore compatible with Android builds
|
||||
|
||||
## Older versions
|
||||
|
||||
Please see the github releases page at https://github.com/bdunderscore/modular-avatar/releases
|
||||
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a7454bc513adb84d9ae85ed7e7268ba
|
||||
guid: fd88882c757966b4fa90915edb8487b1
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
15
COPYING.md
15
COPYING.md
@ -1,12 +1,11 @@
|
||||
Source code is licensed under the MIT license, as reproduced below, with some exceptions:
|
||||
Files under Editor/images are licensed for redistribution as part of an official
|
||||
modular avatar package only. Please replace them with other images (or delete them)
|
||||
if you are making modifications. If you're interested in using the Modular Avatar
|
||||
logo as part of your own asset's advertising, please refer to
|
||||
https://modular-avatar.nadena.dev/docs/distributing-prefabs/logo-usage .
|
||||
|
||||
All other files are under the MIT license.
|
||||
|
||||
* Packages/com.vrchat.core.vpm-resolver is distributed under the VRChat Distro license.
|
||||
See [the associated License.md file](Packages/com.vrchat.core.vpm-resolver/License.md) for details.
|
||||
* Images under docs/static/img/irasutoya are Copyrighted by, and/or a derivative work of works copyrighted by
|
||||
いらすとや (irasutoya.com). See [their license page](https://www.irasutoya.com/p/terms.html) for license details.
|
||||
* The github source code distribution contains placeholder logo assets. The
|
||||
[actual logo assets](https://github.com/bdunderscore/modular-avatar-images) are Copyright (c) Pumo,
|
||||
and for use as part of packaged official modular avatar distributions only.
|
||||
---
|
||||
|
||||
MIT License
|
||||
|
153
Editor/ActiveAnimationRetargeter.cs
Normal file
153
Editor/ActiveAnimationRetargeter.cs
Normal file
@ -0,0 +1,153 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using nadena.dev.modular_avatar.animation;
|
||||
using nadena.dev.ndmf.animator;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using EditorCurveBinding = UnityEditor.EditorCurveBinding;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
/// <summary>
|
||||
/// The class to retarget m_IsActive animation to moved multiple objects
|
||||
/// </summary>
|
||||
internal class ActiveAnimationRetargeter
|
||||
{
|
||||
private readonly BuildContext _context;
|
||||
private readonly BoneDatabase _boneDatabase;
|
||||
private readonly AnimatorServicesContext _asc;
|
||||
private readonly List<IntermediateObj> _intermediateObjs = new List<IntermediateObj>();
|
||||
|
||||
/// <summary>
|
||||
/// Tracks an object whose Active state is animated, and which leads up to this Merge Animator component.
|
||||
/// We use this tracking data to create proxy objects within the main armature, which track the same active
|
||||
/// state.
|
||||
/// </summary>
|
||||
struct IntermediateObj
|
||||
{
|
||||
/// <summary>
|
||||
/// The path of original object
|
||||
/// </summary>
|
||||
public string OriginalPath;
|
||||
|
||||
/// <summary>
|
||||
/// Name of the intermediate object. Used to name proxy objects.
|
||||
/// </summary>
|
||||
public string Name;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this object is initially active.
|
||||
/// </summary>
|
||||
public bool InitiallyActive;
|
||||
|
||||
/// <summary>
|
||||
/// List of created Intermediate Objects
|
||||
/// </summary>
|
||||
public List<GameObject> Created;
|
||||
}
|
||||
|
||||
public ActiveAnimationRetargeter(
|
||||
BuildContext context,
|
||||
BoneDatabase boneDatabase,
|
||||
Transform root
|
||||
)
|
||||
{
|
||||
_context = context;
|
||||
_boneDatabase = boneDatabase;
|
||||
_asc = context.PluginBuildContext.Extension<AnimatorServicesContext>();
|
||||
|
||||
while (root != null && !RuntimeUtil.IsAvatarRoot(root))
|
||||
{
|
||||
var originalPath = RuntimeUtil.AvatarRootPath(root.gameObject);
|
||||
System.Diagnostics.Debug.Assert(originalPath != null);
|
||||
|
||||
if (_asc.AnimationIndex.GetClipsForObjectPath(originalPath).Any(clip =>
|
||||
GetActiveBinding(clip, originalPath) != null
|
||||
))
|
||||
{
|
||||
_intermediateObjs.Add(new IntermediateObj
|
||||
{
|
||||
OriginalPath = originalPath,
|
||||
Name = $"{root.gameObject.name}${Guid.NewGuid()}",
|
||||
InitiallyActive = root.gameObject.activeSelf,
|
||||
Created = new List<GameObject>(),
|
||||
});
|
||||
}
|
||||
|
||||
root = root.parent;
|
||||
}
|
||||
|
||||
// currently _intermediateObjs is in child -> parent order.
|
||||
// we want parent -> child order so reverse entire list
|
||||
_intermediateObjs.Reverse();
|
||||
}
|
||||
|
||||
public IEnumerable<GameObject> AddedGameObjects => _intermediateObjs.SelectMany(x => x.Created);
|
||||
|
||||
public GameObject CreateIntermediateObjects(GameObject sourceBone)
|
||||
{
|
||||
for (var i = 0; i < _intermediateObjs.Count; i++)
|
||||
{
|
||||
var intermediate = _intermediateObjs[i];
|
||||
var preexisting = sourceBone.transform.Find(intermediate.Name);
|
||||
if (preexisting != null)
|
||||
{
|
||||
sourceBone = preexisting.gameObject;
|
||||
continue;
|
||||
}
|
||||
|
||||
var switchObj = new GameObject(intermediate.Name);
|
||||
switchObj.transform.SetParent(sourceBone.transform, false);
|
||||
switchObj.transform.localPosition = Vector3.zero;
|
||||
switchObj.transform.localRotation = Quaternion.identity;
|
||||
switchObj.transform.localScale = Vector3.one;
|
||||
switchObj.SetActive(intermediate.InitiallyActive);
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
// This new leaf can break parent bone physbones. Add a PB Blocker
|
||||
// to prevent this becoming an issue.
|
||||
switchObj.GetOrAddComponent<ModularAvatarPBBlocker>();
|
||||
}
|
||||
|
||||
intermediate.Created.Add(switchObj);
|
||||
|
||||
sourceBone = switchObj;
|
||||
|
||||
// Ensure mesh retargeting looks through this
|
||||
_boneDatabase.AddMergedBone(sourceBone.transform);
|
||||
_boneDatabase.RetainMergedBone(sourceBone.transform);
|
||||
}
|
||||
|
||||
return sourceBone;
|
||||
}
|
||||
|
||||
public void FixupAnimations()
|
||||
{
|
||||
foreach (var intermediate in _intermediateObjs)
|
||||
{
|
||||
var path = intermediate.OriginalPath;
|
||||
|
||||
foreach (var clip in _asc.AnimationIndex.GetClipsForObjectPath(path))
|
||||
{
|
||||
var curve = GetActiveBinding(clip, path);
|
||||
if (curve != null)
|
||||
{
|
||||
foreach (var mapping in intermediate.Created)
|
||||
{
|
||||
clip.SetFloatCurve(_asc.ObjectPathRemapper.GetVirtualPathForObject(mapping), typeof(GameObject), "m_IsActive",
|
||||
curve);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AnimationCurve GetActiveBinding(VirtualClip clip, string path)
|
||||
{
|
||||
return clip.GetFloatCurve(EditorCurveBinding.FloatCurve(path, typeof(GameObject), "m_IsActive"));
|
||||
}
|
||||
}
|
||||
}
|
3
Editor/ActiveAnimationRetargeter.cs.meta
Normal file
3
Editor/ActiveAnimationRetargeter.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ebce0ceba4d48c48992702b5c446936
|
||||
timeCreated: 1691915242
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1058b5946fb23674cad310b1f4bd5b61
|
||||
guid: 9aeea331419795c41a97112c489b1632
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
46
Editor/Animation/FixupAbsolutePlayAudioPass.cs
Normal file
46
Editor/Animation/FixupAbsolutePlayAudioPass.cs
Normal file
@ -0,0 +1,46 @@
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
|
||||
using System.Linq;
|
||||
using nadena.dev.modular_avatar.core;
|
||||
using nadena.dev.ndmf;
|
||||
using nadena.dev.ndmf.animator;
|
||||
using VRC.SDK3.Avatars.Components;
|
||||
|
||||
namespace nadena.dev.modular_avatar.animation
|
||||
{
|
||||
[RunsOnPlatforms(WellKnownPlatforms.VRChatAvatar30)]
|
||||
public class FixupAbsolutePlayAudioPass : Pass<FixupAbsolutePlayAudioPass>
|
||||
{
|
||||
protected override void Execute(BuildContext context)
|
||||
{
|
||||
// Older versions of modular avatar did not adjust Animator Play Audio paths when they were absolute paths.
|
||||
// Replicate this behavior here.
|
||||
|
||||
// Note that this runs before any object movement.
|
||||
|
||||
var asc = context.Extension<AnimatorServicesContext>();
|
||||
|
||||
foreach (var mama in context.AvatarRootTransform.GetComponentsInChildren<ModularAvatarMergeAnimator>(true))
|
||||
{
|
||||
if (!mama._wasRelative) continue;
|
||||
|
||||
var pathPrefix = asc.ObjectPathRemapper.GetVirtualPathForObject(mama.gameObject) + "/";
|
||||
|
||||
foreach (var state in asc.ControllerContext.Controllers[mama].AllReachableNodes()
|
||||
.OfType<VirtualState>())
|
||||
{
|
||||
foreach (var behavior in state.Behaviours.OfType<VRCAnimatorPlayAudio>())
|
||||
{
|
||||
if (asc.ObjectPathRemapper.GetObjectForPath(behavior.SourcePath) != null) continue;
|
||||
if (behavior.SourcePath.StartsWith(pathPrefix))
|
||||
{
|
||||
behavior.SourcePath = behavior.SourcePath.Substring(pathPrefix.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
3
Editor/Animation/FixupAbsolutePlayAudioPass.cs.meta
Normal file
3
Editor/Animation/FixupAbsolutePlayAudioPass.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a763cbc4bac94063b6b084ea3f4d8206
|
||||
timeCreated: 1744422528
|
128
Editor/Animation/GameObjectDisableDelayPass.cs
Normal file
128
Editor/Animation/GameObjectDisableDelayPass.cs
Normal file
@ -0,0 +1,128 @@
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
using System.Linq;
|
||||
using nadena.dev.modular_avatar.core.editor;
|
||||
using nadena.dev.ndmf;
|
||||
using nadena.dev.ndmf.animator;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Animations;
|
||||
using UnityEngine;
|
||||
using VRC.SDK3.Avatars.Components;
|
||||
using BuildContext = nadena.dev.ndmf.BuildContext;
|
||||
|
||||
namespace nadena.dev.modular_avatar.animation
|
||||
{
|
||||
/// <summary>
|
||||
/// This pass delays turning GameObjects OFF by one frame when those objects control a ReadableProperty. This
|
||||
/// ensures that we don't expose hidden meshes when removing articles of clothing, for example.
|
||||
/// </summary>
|
||||
internal class GameObjectDelayDisablePass : Pass<GameObjectDelayDisablePass>
|
||||
{
|
||||
protected override void Execute(BuildContext context)
|
||||
{
|
||||
var asc = context.Extension<AnimatorServicesContext>();
|
||||
var activeProxies = context.GetState<ReadablePropertyExtension.Retained>().proxyProps
|
||||
.ToDictionary(kv => kv.Key, kv => kv.Value);
|
||||
if (activeProxies.Count == 0) return;
|
||||
|
||||
// Filter any proxies not used in animator transitions
|
||||
var usedProxies = asc.ControllerContext.Controllers[VRCAvatarDescriptor.AnimLayerType.FX]
|
||||
.AllReachableNodes().OfType<VirtualTransitionBase>()
|
||||
.SelectMany(t => t.Conditions)
|
||||
.Select(c => c.parameter)
|
||||
.ToHashSet();
|
||||
|
||||
foreach (var proxyBinding in activeProxies.ToList())
|
||||
{
|
||||
if (!usedProxies.Contains(proxyBinding.Value))
|
||||
{
|
||||
activeProxies.Remove(proxyBinding.Key);
|
||||
}
|
||||
}
|
||||
|
||||
var fx = asc.ControllerContext.Controllers[VRCAvatarDescriptor.AnimLayerType.FX];
|
||||
if (fx == null) return;
|
||||
|
||||
var nullMotion = new AnimationClip();
|
||||
nullMotion.name = "NullMotion";
|
||||
|
||||
var blendTree = new BlendTree();
|
||||
blendTree.blendType = BlendTreeType.Direct;
|
||||
blendTree.useAutomaticThresholds = false;
|
||||
|
||||
blendTree.children = activeProxies
|
||||
.Select(prop => GenerateDelayChild(nullMotion, (prop.Key, prop.Value)))
|
||||
.ToArray();
|
||||
|
||||
var layer = fx.AddLayer(LayerPriority.Default, "DelayDisable");
|
||||
var state = layer.StateMachine.AddState("DelayDisable");
|
||||
layer.StateMachine.DefaultState = state;
|
||||
|
||||
state.WriteDefaultValues = true;
|
||||
state.Motion = asc.ControllerContext.Clone(blendTree);
|
||||
|
||||
// Ensure the initial state of readable props matches the actual state of the gameobject
|
||||
foreach (var controller in asc.ControllerContext.GetAllControllers())
|
||||
{
|
||||
foreach (var (binding, prop) in activeProxies)
|
||||
{
|
||||
var obj = asc.ObjectPathRemapper.GetObjectForPath(binding.path);
|
||||
|
||||
if (obj != null && controller.Parameters.TryGetValue(prop, out var p))
|
||||
{
|
||||
p.defaultFloat = obj.activeSelf ? 1 : 0;
|
||||
controller.Parameters = controller.Parameters.SetItem(prop, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ChildMotion GenerateDelayChild(Motion nullMotion, (EditorCurveBinding, string) binding)
|
||||
{
|
||||
var ecb = binding.Item1;
|
||||
var prop = binding.Item2;
|
||||
|
||||
var motion = new AnimationClip();
|
||||
var curve = new AnimationCurve();
|
||||
curve.AddKey(0, 1);
|
||||
AnimationUtility.SetEditorCurve(motion, ecb, curve);
|
||||
|
||||
// Occasionally, we'll have a very small value pop up, probably due to FP errors.
|
||||
// To correct for this, instead of directly using the property in the direct blend tree,
|
||||
// we'll use a 1D blend tree to give ourselves a buffer.
|
||||
|
||||
var bufferBlendTree = new BlendTree();
|
||||
bufferBlendTree.blendType = BlendTreeType.Simple1D;
|
||||
bufferBlendTree.useAutomaticThresholds = false;
|
||||
bufferBlendTree.blendParameter = prop;
|
||||
bufferBlendTree.children = new[]
|
||||
{
|
||||
new ChildMotion
|
||||
{
|
||||
motion = nullMotion,
|
||||
timeScale = 1,
|
||||
threshold = 0
|
||||
},
|
||||
new ChildMotion
|
||||
{
|
||||
motion = nullMotion,
|
||||
timeScale = 1,
|
||||
threshold = 0.01f
|
||||
},
|
||||
new ChildMotion
|
||||
{
|
||||
motion = motion,
|
||||
timeScale = 1,
|
||||
threshold = 1
|
||||
}
|
||||
};
|
||||
|
||||
return new ChildMotion
|
||||
{
|
||||
motion = bufferBlendTree,
|
||||
directBlendParameter = MergeBlendTreePass.ALWAYS_ONE,
|
||||
timeScale = 1
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
3
Editor/Animation/GameObjectDisableDelayPass.cs.meta
Normal file
3
Editor/Animation/GameObjectDisableDelayPass.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b3eb561f76b459fbfbcf29fc4484261
|
||||
timeCreated: 1722222066
|
248
Editor/Animation/MMDRelayPass.cs
Normal file
248
Editor/Animation/MMDRelayPass.cs
Normal file
@ -0,0 +1,248 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using nadena.dev.modular_avatar.core;
|
||||
using nadena.dev.modular_avatar.core.editor;
|
||||
using nadena.dev.ndmf;
|
||||
using nadena.dev.ndmf.animator;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Animations;
|
||||
using UnityEngine;
|
||||
using VRC.SDK3.Avatars.Components;
|
||||
using VRC.SDKBase;
|
||||
using BuildContext = nadena.dev.ndmf.BuildContext;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace nadena.dev.modular_avatar.animation
|
||||
{
|
||||
internal class MMDRelayState
|
||||
{
|
||||
internal HashSet<VirtualLayer> mmdAffectedOriginalLayers = new();
|
||||
}
|
||||
|
||||
[RunsOnPlatforms(WellKnownPlatforms.VRChatAvatar30)]
|
||||
internal class MMDRelayEarlyPass : Pass<MMDRelayEarlyPass>
|
||||
{
|
||||
protected override void Execute(BuildContext context)
|
||||
{
|
||||
if (!MMDRelayPass.ShouldRun(context)) return;
|
||||
|
||||
var asc = context.Extension<AnimatorServicesContext>();
|
||||
if (asc.ControllerContext.Controllers.TryGetValue(VRCAvatarDescriptor.AnimLayerType.FX, out var fx))
|
||||
{
|
||||
context.GetState<MMDRelayState>().mmdAffectedOriginalLayers = new HashSet<VirtualLayer>(
|
||||
fx.Layers.Skip(1).Take(2)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Many MMD worlds animate the first three FX layers to weight zero. When MA injects new layers, this can hit
|
||||
/// unintended layers (eg the RC base state layer).
|
||||
/// To work around this, we'll inject a layer which will relay its active state into a parameter; then, we add a
|
||||
/// layer to relay this to layers which should be affected. Finally, any layer which _shouldn't_ be affected is
|
||||
/// pushed out of the first three layers by injecting dummy layers.
|
||||
/// </summary>
|
||||
[RunsOnPlatforms(WellKnownPlatforms.VRChatAvatar30)]
|
||||
internal class MMDRelayPass : Pass<MMDRelayPass>
|
||||
{
|
||||
private const string MMDRelayParam = "__MA/Internal/MMDNotActive";
|
||||
internal const string ControlLayerName = "Modular Avatar: MMD Control";
|
||||
internal const string DummyLayerName = "Modular Avatar: MMD Dummy";
|
||||
internal const string StateNameInitial = "Initial";
|
||||
internal const string StateNameNotMMD = "NotMMD";
|
||||
internal const string StateNameMMD = "MMD";
|
||||
|
||||
internal static bool ShouldRun(BuildContext context)
|
||||
{
|
||||
var settings = context.AvatarRootObject.GetComponentsInChildren<ModularAvatarVRChatSettings>(true);
|
||||
return settings.FirstOrDefault()?.MMDWorldSupport ?? true;
|
||||
}
|
||||
|
||||
protected override void Execute(BuildContext context)
|
||||
{
|
||||
if (!ShouldRun(context)) return;
|
||||
|
||||
var asc = context.Extension<AnimatorServicesContext>();
|
||||
if (!asc.ControllerContext.Controllers.TryGetValue(VRCAvatarDescriptor.AnimLayerType.FX, out var fx))
|
||||
return;
|
||||
|
||||
var affectedLayers = context.GetState<MMDRelayState>().mmdAffectedOriginalLayers;
|
||||
|
||||
foreach (var layer in fx.Layers)
|
||||
{
|
||||
if (layer.StateMachine == null) continue;
|
||||
|
||||
var rootMMDModeBehaviors = layer.StateMachine.Behaviours
|
||||
.OfType<ModularAvatarMMDLayerControl>()
|
||||
.ToList();
|
||||
|
||||
if (rootMMDModeBehaviors.Count == 0) continue;
|
||||
if (rootMMDModeBehaviors.Count > 1)
|
||||
{
|
||||
ErrorReport.ReportError(Localization.L, ErrorSeverity.Error,
|
||||
"error.mmd.multiple_mmd_mode_behaviors", layer.Name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rootMMDModeBehaviors[0].DisableInMMDMode)
|
||||
{
|
||||
affectedLayers.Add(layer);
|
||||
}
|
||||
else
|
||||
{
|
||||
affectedLayers.Remove(layer);
|
||||
}
|
||||
|
||||
layer.StateMachine.Behaviours = layer.StateMachine.Behaviours
|
||||
.Where(b => b is not ModularAvatarMMDLayerControl).ToImmutableList();
|
||||
Object.DestroyImmediate(rootMMDModeBehaviors[0]);
|
||||
|
||||
// check for child behaviors
|
||||
// TODO: implement filtering on AllReachableNodes
|
||||
foreach (var node in layer.AllReachableNodes())
|
||||
{
|
||||
if (node is VirtualState state)
|
||||
{
|
||||
if (state.Behaviours.Any(b => b is ModularAvatarMMDLayerControl))
|
||||
{
|
||||
ErrorReport.ReportError(Localization.L, ErrorSeverity.Error,
|
||||
"error.mmd.mmd_mode_in_child_state", layer.Name, state.Name);
|
||||
}
|
||||
}
|
||||
else if (node is VirtualStateMachine vsm)
|
||||
{
|
||||
if (vsm.Behaviours.Any(b => b is ModularAvatarMMDLayerControl))
|
||||
{
|
||||
ErrorReport.ReportError(Localization.L, ErrorSeverity.Error,
|
||||
"error.mmd.mmd_mode_in_child_state_machine", layer.Name, vsm.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var needsAdjustment = fx.Layers.Select((layer, index) => (layer, index))
|
||||
.Any(pair => affectedLayers.Contains(pair.layer) != (pair.index < 3 && pair.index != 0));
|
||||
if (!needsAdjustment) return;
|
||||
|
||||
var toDisable = fx.Layers.Where(l => affectedLayers.Contains(l))
|
||||
.Select(l => l.VirtualLayerIndex)
|
||||
.ToList();
|
||||
|
||||
fx.Parameters = fx.Parameters.Add(MMDRelayParam, new AnimatorControllerParameter
|
||||
{
|
||||
name = MMDRelayParam,
|
||||
type = AnimatorControllerParameterType.Float,
|
||||
defaultFloat = 0
|
||||
});
|
||||
|
||||
var currentLayers = fx.Layers.ToList();
|
||||
var newLayers = new List<VirtualLayer>();
|
||||
|
||||
// Layer zero's weight can't be changed anyway, so leave it where it is.
|
||||
newLayers.Add(currentLayers[0]);
|
||||
currentLayers.RemoveAt(0);
|
||||
newLayers.Add(CreateMMDLayer(fx, toDisable));
|
||||
|
||||
// Add a dummy layer
|
||||
var dummy = fx.AddLayer(new LayerPriority(0), DummyLayerName);
|
||||
var s = dummy.StateMachine!.DefaultState = dummy.StateMachine.AddState("Dummy");
|
||||
s.Motion = VirtualClip.Create("empty");
|
||||
newLayers.Add(dummy);
|
||||
|
||||
fx.Layers = newLayers.Concat(currentLayers);
|
||||
}
|
||||
|
||||
private static VirtualLayer CreateMMDLayer(VirtualAnimatorController fx, List<int> virtualLayers)
|
||||
{
|
||||
// We'll reorder this later, so the layer priority doesn't matter
|
||||
var mmdControl = fx.AddLayer(new LayerPriority(0), ControlLayerName);
|
||||
var stateMachine = mmdControl.StateMachine ?? throw new Exception("No state machine on MMD Control layer");
|
||||
|
||||
var motion = VirtualClip.Create("MMDRelay");
|
||||
motion.SetFloatCurve(EditorCurveBinding.FloatCurve("", typeof(Animator), MMDRelayParam),
|
||||
AnimationCurve.Constant(0, 1, 1)
|
||||
);
|
||||
|
||||
var state_initial = stateMachine.AddState(StateNameInitial);
|
||||
state_initial.Motion = motion;
|
||||
|
||||
var state_notmmd = stateMachine.AddState(StateNameNotMMD);
|
||||
state_notmmd.Motion = motion;
|
||||
|
||||
var state_mmd = stateMachine.AddState(StateNameMMD);
|
||||
state_mmd.Motion = motion;
|
||||
|
||||
var t = VirtualStateTransition.Create();
|
||||
t.SetDestination(state_mmd);
|
||||
t.Conditions = ImmutableList.Create(new AnimatorCondition
|
||||
{
|
||||
mode = AnimatorConditionMode.Less,
|
||||
parameter = MMDRelayParam,
|
||||
threshold = 0.5f
|
||||
});
|
||||
|
||||
state_notmmd.Transitions = ImmutableList.Create(t);
|
||||
|
||||
t = VirtualStateTransition.Create();
|
||||
t.SetDestination(state_notmmd);
|
||||
t.Conditions = ImmutableList.Create(new AnimatorCondition
|
||||
{
|
||||
mode = AnimatorConditionMode.Greater,
|
||||
parameter = MMDRelayParam,
|
||||
threshold = 0.5f
|
||||
});
|
||||
|
||||
state_mmd.Transitions = ImmutableList.Create(t);
|
||||
|
||||
t = VirtualStateTransition.Create();
|
||||
t.SetDestination(state_mmd);
|
||||
t.Conditions = ImmutableList.Create(new AnimatorCondition
|
||||
{
|
||||
mode = AnimatorConditionMode.Less,
|
||||
parameter = MMDRelayParam,
|
||||
threshold = 0.5f
|
||||
});
|
||||
|
||||
state_initial.Transitions = ImmutableList.Create(t);
|
||||
|
||||
stateMachine.DefaultState = state_initial;
|
||||
|
||||
var mmd_behaviors = ImmutableList.CreateBuilder<StateMachineBehaviour>();
|
||||
var notmmd_behaviors = ImmutableList.CreateBuilder<StateMachineBehaviour>();
|
||||
|
||||
foreach (var index in virtualLayers)
|
||||
{
|
||||
var behavior = ScriptableObject.CreateInstance<VRCAnimatorLayerControl>();
|
||||
behavior.layer = index;
|
||||
behavior.playable = VRC_AnimatorLayerControl.BlendableLayer.FX;
|
||||
behavior.goalWeight = 0;
|
||||
behavior.blendDuration = 0;
|
||||
|
||||
mmd_behaviors.Add(behavior);
|
||||
|
||||
behavior = ScriptableObject.CreateInstance<VRCAnimatorLayerControl>();
|
||||
behavior.layer = index;
|
||||
behavior.playable = VRC_AnimatorLayerControl.BlendableLayer.FX;
|
||||
behavior.goalWeight = 1;
|
||||
behavior.blendDuration = 0;
|
||||
|
||||
notmmd_behaviors.Add(behavior);
|
||||
}
|
||||
|
||||
state_notmmd.Behaviours = notmmd_behaviors.ToImmutable();
|
||||
state_mmd.Behaviours = mmd_behaviors.ToImmutable();
|
||||
|
||||
return mmdControl;
|
||||
}
|
||||
|
||||
internal static bool IsRelayLayer(string layerName)
|
||||
{
|
||||
return layerName == ControlLayerName || layerName == DummyLayerName;
|
||||
}
|
||||
}
|
||||
}
|
3
Editor/Animation/MMDRelayPass.cs.meta
Normal file
3
Editor/Animation/MMDRelayPass.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 163fd3d0edea43d5969395079f561986
|
||||
timeCreated: 1741745889
|
82
Editor/Animation/ReadablePropertyExtension.cs
Normal file
82
Editor/Animation/ReadablePropertyExtension.cs
Normal file
@ -0,0 +1,82 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using nadena.dev.ndmf;
|
||||
using nadena.dev.ndmf.animator;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace nadena.dev.modular_avatar.animation
|
||||
{
|
||||
[DependsOnContext(typeof(AnimatorServicesContext))]
|
||||
internal class ReadablePropertyExtension : IExtensionContext
|
||||
{
|
||||
// This is a temporary hack for GameObjectDelayDisablePass
|
||||
public class Retained
|
||||
{
|
||||
public Dictionary<EditorCurveBinding, string> proxyProps = new();
|
||||
}
|
||||
|
||||
private AnimatorServicesContext? _asc;
|
||||
private Retained _retained = null!;
|
||||
|
||||
private AnimatorServicesContext asc =>
|
||||
_asc ?? throw new InvalidOperationException("ActiveSelfProxyExtension is not active");
|
||||
|
||||
private Dictionary<EditorCurveBinding, string> proxyProps => _retained.proxyProps;
|
||||
private int index;
|
||||
|
||||
public IEnumerable<(EditorCurveBinding, string)> ActiveProxyProps =>
|
||||
proxyProps.Select(kvp => (kvp.Key, kvp.Value));
|
||||
|
||||
public string GetActiveSelfProxy(GameObject obj)
|
||||
{
|
||||
var path = asc.ObjectPathRemapper.GetVirtualPathForObject(obj);
|
||||
var ecb = EditorCurveBinding.FloatCurve(path, typeof(GameObject), "m_IsActive");
|
||||
|
||||
if (proxyProps.TryGetValue(ecb, out var prop)) return prop;
|
||||
|
||||
prop = $"__MA/ActiveSelfProxy/{obj.name}##{index++}";
|
||||
proxyProps[ecb] = prop;
|
||||
|
||||
// Add prop to all animators
|
||||
foreach (var animator in asc.ControllerContext.GetAllControllers())
|
||||
{
|
||||
animator.Parameters = animator.Parameters.SetItem(
|
||||
prop,
|
||||
new AnimatorControllerParameter
|
||||
{
|
||||
name = prop,
|
||||
type = AnimatorControllerParameterType.Float,
|
||||
defaultFloat = obj.activeSelf ? 1 : 0
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
public void OnActivate(BuildContext context)
|
||||
{
|
||||
_asc = context.Extension<AnimatorServicesContext>();
|
||||
_retained = context.GetState<Retained>();
|
||||
}
|
||||
|
||||
public void OnDeactivate(BuildContext context)
|
||||
{
|
||||
asc.AnimationIndex.EditClipsByBinding(proxyProps.Keys, clip =>
|
||||
{
|
||||
foreach (var b in clip.GetFloatCurveBindings().ToList())
|
||||
{
|
||||
if (proxyProps.TryGetValue(b, out var proxyProp))
|
||||
{
|
||||
var curve = clip.GetFloatCurve(b);
|
||||
clip.SetFloatCurve("", typeof(Animator), proxyProp, curve);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
3
Editor/Animation/ReadablePropertyExtension.cs.meta
Normal file
3
Editor/Animation/ReadablePropertyExtension.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 511cbc0373a2469192e0351e2222a203
|
||||
timeCreated: 1732496091
|
58
Editor/ApplyAnimatorDefaultValuesPass.cs
Normal file
58
Editor/ApplyAnimatorDefaultValuesPass.cs
Normal file
@ -0,0 +1,58 @@
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
#region
|
||||
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using nadena.dev.ndmf;
|
||||
using nadena.dev.ndmf.animator;
|
||||
using UnityEditor.Animations;
|
||||
using UnityEngine;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
[RunsOnPlatforms(WellKnownPlatforms.VRChatAvatar30)]
|
||||
internal class ApplyAnimatorDefaultValuesPass : Pass<ApplyAnimatorDefaultValuesPass>
|
||||
{
|
||||
protected override void Execute(ndmf.BuildContext context)
|
||||
{
|
||||
if (!context.AvatarDescriptor) return;
|
||||
|
||||
var values = context.GetState<DefaultValues>()?.InitialValueOverrides
|
||||
?? ImmutableDictionary<string, float>.Empty;
|
||||
|
||||
var asc = context.Extension<AnimatorServicesContext>();
|
||||
|
||||
foreach (var controller in asc.ControllerContext.GetAllControllers())
|
||||
{
|
||||
var parameters = controller.Parameters;
|
||||
foreach (var (name, parameter) in parameters)
|
||||
{
|
||||
if (!values.TryGetValue(name, out var defaultValue)) continue;
|
||||
|
||||
switch (parameter.type)
|
||||
{
|
||||
case AnimatorControllerParameterType.Bool:
|
||||
parameter.defaultBool = defaultValue != 0.0f;
|
||||
break;
|
||||
case AnimatorControllerParameterType.Int:
|
||||
parameter.defaultInt = Mathf.RoundToInt(defaultValue);
|
||||
break;
|
||||
case AnimatorControllerParameterType.Float:
|
||||
parameter.defaultFloat = defaultValue;
|
||||
break;
|
||||
default:
|
||||
continue; // unhandled type, e.g. trigger
|
||||
}
|
||||
|
||||
parameters = parameters.SetItem(name, parameter);
|
||||
}
|
||||
|
||||
controller.Parameters = parameters;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
3
Editor/ApplyAnimatorDefaultValuesPass.cs.meta
Normal file
3
Editor/ApplyAnimatorDefaultValuesPass.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e8f311932a744459aed7d22dee0e126c
|
||||
timeCreated: 1707045893
|
79
Editor/AvatarProcessor.cs
Normal file
79
Editor/AvatarProcessor.cs
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 bd_
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#region
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using nadena.dev.modular_avatar.ui;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
#endregion
|
||||
|
||||
[assembly: InternalsVisibleTo("Tests")]
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
public class AvatarProcessor
|
||||
{
|
||||
[MenuItem(UnityMenuItems.GameObject_ManualBake, true, UnityMenuItems.GameObject_ManualBakeOrder)]
|
||||
static bool ValidateApplyToCurrentAvatarGameobject()
|
||||
{
|
||||
return ValidateApplyToCurrentAvatar();
|
||||
}
|
||||
|
||||
[MenuItem(UnityMenuItems.GameObject_ManualBake, false, UnityMenuItems.GameObject_ManualBakeOrder)]
|
||||
static void ApplyToCurrentAvatarGameobject()
|
||||
{
|
||||
ApplyToCurrentAvatar();
|
||||
}
|
||||
|
||||
[MenuItem(UnityMenuItems.TopMenu_ManualBakeAvatar, true, UnityMenuItems.TopMenu_ManualBakeAvatarOrder)]
|
||||
private static bool ValidateApplyToCurrentAvatar()
|
||||
{
|
||||
return ndmf.AvatarProcessor.CanProcessObject(Selection.activeGameObject);
|
||||
}
|
||||
|
||||
[MenuItem("Tools/Modular Avatar/Manual bake avatar", false)]
|
||||
private static void ApplyToCurrentAvatar()
|
||||
{
|
||||
ndmf.AvatarProcessor.ProcessAvatarUI(Selection.activeGameObject);
|
||||
}
|
||||
|
||||
public static void ProcessAvatar(GameObject avatarGameObject)
|
||||
{
|
||||
ndmf.AvatarProcessor.ProcessAvatar(avatarGameObject);
|
||||
}
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
// ReSharper disable once MemberCanBeMadeStatic.Global
|
||||
[Obsolete("This is only for compile time compatibility with legacy AAO")]
|
||||
public int callbackOrder => throw new NotImplementedException();
|
||||
|
||||
[Obsolete("This is only for compile time compatibility with legacy AAO")]
|
||||
// ReSharper disable once MemberCanBeMadeStatic.Global
|
||||
public bool OnPreprocessAvatar(GameObject avatarGameObject) => throw new NotImplementedException();
|
||||
}
|
||||
}
|
0
Packages/nadena.dev.modular-avatar/Editor/AvatarProcessor.cs.meta → Editor/AvatarProcessor.cs.meta
0
Packages/nadena.dev.modular-avatar/Editor/AvatarProcessor.cs.meta → Editor/AvatarProcessor.cs.meta
159
Editor/BlendshapeSyncAnimationProcessor.cs
Normal file
159
Editor/BlendshapeSyncAnimationProcessor.cs
Normal file
@ -0,0 +1,159 @@
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using nadena.dev.modular_avatar.editor.ErrorReporting;
|
||||
using nadena.dev.ndmf.animator;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
/**
|
||||
* Ensures that any blendshapes marked for syncing by BlendshapeSync propagate values in all animation clips.
|
||||
*
|
||||
* Note that we only look at the FX layer, as any other layer won't work properly with mirror reflections anyway.
|
||||
*/
|
||||
internal class BlendshapeSyncAnimationProcessor
|
||||
{
|
||||
private readonly ndmf.BuildContext _context;
|
||||
private Dictionary<SummaryBinding, List<SummaryBinding>> _bindingMappings;
|
||||
|
||||
internal BlendshapeSyncAnimationProcessor(ndmf.BuildContext context)
|
||||
{
|
||||
_context = context;
|
||||
_bindingMappings = new Dictionary<SummaryBinding, List<SummaryBinding>>();
|
||||
}
|
||||
|
||||
private struct SummaryBinding : IEquatable<SummaryBinding>
|
||||
{
|
||||
private const string PREFIX = "blendShape.";
|
||||
public string path;
|
||||
public string propertyName;
|
||||
|
||||
public SummaryBinding(string path, string blendShape)
|
||||
{
|
||||
this.path = path;
|
||||
this.propertyName = PREFIX + blendShape;
|
||||
}
|
||||
|
||||
public static SummaryBinding? FromEditorBinding(EditorCurveBinding binding)
|
||||
{
|
||||
if (binding.type != typeof(SkinnedMeshRenderer) || !binding.propertyName.StartsWith(PREFIX))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new SummaryBinding(binding.path, binding.propertyName.Substring(PREFIX.Length));
|
||||
}
|
||||
|
||||
public EditorCurveBinding ToEditorCurveBinding()
|
||||
{
|
||||
return EditorCurveBinding.FloatCurve(
|
||||
path,
|
||||
typeof(SkinnedMeshRenderer),
|
||||
propertyName
|
||||
);
|
||||
}
|
||||
|
||||
public bool Equals(SummaryBinding other)
|
||||
{
|
||||
return path == other.path && propertyName == other.propertyName;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is SummaryBinding other && Equals(other);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(path, propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPreprocessAvatar()
|
||||
{
|
||||
var avatarGameObject = _context.AvatarRootObject;
|
||||
var animDb = _context.Extension<AnimatorServicesContext>().AnimationIndex;
|
||||
|
||||
_bindingMappings = new Dictionary<SummaryBinding, List<SummaryBinding>>();
|
||||
|
||||
var components = avatarGameObject.GetComponentsInChildren<ModularAvatarBlendshapeSync>(true);
|
||||
if (components.Length == 0) return;
|
||||
|
||||
foreach (var component in components)
|
||||
{
|
||||
BuildReport.ReportingObject(component, () => ProcessComponent(avatarGameObject, component));
|
||||
}
|
||||
|
||||
var clips = new HashSet<VirtualClip>();
|
||||
foreach (var key in _bindingMappings.Keys)
|
||||
{
|
||||
var ecb = key.ToEditorCurveBinding();
|
||||
clips.UnionWith(animDb.GetClipsForBinding(ecb));
|
||||
}
|
||||
|
||||
// Walk and transform all clips
|
||||
foreach (var clip in clips)
|
||||
{
|
||||
ProcessClip(clip);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessComponent(GameObject avatarGameObject, ModularAvatarBlendshapeSync component)
|
||||
{
|
||||
var targetObj = RuntimeUtil.RelativePath(avatarGameObject, component.gameObject);
|
||||
|
||||
if (targetObj == null) return;
|
||||
|
||||
foreach (var binding in component.Bindings)
|
||||
{
|
||||
var refObj = binding.ReferenceMesh.Get(component);
|
||||
if (refObj == null) continue;
|
||||
var refSmr = refObj.GetComponent<SkinnedMeshRenderer>();
|
||||
if (refSmr == null) continue;
|
||||
|
||||
var refPath = RuntimeUtil.RelativePath(avatarGameObject, refObj);
|
||||
if (refPath == null) continue;
|
||||
|
||||
var srcBinding = new SummaryBinding(refPath, binding.Blendshape);
|
||||
|
||||
if (!_bindingMappings.TryGetValue(srcBinding, out var dstBindings))
|
||||
{
|
||||
dstBindings = new List<SummaryBinding>();
|
||||
_bindingMappings[srcBinding] = dstBindings;
|
||||
}
|
||||
|
||||
var targetBlendshapeName = string.IsNullOrWhiteSpace(binding.LocalBlendshape)
|
||||
? binding.Blendshape
|
||||
: binding.LocalBlendshape;
|
||||
|
||||
dstBindings.Add(new SummaryBinding(targetObj, targetBlendshapeName));
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessClip(VirtualClip clip)
|
||||
{
|
||||
foreach (var binding in clip.GetFloatCurveBindings().ToList())
|
||||
{
|
||||
var srcBinding = SummaryBinding.FromEditorBinding(binding);
|
||||
if (srcBinding == null || !_bindingMappings.TryGetValue(srcBinding.Value, out var dstBindings))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var curve = clip.GetFloatCurve(binding);
|
||||
foreach (var dst in dstBindings)
|
||||
{
|
||||
clip.SetFloatCurve(dst.ToEditorCurveBinding(), curve);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -22,6 +22,8 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
using nadena.dev.modular_avatar.editor.ErrorReporting;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
@ -41,26 +43,52 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
|
||||
foreach (var proxy in boneProxies)
|
||||
{
|
||||
if (proxy.target != null && ValidateTarget(avatarGameObject, proxy.target) == ValidationResult.OK)
|
||||
{
|
||||
var oldPath = RuntimeUtil.AvatarRootPath(proxy.gameObject);
|
||||
Transform transform = proxy.transform;
|
||||
transform.SetParent(proxy.target, true);
|
||||
if (proxy.attachmentMode != BoneProxyAttachmentMode.AsChildKeepWorldPosition)
|
||||
{
|
||||
transform.localPosition = Vector3.zero;
|
||||
transform.localRotation = Quaternion.identity;
|
||||
}
|
||||
BuildReport.ReportingObject(proxy, () => ProcessProxy(avatarGameObject, proxy));
|
||||
}
|
||||
}
|
||||
|
||||
PathMappings.Remap(oldPath, new PathMappings.MappingEntry()
|
||||
{
|
||||
path = RuntimeUtil.AvatarRootPath(proxy.gameObject),
|
||||
transformPath = RuntimeUtil.AvatarRootPath(proxy.gameObject)
|
||||
});
|
||||
private void ProcessProxy(GameObject avatarGameObject, ModularAvatarBoneProxy proxy)
|
||||
{
|
||||
if (proxy.target != null && ValidateTarget(avatarGameObject, proxy.target) == ValidationResult.OK)
|
||||
{
|
||||
string suffix = "";
|
||||
int i = 1;
|
||||
while (proxy.target.Find(proxy.gameObject.name + suffix) != null)
|
||||
{
|
||||
suffix = $" ({i++})";
|
||||
}
|
||||
|
||||
Object.DestroyImmediate(proxy);
|
||||
proxy.gameObject.name += suffix;
|
||||
|
||||
Transform transform = proxy.transform;
|
||||
transform.SetParent(proxy.target, true);
|
||||
|
||||
bool keepPos, keepRot;
|
||||
switch (proxy.attachmentMode)
|
||||
{
|
||||
default:
|
||||
case BoneProxyAttachmentMode.Unset:
|
||||
case BoneProxyAttachmentMode.AsChildAtRoot:
|
||||
keepPos = keepRot = false;
|
||||
break;
|
||||
case BoneProxyAttachmentMode.AsChildKeepWorldPose:
|
||||
keepPos = keepRot = true;
|
||||
break;
|
||||
case BoneProxyAttachmentMode.AsChildKeepPosition:
|
||||
keepPos = true;
|
||||
keepRot = false;
|
||||
break;
|
||||
case BoneProxyAttachmentMode.AsChildKeepRotation:
|
||||
keepRot = true;
|
||||
keepPos = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!keepPos) transform.localPosition = Vector3.zero;
|
||||
if (!keepRot) transform.localRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
Object.DestroyImmediate(proxy);
|
||||
}
|
||||
|
||||
internal static ValidationResult ValidateTarget(GameObject avatarGameObject, Transform proxyTarget)
|
85
Editor/BuildContext.cs
Normal file
85
Editor/BuildContext.cs
Normal file
@ -0,0 +1,85 @@
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
using VRC.SDK3.Avatars.Components;
|
||||
using VRC.SDK3.Avatars.ScriptableObjects;
|
||||
#endif
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
internal class BuildContext
|
||||
{
|
||||
internal readonly ndmf.BuildContext PluginBuildContext;
|
||||
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
internal VRCAvatarDescriptor AvatarDescriptor => PluginBuildContext.AvatarDescriptor;
|
||||
#endif
|
||||
internal GameObject AvatarRootObject => PluginBuildContext.AvatarRootObject;
|
||||
internal Transform AvatarRootTransform => PluginBuildContext.AvatarRootTransform;
|
||||
|
||||
private bool SaveImmediate = false;
|
||||
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
internal readonly Dictionary<VRCExpressionsMenu, VRCExpressionsMenu> ClonedMenus
|
||||
= new Dictionary<VRCExpressionsMenu, VRCExpressionsMenu>();
|
||||
|
||||
/// <summary>
|
||||
/// This dictionary overrides the _original contents_ of ModularAvatarMenuInstallers. Notably, this does not
|
||||
/// replace the source menu for the purposes of identifying any other MAMIs that might install to the same
|
||||
/// menu asset.
|
||||
/// </summary>
|
||||
internal readonly Dictionary<Object, Action<VRCExpressionsMenu.Control>> PostProcessControls = new();
|
||||
#endif
|
||||
public static implicit operator BuildContext(ndmf.BuildContext ctx) =>
|
||||
ctx.Extension<ModularAvatarContext>().BuildContext;
|
||||
|
||||
public BuildContext(ndmf.BuildContext PluginBuildContext)
|
||||
{
|
||||
this.PluginBuildContext = PluginBuildContext;
|
||||
}
|
||||
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
public BuildContext(VRCAvatarDescriptor avatarDescriptor)
|
||||
: this(new ndmf.BuildContext(avatarDescriptor, null))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
public BuildContext(GameObject avatarGameObject)
|
||||
: this(new ndmf.BuildContext(avatarGameObject, null))
|
||||
{
|
||||
}
|
||||
|
||||
public void SaveAsset(Object obj)
|
||||
{
|
||||
if (!SaveImmediate || AssetDatabase.IsMainAsset(obj) || AssetDatabase.IsSubAsset(obj)) return;
|
||||
|
||||
PluginBuildContext.AssetSaver.SaveAsset(obj);
|
||||
}
|
||||
|
||||
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
public VRCExpressionsMenu CloneMenu(VRCExpressionsMenu menu)
|
||||
{
|
||||
if (menu == null) return null;
|
||||
if (ClonedMenus.TryGetValue(menu, out var newMenu)) return newMenu;
|
||||
newMenu = Object.Instantiate(menu);
|
||||
this.SaveAsset(newMenu);
|
||||
ClonedMenus[menu] = newMenu;
|
||||
|
||||
foreach (var control in newMenu.controls)
|
||||
{
|
||||
if (control.type == VRCExpressionsMenu.Control.ControlType.SubMenu && control.subMenu != newMenu)
|
||||
{
|
||||
control.subMenu = CloneMenu(control.subMenu);
|
||||
}
|
||||
}
|
||||
|
||||
return newMenu;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
3
Editor/BuildContext.cs.meta
Normal file
3
Editor/BuildContext.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41bbb1832c9d409a999605fae058dd19
|
||||
timeCreated: 1671624226
|
32
Editor/CreateBlendTree.cs
Normal file
32
Editor/CreateBlendTree.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Animations;
|
||||
using UnityEditor.ProjectWindowCallback;
|
||||
using UnityEngine;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
internal static class CreateBlendTree
|
||||
{
|
||||
[MenuItem("Assets/Create/BlendTree", priority = 411)]
|
||||
static void CreateNewBlendTree()
|
||||
{
|
||||
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(
|
||||
0,
|
||||
Editor.CreateInstance<DoCreateBlendTree>(),
|
||||
"New BlendTree.asset",
|
||||
EditorGUIUtility.IconContent("BlendTree Icon").image as Texture2D,
|
||||
null);
|
||||
}
|
||||
|
||||
class DoCreateBlendTree : EndNameEditAction
|
||||
{
|
||||
public override void Action(int instanceId, string pathName, string resourceFile)
|
||||
{
|
||||
BlendTree blendTree = new BlendTree { name = Path.GetFileNameWithoutExtension(pathName) };
|
||||
AssetDatabase.CreateAsset(blendTree, pathName);
|
||||
Selection.activeObject = blendTree;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d75fcaecb8b9e7f4bbe783e5f4c9838a
|
||||
guid: e608a27c3d14edf43858004513948da1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
4
Editor/ErrorReporting.meta
Normal file
4
Editor/ErrorReporting.meta
Normal file
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0fb1980d53a548a996bdfca622d468ca
|
||||
timeCreated: 1674039787
|
||||
folderAsset: yes
|
161
Editor/ErrorReporting/ComponentValidation.cs
Normal file
161
Editor/ErrorReporting/ComponentValidation.cs
Normal file
@ -0,0 +1,161 @@
|
||||
using System.Collections.Generic;
|
||||
using nadena.dev.modular_avatar.core;
|
||||
using nadena.dev.ndmf;
|
||||
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
using nadena.dev.modular_avatar.core.menu;
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace nadena.dev.modular_avatar.editor.ErrorReporting
|
||||
{
|
||||
internal static class ComponentValidation
|
||||
{
|
||||
/// <summary>
|
||||
/// Validates the provided tag component.
|
||||
/// </summary>
|
||||
/// <param name="tagComponent"></param>
|
||||
/// <returns>Null if valid, otherwise a list of configuration errors</returns>
|
||||
internal static void CheckComponent(this AvatarTagComponent tagComponent)
|
||||
{
|
||||
ErrorReport.WithContextObject(tagComponent, () =>
|
||||
{
|
||||
switch (tagComponent)
|
||||
{
|
||||
case ModularAvatarBlendshapeSync bs:
|
||||
CheckInternal(bs);
|
||||
break;
|
||||
case ModularAvatarBoneProxy bp:
|
||||
CheckInternal(bp);
|
||||
break;
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
case ModularAvatarMenuInstaller mi:
|
||||
CheckInternal(mi);
|
||||
break;
|
||||
case ModularAvatarMergeAnimator obj:
|
||||
CheckInternal(obj);
|
||||
break;
|
||||
#endif
|
||||
case ModularAvatarMergeArmature obj:
|
||||
CheckInternal(obj);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
internal static void ValidateAll(GameObject root)
|
||||
{
|
||||
foreach (var component in root.GetComponentsInChildren<AvatarTagComponent>(true))
|
||||
{
|
||||
component.CheckComponent();
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckInternal(ModularAvatarBlendshapeSync bs)
|
||||
{
|
||||
var localMesh = bs.GetComponent<SkinnedMeshRenderer>();
|
||||
if (localMesh == null)
|
||||
{
|
||||
BuildReport.Log(ErrorSeverity.NonFatal, "validation.blendshape_sync.no_local_renderer", bs);
|
||||
}
|
||||
|
||||
if (localMesh.sharedMesh == null)
|
||||
{
|
||||
BuildReport.Log(ErrorSeverity.NonFatal, "validation.blendshape_sync.no_local_mesh", bs);
|
||||
}
|
||||
|
||||
if (bs.Bindings == null || bs.Bindings.Count == 0)
|
||||
{
|
||||
BuildReport.Log(ErrorSeverity.Information,"validation.blendshape_sync.no_bindings", bs);
|
||||
}
|
||||
|
||||
foreach (var binding in bs.Bindings)
|
||||
{
|
||||
var localShape = string.IsNullOrWhiteSpace(binding.LocalBlendshape)
|
||||
? binding.Blendshape
|
||||
: binding.LocalBlendshape;
|
||||
|
||||
if (localMesh.sharedMesh.GetBlendShapeIndex(localShape) == -1)
|
||||
{
|
||||
BuildReport.Log(ErrorSeverity.NonFatal, "validation.blendshape_sync.missing_local_shape",
|
||||
localShape, bs);
|
||||
}
|
||||
|
||||
var targetObj = binding.ReferenceMesh.Get(bs.transform);
|
||||
if (targetObj == null)
|
||||
{
|
||||
BuildReport.Log(ErrorSeverity.NonFatal, "validation.blendshape_sync.no_target", bs);
|
||||
continue;
|
||||
}
|
||||
|
||||
var targetRenderer = targetObj.GetComponent<SkinnedMeshRenderer>();
|
||||
if (targetRenderer == null)
|
||||
{
|
||||
BuildReport.Log(ErrorSeverity.NonFatal,
|
||||
"validation.blendshape_sync.missing_target_renderer", bs, targetRenderer);
|
||||
continue;
|
||||
}
|
||||
|
||||
var targetMesh = targetRenderer.sharedMesh;
|
||||
if (targetMesh == null)
|
||||
{
|
||||
BuildReport.Log(ErrorSeverity.NonFatal, "validation.blendshape_sync.missing_target_mesh",
|
||||
bs, targetRenderer);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (targetMesh.GetBlendShapeIndex(binding.Blendshape) == -1)
|
||||
{
|
||||
BuildReport.Log(ErrorSeverity.NonFatal,
|
||||
"validation.blendshape_sync.missing_target_shape", binding.Blendshape, bs,
|
||||
targetRenderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckInternal(ModularAvatarBoneProxy bp)
|
||||
{
|
||||
if (bp.target == null)
|
||||
{
|
||||
BuildReport.Log(ErrorSeverity.NonFatal, "validation.bone_proxy.no_target", bp);
|
||||
}
|
||||
}
|
||||
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
private static void CheckInternal(ModularAvatarMenuInstaller mi)
|
||||
{
|
||||
// TODO - check that target menu is in the avatar
|
||||
if (mi.menuToAppend == null && mi.GetComponent<MenuSource>() == null)
|
||||
{
|
||||
BuildReport.Log(ErrorSeverity.NonFatal, "validation.menu_installer.no_menu", mi);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckInternal(ModularAvatarMergeAnimator ma)
|
||||
{
|
||||
if (ma.animator == null)
|
||||
{
|
||||
BuildReport.Log(ErrorSeverity.NonFatal, "validation.merge_animator.no_animator", ma);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private static void CheckInternal(ModularAvatarMergeArmature ma)
|
||||
{
|
||||
if (ma.mergeTargetObject == null)
|
||||
{
|
||||
BuildReport.Log(ErrorSeverity.NonFatal, "validation.merge_armature.no_target", ma);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ma.mergeTargetObject == ma.gameObject || ma.mergeTargetObject.transform.IsChildOf(ma.transform))
|
||||
{
|
||||
BuildReport.Log(ErrorSeverity.Error, "error.merge_armature.circular_dependency", ma,
|
||||
ma.mergeTargetObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
Editor/ErrorReporting/ComponentValidation.cs.meta
Normal file
3
Editor/ErrorReporting/ComponentValidation.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b500f7714e4401aa090eef81c0bab01
|
||||
timeCreated: 1675855192
|
50
Editor/ErrorReporting/ErrorLog.cs
Normal file
50
Editor/ErrorReporting/ErrorLog.cs
Normal file
@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using nadena.dev.modular_avatar.core;
|
||||
using nadena.dev.modular_avatar.core.editor;
|
||||
using nadena.dev.ndmf;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace nadena.dev.modular_avatar.editor.ErrorReporting
|
||||
{
|
||||
internal class BuildReport
|
||||
{
|
||||
private const string Path = "Library/ModularAvatarBuildReport.json";
|
||||
|
||||
internal static void Log(ErrorSeverity severity, string code, params object[] objects)
|
||||
{
|
||||
ErrorReport.ReportError(Localization.L, severity, code, objects);
|
||||
}
|
||||
|
||||
internal static void LogFatal(string code, params object[] objects)
|
||||
{
|
||||
ErrorReport.ReportError(Localization.L, ErrorSeverity.Error, code, objects);
|
||||
}
|
||||
|
||||
internal static void LogException(Exception e, string additionalStackTrace = "")
|
||||
{
|
||||
ErrorReport.ReportException(e, additionalStackTrace);
|
||||
}
|
||||
|
||||
internal static T ReportingObject<T>(UnityEngine.Object obj, Func<T> action)
|
||||
{
|
||||
return ErrorReport.WithContextObject(obj, action);
|
||||
}
|
||||
|
||||
internal static void ReportingObject(UnityEngine.Object obj, Action action)
|
||||
{
|
||||
ErrorReport.WithContextObject(obj, action);
|
||||
}
|
||||
|
||||
[Obsolete("Use NDMF's ObjectRegistry instead")]
|
||||
public static void RemapPaths(string original, string cloned)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
3
Editor/ErrorReporting/ErrorLog.cs.meta
Normal file
3
Editor/ErrorReporting/ErrorLog.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08d5f5d12365416d94e2d97970a24f5d
|
||||
timeCreated: 1674039799
|
3
Editor/FixupPasses.meta
Normal file
3
Editor/FixupPasses.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 597d4035b7eb43e180a013ceac128a84
|
||||
timeCreated: 1694687629
|
183
Editor/FixupPasses/FixupExpressionsMenuPass.cs
Normal file
183
Editor/FixupPasses/FixupExpressionsMenuPass.cs
Normal file
@ -0,0 +1,183 @@
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using VRC.SDK3.Avatars.ScriptableObjects;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
internal class FixupExpressionsMenuPass
|
||||
{
|
||||
private const string DEFAULT_EXP_MENU_GUID = "024fb8ef5b3988c46b446863c92f4522";
|
||||
private const string DEFAULT_EXP_PARAM_GUID = "03a6d797deb62f0429471c4e17ea99a7";
|
||||
|
||||
internal static void FixupExpressionsMenu(BuildContext context)
|
||||
{
|
||||
if (!context.AvatarDescriptor) return;
|
||||
|
||||
context.AvatarDescriptor.customExpressions = true;
|
||||
|
||||
var expressionsMenu = context.AvatarDescriptor.expressionsMenu;
|
||||
if (expressionsMenu == null)
|
||||
{
|
||||
var defaultExpMenu = AssetDatabase.LoadAssetAtPath<VRCExpressionsMenu>(
|
||||
AssetDatabase.GUIDToAssetPath(DEFAULT_EXP_MENU_GUID)
|
||||
);
|
||||
|
||||
expressionsMenu = Object.Instantiate(defaultExpMenu);
|
||||
context.AvatarDescriptor.expressionsMenu = expressionsMenu;
|
||||
}
|
||||
|
||||
if (context.AvatarDescriptor.expressionParameters == null)
|
||||
{
|
||||
var defaultExpParam = AssetDatabase.LoadAssetAtPath<VRCExpressionParameters>(
|
||||
AssetDatabase.GUIDToAssetPath(DEFAULT_EXP_PARAM_GUID)
|
||||
);
|
||||
|
||||
context.AvatarDescriptor.expressionParameters = Object.Instantiate(defaultExpParam);
|
||||
}
|
||||
|
||||
var parameters = context.AvatarDescriptor.expressionParameters.parameters
|
||||
?? Array.Empty<VRCExpressionParameters.Parameter>();
|
||||
var parameterNames = parameters.Select(p => p.name).ToImmutableHashSet();
|
||||
|
||||
if (!context.PluginBuildContext.IsTemporaryAsset(expressionsMenu))
|
||||
{
|
||||
expressionsMenu = context.CloneMenu(expressionsMenu);
|
||||
context.AvatarDescriptor.expressionsMenu = expressionsMenu;
|
||||
}
|
||||
|
||||
// Walk menu recursively
|
||||
var visitedMenus = new HashSet<VRCExpressionsMenu>();
|
||||
var iconMapping = new Dictionary<Texture2D, Texture2D>();
|
||||
|
||||
VisitMenu(expressionsMenu);
|
||||
|
||||
void VisitMenu(VRCExpressionsMenu menu)
|
||||
{
|
||||
if (!visitedMenus.Add(menu)) return;
|
||||
|
||||
foreach (var control in menu.controls)
|
||||
{
|
||||
if (control.parameter != null &&
|
||||
!string.IsNullOrEmpty(control.parameter.name) &&
|
||||
!parameterNames.Contains(control.parameter.name))
|
||||
{
|
||||
control.parameter.name = "";
|
||||
}
|
||||
|
||||
foreach (var subParam in control.subParameters ??
|
||||
Array.Empty<VRCExpressionsMenu.Control.Parameter>())
|
||||
{
|
||||
if (subParam != null &&
|
||||
!string.IsNullOrEmpty(subParam.name) &&
|
||||
!parameterNames.Contains(subParam.name))
|
||||
{
|
||||
subParam.name = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (control.icon != null)
|
||||
{
|
||||
if (!iconMapping.TryGetValue(control.icon, out var newIcon))
|
||||
{
|
||||
iconMapping[control.icon] = newIcon = MaybeScaleIcon(context, control.icon);
|
||||
}
|
||||
|
||||
control.icon = newIcon;
|
||||
}
|
||||
|
||||
if (control.subMenu != null)
|
||||
{
|
||||
VisitMenu(control.subMenu);
|
||||
}
|
||||
|
||||
if (control.labels != null)
|
||||
{
|
||||
for (int i = 0; i < control.labels.Length; i++)
|
||||
{
|
||||
var label = control.labels[i];
|
||||
|
||||
if (label.icon != null)
|
||||
{
|
||||
if (!iconMapping.TryGetValue(label.icon, out var newIcon))
|
||||
{
|
||||
iconMapping[label.icon] = newIcon = MaybeScaleIcon(context, label.icon);
|
||||
}
|
||||
|
||||
label.icon = newIcon;
|
||||
control.labels[i] = label;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static TextureFormat TargetFormat
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (EditorUserBuildSettings.activeBuildTarget)
|
||||
{
|
||||
case BuildTarget.StandaloneWindows64:
|
||||
return TextureFormat.DXT5;
|
||||
default:
|
||||
return TextureFormat.ASTC_4x4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Texture2D MaybeScaleIcon(BuildContext context, Texture2D original)
|
||||
{
|
||||
if (original.width <= 256 && original.height <= 256 && IsCompressedFormat(original.format))
|
||||
{
|
||||
return original;
|
||||
}
|
||||
|
||||
var newRatio = Math.Min(1, Math.Min(256f / original.width, 256f / original.height));
|
||||
var newWidth = Math.Min(256, Mathf.RoundToInt(original.width * newRatio));
|
||||
var newHeight = Math.Min(256, Mathf.RoundToInt(original.height * newRatio));
|
||||
|
||||
// Round up to a multiple of four
|
||||
newWidth = (newWidth + 3) & ~3;
|
||||
newHeight = (newHeight + 3) & ~3;
|
||||
|
||||
var newTex = new Texture2D(newWidth, newHeight, TextureFormat.RGBA32, true);
|
||||
context.SaveAsset(newTex);
|
||||
|
||||
var tmpRenderTex = RenderTexture.GetTemporary(newWidth, newHeight, 0, RenderTextureFormat.ARGB32);
|
||||
var originalActiveRenderTex = RenderTexture.active;
|
||||
|
||||
try
|
||||
{
|
||||
Graphics.Blit(original, tmpRenderTex);
|
||||
RenderTexture.active = tmpRenderTex;
|
||||
newTex.ReadPixels(new Rect(0, 0, newWidth, newHeight), 0, 0);
|
||||
newTex.Apply();
|
||||
EditorUtility.CompressTexture(newTex, TargetFormat, TextureCompressionQuality.Normal);
|
||||
|
||||
return newTex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
RenderTexture.active = originalActiveRenderTex;
|
||||
RenderTexture.ReleaseTemporary(tmpRenderTex);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsCompressedFormat(TextureFormat format)
|
||||
{
|
||||
var name = format.ToString();
|
||||
return name.StartsWith("DXT") || name.StartsWith("ASTC");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
3
Editor/FixupPasses/FixupExpressionsMenuPass.cs.meta
Normal file
3
Editor/FixupPasses/FixupExpressionsMenuPass.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1020bef86d91452ba6b138c249d25bb5
|
||||
timeCreated: 1694688050
|
3
Editor/HarmonyPatches.meta
Normal file
3
Editor/HarmonyPatches.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf056e4454ad43ababbfff1dd06ec1d0
|
||||
timeCreated: 1708235917
|
41
Editor/HarmonyPatches/PatchLoader.cs
Normal file
41
Editor/HarmonyPatches/PatchLoader.cs
Normal file
@ -0,0 +1,41 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
using HarmonyLib;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor.HarmonyPatches
|
||||
{
|
||||
internal class PatchLoader
|
||||
{
|
||||
private const string HarmonyId = "nadena.dev.modular_avatar";
|
||||
|
||||
private static readonly Action<Harmony>[] patches = new Action<Harmony>[]
|
||||
{
|
||||
//HierarchyViewPatches.Patch,
|
||||
};
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
static void ApplyPatches()
|
||||
{
|
||||
var harmony = new Harmony(HarmonyId);
|
||||
|
||||
foreach (var patch in patches)
|
||||
{
|
||||
try
|
||||
{
|
||||
patch(harmony);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
|
||||
AssemblyReloadEvents.beforeAssemblyReload += () => { harmony.UnpatchAll(HarmonyId); };
|
||||
}
|
||||
}
|
||||
}
|
3
Editor/HarmonyPatches/PatchLoader.cs.meta
Normal file
3
Editor/HarmonyPatches/PatchLoader.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e92aedf0fa324b8fb1b425a7fc2b1771
|
||||
timeCreated: 1708235934
|
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "nadena.dev.modular-avatar.harmony-patches",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"nadena.dev.modular-avatar.core",
|
||||
"nadena.dev.modular-avatar.core.editor",
|
||||
"VRC.SDKBase.Editor",
|
||||
"nadena.dev.modular-avatar.param-introspection"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [
|
||||
"VRCSDK_HAS_HARMONY"
|
||||
],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.vrchat.base",
|
||||
"expression": "(3.3.99999,)",
|
||||
"define": "VRCSDK_HAS_HARMONY"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user