11import { useKeyboardControls } from "@react-three/drei" ;
22import { useFrame } from "@react-three/fiber" ;
3- import { RigidBody , CapsuleCollider , useRapier } from "@react-three/rapier" ;
4- import { useEffect , useRef , useMemo } from "react" ;
3+ import {
4+ RigidBody ,
5+ CapsuleCollider ,
6+ useRapier ,
7+ RapierRigidBody ,
8+ } from "@react-three/rapier" ;
9+ import { useEffect , useRef , useMemo , type ReactNode } from "react" ;
510import * as THREE from "three" ;
611import { useControls } from "leva" ;
7- import useFollowCam from "./hooks/useFollowCam" ;
8- import useGame from "./stores/useGame" ;
12+ import { useFollowCam } from "./hooks/useFollowCam" ;
13+ import { useGame } from "./stores/useGame" ;
14+ import type {
15+ Collider ,
16+ RayColliderToi ,
17+ Vector ,
18+ } from "@dimforge/rapier3d-compat" ;
919
10- export { EcctrlAnimation } from "./EcctrlAnimation"
20+ export { EcctrlAnimation } from "./EcctrlAnimation" ;
1121
1222export default function Ecctrl ( {
1323 children,
@@ -57,10 +67,9 @@ export default function Ecctrl({
5767 autoBalanceDampingOnY = 0.02 ,
5868 // Animation temporary setups
5969 animated = false ,
60- ...props
61- } ) {
62- const characterRef = useRef ( ) ;
63- const characterModelRef = useRef ( ) ;
70+ } : EcctrlProps ) {
71+ const characterRef = useRef < RapierRigidBody > ( ) ;
72+ const characterModelRef = useRef < THREE . Group > ( ) ;
6473
6574 // Animation change functions
6675 const idleAnimation = ! animated ? null : useGame ( ( state ) => state . idle ) ;
@@ -345,7 +354,7 @@ export default function Ecctrl({
345354 /**
346355 * Initial light setup
347356 */
348- let dirLight = null ;
357+ let dirLight : THREE . DirectionalLight = null ;
349358
350359 /**
351360 * Follow camera initial setups from props
@@ -384,28 +393,33 @@ export default function Ecctrl({
384393 const characterMassForce = useMemo ( ( ) => new THREE . Vector3 ( ) , [ ] ) ;
385394 const rayOrigin = useMemo ( ( ) => new THREE . Vector3 ( ) , [ ] ) ;
386395 const rayCast = new rapier . Ray ( rayOrigin , rayDir ) ;
387- let rayHit = null ;
396+ let rayHit : RayColliderToi = null ;
388397
389398 /**Test shape ray */
390399 // const shape = new rapier.Capsule(0.2,0.1)
391400
392401 /**
393402 * Slope detection ray setup
394403 */
395- let slopeAngle = null ;
396- let actualSlopeNormal = null ;
397- let actualSlopeAngle = null ;
404+ let slopeAngle : number = null ;
405+ let actualSlopeNormal : Vector = null ;
406+ let actualSlopeAngle : number = null ;
398407 const actualSlopeNormalVec = useMemo ( ( ) => new THREE . Vector3 ( ) , [ ] ) ;
399408 const floorNormal = useMemo ( ( ) => new THREE . Vector3 ( 0 , 1 , 0 ) , [ ] ) ;
400- const slopeRayOriginRef = useRef ( ) ;
409+ const slopeRayOriginRef = useRef < THREE . Mesh > ( ) ;
401410 const slopeRayorigin = useMemo ( ( ) => new THREE . Vector3 ( ) , [ ] ) ;
402411 const slopeRayCast = new rapier . Ray ( slopeRayorigin , slopeRayDir ) ;
403- let slopeRayHit = null ;
412+ let slopeRayHit : RayColliderToi = null ;
404413
405414 /**
406415 * Character moving function
407416 */
408- const moveCharacter = ( delta , run , slopeAngle , movingObjectVelocity ) => {
417+ const moveCharacter = (
418+ _ : number ,
419+ run : boolean ,
420+ slopeAngle : number ,
421+ movingObjectVelocity : THREE . Vector3
422+ ) => {
409423 /**
410424 * Setup moving direction
411425 */
@@ -520,11 +534,15 @@ export default function Ecctrl({
520534 }
521535
522536 // Move character at proper direction and impulse
523- characterRef . current . applyImpulseAtPoint ( moveImpulse , {
524- x : currentPos . x ,
525- y : currentPos . y + moveImpulsePointY ,
526- z : currentPos . z ,
527- } ) ;
537+ characterRef . current . applyImpulseAtPoint (
538+ moveImpulse ,
539+ {
540+ x : currentPos . x ,
541+ y : currentPos . y + moveImpulsePointY ,
542+ z : currentPos . z ,
543+ } ,
544+ false
545+ ) ;
528546 } ;
529547
530548 /**
@@ -539,7 +557,7 @@ export default function Ecctrl({
539557 - autoBalanceSpringK * characterRef . current . rotation ( ) . z -
540558 characterRef . current . angvel ( ) . z * autoBalanceDampingC
541559 ) ;
542- characterRef . current . applyTorqueImpulse ( dragAngForce ) ;
560+ characterRef . current . applyTorqueImpulse ( dragAngForce , false ) ;
543561 } ;
544562
545563 useEffect ( ( ) => {
@@ -549,7 +567,7 @@ export default function Ecctrl({
549567 ( item ) => {
550568 return item . type === "DirectionalLight" ;
551569 }
552- ) ;
570+ ) as THREE . DirectionalLight ;
553571 }
554572
555573 // Action 1 key subscribe for special animation
@@ -605,14 +623,15 @@ export default function Ecctrl({
605623 characterRef . current . setEnabledRotations (
606624 autoBalance ? true : false ,
607625 autoBalance ? true : false ,
608- autoBalance ? true : false
626+ autoBalance ? true : false ,
627+ false
609628 ) ;
610629 } , [ autoBalance ] ) ;
611630
612631 useFrame ( ( state , delta ) => {
613632 // Character current position
614633 if ( characterRef . current ) {
615- currentPos . copy ( characterRef . current . translation ( ) ) ;
634+ currentPos . copy ( characterRef . current . translation ( ) as THREE . Vector3 ) ;
616635 }
617636
618637 /**
@@ -664,7 +683,7 @@ export default function Ecctrl({
664683
665684 // Character current velocity
666685 if ( characterRef . current ) {
667- currentVel . copy ( characterRef . current . linvel ( ) ) ;
686+ currentVel . copy ( characterRef . current . linvel ( ) as THREE . Vector3 ) ;
668687 }
669688
670689 // Jump impulse
@@ -680,7 +699,8 @@ export default function Ecctrl({
680699 jumpDirection
681700 . set ( 0 , ( run ? sprintJumpMult * jumpVel : jumpVel ) * slopJumpMult , 0 )
682701 . projectOnVector ( actualSlopeNormalVec )
683- . add ( jumpVelocityVec )
702+ . add ( jumpVelocityVec ) ,
703+ false
684704 ) ;
685705 // Apply jump force downward to the standing platform
686706 characterMassForce . y *= jumpForceToGroundMult ;
@@ -710,14 +730,15 @@ export default function Ecctrl({
710730 /**
711731 * Ray casting detect if on ground
712732 */
713- rayOrigin . addVectors ( currentPos , rayOriginOffest ) ;
733+ rayOrigin . addVectors ( currentPos , rayOriginOffest as THREE . Vector3 ) ;
714734 rayHit = world . castRay (
715735 rayCast ,
716736 rayLength ,
717737 false ,
718738 null ,
719739 null ,
720- characterRef . current
740+ // I have no idea
741+ characterRef . current as unknown as Collider
721742 ) ;
722743 /**Test shape ray */
723744 // rayHit = world.castShape(
@@ -765,11 +786,15 @@ export default function Ecctrl({
765786 // Calculate distance between character and moving object
766787 distanceFromCharacterToObject
767788 . copy ( currentPos )
768- . sub ( rayHit . collider . parent ( ) . translation ( ) ) ;
789+ . sub ( rayHit . collider . parent ( ) . translation ( ) as THREE . Vector3 ) ;
769790 // Moving object linear velocity
770- const movingObjectLinvel = rayHit . collider . parent ( ) . linvel ( ) ;
791+ const movingObjectLinvel = rayHit . collider
792+ . parent ( )
793+ . linvel ( ) as THREE . Vector3 ;
771794 // Moving object angular velocity
772- const movingObjectAngvel = rayHit . collider . parent ( ) . angvel ( ) ;
795+ const movingObjectAngvel = rayHit . collider
796+ . parent ( )
797+ . angvel ( ) as THREE . Vector3 ;
773798 // Combine object linear velocity and angular velocity to movingObjectVelocity
774799 movingObjectVelocity . set (
775800 movingObjectLinvel . x +
@@ -823,14 +848,16 @@ export default function Ecctrl({
823848 false ,
824849 null ,
825850 null ,
826- characterRef . current
851+ // Still no idea
852+ characterRef . current as unknown as Collider
827853 ) ;
828854
829855 // Calculate slope angle
830856 if ( slopeRayHit ) {
831857 actualSlopeNormal = slopeRayHit . collider . castRayAndGetNormal (
832858 slopeRayCast ,
833- slopeRayLength
859+ slopeRayLength ,
860+ false
834861 ) ?. normal ;
835862 if ( actualSlopeNormal ) {
836863 actualSlopeNormalVec ?. set (
@@ -843,9 +870,12 @@ export default function Ecctrl({
843870 }
844871 if ( slopeRayHit && rayHit && slopeRayHit . toi < floatingDis + 0.5 ) {
845872 if ( canJump ) {
846- slopeAngle = Math . atan (
847- ( rayHit . toi - slopeRayHit . toi ) / slopeRayOriginOffest
848- ) . toFixed ( 2 ) ;
873+ // Round the slope angle to 2 decimal places
874+ slopeAngle = Number (
875+ Math . atan (
876+ ( rayHit . toi - slopeRayHit . toi ) / slopeRayOriginOffest
877+ ) . toFixed ( 2 )
878+ ) ;
849879 } else {
850880 slopeAngle = null ;
851881 }
@@ -862,7 +892,8 @@ export default function Ecctrl({
862892 springK * ( floatingDis - rayHit . toi ) -
863893 characterRef . current . linvel ( ) . y * dampingC ;
864894 characterRef . current . applyImpulse (
865- springDirVec . set ( 0 , floatingForce , 0 )
895+ springDirVec . set ( 0 , floatingForce , 0 ) ,
896+ false
866897 ) ;
867898
868899 // Apply opposite force to standing object (gravity g in rapier is 0.11 ?_?)
@@ -884,7 +915,7 @@ export default function Ecctrl({
884915 0 ,
885916 - currentVel . z * dragDampingC
886917 ) ;
887- characterRef . current . applyImpulse ( dragForce ) ;
918+ characterRef . current . applyImpulse ( dragForce , false ) ;
888919 }
889920 // on a moving object
890921 else {
@@ -893,7 +924,7 @@ export default function Ecctrl({
893924 0 ,
894925 ( movingObjectVelocity . z - currentVel . z ) * dragDampingC * 2
895926 ) ;
896- characterRef . current . applyImpulse ( dragForce ) ;
927+ characterRef . current . applyImpulse ( dragForce , false ) ;
897928 }
898929 }
899930
@@ -966,3 +997,53 @@ export default function Ecctrl({
966997 </ RigidBody >
967998 ) ;
968999}
1000+
1001+ export type EcctrlProps = {
1002+ children ?: ReactNode ;
1003+ debug ?: boolean ;
1004+ capsuleHalfHeight ?: number ;
1005+ capsuleRadius ?: number ;
1006+ floatHeight ?: number ;
1007+ followLight ?: boolean ;
1008+ // Follow camera setups
1009+ camInitDis ?: number ;
1010+ camMaxDis ?: number ;
1011+ camMinDis ?: number ;
1012+ // Base control setups
1013+ maxVelLimit ?: number ;
1014+ turnVelMultiplier ?: number ;
1015+ turnSpeed ?: number ;
1016+ sprintMult ?: number ;
1017+ jumpVel ?: number ;
1018+ jumpForceToGroundMult ?: number ;
1019+ slopJumpMult ?: number ;
1020+ sprintJumpMult ?: number ;
1021+ airDragMultiplier ?: number ;
1022+ dragDampingC ?: number ;
1023+ accDeltaTime ?: number ;
1024+ rejectVelMult ?: number ;
1025+ moveImpulsePointY ?: number ;
1026+ camFollowMult ?: number ;
1027+ // Floating Ray setups
1028+ rayOriginOffest ?: { x : number ; y : number ; z : number } ;
1029+ rayHitForgiveness ?: number ;
1030+ rayLength ?: number ;
1031+ rayDir ?: { x : number ; y : number ; z : number } ;
1032+ floatingDis ?: number ;
1033+ springK ?: number ;
1034+ dampingC ?: number ;
1035+ // Slope Ray setups
1036+ showSlopeRayOrigin ?: boolean ;
1037+ slopeRayOriginOffest ?: number ;
1038+ slopeRayLength ?: number ;
1039+ slopeRayDir ?: { x : number ; y : number ; z : number } ;
1040+ slopeUpExtraForce ?: number ;
1041+ slopeDownExtraForce ?: number ;
1042+ // AutoBalance Force setups
1043+ autoBalance ?: boolean ;
1044+ autoBalanceSpringK ?: number ;
1045+ autoBalanceDampingC ?: number ;
1046+ autoBalanceDampingOnY ?: number ;
1047+ // Animation temporary setups
1048+ animated ?: boolean ;
1049+ } ;
0 commit comments