pmndrs / ecctrl

🕹️ A floating rigibody character controller
MIT License
465 stars 49 forks source link

The "PositionalAudio" component's position setting is no longer effective; the sound always stays nearby. #44

Closed golden-fruit closed 2 months ago

golden-fruit commented 2 months ago

After I use the ecctrl to create a character, I want to add some noise to the environment, but I found that the "PositionalAudio" component is not working properly! Do you have any suggestions to help with this issue?

ErdongChen-Andrew commented 2 months ago

This might be helpful to you: https://github.com/pmndrs/ecctrl/issues/16#issuecomment-1803260185

golden-fruit commented 2 months ago

do I only need add once listener, and all PositionalAudio will be useful as before

golden-fruit commented 2 months ago

it looks okay! this is my code:


import { PositionalAudio, useGLTF } from "@react-three/drei";
import { EcctrlAnimation, useGame } from "ecctrl";
import { Suspense, useEffect, useRef } from "react";
import Ecctrl from 'ecctrl'
import { Mesh } from "three";
import THREE from 'three';

export default function Player() {
  const { scene } = useGLTF("./models/player.glb")
  const playRef = useRef<THREE.Object3D | undefined>(null); // 玩家模型
  const bgmRef = useRef<THREE.PositionalAudio>(null); // bgm音频
  const stepsRef = useRef<THREE.PositionalAudio>(null); // 脚步音频
  const audios = {
    song: './audios/song.mp3',
    steps: './audios/steps.mp3',
  }

  const curAnimation = useGame((state) => state.curAnimation);
  // 重命名动画
  const animationSet = {
    idle: "Idle",
    walk: "Walk",
    run: "Run",
    jump: "Jump_Start",
    jumpIdle: "Jump_Idle",
    jumpLand: "Jump_Land",
    fall: "Climbing",
    action1: "Wave",
    action2: "Dance",
    action3: "Cheer",
    action4: "Attack(1h)",
  };

  useEffect(() => {
    if (!playRef?.current || !bgmRef?.current) return
    playRef.current.add(bgmRef.current.listener)
  }, [])

  useEffect(() => {
    if (curAnimation == animationSet.walk) {
      stepsRef.current?.play();
    } else {
      stepsRef.current?.stop();
    }
  }, [animationSet.walk, curAnimation])

  // 阴影配置
  useEffect(() => {
    scene.traverse(
      (obj) => (obj instanceof Mesh) && (obj.receiveShadow = obj.castShadow = true)
    );
  });

  return <Ecctrl
    animated
    followLight
    camMaxDis={-1000}
    floatHeight={0.2}
  >
    <Suspense fallback={<capsuleGeometry args={[0.3, 0.7]} />} >
      <EcctrlAnimation animationSet={animationSet} characterURL={'./models/player.glb'}>
        <primitive ref={playRef} castShadow object={scene} position={[0, -0.65, 0]} />
        <PositionalAudio
          ref={bgmRef}
          url={audios.song}
          distance={1}
          loop
          autoplay
        />
        <PositionalAudio
          ref={stepsRef}
          url={audios.steps}
          distance={1}
          loop
        />
      </EcctrlAnimation>
    </Suspense>
  </Ecctrl>
}
useGLTF.preload("./models/player.glb");
```and i will add other Ambiance as child of Canvas  and it work correctly