Skip to content

Commit 56e431b

Browse files
feat: higher falling gravity, max falling velocity
1 parent 37dd076 commit 56e431b

File tree

5 files changed

+63
-24
lines changed

5 files changed

+63
-24
lines changed

example/CharacterModel.tsx

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { useControls } from "leva";
99
import { Suspense, useEffect, useRef, useMemo, useState } from "react";
1010
import * as THREE from "three";
1111
import { useGame } from "../src/stores/useGame";
12-
import { BallCollider, RapierCollider } from "@react-three/rapier";
12+
import { BallCollider, RapierCollider, vec3 } from "@react-three/rapier";
1313
import { useFrame } from "@react-three/fiber";
1414
import type { GLTF } from "three/examples/jsm/loaders/GLTFLoader";
1515

@@ -129,24 +129,21 @@ export default function CharacterModel(props: CharacterModelProps) {
129129
});
130130

131131
useFrame(() => {
132-
if (rightHand && leftHand) {
133-
rightHand.getWorldPosition(rightHandPos);
134-
leftHand.getWorldPosition(leftHandPos);
135-
rightHandRef.current.parent.getWorldPosition(bodyPos);
136-
}
137-
138-
// Apply both hands position to hand colliders
139-
if (rightHandColliderRef.current && leftHandColliderRef.current) {
140-
rightHandRef.current.position.copy(rightHandPos).sub(bodyPos);
141-
rightHandColliderRef.current.setTranslationWrtParent(
142-
rightHandRef.current.position
143-
);
132+
if (curAnimation === animationSet.action4) {
133+
if (rightHand && leftHand) {
134+
rightHand.getWorldPosition(rightHandPos);
135+
leftHand.getWorldPosition(leftHandPos);
136+
rightHandRef.current.parent.getWorldPosition(bodyPos);
137+
}
144138

145-
leftHandRef.current.position.copy(leftHandPos).sub(bodyPos);
146-
leftHandColliderRef.current.setTranslationWrtParent(
147-
leftHandRef.current.position
148-
);
149-
}
139+
// Apply both hands position to hand colliders
140+
if (rightHandColliderRef.current && leftHandColliderRef.current) {
141+
rightHandRef.current.position.copy(rightHandPos).sub(bodyPos);
142+
rightHandColliderRef.current.setTranslationWrtParent(
143+
rightHandRef.current.position
144+
);
145+
}
146+
}
150147
});
151148

152149
useEffect(() => {
@@ -191,6 +188,13 @@ export default function CharacterModel(props: CharacterModelProps) {
191188
resetAnimation()
192189
);
193190
(action as any)._mixer._listeners = [];
191+
192+
// Move hand collider back to initial position after action
193+
if (curAnimation===animationSet.action4) {
194+
if (rightHandColliderRef.current) {
195+
rightHandColliderRef.current.setTranslationWrtParent(vec3({ x: 0, y: 0, z: 0 }))
196+
}
197+
}
194198
};
195199
}, [curAnimation]);
196200

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ecctrl",
3-
"version": "1.0.45",
3+
"version": "1.0.46",
44
"author": "Erdong Chen",
55
"license": "MIT",
66
"description": "A floating rigibody character controller for R3F",

readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ EcctrlProps: {
148148
rejectVelMult: 4, // Reject velocity multiplier
149149
moveImpulsePointY: 0.5, // Move impulse point Y offset
150150
camFollowMult: 11, // Camera follow speed multiplier
151+
fallingGravityScale: 2.5, // Character is falling, apply higher gravity
152+
fallingMaxVel: -20, // Limit character max falling velocity
151153
// Floating Ray setups
152154
rayOriginOffest: { x: 0, y: -capsuleHalfHeight, z: 0 }, // Ray origin offset
153155
rayHitForgiveness: 0.1, // Ray hit forgiveness

src/Ecctrl.tsx

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ const Ecctrl = forwardRef<RapierRigidBody, EcctrlProps>(({
7979
rejectVelMult = 4,
8080
moveImpulsePointY = 0.5,
8181
camFollowMult = 11,
82+
fallingGravityScale = 2.5,
83+
fallingMaxVel = -20,
8284
// Floating Ray setups
8385
rayOriginOffest = { x: 0, y: -capsuleHalfHeight, z: 0 },
8486
rayHitForgiveness = 0.1,
@@ -404,6 +406,7 @@ const Ecctrl = forwardRef<RapierRigidBody, EcctrlProps>(({
404406

405407
// can jump setup
406408
let canJump = false;
409+
let isFalling = false;
407410

408411
// on moving object state
409412
let isOnMovingObject = false;
@@ -646,6 +649,13 @@ const Ecctrl = forwardRef<RapierRigidBody, EcctrlProps>(({
646649
characterRef.current.applyTorqueImpulse(dragAngForce, false)
647650
};
648651

652+
/**
653+
* Character sleep function
654+
*/
655+
const sleepCharacter = () => {
656+
characterRef.current.sleep()
657+
}
658+
649659
useEffect(() => {
650660
// Initialize directional light
651661
if (followLight) {
@@ -768,6 +778,12 @@ const Ecctrl = forwardRef<RapierRigidBody, EcctrlProps>(({
768778
pivot.rotation.x = camInitDir.x
769779
pivot.rotation.y = camInitDir.y
770780
pivot.rotation.z = camInitDir.z
781+
782+
window.addEventListener("blur", sleepCharacter);
783+
784+
return () => {
785+
window.removeEventListener("blur", sleepCharacter);
786+
}
771787
}, [])
772788

773789
useFrame((state, delta) => {
@@ -1068,6 +1084,21 @@ const Ecctrl = forwardRef<RapierRigidBody, EcctrlProps>(({
10681084
}
10691085
}
10701086

1087+
/**
1088+
* Detect character falling state
1089+
*/
1090+
isFalling = (currentVel.y < 0 && !canJump) ? true : false
1091+
1092+
/**
1093+
* Apply larger gravity when falling
1094+
*/
1095+
if (characterRef.current) {
1096+
characterRef.current.setGravityScale(
1097+
currentVel.y > fallingMaxVel ? (isFalling ? fallingGravityScale : 1) : 0,
1098+
true
1099+
)
1100+
}
1101+
10711102
/**
10721103
* Apply auto balance force to the character
10731104
*/
@@ -1103,7 +1134,7 @@ const Ecctrl = forwardRef<RapierRigidBody, EcctrlProps>(({
11031134
jumpIdleAnimation();
11041135
}
11051136
// On high sky, play falling animation
1106-
if (rayHit == null && currentVel.y < 0) {
1137+
if (rayHit == null && isFalling) {
11071138
fallAnimation();
11081139
}
11091140
}
@@ -1176,6 +1207,8 @@ export interface EcctrlProps extends RigidBodyProps {
11761207
rejectVelMult?: number;
11771208
moveImpulsePointY?: number;
11781209
camFollowMult?: number;
1210+
fallingGravityScale?: number;
1211+
fallingMaxVel?: number;
11791212
// Floating Ray setups
11801213
rayOriginOffest?: { x: number; y: number; z: number };
11811214
rayHitForgiveness?: number;

src/stores/useGame.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,10 @@ export type AnimationSet = {
151151
jumpLand: string;
152152
fall: string;
153153
// Currently support four additional animations
154-
action1: string;
155-
action2: string;
156-
action3: string;
157-
action4: string;
154+
action1?: string;
155+
action2?: string;
156+
action3?: string;
157+
action4?: string;
158158
};
159159

160160
type State = {

0 commit comments

Comments
 (0)