Commit ef7f9692 authored by Yuyang's avatar Yuyang

Merge remote-tracking branch 'origin/master' into YuYang

parents fc01a3bf 5d8c54e5
......@@ -6,6 +6,7 @@ using System.Runtime.InteropServices;
using System;
using UnityEngine.UI;
using EPOOutline;
using MoreMountains.NiceVibrations;
public class ChainRopeView : MonoBehaviour
{
......@@ -272,6 +273,7 @@ public class ChainRopeView : MonoBehaviour
{
m_bControlPlayAudio = true;
GameServices.audioServices.PlayAudio(GameServices.configService.audioConfig.clawDownOrUp);
PlayShake();
//m_clawDownOrUpAudioSource = GameServices.audioServices.GetPlayAudioSource(GameServices.configService.audioConfig.clawDownOrUp);
m_lightObj.SetParent(m_clawBody.parent.parent);
if (m_bIsCatch)
......@@ -308,6 +310,14 @@ public class ChainRopeView : MonoBehaviour
// }
//}
}
//震动
void PlayShake()
{
if (!LocalRecord.HasKey(GlobalConfig.VibrationKey) || LocalRecord.GetIntRecord(GlobalConfig.VibrationKey) == 1)
{
MMVibrationManager.Haptic(HapticTypes.HeavyImpact, false, true, this);
}
}
//松手之后
void TouchUpEnd()
{
......@@ -587,6 +597,7 @@ public class ChainRopeView : MonoBehaviour
{
m_bControlPlayAudio = false;
GameServices.audioServices.PlayAudio(GameServices.configService.audioConfig.clawDownOrUp);
PlayShake();
}
m_bIsClawUp = true;
cursor.ChangeLength(rope.restLength - GameServices.configService.playerConfig.ropeReduceSpeed * Time.deltaTime);
......@@ -620,6 +631,7 @@ public class ChainRopeView : MonoBehaviour
{
m_bControlPlayAudio = false;
GameServices.audioServices.PlayAudio(GameServices.configService.audioConfig.clawDownOrUp);
PlayShake();
}
m_bIsClawUp = true;
cursor.ChangeLength(rope.restLength - GameServices.configService.playerConfig.ropeReduceSpeed * Time.deltaTime);
......@@ -669,6 +681,7 @@ public class ChainRopeView : MonoBehaviour
{
m_bControlPlayAudio = false;
GameServices.audioServices.PlayAudio(GameServices.configService.audioConfig.clawDownOrUp);
PlayShake();
}
m_bIsClawUp = true;
cursor.ChangeLength(rope.restLength - GameServices.configService.playerConfig.ropeReduceSpeed * Time.deltaTime);
......
fileFormatVersion: 2
guid: 64e5f5048b2007e49b32b96c1d8c0ddf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 61adcba369637416c847869ffc1682c4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 4e9d703017b5f42b0825088b0ae3136e
folderAsset: yes
timeCreated: 1476095876
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 7a37cd71dcc3d44f9a58950626844491
folderAsset: yes
timeCreated: 1514925654
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unity3d.player"
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="preferExternal"
android:versionCode="1"
android:versionName="1.0">
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true"/>
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:theme="@style/UnityThemeSelector"
android:icon="@drawable/app_icon"
android:label="@string/app_name">
<activity android:name="com.unity3d.player.UnityPlayerActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>
</application>
</manifest>
fileFormatVersion: 2
guid: 381a7af7ed6ac314db34d78323925e29
timeCreated: 1514922105
licenseType: Store
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: bcb572eaa9464459d81c4473feb4b43f
folderAsset: yes
timeCreated: 1476095881
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
// This iOS haptic interface is a pretty straightforward implementation of UIKit's framework :
// You can learn more about these methods at https://developer.apple.com/documentation/uikit/animation_and_haptics
// DO NOT remove this from your project, or iOS vibrations won't work anymore!
#import <Foundation/Foundation.h>
UISelectionFeedbackGenerator* SelectionFeedbackGenerator;
UINotificationFeedbackGenerator* NotificationFeedbackGenerator;
UIImpactFeedbackGenerator* LightImpactFeedbackGenerator;
UIImpactFeedbackGenerator* MediumImpactFeedbackGenerator;
UIImpactFeedbackGenerator* HeavyImpactFeedbackGenerator;
UIImpactFeedbackGenerator* RigidImpactFeedbackGenerator;
UIImpactFeedbackGenerator* SoftImpactFeedbackGenerator;
// INIT METHOD ---------------------------------------------------------------------------
void MMNViOS_InstantiateFeedbackGenerators()
{
SelectionFeedbackGenerator = [[UISelectionFeedbackGenerator alloc] init];
NotificationFeedbackGenerator = [[UINotificationFeedbackGenerator alloc] init];
LightImpactFeedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight];
MediumImpactFeedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium];
HeavyImpactFeedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle: UIImpactFeedbackStyleHeavy];
if (@available(iOS 13, *))
{
RigidImpactFeedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle: UIImpactFeedbackStyleRigid];
SoftImpactFeedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle: UIImpactFeedbackStyleSoft];
}
else
{
RigidImpactFeedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle: UIImpactFeedbackStyleHeavy];
SoftImpactFeedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle: UIImpactFeedbackStyleLight];
}
}
// RELEASE METHOD ---------------------------------------------------------------------------
void MMNViOS_ReleaseFeedbackGenerators ()
{
SelectionFeedbackGenerator = nil;
NotificationFeedbackGenerator = nil;
LightImpactFeedbackGenerator = nil;
MediumImpactFeedbackGenerator = nil;
HeavyImpactFeedbackGenerator = nil;
RigidImpactFeedbackGenerator = nil;
SoftImpactFeedbackGenerator = nil;
}
// PREPARATION METHODS ----------------------------------------------------------------------
void MMNViOS_PrepareSelectionFeedbackGenerator()
{
[SelectionFeedbackGenerator prepare];
}
void MMNViOS_PrepareNotificationFeedbackGenerator()
{
[NotificationFeedbackGenerator prepare];
}
void MMNViOS_PrepareLightImpactFeedbackGenerator()
{
[LightImpactFeedbackGenerator prepare];
}
void MMNViOS_PrepareMediumImpactFeedbackGenerator()
{
[MediumImpactFeedbackGenerator prepare];
}
void MMNViOS_PrepareHeavyImpactFeedbackGenerator()
{
[HeavyImpactFeedbackGenerator prepare];
}
void MMNViOS_PrepareRigidImpactFeedbackGenerator()
{
[RigidImpactFeedbackGenerator prepare];
}
void MMNViOS_PrepareSoftImpactFeedbackGenerator()
{
[SoftImpactFeedbackGenerator prepare];
}
// FEEDBACK TRIGGER METHODS -------------------------------------------------------------------------
void MMNViOS_SelectionHaptic()
{
[SelectionFeedbackGenerator prepare];
[SelectionFeedbackGenerator selectionChanged];
}
void MMNViOS_SuccessHaptic()
{
[NotificationFeedbackGenerator prepare];
[NotificationFeedbackGenerator notificationOccurred:UINotificationFeedbackTypeSuccess];
}
void MMNViOS_WarningHaptic()
{
[NotificationFeedbackGenerator prepare];
[NotificationFeedbackGenerator notificationOccurred:UINotificationFeedbackTypeWarning];
}
void MMNViOS_FailureHaptic()
{
[NotificationFeedbackGenerator prepare];
[NotificationFeedbackGenerator notificationOccurred:UINotificationFeedbackTypeError];
}
void MMNViOS_LightImpactHaptic()
{
[LightImpactFeedbackGenerator prepare];
[LightImpactFeedbackGenerator impactOccurred];
}
void MMNViOS_MediumImpactHaptic()
{
[MediumImpactFeedbackGenerator prepare];
[MediumImpactFeedbackGenerator impactOccurred];
}
void MMNViOS_HeavyImpactHaptic()
{
[HeavyImpactFeedbackGenerator prepare];
[HeavyImpactFeedbackGenerator impactOccurred];
}
void MMNViOS_RigidImpactHaptic()
{
[RigidImpactFeedbackGenerator prepare];
[RigidImpactFeedbackGenerator impactOccurred];
}
void MMNViOS_SoftImpactHaptic()
{
[SoftImpactFeedbackGenerator prepare];
[SoftImpactFeedbackGenerator impactOccurred];
}
fileFormatVersion: 2
guid: 60b2a35a0cfd04a85a26522b005847f1
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 1d9d8907be3d34a778808103de04f4f6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
#import <Foundation/Foundation.h>
#import <CoreHaptics/CoreHaptics.h>
//#import "unityswift-Swift.h"
#import "UnitySwift-Bridging-Header.h"
#import "UnityFramework/UnityFramework-Swift.h"
extern "C"
{
void MMNViOS_CoreHapticsRegisterHapticEngineFinishedCallback(HapticCallback callback)
{
[MMNViOSCoreHapticsInterface RegisterHapticEngineFinishedCallbackWithCallback:callback];
}
void MMNViOS_CoreHapticsRegisterHapticEngineErrorCallback(HapticCallback callback)
{
[MMNViOSCoreHapticsInterface RegisterHapticEngineErrorCallbackWithCallback:callback];
}
void MMNViOS_CoreHapticsRegisterHapticEngineResetCallback(HapticCallback callback)
{
[MMNViOSCoreHapticsInterface RegisterHapticEngineResetCallbackWithCallback:callback];
}
bool MMNViOS_CoreHapticsSupported()
{
return [MMNViOSCoreHapticsInterface CoreHapticsSupported];
}
void MMNViOS_CoreHapticsSetDebugMode(bool status)
{
[MMNViOSCoreHapticsInterface SetDebugModeWithStatus:status];
}
void MMNViOS_CreateEngine()
{
[MMNViOSCoreHapticsInterface CreateEngine];
}
void MMNViOS_StopEngine()
{
[MMNViOSCoreHapticsInterface StopEngine];
}
void MMNViOS_PlayTransientHapticPattern(float intensity, float sharpness, bool threaded)
{
[MMNViOSCoreHapticsInterface PlayTransientHapticWithIntensity:intensity sharpness:sharpness threaded:threaded];
}
void MMNViOS_PlayContinuousHapticPattern(float intensity, float sharpness, float duration, bool threaded, bool fullIntensity)
{
[MMNViOSCoreHapticsInterface PlayContinuousHapticWithIntensity: intensity sharpness:sharpness duration:duration threaded:threaded fullIntensity:fullIntensity];
}
void MMNViOS_StopContinuousHaptic()
{
[MMNViOSCoreHapticsInterface StopContinuousHaptic];
}
void MMNViOS_UpdateContinuousHapticPattern(float intensity, float sharpness, bool threaded)
{
[MMNViOSCoreHapticsInterface UpdateContinuousHapticWithIntensity:intensity sharpness:sharpness threaded:threaded];
}
void MMNViOS_PlayCoreHapticsFromJSON(const char* jsonDict, bool threaded)
{
if (jsonDict == nil)
{
printf("jsonDict is nil");
return;
}
NSError* error = nil;
NSString *jsonAsString = [[NSString alloc] initWithUTF8String:jsonDict];
//NSLog(jsonAsString);
/*NSData* data = [jsonAsString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
CHHapticPattern* pattern = [[CHHapticPattern alloc] initWithDictionary:dict error:&error];*/
[MMNViOSCoreHapticsInterface PlayHapticsFromJSONWithPatternAsString:jsonAsString threaded:threaded];
}
}
fileFormatVersion: 2
guid: 19540685ad72e463791cb3726a1d2f58
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings: {}
- first:
tvOS: tvOS
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: a7f3be31fd9b2488f8dd1351850f9204
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
iPhone: iOS
second:
enabled: 1
settings: {}
- first:
tvOS: tvOS
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:
#import <Foundation/Foundation.h>
#import <CoreHaptics/CoreHaptics.h>
#import "UnityInterface.h"
typedef void (*HapticCallback)();
fileFormatVersion: 2
guid: 88b4979ff1a0248bfb77546e7e843696
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude WebGL: 1
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 0
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
CPU: AnyCPU
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:
module UnityFramework_NiceVibrationsPrivate {
header "UnitySwift-Bridging-Header.h"
export *
}
fileFormatVersion: 2
guid: 6cc9b30fec8fd462cb317c9735b5bec5
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 89067a09c7a21d243a9a1c9059761fd2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 258c36e07f5da5d438332fef965d7d8e, type: 3}
m_Name: MMNVPathDefinition
m_EditorClassIdentifier:
PluginPath:
ModuleFileName:
PluginRelativePath:
ForceAlwaysEmbedSwiftStandardLibraries: 0
fileFormatVersion: 2
guid: 26ed4a60d6c4b6b40b0f04a8c181d66b
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 42f03fcbaf27f4e0b8661f490cdd8754
folderAsset: yes
timeCreated: 1514912150
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 4772e47ea134fe94dba7fe9d9daa153b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: aafe8fb128f742e40a8413c8c7ea17b2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.NiceVibrations
{
#if UNITY_EDITOR
/// <summary>
/// This class lets you specify (in code, by editing it) symbols that will be added to the build settings' define symbols list automatically
/// </summary>
[InitializeOnLoad]
public class NiceVibrationsDefineSymbols
{
/// <summary>
/// A list of all the symbols you want added to the build settings
/// </summary>
public static readonly string[] Symbols = new string[]
{
"MOREMOUNTAINS_NICEVIBRATIONS"
};
/// <summary>
/// As soon as this class has finished compiling, adds the specified define symbols to the build settings
/// </summary>
static NiceVibrationsDefineSymbols()
{
string scriptingDefinesString = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
List<string> scriptingDefinesStringList = scriptingDefinesString.Split(';').ToList();
scriptingDefinesStringList.AddRange(Symbols.Except(scriptingDefinesStringList));
PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, string.Join(";", scriptingDefinesStringList.ToArray()));
}
}
#endif
}
fileFormatVersion: 2
guid: 6b2b51febacf4564ab92a1a04d6cd1ec
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace MoreMountains.NiceVibrations
{
#if UNITY_EDITOR
/// <summary>
/// This custom inspector for MMNVAndroidWaveFormAssets adds a button to import values from an AHAP file
/// </summary>
[CustomEditor(typeof(MMNVAndroidWaveFormAsset))]
public class MMNVAndroidWaveFormAssetEditor : Editor
{
/// <summary>
/// On inspector GUI, we draw an extra button
/// </summary>
public override void OnInspectorGUI()
{
serializedObject.Update();
MMNVAndroidWaveFormAsset waveformAsset = (MMNVAndroidWaveFormAsset)target;
DrawDefaultInspector();
if (waveformAsset.AHAPFile != null)
{
if (GUILayout.Button("Import from AHAP"))
{
MMNVAndroidWaveForm tempWaveform = MMNVAHAP.AHAPtoAndroidWaveForm(waveformAsset.AHAPFile.text, waveformAsset.IntensityMultiplier, waveformAsset.SharpnessMultiplier);
waveformAsset.WaveForm.Pattern = tempWaveform.Pattern;
waveformAsset.WaveForm.Amplitudes = tempWaveform.Amplitudes;
}
}
serializedObject.ApplyModifiedProperties();
}
}
#endif
}
fileFormatVersion: 2
guid: b384fa36cd33d1d40a8f635f1c648176
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MoreMountains.NiceVibrations
{
/// <summary>
/// An asset post processor used to compensate for a new bug introduced by Unity in 2019.3.12f1
/// </summary>
public class MMNVAssetPostProcessor : AssetPostprocessor
{
/// <summary>
/// On GeneratedCSProject, we force ReferenceOutputAssembly to true to avoid missing references in VS.
/// </summary>
/// <param name="path"></param>
/// <param name="content"></param>
/// <returns></returns>
private static string OnGeneratedCSProject(string path, string content)
{
return content.Replace("<ReferenceOutputAssembly>false</ReferenceOutputAssembly>", "<ReferenceOutputAssembly>true</ReferenceOutputAssembly>");
}
}
}
#endif
\ No newline at end of file
fileFormatVersion: 2
guid: 433967178997d39458757004d883d804
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: d7bb09ebd427b4bf69534887e7899e55
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace MoreMountains.NiceVibrations
{
#if UNITY_EDITOR
/// <summary>
/// This custom inspector for MMNVAndroidWaveFormAssets adds a button to import values from an AHAP file
/// </summary>
[CustomEditor(typeof(MMNVRumbleWaveFormAsset))]
public class MMNVRumbleWaveFormAssetEditor : Editor
{
/// <summary>
/// On inspector GUI, we draw an extra button
/// </summary>
public override void OnInspectorGUI()
{
serializedObject.Update();
MMNVRumbleWaveFormAsset waveformAsset = (MMNVRumbleWaveFormAsset)target;
DrawDefaultInspector();
if (waveformAsset.AHAPFile != null)
{
if (GUILayout.Button("Import from AHAP"))
{
MMNVRumbleWaveForm tempWaveform = MMNVAHAP.AHAPtoRumbleWaveForm(waveformAsset.AHAPFile.text, waveformAsset.IntensityMultiplier, waveformAsset.SharpnessMultiplier);
waveformAsset.WaveForm.Pattern = tempWaveform.Pattern;
waveformAsset.WaveForm.LowFrequencyAmplitudes = tempWaveform.LowFrequencyAmplitudes;
waveformAsset.WaveForm.HighFrequencyAmplitudes = tempWaveform.HighFrequencyAmplitudes;
}
}
serializedObject.ApplyModifiedProperties();
}
}
#endif
}
fileFormatVersion: 2
guid: e845c46b827ec3044a72829bd9e6f00c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
{
"name": "MoreMountains.NiceVibrations.Editor",
"references": [
"GUID:865b414a121ed594e91db2e09f65d38c",
"GUID:041029188fa88c54f9efffc039b6a1c9"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": []
}
\ No newline at end of file
fileFormatVersion: 2
guid: 4d05703db82581d42ac13a6e1edd0ba2
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: b20a45af8a7ea4f4bbb2941cfdf61140
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using Newtonsoft.Json;
#endif
namespace MoreMountains.NiceVibrations
{
/// <summary>
/// A class to store AHAP metadata
/// </summary>
[System.Serializable]
public class MMNVAHAPMetadata
{
public string Project;
public string Created;
}
/// <summary>
/// A class to store AHAP event parameters
/// </summary>
[System.Serializable]
public class MMNVAHAPEventParameter
{
public string ParameterID;
public int ParameterValue;
}
/// <summary>
/// A class to store AHAP events
/// </summary>
[System.Serializable]
public class MMNVAHAPEvent
{
public int Time;
public string EventType;
public double EventDuration;
public List<MMNVAHAPEventParameter> EventParameters;
}
/// <summary>
/// A class to store AHAP parameter curve control points
/// </summary>
[System.Serializable]
public class MMNVAHAPParameterCurveControlPoint
{
public double Time;
public double ParameterValue;
}
/// <summary>
/// A class to store AHAP parameter curves
/// </summary>
[System.Serializable]
public class MMNVAHAPParameterCurve
{
public string ParameterID;
public double Time;
public List<MMNVAHAPParameterCurveControlPoint> ParameterCurveControlPoints;
}
/// <summary>
/// A class to store AHAP patterns
/// </summary>
[System.Serializable]
public class MMNVAHAPPattern
{
public MMNVAHAPEvent Event;
public MMNVAHAPParameterCurve ParameterCurve;
}
/// <summary>
/// A class used to store and manipulate AHAP json contents
/// </summary>
[System.Serializable]
public class MMNVAHAP
{
public float Version;
public MMNVAHAPMetadata Metadata;
public List<MMNVAHAPPattern> Pattern;
#if UNITY_EDITOR
/// <summary>
/// Converts a AHAP string into a MMNVAndroidWaveForm
/// </summary>
/// <param name="AHAPasString"></param>
/// <returns></returns>
public static MMNVAndroidWaveForm AHAPtoAndroidWaveForm(string AHAPasString, float intensityMultiplier, float sharpnessMultiplier)
{
MMNVAHAP ahap = JsonConvert.DeserializeObject<MMNVAHAP>(AHAPasString);
List<long> patterns = new List<long>();
List<int> amplitudes = new List<int>();
double totalTimeStamp = 0f;
double previousTimeStamp = 0f;
foreach (MMNVAHAPPattern pattern in ahap.Pattern)
{
if (pattern.ParameterCurve != null)
{
if (pattern.ParameterCurve.ParameterID == "HapticIntensityControl")
{
foreach (MMNVAHAPParameterCurveControlPoint point in pattern.ParameterCurve.ParameterCurveControlPoints)
{
double timeStamp = point.Time - previousTimeStamp;
totalTimeStamp += timeStamp;
patterns.Add((long)(timeStamp * 1000));
float originalIntensity = (float)point.ParameterValue * intensityMultiplier;
int intensity = (int)Remap(originalIntensity, 0f, 1f, 0f, 255f);
amplitudes.Add(intensity);
previousTimeStamp = point.Time;
}
}
}
}
MMNVAndroidWaveForm returnWaveForm = new MMNVAndroidWaveForm();
returnWaveForm.Amplitudes = amplitudes.ToArray();
returnWaveForm.Pattern = patterns.ToArray();
return returnWaveForm;
}
/// <summary>
/// Converts a AHAP string into a MMNRumbleWaveForm
/// </summary>
/// <param name="AHAPasString"></param>
/// <returns></returns>
public static MMNVRumbleWaveForm AHAPtoRumbleWaveForm(string AHAPasString, float intensityMultiplier, float sharpnessMultiplier)
{
MMNVAHAP ahap = JsonConvert.DeserializeObject<MMNVAHAP>(AHAPasString);
List<long> patterns = new List<long>();
List<int> lowFreqAmplitudes = new List<int>();
List<int> highFreqAmplitudes = new List<int>();
double totalTimeStamp = 0f;
double previousTimeStamp = 0f;
foreach (MMNVAHAPPattern pattern in ahap.Pattern)
{
if (pattern.ParameterCurve != null)
{
if (pattern.ParameterCurve.ParameterID == "HapticIntensityControl")
{
foreach (MMNVAHAPParameterCurveControlPoint point in pattern.ParameterCurve.ParameterCurveControlPoints)
{
double timeStamp = point.Time - previousTimeStamp;
totalTimeStamp += timeStamp;
patterns.Add((long)(timeStamp * 1000));
float originalIntensity = (float)point.ParameterValue * intensityMultiplier;
int intensity = (int)Remap(originalIntensity, 0f, 1f, 0f, 255f);
lowFreqAmplitudes.Add(intensity);
previousTimeStamp = point.Time;
}
}
if (pattern.ParameterCurve.ParameterID == "HapticSharpnessControl")
{
foreach (MMNVAHAPParameterCurveControlPoint point in pattern.ParameterCurve.ParameterCurveControlPoints)
{
double timeStamp = point.Time - previousTimeStamp;
totalTimeStamp += timeStamp;
patterns.Add((long)(timeStamp * 1000));
float originalIntensity = (float)point.ParameterValue * sharpnessMultiplier;
int intensity = (int)Remap(originalIntensity, 0f, 1f, 0f, 255f);
highFreqAmplitudes.Add(intensity);
previousTimeStamp = point.Time;
}
}
}
}
MMNVRumbleWaveForm returnWaveForm = new MMNVRumbleWaveForm();
returnWaveForm.LowFrequencyAmplitudes = lowFreqAmplitudes.ToArray();
returnWaveForm.HighFrequencyAmplitudes = highFreqAmplitudes.ToArray();
returnWaveForm.Pattern = patterns.ToArray();
return returnWaveForm;
}
#endif
/// <summary>
/// Remaps value x between AB to CD
/// </summary>
/// <param name="x"></param>
/// <param name="A"></param>
/// <param name="B"></param>
/// <param name="C"></param>
/// <param name="D"></param>
/// <returns></returns>
public static float Remap(float x, float A, float B, float C, float D)
{
float remappedValue = C + (x - A) / (B - A) * (D - C);
return remappedValue;
}
}
}
fileFormatVersion: 2
guid: 9fc7a58b1a8c38c4abfc83bab4224a24
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using System;
namespace MoreMountains.NiceVibrations
{
/// <summary>
/// This class handles all Android haptics specific calls
/// </summary>
public static class MMNVAndroid
{
private static int _sdkVersion = -1;
#if UNITY_ANDROID && !UNITY_EDITOR
private static AndroidJavaClass UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
private static AndroidJavaObject CurrentActivity = UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
private static AndroidJavaObject AndroidVibrator = CurrentActivity.Call<AndroidJavaObject>("getSystemService", "vibrator");
private static AndroidJavaClass VibrationEffectClass;
private static AndroidJavaObject VibrationEffect;
private static int DefaultAmplitude;
private static IntPtr AndroidVibrateMethodRawClass = AndroidJNIHelper.GetMethodID(AndroidVibrator.GetRawClass(), "vibrate", "(J)V", false);
private static jvalue[] AndroidVibrateMethodRawClassParameters = new jvalue[1];
#else
private static AndroidJavaClass UnityPlayer;
private static AndroidJavaObject CurrentActivity;
private static AndroidJavaObject AndroidVibrator = null;
private static AndroidJavaClass VibrationEffectClass = null;
private static AndroidJavaObject VibrationEffect;
private static int DefaultAmplitude;
private static IntPtr AndroidVibrateMethodRawClass = IntPtr.Zero;
private static jvalue[] AndroidVibrateMethodRawClassParameters = null;
#endif
/// <summary>
/// Requests a default vibration on Android, for the specified duration, in milliseconds
/// </summary>
/// <param name="milliseconds">Milliseconds.</param>
public static void AndroidVibrate(long milliseconds)
{
if (!MMNVPlatform.Android()) { return; }
AndroidVibrateMethodRawClassParameters[0].j = milliseconds;
AndroidJNI.CallVoidMethod(AndroidVibrator.GetRawObject(), AndroidVibrateMethodRawClass, AndroidVibrateMethodRawClassParameters);
}
/// <summary>
/// Requests a vibration of the specified amplitude and duration. If amplitude is not supported by the device's SDK, a default vibration will be requested
/// </summary>
/// <param name="milliseconds">Milliseconds.</param>
/// <param name="amplitude">Amplitude.</param>
public static void AndroidVibrate(long milliseconds, int amplitude)
{
if (!MMNVPlatform.Android()) { return; }
// amplitude is only supported after API26
if ((AndroidSDKVersion() < 26))
{
AndroidVibrate(milliseconds);
}
else
{
AndroidVibrationEffectClassInitialization();
VibrationEffect = VibrationEffectClass.CallStatic<AndroidJavaObject>("createOneShot", new object[] { milliseconds, amplitude });
AndroidVibrator.Call("vibrate", VibrationEffect);
}
}
// Requests a vibration on Android for the specified pattern and optional repeat
// Straight out of the Android documentation :
// Pass in an array of ints that are the durations for which to turn on or off the vibrator in milliseconds.
// The first value indicates the number of milliseconds to wait before turning the vibrator on.
// The next value indicates the number of milliseconds for which to keep the vibrator on before turning it off.
// Subsequent values alternate between durations in milliseconds to turn the vibrator off or to turn the vibrator on.
// repeat: the index into pattern at which to repeat, or -1 if you don't want to repeat.
public static void AndroidVibrate(long[] pattern, int repeat)
{
if (!MMNVPlatform.Android()) { return; }
if ((AndroidSDKVersion() < 26))
{
AndroidVibrator.Call("vibrate", pattern, repeat);
}
else
{
AndroidVibrationEffectClassInitialization();
VibrationEffect = VibrationEffectClass.CallStatic<AndroidJavaObject>("createWaveform", new object[] { pattern, repeat });
AndroidVibrator.Call("vibrate", VibrationEffect);
}
}
/// <summary>
/// Requests a vibration on Android for the specified pattern, amplitude and optional repeat
/// </summary>
/// <param name="pattern">Pattern.</param>
/// <param name="amplitudes">Amplitudes.</param>
/// <param name="repeat">Repeat : -1 : no repeat, 0 : infinite, 1 : repeat once, 2 : repeat twice, etc</param>
public static void AndroidVibrate(long[] pattern, int[] amplitudes, int repeat)
{
if (!MMNVPlatform.Android()) { return; }
if ((AndroidSDKVersion() < 26))
{
AndroidVibrator.Call("vibrate", pattern, repeat);
}
else
{
AndroidVibrationEffectClassInitialization();
VibrationEffect = VibrationEffectClass.CallStatic<AndroidJavaObject>("createWaveform", new object[] { pattern, amplitudes, repeat });
AndroidVibrator.Call("vibrate", VibrationEffect);
}
}
/// <summary>
/// Stops all Android vibrations that may be active
/// </summary>
public static void AndroidCancelVibrations()
{
if (!MMNVPlatform.Android()) { return; }
AndroidVibrator.Call("cancel");
}
/// <summary>
/// Returns true if the device running the game has vibrations
/// </summary>
/// <returns></returns>
public static bool AndroidHasVibrator()
{
if (!MMNVPlatform.Android()) { return false; }
return AndroidVibrator.Call<bool>("hasVibrator");
}
/// <summary>
/// Returns true if the device running the game has amplitude control
/// </summary>
/// <returns></returns>
public static bool AndroidHasAmplitudeControl()
{
if ((AndroidSDKVersion() < 26))
{
return false;
}
if (!MMNVPlatform.Android()) { return false; }
return AndroidVibrator.Call<bool>("hasAmplitudeControl");
}
/// <summary>
/// Initializes the VibrationEffectClass if needed.
/// </summary>
private static void AndroidVibrationEffectClassInitialization()
{
if (VibrationEffectClass == null)
{
VibrationEffectClass = new AndroidJavaClass("android.os.VibrationEffect");
}
}
/// <summary>
/// Returns the current Android SDK version as an int
/// </summary>
/// <returns>The SDK version.</returns>
public static int AndroidSDKVersion()
{
if (_sdkVersion == -1)
{
int apiLevel = int.Parse(SystemInfo.operatingSystem.Substring(SystemInfo.operatingSystem.IndexOf("-") + 1, 3));
_sdkVersion = apiLevel;
return apiLevel;
}
else
{
return _sdkVersion;
}
}
}
}
fileFormatVersion: 2
guid: b922262d9e4809f4a8ce2b27988275fb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.NiceVibrations
{
/// <summary>
/// A class used to store android waveform values, used to trigger haptics with varying intensity
/// </summary>
[System.Serializable]
public class MMNVAndroidWaveForm
{
public long[] Pattern;
public int[] Amplitudes;
}
/// <summary>
/// A scriptable object used to store waveform values
/// </summary>
[CreateAssetMenu(fileName = "AndroidWaveFormAsset", menuName = "MoreMountains/NiceVibrations/AndroidWaveFormAsset")]
public class MMNVAndroidWaveFormAsset : ScriptableObject
{
[Header("Properties")]
public MMNVAndroidWaveForm WaveForm;
[Header("AHAP")]
public TextAsset AHAPFile;
public float IntensityMultiplier = 1f;
public float SharpnessMultiplier = 1f;
}
}
fileFormatVersion: 2
guid: 878a46a2e5200af4ca0b198530f29690
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.NiceVibrations
{
/// <summary>
/// An attribute to conditionnally hide fields based on the current selection in an enum.
/// Usage : [MMNVEnumCondition("rotationMode", (int)RotationMode.LookAtTarget, (int)RotationMode.RotateToAngles)]
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct, Inherited = true)]
public class MMNVEnumConditionAttribute : PropertyAttribute
{
public string ConditionEnum = "";
public bool Hidden = false;
BitArray bitArray = new BitArray(32);
public bool ContainsBitFlag(int enumValue)
{
return bitArray.Get(enumValue);
}
public MMNVEnumConditionAttribute(string conditionBoolean, params int[] enumValues)
{
this.ConditionEnum = conditionBoolean;
this.Hidden = true;
for (int i = 0; i < enumValues.Length; i++)
{
bitArray.Set(enumValues[i], true);
}
}
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(MMNVEnumConditionAttribute))]
public class EnumConditionAttributeDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
MMNVEnumConditionAttribute enumConditionAttribute = (MMNVEnumConditionAttribute)attribute;
bool enabled = GetConditionAttributeResult(enumConditionAttribute, property);
bool previouslyEnabled = GUI.enabled;
GUI.enabled = enabled;
if (!enumConditionAttribute.Hidden || enabled)
{
EditorGUI.PropertyField(position, property, label, true);
}
GUI.enabled = previouslyEnabled;
}
private bool GetConditionAttributeResult(MMNVEnumConditionAttribute enumConditionAttribute, SerializedProperty property)
{
bool enabled = true;
string propertyPath = property.propertyPath;
string conditionPath = propertyPath.Replace(property.name, enumConditionAttribute.ConditionEnum);
SerializedProperty sourcePropertyValue = property.serializedObject.FindProperty(conditionPath);
if (sourcePropertyValue != null)
{
int currentEnum = sourcePropertyValue.enumValueIndex;
enabled = enumConditionAttribute.ContainsBitFlag(currentEnum);
}
else
{
Debug.LogWarning("No matching boolean found for ConditionAttribute in object: " + enumConditionAttribute.ConditionEnum);
}
return enabled;
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
MMNVEnumConditionAttribute enumConditionAttribute = (MMNVEnumConditionAttribute)attribute;
bool enabled = GetConditionAttributeResult(enumConditionAttribute, property);
if (!enumConditionAttribute.Hidden || enabled)
{
return EditorGUI.GetPropertyHeight(property, label);
}
else
{
return -EditorGUIUtility.standardVerticalSpacing;
}
}
}
#endif
}
fileFormatVersion: 2
guid: eb05d5d3c4efbc14cb10fa6c533b57f3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.NiceVibrations
{
/// <summary>
/// The list of the all the haptic presets that come bundled with Nice Vibrations
/// </summary>
public enum HapticTypes { Selection, Success, Warning, Failure, LightImpact, MediumImpact, HeavyImpact, RigidImpact, SoftImpact, None }
}
fileFormatVersion: 2
guid: cae0cc22a7febe642a01c40b2778d020
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
using System.Reflection;
namespace MoreMountains.NiceVibrations
{
[System.AttributeUsage(System.AttributeTargets.Field)]
public class MMNVInspectorButtonAttribute : PropertyAttribute
{
public readonly string MethodName;
public MMNVInspectorButtonAttribute(string MethodName)
{
this.MethodName = MethodName;
}
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(MMNVInspectorButtonAttribute))]
public class InspectorMMNVButtonPropertyDrawer : PropertyDrawer
{
private MethodInfo _eventMethodInfo = null;
public override void OnGUI(Rect position, SerializedProperty prop, GUIContent label)
{
MMNVInspectorButtonAttribute inspectorButtonAttribute = (MMNVInspectorButtonAttribute)attribute;
float buttonLength = position.width;
Rect buttonRect = new Rect(position.x, position.y, buttonLength, position.height);
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
if (GUI.Button(buttonRect, inspectorButtonAttribute.MethodName))
{
System.Type eventOwnerType = prop.serializedObject.targetObject.GetType();
string eventName = inspectorButtonAttribute.MethodName;
if (_eventMethodInfo == null)
{
_eventMethodInfo = eventOwnerType.GetMethod(eventName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
}
if (_eventMethodInfo != null)
{
_eventMethodInfo.Invoke(prop.serializedObject.targetObject, null);
}
else
{
Debug.LogWarning(string.Format("InspectorButton: Unable to find method {0} in {1}", eventName, eventOwnerType));
}
}
}
}
#endif
}
\ No newline at end of file
fileFormatVersion: 2
guid: 1d9bf2d53397a294eacdbab9b13bc653
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.NiceVibrations
{
public static class MMNVPlatform
{
/// <summary>
/// Returns true if the current platform is Android, false otherwise.
/// </summary>
public static bool Android()
{
#if UNITY_ANDROID && !UNITY_EDITOR
return true;
#else
return false;
#endif
}
/// <summary>
/// Returns true if the current platform is iOS, false otherwise
/// </summary>
/// <returns><c>true</c>, if O was ied, <c>false</c> otherwise.</returns>
public static bool iOS()
{
#if UNITY_IOS && !UNITY_EDITOR
return true;
#else
return false;
#endif
}
}
}
fileFormatVersion: 2
guid: b84b1c665a0538d498b5bb2d5cf7de06
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.NiceVibrations
{
/// <summary>
/// A class used to store android waveform values, used to trigger haptics with varying intensity
/// </summary>
[System.Serializable]
public class MMNVRumbleWaveForm
{
public long[] Pattern;
public int[] LowFrequencyAmplitudes;
public int[] HighFrequencyAmplitudes;
}
/// <summary>
/// A scriptable object used to store waveform values
/// </summary>
[CreateAssetMenu(fileName = "RumbleWaveFormAsset", menuName = "MoreMountains/NiceVibrations/RumbleWaveFormAsset")]
public class MMNVRumbleWaveFormAsset : ScriptableObject
{
[Header("Properties")]
public MMNVRumbleWaveForm WaveForm;
[Header("AHAP")]
public TextAsset AHAPFile;
public float IntensityMultiplier = 1f;
public float SharpnessMultiplier = 1f;
}
}
fileFormatVersion: 2
guid: 293e87131443fc542ba7cdc54a7314f4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using System;
#if UNITY_IOS
using UnityEngine.iOS;
#endif
namespace MoreMountains.NiceVibrations
{
/// <summary>
/// This class handles all iOS haptics specific calls, pre-CoreHaptics API
/// </summary>
public static class MMNViOS
{
// The following will only work if the iOSHapticInterface.m file is in a Plugins folder in your project.
// It's a pretty straightforward implementation of iOS's UIFeedbackGenerator's methods.
// You can learn more about them there : https://developer.apple.com/documentation/uikit/uifeedbackgenerator
#if UNITY_IOS && !UNITY_EDITOR
[DllImport ("__Internal")]
private static extern void MMNViOS_InstantiateFeedbackGenerators();
[DllImport ("__Internal")]
private static extern void MMNViOS_ReleaseFeedbackGenerators();
[DllImport ("__Internal")]
private static extern void MMNViOS_SelectionHaptic();
[DllImport ("__Internal")]
private static extern void MMNViOS_SuccessHaptic();
[DllImport ("__Internal")]
private static extern void MMNViOS_WarningHaptic();
[DllImport ("__Internal")]
private static extern void MMNViOS_FailureHaptic();
[DllImport ("__Internal")]
private static extern void MMNViOS_LightImpactHaptic();
[DllImport ("__Internal")]
private static extern void MMNViOS_MediumImpactHaptic();
[DllImport ("__Internal")]
private static extern void MMNViOS_HeavyImpactHaptic();
[DllImport ("__Internal")]
private static extern void MMNViOS_RigidImpactHaptic();
[DllImport ("__Internal")]
private static extern void MMNViOS_SoftImpactHaptic();
#else
private static void MMNViOS_InstantiateFeedbackGenerators() { }
private static void MMNViOS_ReleaseFeedbackGenerators() { }
private static void MMNViOS_SelectionHaptic() { }
private static void MMNViOS_SuccessHaptic() { }
private static void MMNViOS_WarningHaptic() { }
private static void MMNViOS_FailureHaptic() { }
private static void MMNViOS_LightImpactHaptic() { }
private static void MMNViOS_MediumImpactHaptic() { }
private static void MMNViOS_HeavyImpactHaptic() { }
private static void MMNViOS_RigidImpactHaptic() { }
private static void MMNViOS_SoftImpactHaptic() { }
#endif
private static bool iOSHapticsInitialized = false;
/// <summary>
/// Call this method to initialize the haptics. If you forget to do it, Nice Vibrations will do it for you the first time you
/// call iOSTriggerHaptics. It's better if you do it though.
/// </summary>
public static void iOSInitializeHaptics()
{
if (!MMNVPlatform.iOS()) { return; }
MMNViOS_InstantiateFeedbackGenerators();
iOSHapticsInitialized = true;
}
/// <summary>
/// Releases the feedback generators, usually you'll want to call this at OnDisable(); or anytime you know you won't need
/// vibrations anymore.
/// </summary>
public static void iOSReleaseHaptics()
{
if (!MMNVPlatform.iOS()) { return; }
MMNViOS_ReleaseFeedbackGenerators();
}
/// <summary>
/// iOS only : triggers a haptic feedback of the specified type
/// </summary>
/// <param name="type">Type.</param>
public static void iOSTriggerHaptics(HapticTypes type, bool defaultToRegularVibrate = false)
{
if (!MMNVPlatform.iOS()) { return; }
if (!iOSHapticsInitialized)
{
iOSInitializeHaptics();
}
// this will trigger a standard vibration on all the iOS devices that don't support haptic feedback
if (iOSHapticsSupported())
{
switch (type)
{
case HapticTypes.Selection:
MMNViOS_SelectionHaptic();
break;
case HapticTypes.Success:
MMNViOS_SuccessHaptic();
break;
case HapticTypes.Warning:
MMNViOS_WarningHaptic();
break;
case HapticTypes.Failure:
MMNViOS_FailureHaptic();
break;
case HapticTypes.LightImpact:
MMNViOS_LightImpactHaptic();
break;
case HapticTypes.MediumImpact:
MMNViOS_MediumImpactHaptic();
break;
case HapticTypes.HeavyImpact:
MMNViOS_HeavyImpactHaptic();
break;
case HapticTypes.RigidImpact:
MMNViOS_RigidImpactHaptic();
break;
case HapticTypes.SoftImpact:
MMNViOS_SoftImpactHaptic();
break;
}
}
else if (defaultToRegularVibrate)
{
#if UNITY_IOS
Handheld.Vibrate();
#endif
}
}
/// <summary>
/// Returns a string containing iOS SDK informations
/// </summary>
/// <returns>The OSSDK version.</returns>
public static string iOSSDKVersion()
{
#if UNITY_IOS && !UNITY_EDITOR
return Device.systemVersion;
#else
return null;
#endif
}
/// <summary>
/// This methods tests the current device generation against a list of devices that don't support haptics, and returns true if haptics are supported, false otherwise.
/// </summary>
/// <returns><c>true</c>, if supported was hapticsed, <c>false</c> otherwise.</returns>
public static bool iOSHapticsSupported()
{
bool hapticsSupported = false;
#if UNITY_IOS
DeviceGeneration generation = Device.generation;
if ((generation == DeviceGeneration.iPhone3G)
|| (generation == DeviceGeneration.iPhone3GS)
|| (generation == DeviceGeneration.iPodTouch1Gen)
|| (generation == DeviceGeneration.iPodTouch2Gen)
|| (generation == DeviceGeneration.iPodTouch3Gen)
|| (generation == DeviceGeneration.iPodTouch4Gen)
|| (generation == DeviceGeneration.iPhone4)
|| (generation == DeviceGeneration.iPhone4S)
|| (generation == DeviceGeneration.iPhone5)
|| (generation == DeviceGeneration.iPhone5C)
|| (generation == DeviceGeneration.iPhone5S)
|| (generation == DeviceGeneration.iPhone6)
|| (generation == DeviceGeneration.iPhone6Plus)
|| (generation == DeviceGeneration.iPhone6S)
|| (generation == DeviceGeneration.iPhone6SPlus)
|| (generation == DeviceGeneration.iPhoneSE1Gen)
|| (generation == DeviceGeneration.iPad1Gen)
|| (generation == DeviceGeneration.iPad2Gen)
|| (generation == DeviceGeneration.iPad3Gen)
|| (generation == DeviceGeneration.iPad4Gen)
|| (generation == DeviceGeneration.iPad5Gen)
|| (generation == DeviceGeneration.iPadAir1)
|| (generation == DeviceGeneration.iPadAir2)
|| (generation == DeviceGeneration.iPadMini1Gen)
|| (generation == DeviceGeneration.iPadMini2Gen)
|| (generation == DeviceGeneration.iPadMini3Gen)
|| (generation == DeviceGeneration.iPadMini4Gen)
|| (generation == DeviceGeneration.iPadPro10Inch1Gen)
|| (generation == DeviceGeneration.iPadPro10Inch2Gen)
|| (generation == DeviceGeneration.iPadPro11Inch)
|| (generation == DeviceGeneration.iPadPro1Gen)
|| (generation == DeviceGeneration.iPadPro2Gen)
|| (generation == DeviceGeneration.iPadPro3Gen)
|| (generation == DeviceGeneration.iPadUnknown)
|| (generation == DeviceGeneration.iPodTouch1Gen)
|| (generation == DeviceGeneration.iPodTouch2Gen)
|| (generation == DeviceGeneration.iPodTouch3Gen)
|| (generation == DeviceGeneration.iPodTouch4Gen)
|| (generation == DeviceGeneration.iPodTouch5Gen)
|| (generation == DeviceGeneration.iPodTouch6Gen)
|| (generation == DeviceGeneration.iPhone6SPlus))
{
hapticsSupported = false;
}
else
{
hapticsSupported = true;
}
#endif
return hapticsSupported;
}
}
}
fileFormatVersion: 2
guid: 170430725db1fd14585bf5445517f544
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 17c60a018b5ca4d8489e2f3e7c767bb8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
{
"name": "MoreMountains.NiceVibrations.Haptics",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": []
}
\ No newline at end of file
fileFormatVersion: 2
guid: 041029188fa88c54f9efffc039b6a1c9
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 8e41fcc8d7592d0478c7e3267a18ce79
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.NiceVibrations
{
[CreateAssetMenu(fileName = "MMNVPathDefinition", menuName = "MoreMountains/NiceVibrations/MMNVPathDefinition")]
public class MMNVPath : ScriptableObject
{
[Header("Paths")]
/// the path to the plugin in XCode (usually Libraries/NiceVibrations/Common/Plugins/iOS/Swift/)
public string PluginPath;
/// the name of the module (module.modulemap by default)
public string ModuleFileName;
/// the path in Unity (without Assets/, so usually NiceVibrations/Common/Plugins/Swift/)
public string PluginRelativePath;
[Header("Swift")]
/// whether or not the post processing build should force ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES to true on the Framework
/// it's usually not needed, but it's solved build errors for some people
public bool ForceAlwaysEmbedSwiftSLForFramework = false;
/// whether or not the post processing build should force ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES to true on the Main Project
public bool ForceAlwaysEmbedSwiftSLForMainTarget = false;
}
}
fileFormatVersion: 2
guid: 258c36e07f5da5d438332fef965d7d8e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 20c4424cca8b44ea9aa36cd233abf0d8
timeCreated: 1514906462
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.NiceVibrations
{
/// <summary>
/// A minimal test class you can drop in any scene that can be used to trigger vibrations from its inspector
/// </summary>
public class MMVibrationManagerTester : MonoBehaviour
{
/// the possible haptic methods for this feedback
public enum HapticMethods { NativePreset, Transient, Continuous, AdvancedPattern, Stop }
/// the timescale to operate on
public enum Timescales { ScaledTime, UnscaledTime }
[Header("Haptics")]
public HapticMethods HapticMethod = HapticMethods.NativePreset;
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.NativePreset)]
public HapticTypes HapticType = HapticTypes.None;
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.Transient)]
public float TransientIntensity = 1f;
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.Transient)]
public float TransientSharpness = 1f;
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.Continuous)]
public float InitialContinuousIntensity = 1f;
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.Continuous)]
public AnimationCurve ContinuousIntensityCurve = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1f, 1f));
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.Continuous)]
public float InitialContinuousSharpness = 1f;
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.Continuous)]
public AnimationCurve ContinuousSharpnessCurve = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1f, 1f));
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.Continuous)]
public float ContinuousDuration = 1f;
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.AdvancedPattern)]
public TextAsset AHAPFileForIOS;
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.AdvancedPattern)]
public MMNVAndroidWaveFormAsset AndroidWaveFormFile;
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.AdvancedPattern)]
public MMNVRumbleWaveFormAsset RumbleWaveFormFile;
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.AdvancedPattern)]
public int AndroidRepeat = -1;
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.AdvancedPattern)]
public int RumbleRepeat = -1;
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.AdvancedPattern)]
public HapticTypes OldIOSFallback;
[MMNVEnumCondition("HapticMethod", (int)HapticMethods.AdvancedPattern)]
public Timescales Timescale = Timescales.UnscaledTime;
[Header("Rumble")]
public bool AllowRumble = true;
[MMNVInspectorButton("TestVibration")]
public bool TestVibrationButton;
protected static bool _continuousPlaying = false;
protected static float _continuousStartedAt = 0f;
/// <summary>
/// When this feedback gets played
/// </summary>
/// <param name="position"></param>
/// <param name="attenuation"></param>
protected virtual void TestVibration()
{
Vector3 position = this.transform.position;
switch (HapticMethod)
{
case HapticMethods.AdvancedPattern:
string iOSString = (AHAPFileForIOS == null) ? "" : AHAPFileForIOS.text;
long[] androidPattern = (AndroidWaveFormFile == null) ? null : AndroidWaveFormFile.WaveForm.Pattern;
int[] androidAmplitude = (AndroidWaveFormFile == null) ? null : AndroidWaveFormFile.WaveForm.Amplitudes;
long[] rumblePattern = (RumbleWaveFormFile == null) ? null : RumbleWaveFormFile.WaveForm.Pattern;
int[] lowFreqAmplitude = (RumbleWaveFormFile == null) ? null : RumbleWaveFormFile.WaveForm.LowFrequencyAmplitudes;
int[] highFreqAmplitude = (RumbleWaveFormFile == null) ? null : RumbleWaveFormFile.WaveForm.HighFrequencyAmplitudes;
MMVibrationManager.AdvancedHapticPattern(iOSString, androidPattern, androidAmplitude, AndroidRepeat,
rumblePattern, lowFreqAmplitude, highFreqAmplitude, RumbleRepeat,
OldIOSFallback, this);
break;
case HapticMethods.Continuous:
StartCoroutine(ContinuousHapticsCoroutine());
break;
case HapticMethods.NativePreset:
MMVibrationManager.Haptic(HapticType, false, AllowRumble, this);
break;
case HapticMethods.Transient:
MMVibrationManager.TransientHaptic(TransientIntensity, TransientSharpness, AllowRumble, this);
break;
case HapticMethods.Stop:
if (_continuousPlaying)
{
MMVibrationManager.StopContinuousHaptic(AllowRumble);
_continuousPlaying = false;
}
break;
}
}
/// <summary>
/// A coroutine used to update continuous haptics as they're playing
/// </summary>
/// <returns></returns>
protected virtual IEnumerator ContinuousHapticsCoroutine()
{
_continuousStartedAt = (Timescale == Timescales.ScaledTime) ? Time.time : Time.unscaledTime;
_continuousPlaying = true;
float elapsedTime = ComputeElapsedTime();
MMVibrationManager.ContinuousHaptic(InitialContinuousIntensity, InitialContinuousSharpness, ContinuousDuration, HapticTypes.Success, this);
while (_continuousPlaying && (elapsedTime < ContinuousDuration))
{
elapsedTime = ComputeElapsedTime();
float remappedTime = Remap(elapsedTime, 0f, ContinuousDuration, 0f, 1f);
float intensity = ContinuousIntensityCurve.Evaluate(remappedTime);
float sharpness = ContinuousSharpnessCurve.Evaluate(remappedTime);
MMVibrationManager.UpdateContinuousHaptic(intensity, sharpness, true);
if (AllowRumble)
{
#if MOREMOUNTAINS_NICEVIBRATIONS_RUMBLE
MMNVRumble.RumbleContinuous(intensity, sharpness);
#endif
}
yield return null;
}
if (_continuousPlaying)
{
_continuousPlaying = false;
MMVibrationManager.StopContinuousHaptic(AllowRumble);
}
}
/// <summary>
/// This methods computes and returns the elapsed time since the start of the last played continuous haptic
/// </summary>
/// <returns></returns>
protected virtual float ComputeElapsedTime()
{
float elapsedTime = (Timescale == Timescales.ScaledTime) ? Time.time - _continuousStartedAt : Time.unscaledTime - _continuousStartedAt;
return elapsedTime;
}
/// <summary>
/// Remaps value x from AB to CD
/// </summary>
/// <param name="x"></param>
/// <param name="A"></param>
/// <param name="B"></param>
/// <param name="C"></param>
/// <param name="D"></param>
/// <returns></returns>
public static float Remap(float x, float A, float B, float C, float D)
{
float remappedValue = C + (x - A) / (B - A) * (D - C);
return remappedValue;
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: f1819f64dde59594ca91dd55ebc7cce0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
{
"name": "MoreMountains.NiceVibrations",
"references": [
"GUID:041029188fa88c54f9efffc039b6a1c9",
"GUID:426ad1839a76a3e4db8c1e4fde3eb745"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": []
}
\ No newline at end of file
fileFormatVersion: 2
guid: 865b414a121ed594e91db2e09f65d38c
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: e58da89edf2b4024096913db4cb82a54
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: fa3136c0e2d9cfb4da6f56b05b809ebb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 4925aa68bf342ca42a6edd9fddf1894a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Feedbacks
{
#if UNITY_EDITOR
/// <summary>
/// This class lets you specify (in code, by editing it) symbols that will be added to the build settings' define symbols list automatically
/// </summary>
[InitializeOnLoad]
public class NiceVibrationsRumbleDefineSymbols
{
/// <summary>
/// A list of all the symbols you want added to the build settings
/// </summary>
public static readonly string[] Symbols = new string[]
{
"MOREMOUNTAINS_NICEVIBRATIONS_RUMBLE"
};
/// <summary>
/// As soon as this class has finished compiling, adds the specified define symbols to the build settings
/// </summary>
static NiceVibrationsRumbleDefineSymbols()
{
string scriptingDefinesString = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
List<string> scriptingDefinesStringList = scriptingDefinesString.Split(';').ToList();
scriptingDefinesStringList.AddRange(Symbols.Except(scriptingDefinesStringList));
PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, string.Join(";", scriptingDefinesStringList.ToArray()));
}
}
#endif
}
fileFormatVersion: 2
guid: a1809e2ead76b7942b0053af685ef036
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
{
"name": "MoreMountains.NiceVibrations.Rumble.Editor",
"references": [
"GUID:426ad1839a76a3e4db8c1e4fde3eb745",
"GUID:75469ad4d38634e559750d17036d5f7c"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [
"MOREMOUNTAINS_INPUTSYSTEM_INSTALLED"
],
"versionDefines": [
{
"name": "com.unity.inputsystem",
"expression": "0.0.1",
"define": "MOREMOUNTAINS_INPUTSYSTEM_INSTALLED"
}
]
}
\ No newline at end of file
fileFormatVersion: 2
guid: f67459fb0878e0b49ad2e16270f8b130
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 48d33dfedcb3f0e41820b1c1b114fc51
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
namespace MoreMountains.NiceVibrations
{
public static class MMNVRumble
{
/// whether or not the rumble engine is running right now
public static bool Rumbling = false;
/// whether or not we're playing a continuous rumble right now
public static bool RumblingContinuous = false;
public static Gamepad GetGamepad(int id)
{
if (id != -1)
{
if (id >= Gamepad.all.Count)
{
return Gamepad.current;
}
else
{
return Gamepad.all[id];
}
}
return Gamepad.current;
}
/// <summary>
/// Rumbles the controller at the specified frequencies for the specified duration
/// </summary>
/// <param name="lowFrequency">from 0 to 1</param>
/// <param name="highFrequency">from 0 to 1</param>
/// <param name="duration">the duration of the rumble, in seconds</param>
/// <param name="coroutineSupport">a monobehaviour to run the coroutine on (usually just use "this")</param>
public static void Rumble(float lowFrequency, float highFrequency, float duration, MonoBehaviour coroutineSupport, int controllerID = -1)
{
coroutineSupport.StartCoroutine(RumbleCoroutine(lowFrequency, highFrequency, duration, controllerID));
}
/// <summary>
/// A coroutine used to rumble
/// </summary>
/// <param name="lowFrequency"></param>
/// <param name="highFrequency"></param>
/// <param name="duration"></param>
/// <returns></returns>
private static IEnumerator RumbleCoroutine(float lowFrequency, float highFrequency, float duration, int controllerID = -1)
{
if (GetGamepad(controllerID) == null)
{
yield break;
}
Rumbling = true;
GetGamepad(controllerID).SetMotorSpeeds(lowFrequency, highFrequency);
float startedAt = Time.unscaledTime;
while (Time.unscaledTime - startedAt < duration)
{
yield return null;
}
InputSystem.ResetHaptics();
Rumbling = false;
}
/// <summary>
/// Requests a rumble for the specified pattern, amplitude and optional repeat
/// </summary>
/// <param name="pattern">Pattern.</param>
/// <param name="amplitudes">Amplitudes (from 0 to 255).</param>
/// <param name="repeat">Repeat : -1 : no repeat, 0 : infinite, 1 : repeat once, 2 : repeat twice, etc</param>
public static void Rumble(long[] pattern, int[] amplitudes, int repeat, MonoBehaviour coroutineSupport, int controllerID = -1)
{
coroutineSupport.StartCoroutine(RumblePatternCoroutine(pattern, amplitudes, amplitudes, repeat, coroutineSupport, controllerID));
}
/// <summary>
/// Requests a rumble for the specified pattern, low and high frequency amplitudes and optional repeat
/// </summary>
/// <param name="pattern"></param>
/// <param name="lowFreqAmplitudes"></param>
/// <param name="highFreqAmplitudes"></param>
/// <param name="repeat"></param>
/// <param name="coroutineSupport"></param>
public static void Rumble(long[] pattern, int[] lowFreqAmplitudes, int[] highFreqAmplitudes, int repeat, MonoBehaviour coroutineSupport, int controllerID = -1)
{
coroutineSupport.StartCoroutine(RumblePatternCoroutine(pattern, lowFreqAmplitudes, highFreqAmplitudes, repeat, coroutineSupport, controllerID));
}
/// <summary>
/// A coroutine used to play patterns
/// </summary>
/// <param name="pattern"></param>
/// <param name="lowFreqAmplitudes"></param>
/// <param name="highFreqAmplitudes"></param>
/// <param name="repeat"></param>
/// <returns></returns>
private static IEnumerator RumblePatternCoroutine(long[] pattern, int[] lowFreqAmplitudes, int[] highFreqAmplitudes, int repeat, MonoBehaviour coroutineSupport, int controllerID = -1)
{
float startedAt = Time.unscaledTime;
float duration = 0f;
for (int i = 0; i < pattern.Length; i++)
{
if (GetGamepad(controllerID) == null)
{
yield break;
}
duration = pattern[i];
startedAt = Time.unscaledTime;
float lowFreqAmplitude = (lowFreqAmplitudes.Length > i) ? lowFreqAmplitudes[i] / 255f : 0f;
float highFreqAmplitude = (highFreqAmplitudes.Length > i) ? highFreqAmplitudes[i] / 255f : 0f;
GetGamepad(controllerID).SetMotorSpeeds(lowFreqAmplitude, highFreqAmplitude);
while (Time.unscaledTime - startedAt < (duration/1000f))
{
yield return null;
}
}
InputSystem.ResetHaptics();
if (repeat == -1)
{
yield break;
}
if (repeat > 1)
{
repeat--;
coroutineSupport.StartCoroutine(RumblePatternCoroutine(pattern, lowFreqAmplitudes, highFreqAmplitudes, repeat, coroutineSupport));
}
if (repeat == 0)
{
coroutineSupport.StartCoroutine(RumblePatternCoroutine(pattern, lowFreqAmplitudes, highFreqAmplitudes, repeat, coroutineSupport));
}
}
/// <summary>
/// Lets you update rumble values while playing them
/// </summary>
/// <param name="lowFrequency"></param>
/// <param name="highFrequency"></param>
public static void RumbleContinuous(float lowFrequency, float highFrequency, int controllerID = -1)
{
if (GetGamepad(controllerID) == null)
{
return;
}
Rumbling = true;
RumblingContinuous = true;
GetGamepad(controllerID).SetMotorSpeeds(lowFrequency, highFrequency);
}
/// <summary>
/// Stops all rumbles
/// </summary>
public static void StopRumble()
{
Rumbling = false;
RumblingContinuous = false;
InputSystem.ResetHaptics();
}
/// <summary>
/// Pauses all rumbles
/// </summary>
public static void PauseRumble()
{
Rumbling = false;
RumblingContinuous = false;
InputSystem.PauseHaptics();
}
/// <summary>
/// Resumes all rumbles
/// </summary>
public static void ResumeRumble()
{
Rumbling = true;
InputSystem.ResumeHaptics();
}
}
}
fileFormatVersion: 2
guid: bfe0f13b99e233d4181abce97b08e738
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
{
"name": "MoreMountains.NiceVibrations.Rumble",
"references": [
"GUID:75469ad4d38634e559750d17036d5f7c",
"GUID:041029188fa88c54f9efffc039b6a1c9"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [
"MOREMOUNTAINS_INPUTSYSTEM_INSTALLED"
],
"versionDefines": [
{
"name": "com.unity.inputsystem",
"expression": "0.8.0",
"define": "MOREMOUNTAINS_INPUTSYSTEM_INSTALLED"
}
],
"noEngineReferences": false
}
\ No newline at end of file
fileFormatVersion: 2
guid: 426ad1839a76a3e4db8c1e4fde3eb745
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 7cdd6a8ec43092743a6a66b8ae053b61
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: c0ab2419d02d5f54690ac6db3a5188cb
AudioImporter:
externalObjects: {}
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 4cb55e2084a872b4fa4051ba3320c8a7
AudioImporter:
externalObjects: {}
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 28fd9fa68ff664a36b001883f9a16e69
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: dd1644ba0cb55b14dace78bdb4ccc5a5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 3068fea84a2674c79b4cd1b8e387fcb0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 14dce09abd4a5d44a8f4b9df6ba8f833
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: ff094eb44889d03439067dbd231dcb5c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
{
"Version": 1.0,
"Metadata":
{
"Project" : "Haptic Sampler",
"Created" : "5 June 2019",
"Description" : "A continuous event tweaked by sloped parameter curves, emphasized by a precisely placed transient event, creating the feeling of a spring or rubberband."
},
"Pattern":
[
{
"Event":
{
"Time": 0.0,
"EventType": "HapticTransient",
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 0.8 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.4 }
]
}
},
{
"Event":
{
"Time": 0.015,
"EventType": "HapticContinuous",
"EventDuration": 0.25,
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 0.8 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.4 }
]
}
},
{
"ParameterCurve":
{
"ParameterID": "HapticIntensityControl",
"Time": 0.015,
"ParameterCurveControlPoints":
[
{ "Time": 0, "ParameterValue": 1 },
{ "Time": 0.1, "ParameterValue": 0.5 },
{ "Time": 0.25, "ParameterValue": 0.0 }
]
}
},
{
"ParameterCurve":
{
"ParameterID": "HapticSharpnessControl",
"Time": 0.015,
"ParameterCurveControlPoints":
[
{ "Time": 0, "ParameterValue": 0.0 },
{ "Time": 0.25, "ParameterValue": -0.3 }
]
}
}
]
}
\ No newline at end of file
fileFormatVersion: 2
guid: 712d094a1648640c39a1b776752aa8dc
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
{
"Version": 1,
"Metadata":
{
"Project" : "Haptic Sampler",
"Created" : "5 June 2019",
"Description" : "A sequence of haptic events paired with a custom audio file."
},
"Pattern":
[
{"Event":
{"Time":0,"EventType":"HapticTransient",
"EventParameters":
[
{"ParameterID":"HapticSharpness","ParameterValue":0}
]
}
},
{"Event":
{"Time":0.391,"EventType":"HapticTransient",
"EventParameters":
[
{"ParameterID":"HapticSharpness","ParameterValue":0},
{"ParameterID":"HapticIntensity","ParameterValue":1}
]
}
},
{"Event":
{"Time":0.8,"EventType":"HapticTransient",
"EventParameters":
[
{"ParameterID":"HapticSharpness","ParameterValue":0.3},
{"ParameterID":"HapticIntensity","ParameterValue":1}
]
}
},
{"Event":
{"Time":1.2,"EventType":"HapticTransient",
"EventParameters":
[
{"ParameterID":"HapticSharpness","ParameterValue":0},
{"ParameterID":"HapticIntensity","ParameterValue":1}
]
}
},
{"Event":
{"Time":1.41,"EventType":"HapticTransient",
"EventParameters":
[
{"ParameterID":"HapticSharpness","ParameterValue":0},
{"ParameterID":"HapticIntensity","ParameterValue":1}
]
}
},
{"Event":
{"Time":1.6,"EventType":"HapticTransient",
"EventParameters":
[
{"ParameterID":"HapticSharpness","ParameterValue":0}
]
}
},
{"Event":
{"Time":0,"EventType":"HapticContinuous","EventDuration":0.2,
"EventParameters":
[
{"ParameterID":"HapticIntensity","ParameterValue":0.6}
]
}
},
{"Event":
{"Time":0.2,"EventType":"HapticContinuous","EventDuration":0.2,
"EventParameters":
[
{"ParameterID":"HapticIntensity","ParameterValue":0.3}
]
}
},
{"Event":
{"Time":0.4,"EventType":"HapticContinuous","EventDuration":0.15,
"EventParameters":
[
{"ParameterID":"HapticIntensity","ParameterValue":0.25},
{"ParameterID":"HapticSharpness","ParameterValue":1.0}
]
}
},
{"Event":
{"Time":0.8,"EventType":"HapticContinuous","EventDuration":0.15,
"EventParameters":
[
{"ParameterID":"HapticIntensity","ParameterValue":0.25},
{"ParameterID":"HapticSharpness","ParameterValue":1.0}
]
}
},
{"Event":
{"Time":1.2,"EventType":"HapticContinuous","EventDuration":0.15,
"EventParameters":
[
{"ParameterID":"HapticIntensity","ParameterValue":0.25},
{"ParameterID":"HapticSharpness","ParameterValue":1.0}
]
}
},
{"Event":
{"Time":1.6,"EventType":"HapticContinuous","EventDuration":1,
"EventParameters":
[
{"ParameterID":"HapticIntensity","ParameterValue":0.45},
{"ParameterID":"HapticSharpness","ParameterValue":0.9},
{"ParameterID":"DecayTime","ParameterValue":1},
{"ParameterID":"Sustained","ParameterValue":0}
]
}
}
]
}
fileFormatVersion: 2
guid: f2bc68522a88747caa699855a188c399
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: a9e641b95ef554d348cae00bdc77429d
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
{
"Version": 1.0,
"Metadata":
{
"Project" : "Haptic Sampler",
"Created" : "5 June 2019",
"Description" : "Three organic heartbeats over three seconds, made using precisely spaced transient events at varying parameters."
},
"Pattern":
[
{
"Event":
{
"Time": 0.0,
"EventType": "HapticTransient",
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 0.8 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.2 }
]
}
},
{
"Event":
{
"Time": 0.013,
"EventType": "HapticTransient",
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 1.0 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.3 }
]
}
},
{
"Event":
{
"Time": 0.220,
"EventType": "HapticTransient",
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 0.8 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.1 }
]
}
},
{
"Event":
{
"Time": 0.255,
"EventType": "HapticTransient",
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 0.7 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.0 }
]
}
},
{
"Event":
{
"Time": 1.0,
"EventType": "HapticTransient",
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 0.8 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.2 }
]
}
},
{
"Event":
{
"Time": 1.013,
"EventType": "HapticTransient",
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 1.0 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.3 }
]
}
},
{
"Event":
{
"Time": 1.220,
"EventType": "HapticTransient",
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 0.8 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.1 }
]
}
},
{
"Event":
{
"Time": 1.255,
"EventType": "HapticTransient",
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 0.7 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.0 }
]
}
},
{
"Event":
{
"Time": 2.0,
"EventType": "HapticTransient",
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 0.8 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.2 }
]
}
},
{
"Event":
{
"Time": 2.013,
"EventType": "HapticTransient",
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 1.0 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.3 }
]
}
},
{
"Event":
{
"Time": 2.220,
"EventType": "HapticTransient",
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 0.8 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.1 }
]
}
},
{
"Event":
{
"Time": 2.255,
"EventType": "HapticTransient",
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 0.7 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.0 }
]
}
}
]
}
fileFormatVersion: 2
guid: 851514207e69d42eb89a4dfa8c0eda0b
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
{
"Version": 1.0,
"Metadata":
{
"Project" : "Haptic Sampler",
"Created" : "5 June 2019",
"Description" : "An effect that builds in sharpness and intensity."
},
"Pattern":
[
{
"Event":
{
"Time": 0.0,
"EventType": "HapticContinuous",
"EventDuration": 1.7,
"EventParameters":
[
{ "ParameterID": "HapticIntensity", "ParameterValue": 1.0 },
{ "ParameterID": "HapticSharpness", "ParameterValue": 0.5 }
]
}
},
{
"ParameterCurve":
{
"ParameterID": "HapticIntensityControl",
"Time": 0.0,
"ParameterCurveControlPoints":
[
{ "Time": 0, "ParameterValue": 0.0 },
{ "Time": 1.1, "ParameterValue": 0.5 },
{ "Time": 1.7, "ParameterValue": 0.0 }
]
}
},
{
"ParameterCurve":
{
"ParameterID": "HapticSharpnessControl",
"Time": 0.0,
"ParameterCurveControlPoints":
[
{ "Time": 0, "ParameterValue": -0.8 },
{ "Time": 1.7, "ParameterValue": 0.8 }
]
}
}
]
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment