HCI/Graphics

[Unity] bHaptics 슬라이더로 강도(intensity) 조절하기

sillon 2024. 10. 7. 17:23
728x90
반응형

 

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

namespace Bhaptics.SDK2
{
    public class PlayParamSample : MonoBehaviour
    {
        [Header("Canvas")]
        [SerializeField] private Canvas initCanvas;
        [SerializeField] private Canvas mainCanvas;

        [Header("Slider")]
        [SerializeField] private Slider sliderIntensity; // Intensity 슬라이더만 사용

        [Header("Text")]
        [SerializeField] private Text intensityValueText;
        [SerializeField] private Text playButtonText;

        [Header("Button")]
        [SerializeField] private Button intensityResetButton;

        [Header("Sample")]
        [SerializeField] private BhapticsSettings sampleSettings;

        private Coroutine onClickPlayCoroutine;
        private BhapticsSettings currentSettings;

        #region Properties
        private float intensity = 1f; // Intensity 값만 남김

        public float Intensity
        {
            get
            {
                return intensity;
            }
            set
            {
                intensity = value;
                if (intensityValueText != null)
                {
                    // Intensity 값을 0~100 범위로 표시
                    intensityValueText.text = intensity.ToString("0.0");
                }
                if (intensityResetButton != null)
                {
                    intensityResetButton.gameObject.SetActive(!intensity.Equals(1f));
                }

                // 슬라이더 값이 변경될 때마다 즉시 Haptic 재생
                PlayHaptic(Intensity);
            }
        }
        #endregion

        private void Start()
        {
            currentSettings = BhapticsSettings.Instance;
            CheckApplicationSetting();

            // 슬라이더 값을 0~100으로 설정하고 변경 시 Intensity 값 업데이트
            sliderIntensity.minValue = 0;
            sliderIntensity.maxValue = 100;
            sliderIntensity.onValueChanged.AddListener(delegate { OnIntensitySliderChange(); });

            // 장치 연결 상태 확인 및 출력
            CheckDeviceConnection();
        }

        private void OnDisable()
        {
            StopAllCoroutines();
            onClickPlayCoroutine = null;
        }

        // 슬라이더 값 변경 이벤트 핸들러
        public void OnIntensitySliderChange()
        {
            // 0~100 범위의 슬라이더 값을 그대로 Intensity 설정
            Intensity = sliderIntensity.value;
        }

        public void OnClickPlay()
        {
            if (onClickPlayCoroutine == null)
            {
                onClickPlayCoroutine = StartCoroutine(OnClickPlayCor());
            }
            else
            {
                StopHaptic();
                playButtonText.text = "Play";
            }
        }

        private void PlayHaptic(float intensity)
        {
            // 여러 장치에서 진동을 발생시킬 수 있도록 PositionType 배열을 설정
            PositionType[] positions = new PositionType[]
            {
                PositionType.HandL,
                PositionType.HandR,
                PositionType.Vest,
                PositionType.FootL,
                PositionType.FootR
            };

            int durationMillis = 1000; // 진동 지속 시간 (밀리초)

            // 각 장치별로 진동을 발생시킴
            foreach (var position in positions)
            {
                var connectedDevices = BhapticsLibrary.GetConnectedDevices(position);

                if (connectedDevices.Count > 0)
                {
                    // 각 장치에 맞게 모터 강도를 설정
                    int[] motors = new int[40]; // 모터 강도 배열 (0~100 범위)

                    // 모든 모터에 동일한 강도를 설정하거나 개별 모터 강도를 설정할 수 있음
                    for (int i = 0; i < motors.Length; i++)
                    {
                        motors[i] = Mathf.RoundToInt(intensity); // 모터 강도를 intensity에 맞춰 설정
                    }

                    // PlayMotors 함수 호출하여 각 장치에서 진동 실행
                    BhapticsLibrary.PlayMotors((int)position, motors, durationMillis);
                    Debug.Log($"Haptic playing on {position} with intensity: {intensity}");
                }
                else
                {
                    Debug.Log($"{position} device is not connected.");
                }
            }
        }

        private void StopHaptic()
        {
            BhapticsLibrary.StopAll();
            if (onClickPlayCoroutine != null)
            {
                StopCoroutine(onClickPlayCoroutine);
                onClickPlayCoroutine = null;
            }
            Debug.Log("Haptic stopped");
        }

        private IEnumerator OnClickPlayCor()
        {
            playButtonText.text = "Stop";

            // Intensity 값으로만 Haptic 재생
            PlayHaptic(Intensity);

            yield return null;

            while (BhapticsLibrary.IsPlaying())
            {
                yield return null;
            }

            playButtonText.text = "Play";
            onClickPlayCoroutine = null;
        }

        private void CheckApplicationSetting()
        {
            if (currentSettings.LastDeployVersion <= 0)
            {
                initCanvas.gameObject.SetActive(true);
                mainCanvas.gameObject.SetActive(false);
                return;
            }

            initCanvas.gameObject.SetActive(false);
            mainCanvas.gameObject.SetActive(true);
        }

        private void ResetValues()
        {
            Intensity = 1f;
            sliderIntensity.value = Intensity; // 슬라이더 값을 0~100으로 맞춤
        }

        private void CheckDeviceConnection()
        {
            // 각 위치 타입에 대해 연결된 장치 확인
            PositionType[] positions = new PositionType[]
            {
                PositionType.Vest,
                PositionType.HandL,
                PositionType.HandR,
                PositionType.FootL,
                PositionType.FootR
            };

            foreach (var position in positions)
            {
                var devices = BhapticsLibrary.GetConnectedDevices(position);
                if (devices.Count > 0)
                {
                    Debug.Log($"{position} device connected: {devices[0].DeviceName}");
                }
                else
                {
                    Debug.Log($"{position} device is not connected.");
                }
            }
        }
    }
}
728x90
반응형