@@ -11,14 +11,19 @@ import {
1111} from "@pixiv/three-vrm-animation" ;
1212import { AnimationMixer , LoopOnce , LoopRepeat } from "three" ;
1313
14+ const animations = [
15+ { url : "https://cdn.mikn.dev/vroid/shikanoko.vrma" , loop : true , percentage : 30 } ,
16+ { url : "https://cdn.mikn.dev/vroid/hi.vrma" , loop : false , percentage : 70 } ,
17+ ] ;
18+
1419export const VRMModel : React . FC < {
1520 vrm : import ( "@pixiv/three-vrm" ) . VRM | null ;
1621 mixer : AnimationMixer | null ;
1722} > = ( { vrm, mixer } ) => {
1823 useFrame ( ( { clock } , delta ) => {
1924 if ( vrm ) {
20- vrm . scene . position . set ( 0 , - 4 , 0 ) ;
21- vrm . scene . scale . set ( 5 , 5 , 5 ) ;
25+ vrm . scene . position . set ( 0 , - 4.2 , 0 ) ;
26+ vrm . scene . scale . set ( 6. 5, 5 , 5 ) ;
2227 vrm . scene . rotation . y = Math . PI ;
2328 vrm . expressionManager ?. setValue ( "neutral" , 1 ) ;
2429
@@ -46,7 +51,7 @@ export function VRM() {
4651 return new Promise < import ( "@pixiv/three-vrm" ) . VRM > (
4752 ( resolve , reject ) => {
4853 loader . load (
49- "https://cdn.mikn.dev/vroid/mikan.dev(web ).vrm" ,
54+ "https://cdn.mikn.dev/vroid/mikan.dev(kyonyu ).vrm" ,
5055 ( gltf : GLTF ) => {
5156 const loadedVrm = gltf . userData . vrm ;
5257 setVrm ( loadedVrm ) ;
@@ -65,14 +70,22 @@ export function VRM() {
6570 ) ;
6671 } ;
6772
73+ function pickAnimation ( ) {
74+ const total = animations . reduce ( ( sum , anim ) => sum + anim . percentage , 0 ) ;
75+ const rand = Math . random ( ) * total ;
76+ let acc = 0 ;
77+ for ( const anim of animations ) {
78+ acc += anim . percentage ;
79+ if ( rand < acc ) return anim ;
80+ }
81+ return animations [ 0 ] ; // fallback
82+ }
83+
6884 const loadAnimation = ( loadedVrm : import ( "@pixiv/three-vrm" ) . VRM ) => {
69- const animationUrl =
70- Math . random ( ) < 0.3
71- ? "https://cdn.mikn.dev/vroid/shikanoko.vrma"
72- : "https://cdn.mikn.dev/vroid/hi.vrma" ;
85+ const { url, loop } = pickAnimation ( ) ;
7386
7487 loader . load (
75- animationUrl ,
88+ url ,
7689 ( gltf : GLTF ) => {
7790 const vrmAnimations = gltf . userData . vrmAnimations ;
7891 if ( vrmAnimations && vrmAnimations . length > 0 ) {
@@ -81,37 +94,26 @@ export function VRM() {
8194 vrmAnimations [ 0 ] ,
8295 loadedVrm ,
8396 ) ;
84- const animationMixer = new AnimationMixer (
85- loadedVrm . scene ,
86- ) ;
87- const action =
88- animationMixer . clipAction ( animationClip ) ;
97+ const animationMixer = new AnimationMixer ( loadedVrm . scene ) ;
98+ const action = animationMixer . clipAction ( animationClip ) ;
8999
90- if (
91- animationUrl ===
92- "https://cdn.mikn.dev/vroid/hi.vrma"
93- ) {
100+ if ( loop ) {
101+ action . setLoop ( LoopRepeat , Infinity ) ;
102+ } else {
94103 action . setLoop ( LoopOnce , 1 ) ;
95104 action . clampWhenFinished = true ;
96- } else {
97- action . setLoop ( LoopRepeat , Infinity ) ;
98105 }
99106
100107 action . play ( ) ;
101108 setMixer ( animationMixer ) ;
102109 } else {
103- console . error (
104- "VRM model or humanoid is not loaded correctly." ,
105- ) ;
110+ console . error ( "VRM model or humanoid is not loaded correctly." ) ;
106111 }
107112 }
108113 } ,
109114 undefined ,
110115 ( error : Error ) => {
111- console . error (
112- "An error occurred while loading the animation:" ,
113- error ,
114- ) ;
116+ console . error ( "An error occurred while loading the animation:" , error ) ;
115117 } ,
116118 ) ;
117119 } ;
@@ -130,14 +132,13 @@ export function VRM() {
130132 < div className = "flex justify-center items-center w-96 h-96" >
131133 { ! isLoaded ? (
132134 < div className = "flex items-center justify-center p-4" >
133- < AiOutlineLoading3Quarters
134- className = "animate-spin text-primary"
135- size = { 80 }
135+ < span
136+ className = "loading loading-xl loading-spinner text-primary"
136137 />
137138 </ div >
138139 ) : (
139140 < Canvas camera = { { position : [ 0 , 0 , 3 ] } } >
140- < ambientLight intensity = { 2.1 } />
141+ < ambientLight intensity = { 1.5 } />
141142 < VRMModel vrm = { vrm } mixer = { mixer } />
142143 </ Canvas >
143144 ) }
0 commit comments