vibe-starter-3d
TypeScript icon, indicating that this package has built-in type declarations

0.3.10 • Public • Published

Vibe Starter 3D

This project is a foundational library for 3D projects used in Verse8. It provides essential components to start 3D development.

Introduction

Vibe Starter 3D is a library designed to easily integrate 3D elements into React applications. Built on Three.js, React Three Fiber, and related technologies, it specifically offers functionality for easily rendering and animating 3D character models in VRM and GLTF/GLB formats.

Installation

npm install vibe-starter-3d

Key Features

Components

  • CharacterRenderer: Unified component for rendering VRM and GLTF/GLB models
    • CharacterRendererRef: Reference interface providing bounding box information of the model
  • View Controllers: Components providing various camera perspectives
    • FreeViewController: Free camera perspective
    • FirstPersonViewController: First-person perspective
    • QuarterViewController: Quarter view perspective
    • SideViewController: Side view perspective
    • FlightViewController: Flight perspective with configurable handle
    • PointToMoveController: Point-to-move perspective with configurable camera mode and zoom
  • NetworkObject: Component for handling network-connected objects
    • NetworkObjectProps: Defines network object properties
    • NetworkObjectHandle: Handle for manipulating network objects

Utilities

  • controllerUtils: Controller-related utilities
    • position, camInitDis, camMinDis, camMaxDis, targetHeight, capsuleRadius, etc.
  • collisionUtils: Collision detection and handling utilities
    • isInCollisionGroup, createLocalPlayerCollisionGroups, collisionGroups, etc.
  • typeUtils: Type conversion utilities between Three.js and React Three Fiber
    • toVector3, toVector3Array, toQuaternion, toQuaternionArray etc.

Types

  • Animation-related Types:

    • AnimationType: Defines animation types such as 'IDLE', 'WALK', 'RUN', 'JUMP', etc.
    • AnimationConfig: Provides animation settings (loop, duration, clampWhenFinished, etc.)
    • AnimationConfigMap: Maps action types to animation settings
  • CharacterResource Type:

    • Interface defining character model information (name, url, animations)
  • Controller-related Types:

    • ControllerProps: Defines controller component properties
    • ControllerHandle: Controller handle interface for rigid body reference, offset, etc.
    • FollowLightProps: Settings for following light (position, intensity, color, etc.)
    • ControllerMode: Controller modes such as 'CameraBasedMovement', 'FixedCamera', 'PointToMove', etc.

Constants

  • Animation Constants:

    • ANIMATION_KEYWORDS: Keyword mapping for identifying animation types
  • Collision Group Constants:

    • CollisionGroup: Defines collision detection groups (Default, Player, Enemy, NPC, Projectile, etc.)

Collision Groups (CollisionGroup)

Below is the complete list of collision groups used in the Rapier physics engine. Each value represents a group index between 0 and 15.

Group Value Description
Default 0 General object (default)
Player 1 Player character
Enemy 2 Enemy character
NPC 3 Neutral character
Projectile 4 Projectile
Environment 5 Walls, floors, roads, structures, etc.
Item 6 Interactive or acquirable item
Trigger 7 Event trigger
UI 8 For UI raycast
Sensor 9 Invisible sensor (vision, proximity, etc.)
DeadBody 10 Deceased unit
LocalPlayer 11 Self in multiplayer
RemotePlayer 12 Other user characters in multiplayer
Vehicle 13 Vehicle/mount
Terrain 14 Terrain for special judgment
Particle 15 Particle effect (for hit judgment or to ignore)

Note: The rigid bodies of all controller components (FreeViewController, FirstPersonViewController, QuarterViewController, SideViewController, FlightViewController) are automatically set to the LocalPlayer collision group. This is handled internally through the createLocalPlayerCollisionGroups function.

Detailed Interface Descriptions

CharacterRendererProps

The CharacterRenderer component is a unified component for rendering and animating 3D character models in VRM and GLTF/GLB formats. It allows controlling various aspects like visibility, resource information, animation configuration, and current action state through its props.

The CharacterRenderer component accepts the following CharacterRendererProps:

Property Type Description Default Value
visible boolean Determines whether the character model is displayed on the screen. true
characterResource CharacterResource Character resource containing model and animation information. Required
animationConfigMap Partial<AnimationConfigMap<ActionType>> A map defining animation settings for each action type. Required
currentActionRef RefObject<ActionType | undefined> A Ref object pointing to the current character action. Required
targetHeight number Target height for the character model. Optional
disableAnimationAdjustmentToModelProportion boolean If true, animation won't be adjusted to fit the model's body proportion (GLTF/GLB only). Optional
onAnimationComplete (action: ActionType) => void Optional callback function invoked when a specific animation completes. Optional
onSizeChange (boundingBox: THREE.Box3) => void Optional callback function invoked when the model's bounding box size information changes. Optional
children React.ReactNode Optional child components to render inside the CharacterRenderer. Optional

Note: CharacterRenderer provides a CharacterRendererRef interface accessible via forwardRef. This interface allows accessing the boundingBox (THREE.Box3 | null) information of the currently rendered model.

ControllerHandle

Interface exposed externally by the controller component.

Property Type Description
rigidBodyRef React.RefObject<RapierRigidBody> Reference to the physics rigid body
offsetY number Y-axis offset value

ControllerProps

Defines the basic properties of all controller components. FreeViewController, FirstPersonViewController, QuarterViewController, and SideViewController all inherit (extend) this interface.

Property Type Description Default Value
position Vector3 Initial position of the rigid body [0, 5, 0]
camInitDis number Initial camera distance -4
camMinDis number Minimum camera zoom-in distance -4
camMaxDis number Maximum camera zoom-out distance -4
targetHeight number Character height (m) 1.6
floatHeight number Height above ground (m) 0.01
followLight FollowLightProps Settings for the following light (e.g., position, intensity, color) -
followCameraForward boolean Whether to follow camera direction false
children React.ReactNode Child components to render inside -
userData object Associates custom data with the controller's RigidBody. This data can be useful for identifying specific RigidBodies in collision detection callbacks or managing related additional information (e.g., userData={{ type: 'Player', id: 'user123' }}). See -

FollowLightProps

Defines settings for the light that follows the controller.

Property Type Description Default Value
position Vector3 Light position offset relative to the controller. Defaults to [0, 1, 0] (shining down from above). [0, 1, 0]
intensity number Light intensity. 1
color Color Light color. 0xffffff (white)
shadowCameraNear number Near plane for the shadow camera's perspective frustum. 0.5
shadowCameraFar number Far plane for the shadow camera's perspective frustum. 50
shadowCameraLeft number Left plane for the shadow camera's perspective frustum. -20
shadowCameraRight number Right plane for the shadow camera's perspective frustum. 20
shadowCameraTop number Top plane for the shadow camera's perspective frustum. 20
shadowCameraBottom number Bottom plane for the shadow camera's perspective frustum. -20
shadowMapSize number[]|Vector2 Shadow map size (width, height). Must be powers of 2. Higher values improve shadow quality but increase computation time. [2048, 2048]
shadowBias number Shadow map bias. Very tiny adjustments (e.g., 0.0001) can help reduce shadow artifacts. 0
shadowNormalBias number Offset along the object normal for shadow map queries. Helps reduce shadow acne, especially at shallow angles. 0

QuarterViewControllerProps

Defines properties for the quarter view controller. (extends ControllerProps)

Property Type Description Default Value
followCharacter boolean Whether to follow the character false
inputMode 'keyboard' | 'pointToMove' Input mode 'pointToMove'
cameraMode 'perspective' | 'orthographic' Camera mode 'perspective'

Note: This interface inherits all properties from ControllerProps.

SideViewControllerProps

Defines properties for the side view controller. (extends ControllerProps)

Property Type Description Default Value
cameraMode 'perspective' | 'orthographic' Camera mode 'orthographic'

Note: This interface inherits all properties from ControllerProps.

FlightViewControllerProps

Defines properties for the flight view controller. (Does not inherit ControllerProps)

Property Type Description Default Value
minSpeed number Minimum flight speed (m/s) 0
maxSpeed number Maximum flight speed (m/s) 120
speedIncreasePerSecond number Speed increase per second (m/s) 20
speedDecreasePerSecond number Speed decrease per second (m/s) 80
pitchRotationSpeed number Pitch rotation speed 0.5
rollRotationSpeed number Roll rotation speed Math.PI
directionRotationAcceleration number Direction rotation acceleration 0.3
maxRollAngle number Maximum roll angle Math.PI / 2
maxPitchAngle number Maximum pitch angle Math.PI / 2
hitBodySize Vector3 Body size for collision detection [1, 0.6, 3]
followLightOffset Vector3 Light offset position [-20, 30, 0]
cameraOffset Vector3 Camera offset position [0, 3, 15]
onIntersectionEnter (event: CollisionPayload) => void Callback when collision starts -
onIntersectionExit (event: CollisionPayload) => void Callback when collision ends -
userData object Associates custom data with the controller's RigidBody. Useful for identifying specific RigidBodies in collision callbacks or managing related info (e.g., userData={{ type: 'Vehicle', id: 'falcon01' }}). See -

PointToMoveControllerProps

Defines properties for the point-to-move view controller. (extends ControllerProps)

Property Type Description Default Value
followCharacter boolean Whether the camera follows the character false
cameraMode 'perspective' | 'orthographic' Camera mode 'perspective'
maxVelLimit number Maximum velocity limit for the character 3
sprintMult number Multiplier for sprint speed 2
zoom number Camera zoom level (adjusts distance and angle) 1

Note: This interface inherits all properties from ControllerProps.

Hooks

  • useMouseControls: Hook for mouse controls
  • useGame: Hook for managing game state, particularly for moveToPoint used in point-and-click movement.
    • setMoveToPoint(point: THREE.Vector3): Function to set the target point for movement.
    • moveToPoint: THREE.Vector3: Current target point for movement.
  • useControllerState: Hook providing access to the controller's internal state.
    • rigidBody: RapierRigidBody | null: Reference to the controller's Rapier rigid body.
    • childrenGroup: THREE.Group | null: Reference to the group containing children rendered inside the controller.
    • userData: { [key: string]: any }: Object containing additional user-defined data associated with the controller's state.
    • setEnableInput: (enabled: boolean) => void: Function to enable or disable controller input.
    • setPosition: (position: THREE.Vector3) => void: Function to set the controller's position.
    • setRotation: (rotation: THREE.Quaternion) => void: Function to set the controller's rotation.
    • setVelocity: (velocity: THREE.Vector3) => void: Function to set the controller's velocity.
    • setMoveToPoint: (point: THREE.Vector3 | null) => void: Function to set the target point for point-to-move navigation.
    • isPointMoving: boolean: Indicates whether the controller is currently moving towards a point.

Usage Examples

Basic Character Rendering

import { CharacterRenderer } from 'vibe-starter-3d';
import { useRef } from 'react';

function MyCharacter() {
  const actionRef = useRef<string>();

  const characterResource = {
    url: '/models/my-character.vrm',
    animations: {
      idle: '/animations/idle.fbx',
    },
  };

  const animationConfig = {
    idle: { loop: true },
  };

  return <CharacterRenderer characterResource={characterResource} animationConfigMap={animationConfig} currentActionRef={actionRef} />;
}

Free View Camera Application

import { FreeViewController } from 'vibe-starter-3d';

function My3DScene() {
  return <FreeViewController>{/* Typically place Player objects here */}</FreeViewController>;
}

First-Person View Camera Application

import { FirstPersonViewController } from 'vibe-starter-3d';

function My3DScene() {
  return <FirstPersonViewController>{/* Important: Never place character models here! */}</FirstPersonViewController>;
}

Important: Since FirstPersonViewController provides a first-person perspective, you should not place character models inside the controller. This is because the camera would be positioned inside the character model, causing obscured vision or camera clipping issues. In first-person perspective, the controller itself already acts as the player, so a separate character model is not needed. If necessary, place only weapon or hand models separately, and use full character models only in third-person perspectives.

Using useGame for Point-to-Move

import { useGame } from 'vibe-starter-3d';
import * as THREE from 'three';

function MyComponent() {
  // Get the function to set the movement target point
  const setMoveToPoint = useGame((state) => state.setMoveToPoint);

  // Example: Set the target point when the user clicks
  const handleCanvasClick = (event: MouseEvent) => {
    // Assuming you have a way to calculate the 3D point from the click event
    const clickPoint = new THREE.Vector3(/* calculated 3D coordinates */);
    setMoveToPoint(clickPoint);
  };

  // ... rest of your component logic
}

Using useControllerState Hook

import { useControllerState } from 'vibe-starter-3d';
import { useEffect, useRef } from 'react';
import { RapierRigidBody } from '@react-three/rapier';

function MyComponentInsideController() {
  // Access the controller's rigid body and childrenGroup
  const { rigidBody, childrenGroup, userData } = useControllerState();
  const playerRef = useRef<RapierRigidBody>(null);

  useEffect(() => {
    if (rigidBody) {
      console.log('Controller rigid body is available:', rigidBody);
      // Example: Store the rigid body reference if needed
      playerRef.current = rigidBody;
    }
    if (childrenGroup) {
      // Example: Current controller Y offset
      console.log('Current controller Y offset:', childrenGroup.position.y);
    }
    // Example: Accessing custom data if set via ControllerProps
    console.log('User data from controller:', userData);
  }, [rigidBody, childrenGroup, userData]);

  // IMPORTANT: This component must be placed *inside* a controller component
  // (e.g., FreeViewController, FirstPersonViewController) for the hook to work.
  return <mesh>{/* Your component's visual representation */}</mesh>;
}

// Example Usage within a Controller:
// <FreeViewController >
//   <MyComponentInsideController />
// </FreeViewController>

Technology Stack

  • React
  • Three.js
  • React Three Fiber
  • React Three Drei
  • Rapier Physics Engine
  • VRM (Virtual Reality Model)

Readme

Keywords

none

Package Sidebar

Install

npm i vibe-starter-3d

Weekly Downloads

857

Version

0.3.10

License

none

Unpacked Size

6.63 MB

Total Files

291

Last publish

Collaborators

  • rareboy
  • verse8dev