birkir / react-three-gui

GUI tools for react-three-fiber and react-spring
528 stars 29 forks source link

Cannot access control values in a button control onClick event #69

Open caseymilne opened 1 year ago

caseymilne commented 1 year ago

I am using a button control to begin a tennis shot simulation and in the onClick, I cannot seem to access the values from the other controls which are supposed to set parameters for the shot. I am using arrow functions everywhere and yet the values for the controls seem to be out of scope. Is there such a thing as a getValue() function available, or a way to keep the other controls value in scope during onClick?

import { useRef, useEffect, useState } from 'react'
import { useFrame } from '@react-three/fiber'
import { Line } from '@react-three/drei'
import { RigidBody } from "@react-three/rapier";
import { useControl } from 'react-three-gui';

export default function Animation() {

    const shotDirectionControl = useControl('Shot Direction', {
      type: 'number',
        value: 0,
        min: -0.75,
        max: 0.75,
    });

    const aShot = ( e ) => {

                 // EXPECTING shotDirectionControl to be set here and it is when called directly, but it is not when called by onClick from GUI button.

        makeBouncy = true

        if(ball.current && !shooting) {
            const shotHeightForce = shotHeightControl + forceRandomizer( 10, .01 );
            const shotLengthForce = shotStrengthControl + forceRandomizer( 10, .01 );
            ball.current.applyImpulse({ x: shotLengthForce, y: shotHeightForce, z: shotDirectionControl }, true);
            shooting = true
            setTimeout(() => { shooting = false }, 1000)
        }

    }

    const shotAControl = useControl('Shot A', {
      type: 'button',
        onClick: (e) => aShot() // ONCLICK CALLED HERE
    });

    let makeBouncy = false

    useEffect(() => {
        ball.current.setLinearDamping(0.5)
    ball.current.setAngularDamping(1.0);
    }, [])

    const ball = useRef(null);

    let shooting = false

    function forceRandomizer( max, multiplier ) {
        return  multiplier * (Math.floor(Math.random() * max))
    }

    return (
        <group>
            <RigidBody
                ref={ball}
                type="dynamic"
                colliders="ball"
                mass="0.056"
                position={[-11.86,0.1,0.15]}
                onCollisionEnter={({ manifold, target, other }) => {
                    if( makeBouncy == true ) {
                        target.rigidBody.gravityScale(0)
                        target.rigidBody.applyImpulse({ x: 0, y:0.8, z: 0 }, true);
                        target.rigidBody.setLinearDamping(5)
                        makeBouncy = false
                    }
                }}
                onCollisionExit={({ manifold, target, other }) => {
                    setTimeout(() => {
                        target.rigidBody.gravityScale(1)
                        target.rigidBody.setLinearDamping(0.5)
                    },100)
                }}
            >
                <mesh scale={[0.2, 0.2, 0.2]} onClick={bShot}>
                    <sphereGeometry args={[0.5,16,16]} />
                    <meshStandardMaterial color='yellow' />
                </mesh>
            </RigidBody>
            <Line className="center-line" points={[[-6.4, 0, 0], [6.4, 0, 0]]} color="white" lineWidth="3" />
            <Line className="service-line-east" points={[[-6.4, 0, -4.115], [-6.4, 0, 4.115]]} color="white" lineWidth="3" />
            <Line className="service-line-west" points={[[6.4, 0, -4.115], [6.4, 0, 4.115]]} color="white" lineWidth="3" />
            <Line className="back-line-east" points={[[11.885, 0, -4.115], [11.885, 0, 4.115]]} color="white" lineWidth="3" />
            <Line className="back-line-west" points={[[-11.885, 0, -4.115], [-11.885, 0, 4.115]]} color="white" lineWidth="3" />
            <Line className="single-sideline-north" points={[[-11.885, 0, -4.115], [11.885, 0, -4.115]]} color="white" lineWidth="3" />
            <Line className="single-sideline-south" points={[[-11.885, 0, 4.115], [11.885, 0, 4.115]]} color="white" lineWidth="3" />
            <Line className="service-marker-east" points={[[-11.885, 0, 0], [-11.685, 0, 0]]} color="white" lineWidth="5" />
            <Line className="service-marker-west" points={[[11.885, 0, 0], [11.685, 0, 0]]} color="white" lineWidth="5" />
        </group>
  )

}