// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. using System; using UnityEngine; namespace Oculus.Haptics { /// /// Provides playback functionality for a single haptic clip by wrapping . /// /// /// /// If you don't need a MonoBehaviour and a C# class would be more suitable, use HapticClipPlayer /// instead. It has the same functionality. ///
/// /// Once you have assigned a to the property you can play /// the HapticSource, enable or disable looping, and modulate the amplitude and frequency. ///
/// /// You can place multiple HapticSource components in your scene, with a different /// HapticClip assigned to each. ///
public class HapticSource : MonoBehaviour, ISerializationCallbackReceiver { // The HapticClipPlayer that HapticSource wraps. private HapticClipPlayer _player; // The following are serializable fields that Unity uses to persist the various // properties and that HapticSourceEditor uses as the PropertyField. The // default values set here are the ones that the sliders etc. are set to in the // Unity editor. // A serializable field for . [SerializeField] private HapticClip _clip; // A serializable field for . [SerializeField] Controller _controller = Controller.Both; // A serializable field for . [SerializeField] private bool _loop = false; // A serializable field for . [SerializeField] [Range(0.0f, float.MaxValue)] private float _amplitude = 1.0f; // A serializable field for . [SerializeField] [Range(-1.0f, 1.0f)] private float _frequencyShift = 0.0f; // A serializable field for . [SerializeField] [Range(0, 255)] private uint _priority = 128; /// /// Awake() creates a new HapticClipPlayer, assigns the /// serialized clip to it, and applies all serialized properties. /// void Awake() { _player = new HapticClipPlayer(); _player.clip = _clip; SyncSerializedFieldsToPlayer(); } /// /// Starts playback of the HapticClip that has been assigned with the clip /// property from the start of the clip. /// /// /// /// /// All properties applied to this will be effective during playback.
/// Although multiple HapticSources can play simultaneously, the output of only one will be felt at any given moment on /// a given controller.
/// See for a description of how this works. ///
/// /// /// For further information on Play() see .
/// For more details on playback states and playback behaviour, see . ///
///
public void Play() { _player.Play(_controller); } /// /// Starts playback of the HapticClip that has been assigned with the clip /// property on the controller passed by argument. /// /// /// /// The controller assigned to this HapticSource will be reassigned to the one /// passed to this method. /// /// /// For more information on playback behaviour see and /// . /// /// /// The physical controller to play haptics on. public void Play(Controller controller) { this.controller = controller; _player.Play(_controller); } /// /// Pause playback of the HapticSource. /// /// /// /// See also: .
/// For details on playback states and playback behaviour, see . ///
public void Pause() { _player.Pause(); } /// /// Resume playback of the HapticSource. /// /// /// /// See also: .
/// For details on playback states and playback behaviour, see . ///
public void Resume() { _player.Resume(); } /// /// Stops playback of the HapticSource. /// /// /// /// See also: .
/// For details on playback states and playback behaviour, see . ///
public void Stop() { _player.Stop(); } /// /// Seeks the current playback position of the HapticSource. /// /// /// /// See also: .
/// For details on playback states and playback behaviour, see . ///
public void Seek(float time) { _player.Seek(time); } /// /// Assigns a HapticClip to this HapticSource. /// /// /// /// See also: .
/// For details on playback states and playback behaviour, see . ///
public HapticClip clip { set { _clip = value; if (_player != null) { _player.clip = _clip; } } } /// /// The duration of the assigned HapticClip in seconds. /// public float clipDuration => _player.clipDuration; /// /// Assigns a physical controller to this HapticSource that /// haptics should output to. /// /// /// /// The controller will only be applied the next time /// is called. It can also be assigned as an argument to /// if preferred. /// public Controller controller { set { _controller = value; } } /// [System.ComponentModel.DefaultValue(false)] public bool loop { get => _loop; set { _loop = value; _player.isLooping = _loop; } } /// /// Sets/gets the HapticSource's amplitude. /// /// /// /// See for details. /// /// [System.ComponentModel.DefaultValue(1.0)] public float amplitude { get => _amplitude; set { _amplitude = value; _player.amplitude = _amplitude; } } /// /// Sets/gets the HapticSource's frequency shift. /// /// See for details. /// /// [System.ComponentModel.DefaultValue(0.0)] public float frequencyShift { get => _frequencyShift; set { _frequencyShift = value; _player.frequencyShift = _frequencyShift; } } /// /// Sets/gets the HapticSource's playback priority. /// /// /// /// See for details. /// /// [System.ComponentModel.DefaultValue(128)] public uint priority { get => _priority; set { _priority = value; _player.priority = _priority; } } private void SyncSerializedFieldsToPlayer() { if (_player is null) { return; } // Send properties to the HapticClipPlayer. _player.isLooping = _loop; _player.amplitude = _amplitude; _player.frequencyShift = _frequencyShift; _player.priority = _priority; } /// /// Serialization callback from the ISerializationCallbackReceiver interface. /// Unused for now but declared to fulfill the interface. /// public void OnBeforeSerialize() { } /// /// Serialization callback from the ISerializationCallbackReceiver interface. /// HapticSource uses it to synchronize the properties of the wrapped /// HapticClipPlayer to the serializable fields on this HapticSource. /// This occurs whenever a user updates any of the values on the custom inspector or /// whenever Unity loads the persisted data. /// public void OnAfterDeserialize() { if (_player != null) { SyncSerializedFieldsToPlayer(); } } /// /// Ensures that the lifetime of the wrapped HapticClipPlayer matches that of /// the HapticSource. /// protected virtual void OnDestroy() { _player.Dispose(); } } }