@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: a0a0bd2b6c0d93b42a8788ed13d2bb94 | |||
folderAsset: yes | |||
DefaultImporter: | |||
externalObjects: {} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 3b5e85298c67f4a64bdd2fe534ccc158 | |||
folderAsset: yes | |||
DefaultImporter: | |||
externalObjects: {} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: 29ab7e927676ef74a93aeedf4146f1ac | |||
folderAsset: yes | |||
timeCreated: 1470780399 | |||
licenseType: Pro | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: 180c8a539f95cce428f820b0ba392c1f | |||
folderAsset: yes | |||
timeCreated: 1468506676 | |||
licenseType: Pro | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
size 40180 |
@ -0,0 +1,22 @@ | |||
fileFormatVersion: 2 | |||
guid: 485ac48a563e2bf44bb4de7ead5a1f68 | |||
timeCreated: 1461716881 | |||
licenseType: Pro | |||
AudioImporter: | |||
serializedVersion: 6 | |||
defaultSettings: | |||
loadType: 0 | |||
sampleRateSetting: 0 | |||
sampleRateOverride: 44100 | |||
compressionFormat: 1 | |||
quality: 1 | |||
conversionMode: 0 | |||
platformSettingOverrides: {} | |||
forceToMono: 0 | |||
normalize: 1 | |||
preloadAudioData: 1 | |||
loadInBackground: 0 | |||
3D: 1 | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
size 40178 |
@ -0,0 +1,22 @@ | |||
fileFormatVersion: 2 | |||
guid: d3994560fb567c34a821fd9355c10eef | |||
timeCreated: 1461716882 | |||
licenseType: Pro | |||
AudioImporter: | |||
serializedVersion: 6 | |||
defaultSettings: | |||
loadType: 0 | |||
sampleRateSetting: 0 | |||
sampleRateOverride: 44100 | |||
compressionFormat: 1 | |||
quality: 1 | |||
conversionMode: 0 | |||
platformSettingOverrides: {} | |||
forceToMono: 0 | |||
normalize: 1 | |||
preloadAudioData: 1 | |||
loadInBackground: 0 | |||
3D: 1 | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
size 47956 |
@ -0,0 +1,22 @@ | |||
fileFormatVersion: 2 | |||
guid: 7000b4d67a1320940b363f3cf891dfff | |||
timeCreated: 1461716881 | |||
licenseType: Pro | |||
AudioImporter: | |||
serializedVersion: 6 | |||
defaultSettings: | |||
loadType: 0 | |||
sampleRateSetting: 0 | |||
sampleRateOverride: 44100 | |||
compressionFormat: 1 | |||
quality: 1 | |||
conversionMode: 0 | |||
platformSettingOverrides: {} | |||
forceToMono: 0 | |||
normalize: 1 | |||
preloadAudioData: 1 | |||
loadInBackground: 0 | |||
3D: 1 | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
size 51014 |
@ -0,0 +1,22 @@ | |||
fileFormatVersion: 2 | |||
guid: 8198ccc08475a764daaf226b841a55f1 | |||
timeCreated: 1461716882 | |||
licenseType: Pro | |||
AudioImporter: | |||
serializedVersion: 6 | |||
defaultSettings: | |||
loadType: 0 | |||
sampleRateSetting: 0 | |||
sampleRateOverride: 44100 | |||
compressionFormat: 1 | |||
quality: 1 | |||
conversionMode: 0 | |||
platformSettingOverrides: {} | |||
forceToMono: 0 | |||
normalize: 1 | |||
preloadAudioData: 1 | |||
loadInBackground: 0 | |||
3D: 1 | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: 6d597fe114807b54a99033a3dae9ce0d | |||
folderAsset: yes | |||
timeCreated: 1470780399 | |||
licenseType: Pro | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: 7ee6cbebddf12044c95f9d6eb6e40823 | |||
folderAsset: yes | |||
timeCreated: 1470780399 | |||
licenseType: Pro | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,36 @@ | |||
using UnityEngine; | |||
using System.Collections; | |||
namespace OVR | |||
{ | |||
public class TestScript : MonoBehaviour { | |||
[InspectorNote( "Sound Setup", "Press '1' to play testSound1 and '2' to play testSound2")] | |||
public SoundFXRef testSound1; | |||
public SoundFXRef testSound2; | |||
// Use this for initialization | |||
void Start () { | |||
} | |||
// Update is called once per frame | |||
void Update () | |||
{ | |||
// use attached game object location | |||
if ( Input.GetKeyDown( KeyCode.Alpha1 ) ) | |||
{ | |||
testSound1.PlaySoundAt( transform.position ); | |||
} | |||
// hard code information | |||
if ( Input.GetKeyDown( KeyCode.Alpha2 ) ) { | |||
testSound2.PlaySoundAt( new Vector3( 5.0f, 0.0f, 0.0f ) ); | |||
} | |||
} | |||
} | |||
} // namespace OVR |
@ -0,0 +1,12 @@ | |||
fileFormatVersion: 2 | |||
guid: cfae243ecd01edd49bd439c56a8b18cf | |||
timeCreated: 1468506975 | |||
licenseType: Pro | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
size 11647 |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 600e5d49b0a68254286400e32c53addc | |||
timeCreated: 1468506358 | |||
licenseType: Pro | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: 25be027379f7fce4d97ba2bcaf313019 | |||
folderAsset: yes | |||
timeCreated: 1470780399 | |||
licenseType: Pro | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: b8c0d722519c64144a78f8fc99cd40b5 | |||
folderAsset: yes | |||
timeCreated: 1468505670 | |||
licenseType: Pro | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,118 @@ | |||
using UnityEngine; | |||
using System.Collections; | |||
namespace OVR | |||
{ | |||
/* | |||
----------------------- | |||
AmbienceEmitter() | |||
----------------------- | |||
*/ | |||
public class AmbienceEmitter : MonoBehaviour { | |||
public SoundFXRef[] ambientSounds = new SoundFXRef[0]; | |||
public bool autoActivate = true; | |||
[Tooltip("Automatically play the sound randomly again when checked. Should be OFF for looping sounds")] | |||
public bool autoRetrigger = true; | |||
[MinMax( 2.0f, 4.0f, 0.1f, 10.0f )] | |||
public Vector2 randomRetriggerDelaySecs = new Vector2( 2.0f, 4.0f ); | |||
[Tooltip( "If defined, the sounds will randomly play from these transform positions, otherwise the sound will play from this transform" )] | |||
public Transform[] playPositions = new Transform[0]; | |||
private bool activated = false; | |||
private int playingIdx = -1; | |||
private float nextPlayTime = 0.0f; | |||
private float fadeTime = 0.25f; | |||
private int lastPosIdx = -1; | |||
/* | |||
----------------------- | |||
Awake() | |||
----------------------- | |||
*/ | |||
void Awake() { | |||
if ( autoActivate ) { | |||
activated = true; | |||
nextPlayTime = Time.time + Random.Range( randomRetriggerDelaySecs.x, randomRetriggerDelaySecs.y ); | |||
} | |||
// verify all the play positions are valid | |||
foreach ( Transform t in playPositions ) { | |||
if ( t == null ) { | |||
Debug.LogWarning( "[AmbienceEmitter] Invalid play positions in " + name ); | |||
playPositions = new Transform[0]; | |||
break; | |||
} | |||
} | |||
} | |||
/* | |||
----------------------- | |||
Update() | |||
----------------------- | |||
*/ | |||
void Update() { | |||
if ( activated ) { | |||
if ( ( playingIdx == -1 ) || autoRetrigger ) { | |||
if ( Time.time >= nextPlayTime ) { | |||
Play(); | |||
if ( !autoRetrigger ) { | |||
activated = false; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
/* | |||
----------------------- | |||
OnTriggerEnter() | |||
----------------------- | |||
*/ | |||
public void OnTriggerEnter( Collider col ) { | |||
activated = !activated; | |||
} | |||
/* | |||
----------------------- | |||
Play() | |||
----------------------- | |||
*/ | |||
public void Play() { | |||
Transform transformToPlayFrom = transform; | |||
if ( playPositions.Length > 0 ) { | |||
int idx = Random.Range( 0, playPositions.Length ); | |||
while ( ( playPositions.Length > 1 ) && ( idx == lastPosIdx ) ) { | |||
idx = Random.Range( 0, playPositions.Length ); | |||
} | |||
transformToPlayFrom = playPositions[idx]; | |||
lastPosIdx = idx; | |||
} | |||
playingIdx = ambientSounds[Random.Range(0, ambientSounds.Length)].PlaySoundAt( transformToPlayFrom.position ); | |||
if ( playingIdx != -1 ) { | |||
AudioManager.FadeInSound( playingIdx, fadeTime ); | |||
nextPlayTime = Time.time + Random.Range( randomRetriggerDelaySecs.x, randomRetriggerDelaySecs.y ); | |||
} | |||
} | |||
/* | |||
----------------------- | |||
EnableEmitter() | |||
----------------------- | |||
*/ | |||
public void EnableEmitter( bool enable ) { | |||
activated = enable; | |||
if ( enable ) { | |||
Play(); | |||
} else { | |||
if ( playingIdx != -1 ) { | |||
AudioManager.FadeOutSound( playingIdx, fadeTime ); | |||
} | |||
} | |||
} | |||
} | |||
} // namespace OVR |
@ -0,0 +1,12 @@ | |||
fileFormatVersion: 2 | |||
guid: c11944691f6b9cf44a391c95cb3f7dea | |||
timeCreated: 1455050294 | |||
licenseType: Pro | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,429 @@ | |||
using UnityEngine; | |||
using UnityEngine.Audio; | |||
using System.Collections; | |||
using System.Collections.Generic; | |||
#if UNITY_EDITOR | |||
using UnityEditor; | |||
using System; | |||
using System.Reflection; | |||
#endif | |||
namespace OVR | |||
{ | |||
public enum PreloadSounds { | |||
Default, // default unity behavior | |||
Preload, // audio clips are forced to preload | |||
ManualPreload, // audio clips are forced to not preload, preloading must be done manually | |||
} | |||
public enum Fade | |||
{ | |||
In, | |||
Out | |||
} | |||
[System.Serializable] | |||
public class SoundGroup { | |||
public SoundGroup( string name ) { | |||
this.name = name; | |||
} | |||
public SoundGroup() { | |||
mixerGroup = null; | |||
maxPlayingSounds = 0; | |||
preloadAudio = PreloadSounds.Default; | |||
volumeOverride = 1.0f; | |||
} | |||
public void IncrementPlayCount() { | |||
playingSoundCount = Mathf.Clamp( ++playingSoundCount, 0, maxPlayingSounds ); | |||
} | |||
public void DecrementPlayCount() { | |||
playingSoundCount = Mathf.Clamp( --playingSoundCount, 0, maxPlayingSounds ); | |||
} | |||
public bool CanPlaySound() { | |||
return ( maxPlayingSounds == 0 ) || ( playingSoundCount < maxPlayingSounds ); | |||
} | |||
public string name = string.Empty; | |||
public SoundFX[] soundList = new SoundFX[0]; | |||
public AudioMixerGroup mixerGroup = null; // default = AudioManager.defaultMixerGroup | |||
[Range(0,64)] | |||
public int maxPlayingSounds = 0; // default = 0, unlimited | |||
// TODO: this preload behavior is not yet implemented | |||
public PreloadSounds preloadAudio = PreloadSounds.Default; // default = true, audio clip data will be preloaded | |||
public float volumeOverride = 1.0f; // default = 1.0 | |||
[HideInInspector] | |||
public int playingSoundCount = 0; | |||
} | |||
/* | |||
----------------------- | |||
AudioManager | |||
----------------------- | |||
*/ | |||
public partial class AudioManager : MonoBehaviour { | |||
[Tooltip("Make the audio manager persistent across all scene loads")] | |||
public bool makePersistent = true; // true = don't destroy on load | |||
[Tooltip("Enable the OSP audio plugin features")] | |||
public bool enableSpatializedAudio = true; // true = enable spatialized audio | |||
[Tooltip("Always play spatialized sounds with no reflections (Default)")] | |||
public bool enableSpatializedFastOverride = false; // true = disable spatialized reflections override | |||
[Tooltip("The audio mixer asset used for snapshot blends, etc.")] | |||
public AudioMixer audioMixer = null; | |||
[Tooltip( "The audio mixer group used for the pooled emitters" )] | |||
public AudioMixerGroup defaultMixerGroup = null; | |||
[Tooltip( "The audio mixer group used for the reserved pool emitter" )] | |||
public AudioMixerGroup reservedMixerGroup = null; | |||
[Tooltip( "The audio mixer group used for voice chat" )] | |||
public AudioMixerGroup voiceChatMixerGroup = null; | |||
[Tooltip("Log all PlaySound calls to the Unity console")] | |||
public bool verboseLogging = false; // true = log all PlaySounds | |||
[Tooltip("Maximum sound emitters")] | |||
public int maxSoundEmitters = 32; // total number of sound emitters created | |||
[Tooltip("Default volume for all sounds modulated by individual sound FX volumes")] | |||
public float volumeSoundFX = 1.0f; // user pref: volume of all sound FX | |||
[Tooltip("Sound FX fade time")] | |||
public float soundFxFadeSecs = 1.0f; // sound FX fade time | |||
public float audioMinFallOffDistance = 1.0f; // minimum falloff distance | |||
public float audioMaxFallOffDistance = 25.0f; // maximum falloff distance | |||
public SoundGroup[] soundGroupings = new SoundGroup[0]; | |||
private Dictionary<string,SoundFX> soundFXCache = null; | |||
static private AudioManager theAudioManager = null; | |||
static private FastList<string> names = new FastList<string>(); | |||
static private string[] defaultSound = new string[1] { "Default Sound" }; | |||
static private SoundFX nullSound = new SoundFX(); | |||
static private bool hideWarnings = false; | |||
static public bool enableSpatialization { get { return ( theAudioManager !=null ) ? theAudioManager.enableSpatializedAudio : false; } } | |||
static public AudioManager Instance { get { return theAudioManager; } } | |||
static public float NearFallOff { get { return theAudioManager.audioMinFallOffDistance; } } | |||
static public float FarFallOff { get { return theAudioManager.audioMaxFallOffDistance; } } | |||
static public AudioMixerGroup EmitterGroup { get { return theAudioManager.defaultMixerGroup; } } | |||
static public AudioMixerGroup ReservedGroup { get { return theAudioManager.reservedMixerGroup; } } | |||
static public AudioMixerGroup VoipGroup { get { return theAudioManager.voiceChatMixerGroup; } } | |||
/* | |||
----------------------- | |||
Awake() | |||
----------------------- | |||
*/ | |||
void Awake() { | |||
Init(); | |||
} | |||
/* | |||
----------------------- | |||
OnDestroy() | |||
----------------------- | |||
*/ | |||
void OnDestroy() { | |||
// we only want the initialized audio manager instance cleaning up the sound emitters | |||
if ( theAudioManager == this ) { | |||
if ( soundEmitterParent != null ) { | |||
Destroy( soundEmitterParent ); | |||
} | |||
} | |||
///TODO - if you change scenes you'll want to call OnPreSceneLoad to detach the sound emitters | |||
///from anything they might be parented to or they will get destroyed with that object | |||
///there should only be one instance of the AudioManager across the life of the game/app | |||
///GameManager.OnPreSceneLoad -= OnPreSceneLoad; | |||
} | |||
/* | |||
----------------------- | |||
Init() | |||
----------------------- | |||
*/ | |||
void Init() { | |||
if ( theAudioManager != null ) { | |||
if ( Application.isPlaying && ( theAudioManager != this ) ) { | |||
enabled = false; | |||
} | |||
return; | |||
} | |||
theAudioManager = this; | |||
///TODO - if you change scenes you'll want to call OnPreSceneLoad to detach the sound emitters | |||
///from anything they might be parented to or they will get destroyed with that object | |||
///there should only be one instance of the AudioManager across the life of the game/app | |||
///GameManager.OnPreSceneLoad += OnPreSceneLoad; | |||
// make sure the first one is a null sound | |||
nullSound.name = "Default Sound"; | |||
// build the sound FX cache | |||
RebuildSoundFXCache(); | |||
// create the sound emitters | |||
if ( Application.isPlaying ) { | |||
InitializeSoundSystem(); | |||
if ( makePersistent && ( transform.parent == null ) ) { | |||
// don't destroy the audio manager on scene loads | |||
DontDestroyOnLoad( gameObject ); | |||
} | |||
} | |||
#if UNITY_EDITOR | |||
Debug.Log( "[AudioManager] Initialized..." ); | |||
#endif | |||
} | |||
/* | |||
----------------------- | |||
Update() | |||
----------------------- | |||
*/ | |||
void Update() { | |||
// update the free and playing lists | |||
UpdateFreeEmitters(); | |||
} | |||
/* | |||
----------------------- | |||
RebuildSoundFXCache() | |||
----------------------- | |||
*/ | |||
void RebuildSoundFXCache() { | |||
// build the SoundFX dictionary for quick name lookups | |||
int count = 0; | |||
for ( int group = 0; group < soundGroupings.Length; group++ ) { | |||
count += soundGroupings[group].soundList.Length; | |||
} | |||
soundFXCache = new Dictionary<string,SoundFX>( count + 1 ); | |||
// add the null sound | |||
soundFXCache.Add( nullSound.name, nullSound ); | |||
// add the rest | |||
for ( int group = 0; group < soundGroupings.Length; group++ ) { | |||
for ( int i = 0; i < soundGroupings[group].soundList.Length; i++ ) { | |||
if ( soundFXCache.ContainsKey( soundGroupings[group].soundList[i].name ) ) { | |||
Debug.LogError( "ERROR: Duplicate Sound FX name in the audio manager: '" + soundGroupings[group].name + "' > '" + soundGroupings[group].soundList[i].name + "'" ); | |||
} else { | |||
soundGroupings[group].soundList[i].Group = soundGroupings[group]; | |||
soundFXCache.Add( soundGroupings[group].soundList[i].name, soundGroupings[group].soundList[i] ); | |||
} | |||
} | |||
soundGroupings[group].playingSoundCount = 0; | |||
} | |||
} | |||
/* | |||
----------------------- | |||
FindSoundFX() | |||
----------------------- | |||
*/ | |||
static public SoundFX FindSoundFX( string name, bool rebuildCache = false ) { | |||
#if UNITY_EDITOR | |||
if ( theAudioManager == null ) { | |||
Debug.LogError( "ERROR: audio manager not yet initialized or created!" + " Time: " + Time.time ); | |||
return null; | |||
} | |||
#endif | |||
if ( string.IsNullOrEmpty( name ) ) { | |||
return nullSound; | |||
} | |||
if ( rebuildCache ) { | |||
theAudioManager.RebuildSoundFXCache(); | |||
} | |||
if ( !theAudioManager.soundFXCache.ContainsKey( name ) ) { | |||
#if DEBUG_BUILD || UNITY_EDITOR | |||
Debug.LogError( "WARNING: Missing Sound FX in cache: " + name ); | |||
#endif | |||
return nullSound; | |||
} | |||
return theAudioManager.soundFXCache[name]; | |||
} | |||
/* | |||
----------------------- | |||
FindAudioManager() | |||
----------------------- | |||
*/ | |||
static private bool FindAudioManager() { | |||
GameObject audioManagerObject = GameObject.Find( "AudioManager" ); | |||
if ( ( audioManagerObject == null ) || ( audioManagerObject.GetComponent<AudioManager>() == null ) ) { | |||
if ( !hideWarnings ) { | |||
Debug.LogError( "[ERROR] AudioManager object missing from hierarchy!" ); | |||
hideWarnings = true; | |||
} | |||
return false; | |||
} else { | |||
audioManagerObject.GetComponent<AudioManager>().Init(); | |||
} | |||
return true; | |||
} | |||
/* | |||
----------------------- | |||
GetGameObject() | |||
----------------------- | |||
*/ | |||
static public GameObject GetGameObject() { | |||
if ( theAudioManager == null ) { | |||
if ( !FindAudioManager() ) { | |||
return null; | |||
} | |||
} | |||
return theAudioManager.gameObject; | |||
} | |||
/* | |||
----------------------- | |||
NameMinusGroup() | |||
strip off the sound group from the inspector dropdown | |||
----------------------- | |||
*/ | |||
static public string NameMinusGroup( string name ) { | |||
if ( name.IndexOf( "/" ) > -1 ) { | |||
return name.Substring( name.IndexOf( "/" ) + 1 ); | |||
} | |||
return name; | |||
} | |||
/* | |||
----------------------- | |||
GetSoundFXNames() | |||
used by the inspector | |||
----------------------- | |||
*/ | |||
static public string[] GetSoundFXNames( string currentValue, out int currentIdx ) { | |||
currentIdx = 0; | |||
names.Clear(); | |||
if ( theAudioManager == null ) { | |||
if ( !FindAudioManager() ) { | |||
return defaultSound; | |||
} | |||
} | |||
names.Add( nullSound.name ); | |||
for ( int group = 0; group < theAudioManager.soundGroupings.Length; group++ ) { | |||
for ( int i = 0; i < theAudioManager.soundGroupings[group].soundList.Length; i++ ) { | |||
if ( string.Compare( currentValue, theAudioManager.soundGroupings[group].soundList[i].name, true ) == 0 ) { | |||
currentIdx = names.Count; | |||
} | |||
names.Add( theAudioManager.soundGroupings[group].name + "/" + theAudioManager.soundGroupings[group].soundList[i].name ); | |||
} | |||
} | |||
//names.Sort( delegate( string s1, string s2 ) { return s1.CompareTo( s2 ); } ); | |||
return names.ToArray(); | |||
} | |||
#if UNITY_EDITOR | |||
/* | |||
----------------------- | |||
OnPrefabReimported() | |||
----------------------- | |||
*/ | |||
static public void OnPrefabReimported() { | |||
if ( theAudioManager != null ) { | |||
Debug.Log( "[AudioManager] Reimporting the sound FX cache." ); | |||
theAudioManager.RebuildSoundFXCache(); | |||
} | |||
} | |||
/* | |||
----------------------- | |||
PlaySound() | |||
used in the editor | |||
----------------------- | |||
*/ | |||
static public void PlaySound( string soundFxName ) { | |||
if ( theAudioManager == null ) { | |||
if ( !FindAudioManager() ) { | |||
return; | |||
} | |||
} | |||
SoundFX soundFX = FindSoundFX( soundFxName, true ); | |||
if ( soundFX == null ) { | |||
return; | |||
} | |||
AudioClip clip = soundFX.GetClip(); | |||
if ( clip != null ) { | |||
Assembly unityEditorAssembly = typeof(AudioImporter).Assembly; | |||
Type audioUtilClass = unityEditorAssembly.GetType("UnityEditor.AudioUtil"); | |||
MethodInfo method = audioUtilClass.GetMethod( | |||
"PlayClip", | |||
BindingFlags.Static | BindingFlags.Public, | |||
null, | |||
new System.Type[] { typeof(AudioClip) }, | |||
null ); | |||
method.Invoke( null, new object[] { clip } ); | |||
} | |||
} | |||
/* | |||
----------------------- | |||
IsSoundPlaying() | |||
used in the editor | |||
----------------------- | |||
*/ | |||
static public bool IsSoundPlaying( string soundFxName ) { | |||
if ( theAudioManager == null ) { | |||
if ( !FindAudioManager() ) { | |||
return false; | |||
} | |||
} | |||
SoundFX soundFX = FindSoundFX( soundFxName, true ); | |||
if ( soundFX == null ) { | |||
return false; | |||
} | |||
AudioClip clip = soundFX.GetClip(); | |||
if ( clip != null ) { | |||
Assembly unityEditorAssembly = typeof(AudioImporter).Assembly; | |||
Type audioUtilClass = unityEditorAssembly.GetType("UnityEditor.AudioUtil"); | |||
MethodInfo method = audioUtilClass.GetMethod( | |||
"IsClipPlaying", | |||
BindingFlags.Static | BindingFlags.Public, | |||
null, | |||
new System.Type[] { typeof(AudioClip) }, | |||
null ); | |||
return Convert.ToBoolean( method.Invoke( null, new object[] { clip } ) ); | |||
} | |||
return false; | |||
} | |||
/* | |||
----------------------- | |||
StopSound() | |||
used in the editor | |||
----------------------- | |||
*/ | |||
static public void StopSound(string soundFxName) | |||
{ | |||
if (theAudioManager == null) | |||
{ | |||
if (!FindAudioManager()) | |||
{ | |||
return; | |||
} | |||
} | |||
SoundFX soundFX = FindSoundFX(soundFxName, true); | |||
if (soundFX == null) | |||
{ | |||
return; | |||
} | |||
AudioClip clip = soundFX.GetClip(); | |||
if (clip != null) | |||
{ | |||
Assembly unityEditorAssembly = typeof(AudioImporter).Assembly; | |||
Type audioUtilClass = unityEditorAssembly.GetType("UnityEditor.AudioUtil"); | |||
MethodInfo method = audioUtilClass.GetMethod( | |||
"StopClip", | |||
BindingFlags.Static | BindingFlags.Public, | |||
null, | |||
new System.Type[] { typeof(AudioClip) }, | |||
null); | |||
method.Invoke(null, new object[] { clip }); | |||
} | |||
} | |||
#endif | |||
} | |||
} // namespace OVR |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 6d1d30b41806244fca035fdae2896fb7 | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: |
@ -0,0 +1,787 @@ | |||
using UnityEngine; | |||
using UnityEngine.Audio; | |||
namespace OVR | |||
{ | |||
//------------------------------------------------------------------------- | |||
// Types | |||
//------------------------------------------------------------------------- | |||
public enum EmitterChannel { | |||
None = -1, | |||
Reserved = 0, // plays on the single reserved emitter | |||
Any // queues to the next available emitter | |||
} | |||
[System.Serializable] | |||
public class MixerSnapshot { | |||
public AudioMixerSnapshot snapshot = null; | |||
public float transitionTime = 0.25f; | |||
} | |||
/* | |||
----------------------- | |||
GameManager Sound Routines | |||
----------------------- | |||
*/ | |||
public partial class AudioManager : MonoBehaviour { | |||
public enum Fade { | |||
In, | |||
Out | |||
} | |||
private float audioMaxFallOffDistanceSqr = 25.0f * 25.0f; // past this distance, sounds are ignored for the local player | |||
private SoundEmitter[] soundEmitters = null; // pool of sound emitters to play sounds through | |||
private FastList<SoundEmitter> playingEmitters = new FastList<SoundEmitter>(); | |||
private FastList<SoundEmitter> nextFreeEmitters = new FastList<SoundEmitter>(); | |||
private MixerSnapshot currentSnapshot = null; | |||
static private GameObject soundEmitterParent = null; // parent object for the sound emitters | |||
static private Transform staticListenerPosition = null; // play position for regular 2D sounds | |||
static private bool showPlayingEmitterCount = false; | |||
static private bool forceShowEmitterCount = false; | |||
static private bool soundEnabled = true; | |||
static public bool SoundEnabled { get { return soundEnabled; } } | |||
static readonly AnimationCurve defaultReverbZoneMix = new AnimationCurve( new Keyframe[2] { new Keyframe( 0f, 1.0f ), new Keyframe( 1f, 1f ) } ); | |||
/* | |||
----------------------- | |||
InitializeSoundSystem() | |||
initialize persistent sound emitter objects that live across scene loads | |||
----------------------- | |||
*/ | |||
void InitializeSoundSystem() { | |||
int bufferLength = 960; | |||
int numBuffers = 4; | |||
AudioSettings.GetDSPBufferSize( out bufferLength, out numBuffers ); | |||
if ( Application.isPlaying ) { | |||
Debug.Log( "[AudioManager] Audio Sample Rate: " + AudioSettings.outputSampleRate ); | |||
Debug.Log( "[AudioManager] Audio Buffer Length: " + bufferLength + " Size: " + numBuffers ); | |||
} | |||
// find the audio listener for playing regular 2D sounds | |||
AudioListener audioListenerObject = GameObject.FindObjectOfType<AudioListener>() as AudioListener; | |||
if ( audioListenerObject == null ) { | |||
Debug.LogError( "[AudioManager] Missing AudioListener object! Add one to the scene." ); | |||
} else { | |||
staticListenerPosition = audioListenerObject.transform; | |||
} | |||
// we allocate maxSoundEmitters + reserved channels | |||
soundEmitters = new SoundEmitter[maxSoundEmitters+(int)EmitterChannel.Any]; | |||
// see if the sound emitters have already been created, if so, nuke it, it shouldn't exist in the scene upon load | |||
soundEmitterParent = GameObject.Find( "__SoundEmitters__" ); | |||
if ( soundEmitterParent != null ) { | |||
// delete any sound emitters hanging around | |||
Destroy( soundEmitterParent ); | |||
} | |||
// create them all | |||
soundEmitterParent = new GameObject( "__SoundEmitters__" ); | |||
for ( int i = 0; i < maxSoundEmitters + (int)EmitterChannel.Any; i++ ) { | |||
GameObject emitterObject = new GameObject( "SoundEmitter_" + i ); | |||
emitterObject.transform.parent = soundEmitterParent.transform; | |||
emitterObject.transform.position = Vector3.zero; | |||
// don't ever save this to the scene | |||
emitterObject.hideFlags = HideFlags.DontSaveInEditor; | |||
// add the sound emitter components | |||
soundEmitters[i] = emitterObject.AddComponent<SoundEmitter>(); | |||
soundEmitters[i].SetDefaultParent( soundEmitterParent.transform ); | |||
soundEmitters[i].SetChannel( i ); | |||
soundEmitters[i].Stop(); | |||
// save off the original index | |||
soundEmitters[i].originalIdx = i; | |||
} | |||
// reset the free emitter lists | |||
ResetFreeEmitters(); | |||
soundEmitterParent.hideFlags = HideFlags.DontSaveInEditor; | |||
audioMaxFallOffDistanceSqr = audioMaxFallOffDistance * audioMaxFallOffDistance; | |||
} | |||
/* | |||
----------------------- | |||
UpdateFreeEmitters() | |||
----------------------- | |||
*/ | |||
void UpdateFreeEmitters() { | |||
if ( verboseLogging ) { | |||
if ( Input.GetKeyDown( KeyCode.A ) ) { | |||
forceShowEmitterCount = !forceShowEmitterCount; | |||
} | |||
if ( forceShowEmitterCount ) { | |||
showPlayingEmitterCount = true; | |||
} | |||
} | |||
// display playing emitter count when the sound system is overwhelmed | |||
int total = 0, veryLow = 0, low = 0, def = 0, high = 0, veryHigh = 0; | |||
// find emitters that are done playing and add them to the nextFreeEmitters list | |||
for ( int i = 0; i < playingEmitters.size; ) { | |||
if ( playingEmitters[i] == null ) { | |||
Debug.LogError( "[AudioManager] ERROR: playingEmitters list had a null emitter! Something nuked a sound emitter!!!" ); | |||
playingEmitters.RemoveAtFast( i ); | |||
return; | |||
} | |||
if ( !playingEmitters[i].IsPlaying() ) { | |||
// add to the free list and remove from the playing list | |||
if ( verboseLogging ) { | |||
if ( nextFreeEmitters.Contains( playingEmitters[i] ) ) { | |||
Debug.LogError( "[AudioManager] ERROR: playing sound emitter already in the free emitters list!" ); | |||
} | |||
} | |||
playingEmitters[i].Stop(); | |||
nextFreeEmitters.Add( playingEmitters[i] ); | |||
playingEmitters.RemoveAtFast( i ); | |||
continue; | |||
} | |||
// debugging/profiling | |||
if ( verboseLogging && showPlayingEmitterCount ) { | |||
total++; | |||
switch ( playingEmitters[i].priority ) { | |||
case SoundPriority.VeryLow: veryLow++; break; | |||
case SoundPriority.Low: low++; break; | |||
case SoundPriority.Default: def++; break; | |||
case SoundPriority.High: high++; break; | |||
case SoundPriority.VeryHigh: veryHigh++; break; | |||
} | |||
} | |||
i++; | |||
} | |||
if ( verboseLogging && showPlayingEmitterCount ) { | |||
Debug.LogWarning( string.Format( "[AudioManager] Playing sounds: Total {0} | VeryLow {1} | Low {2} | Default {3} | High {4} | VeryHigh {5} | Free {6}", Fmt( total ), Fmt( veryLow ), Fmt( low ), Fmt( def ), Fmt( high ), Fmt( veryHigh ), FmtFree( nextFreeEmitters.Count ) ) ); | |||
showPlayingEmitterCount = false; | |||
} | |||
} | |||
/* | |||
----------------------- | |||
Fmt() | |||
----------------------- | |||
*/ | |||
string Fmt( int count ) { | |||
float t = count / (float)theAudioManager.maxSoundEmitters; | |||
if ( t < 0.5f ) { | |||
return "<color=green>" + count.ToString() + "</color>"; | |||
} else if ( t < 0.7 ) { | |||
return "<color=yellow>" + count.ToString() + "</color>"; | |||
} else { | |||
return "<color=red>" + count.ToString() + "</color>"; | |||
} | |||
} | |||
/* | |||
----------------------- | |||
FmtFree() | |||
----------------------- | |||
*/ | |||
string FmtFree( int count ) { | |||
float t = count / (float)theAudioManager.maxSoundEmitters; | |||
if ( t < 0.2f ) { | |||
return "<color=red>" + count.ToString() + "</color>"; | |||
} else if ( t < 0.3 ) { | |||
return "<color=yellow>" + count.ToString() + "</color>"; | |||
} else { | |||
return "<color=green>" + count.ToString() + "</color>"; | |||
} | |||
} | |||
/* | |||
----------------------- | |||
OnPreSceneLoad() | |||
----------------------- | |||
*/ | |||
void OnPreSceneLoad() { | |||
// move any attached sounds back to the sound emitters parent before changing levels so they don't get destroyed | |||
Debug.Log( "[AudioManager] OnPreSceneLoad cleanup" ); | |||
for ( int i = 0; i < soundEmitters.Length; i++ ) { | |||
soundEmitters[i].Stop(); | |||
soundEmitters[i].ResetParent( soundEmitterParent.transform ); | |||
} | |||
// reset our emitter lists | |||
ResetFreeEmitters(); | |||
} | |||
/* | |||
----------------------- | |||
ResetFreeEmitters() | |||
----------------------- | |||
*/ | |||
void ResetFreeEmitters() { | |||
nextFreeEmitters.Clear(); | |||
playingEmitters.Clear(); | |||
for ( int i = (int)EmitterChannel.Any; i < soundEmitters.Length; i++ ) { | |||
nextFreeEmitters.Add( soundEmitters[i] ); | |||
} | |||
} | |||
/* | |||
----------------------- | |||
FadeOutSoundChannel() | |||
utility function to fade out a playing sound channel | |||
----------------------- | |||
*/ | |||
static public void FadeOutSoundChannel( int channel, float delaySecs, float fadeTime ) { | |||
theAudioManager.soundEmitters[channel].FadeOutDelayed( delaySecs, fadeTime ); | |||
} | |||
/* | |||
----------------------- | |||
StopSound() | |||
----------------------- | |||
*/ | |||
static public bool StopSound( int idx, bool fadeOut = true, bool stopReserved = false ) { | |||
if ( !stopReserved && ( idx == (int)EmitterChannel.Reserved ) ) { | |||
return false; | |||
} | |||
if ( !fadeOut ) { | |||
theAudioManager.soundEmitters[idx].Stop(); | |||
} | |||
else { | |||
theAudioManager.soundEmitters[idx].FadeOut( theAudioManager.soundFxFadeSecs ); | |||
} | |||
return true; | |||
} | |||
/* | |||
----------------------- | |||
FadeInSound() | |||
----------------------- | |||
*/ | |||
public static void FadeInSound( int idx, float fadeTime, float volume ) { | |||
theAudioManager.soundEmitters[idx].FadeIn( fadeTime, volume ); | |||
} | |||
/* | |||
----------------------- | |||
FadeInSound() | |||
----------------------- | |||
*/ | |||
public static void FadeInSound( int idx, float fadeTime ) { | |||
theAudioManager.soundEmitters[idx].FadeIn( fadeTime ); | |||
} | |||
/* | |||
----------------------- | |||
FadeOutSound() | |||
----------------------- | |||
*/ | |||
public static void FadeOutSound( int idx, float fadeTime ) { | |||
theAudioManager.soundEmitters[idx].FadeOut( fadeTime ); | |||
} | |||
/* | |||
----------------------- | |||
StopAllSounds() | |||
----------------------- | |||
*/ | |||
public static void StopAllSounds( bool fadeOut, bool stopReserved = false ) { | |||
for ( int i = 0; i < theAudioManager.soundEmitters.Length; i++ ) { | |||
StopSound( i, fadeOut, stopReserved ); | |||
} | |||
} | |||
/* | |||
----------------------- | |||
MuteAllSounds() | |||
----------------------- | |||
*/ | |||
public void MuteAllSounds( bool mute, bool muteReserved = false ) { | |||
for ( int i = 0; i < soundEmitters.Length; i++ ) { | |||
if ( !muteReserved && ( i == (int)EmitterChannel.Reserved ) ) { | |||
continue; | |||
} | |||
soundEmitters[i].audioSource.mute = true; | |||
} | |||
} | |||
/* | |||
----------------------- | |||
UnMuteAllSounds() | |||
----------------------- | |||
*/ | |||
public void UnMuteAllSounds( bool unmute, bool unmuteReserved = false ) { | |||
for ( int i = 0; i < soundEmitters.Length; i++ ) { | |||
if ( !unmuteReserved && ( i == (int)EmitterChannel.Reserved ) ) { | |||
continue; | |||
} | |||
if ( soundEmitters[i].audioSource.isPlaying ) { | |||
soundEmitters[i].audioSource.mute = false; | |||
} | |||
} | |||
} | |||
/* | |||
----------------------- | |||
GetEmitterEndTime() | |||
----------------------- | |||
*/ | |||
static public float GetEmitterEndTime( int idx ) { | |||
return theAudioManager.soundEmitters[idx].endPlayTime; | |||
} | |||
/* | |||
----------------------- | |||
SetEmitterTime() | |||
----------------------- | |||
*/ | |||
static public float SetEmitterTime( int idx, float time ) { | |||
return theAudioManager.soundEmitters[idx].time = time; | |||
} | |||
/* | |||
----------------------- | |||
PlaySound() | |||
----------------------- | |||
*/ | |||
static public int PlaySound( AudioClip clip, float volume, EmitterChannel src = EmitterChannel.Any, float delay = 0.0f, float pitchVariance = 1.0f, bool loop = false ) { | |||
if ( !SoundEnabled ) { | |||
return -1; | |||
} | |||
return PlaySoundAt( ( staticListenerPosition != null ) ? staticListenerPosition.position : Vector3.zero, clip, volume, src, delay, pitchVariance, loop ); | |||
} | |||
/* | |||
----------------------- | |||
FindFreeEmitter() | |||
----------------------- | |||
*/ | |||
static private int FindFreeEmitter( EmitterChannel src, SoundPriority priority ) { | |||
// default to the reserved emitter | |||
SoundEmitter next = theAudioManager.soundEmitters[0]; | |||
if ( src == EmitterChannel.Any ) { | |||
// pull from the free emitter list if possible | |||
if ( theAudioManager.nextFreeEmitters.size > 0 ) { | |||
// return the first in the list | |||
next = theAudioManager.nextFreeEmitters[0]; | |||
// remove it from the free list | |||
theAudioManager.nextFreeEmitters.RemoveAtFast( 0 ); | |||
} else { | |||
// no free emitters available so pull from the lowest priority sound | |||
if ( priority == SoundPriority.VeryLow ) { | |||
// skip low priority sounds | |||
return -1; | |||
} else { | |||
// find a playing emitter that has a lower priority than what we're requesting | |||
// TODO - we could first search for Very Low, then Low, etc ... TBD if it's worth the effort | |||
next = theAudioManager.playingEmitters.Find( item => item != null && item.priority < priority ); | |||
if ( next == null ) { | |||
// last chance to find a free emitter | |||
if ( priority < SoundPriority.Default ) { | |||
// skip sounds less than the default priority | |||
if ( theAudioManager.verboseLogging ) { | |||
Debug.LogWarning( "[AudioManager] skipping sound " + priority ); | |||
} | |||
return -1; | |||
} else { | |||
// grab a default priority emitter so that we don't cannabalize a high priority sound | |||
next = theAudioManager.playingEmitters.Find( item => item != null && item.priority <= SoundPriority.Default ); ; | |||
} | |||
} | |||
if ( next != null ) { | |||
if ( theAudioManager.verboseLogging ) { | |||
Debug.LogWarning( "[AudioManager] cannabalizing " + next.originalIdx + " Time: " + Time.time ); | |||
} | |||
// remove it from the playing list | |||
next.Stop(); | |||
theAudioManager.playingEmitters.RemoveFast( next ); | |||
} | |||
} | |||
} | |||
} | |||
if ( next == null ) { | |||
Debug.LogError( "[AudioManager] ERROR - absolutely couldn't find a free emitter! Priority = " + priority + " TOO MANY PlaySound* calls!" ); | |||
showPlayingEmitterCount = true; | |||
return -1; | |||
} | |||
return next.originalIdx; | |||
} | |||
/* | |||
----------------------- | |||
PlaySound() | |||
----------------------- | |||
*/ | |||
static public int PlaySound( SoundFX soundFX, EmitterChannel src = EmitterChannel.Any, float delay = 0.0f ) { | |||
if ( !SoundEnabled ) { | |||
return -1; | |||
} | |||
return PlaySoundAt( ( staticListenerPosition != null ) ? staticListenerPosition.position : Vector3.zero, soundFX, src, delay ); | |||
} | |||
/* | |||
----------------------- | |||
PlaySoundAt() | |||
----------------------- | |||
*/ | |||
static public int PlaySoundAt( Vector3 position, SoundFX soundFX, EmitterChannel src = EmitterChannel.Any, float delay = 0.0f, float volumeOverride = 1.0f, float pitchMultiplier = 1.0f ) { | |||
if ( !SoundEnabled ) { | |||
return -1; | |||
} | |||
AudioClip clip = soundFX.GetClip(); | |||
if ( clip == null ) { | |||
return -1; | |||
} | |||
// check the distance from the local player and ignore sounds out of range | |||
if ( staticListenerPosition != null ) { | |||
float distFromListener = ( staticListenerPosition.position - position ).sqrMagnitude; | |||
if ( distFromListener > theAudioManager.audioMaxFallOffDistanceSqr ) { | |||
return -1; | |||
} | |||
if ( distFromListener > soundFX.MaxFalloffDistSquared ) { | |||
return -1; | |||
} | |||
} | |||
// check max playing sounds | |||
if ( soundFX.ReachedGroupPlayLimit() ) { | |||
if ( theAudioManager.verboseLogging ) { | |||
Debug.Log( "[AudioManager] PlaySoundAt() with " + soundFX.name + " skipped due to group play limit" ); | |||
} | |||
return -1; | |||
} | |||
int idx = FindFreeEmitter( src, soundFX.priority ); | |||
if ( idx == -1 ) { | |||
// no free emitters - should only happen on very low priority sounds | |||
return -1; | |||
} | |||
SoundEmitter emitter = theAudioManager.soundEmitters[idx]; | |||
// make sure to detach the emitter from a previous parent | |||
emitter.ResetParent( soundEmitterParent.transform ); | |||
emitter.gameObject.SetActive( true ); | |||
// set up the sound emitter | |||
AudioSource audioSource = emitter.audioSource; | |||
ONSPAudioSource osp = emitter.osp; | |||
audioSource.enabled = true; | |||
audioSource.volume = Mathf.Clamp01( Mathf.Clamp01( theAudioManager.volumeSoundFX * soundFX.volume ) * volumeOverride * soundFX.GroupVolumeOverride ); | |||
audioSource.pitch = soundFX.GetPitch() * pitchMultiplier; | |||
audioSource.time = 0.0f; | |||
audioSource.spatialBlend = 1.0f; | |||
audioSource.rolloffMode = soundFX.falloffCurve; | |||
if ( soundFX.falloffCurve == AudioRolloffMode.Custom ) { | |||
audioSource.SetCustomCurve( AudioSourceCurveType.CustomRolloff, soundFX.volumeFalloffCurve ); | |||
} | |||
audioSource.SetCustomCurve( AudioSourceCurveType.ReverbZoneMix, soundFX.reverbZoneMix ); | |||
audioSource.dopplerLevel = 0; | |||
audioSource.clip = clip; | |||
audioSource.spread = soundFX.spread; | |||
audioSource.loop = soundFX.looping; | |||
audioSource.mute = false; | |||
audioSource.minDistance = soundFX.falloffDistance.x; | |||
audioSource.maxDistance = soundFX.falloffDistance.y; | |||
audioSource.outputAudioMixerGroup = soundFX.GetMixerGroup( AudioManager.EmitterGroup ); | |||
// set the play time so we can check when sounds are done | |||
emitter.endPlayTime = Time.time + clip.length + delay; | |||
// cache the default volume for fading | |||
emitter.defaultVolume = audioSource.volume; | |||
// sound priority | |||
emitter.priority = soundFX.priority; | |||
// reset this | |||
emitter.onFinished = null; | |||
// update the sound group limits | |||
emitter.SetPlayingSoundGroup( soundFX.Group ); | |||
// add to the playing list | |||
if ( src == EmitterChannel.Any ) { | |||
theAudioManager.playingEmitters.AddUnique( emitter ); | |||
} | |||
// OSP properties | |||
if ( osp != null ) { | |||
osp.EnableSpatialization = soundFX.ospProps.enableSpatialization; | |||
osp.EnableRfl = theAudioManager.enableSpatializedFastOverride || soundFX.ospProps.useFastOverride ? true : false; | |||
osp.Gain = soundFX.ospProps.gain; | |||
osp.UseInvSqr = soundFX.ospProps.enableInvSquare; | |||
osp.Near = soundFX.ospProps.invSquareFalloff.x; | |||
osp.Far = soundFX.ospProps.invSquareFalloff.y; | |||
audioSource.spatialBlend = (soundFX.ospProps.enableSpatialization) ? 1.0f : 0.8f; | |||
// make sure to set the properties in the audio source before playing | |||
osp.SetParameters(ref audioSource); | |||
} | |||
audioSource.transform.position = position; | |||
if ( theAudioManager.verboseLogging ) { | |||
Debug.Log( "[AudioManager] PlaySoundAt() channel = " + idx + " soundFX = " + soundFX.name + " volume = " + emitter.volume + " Delay = " + delay + " time = " + Time.time + "\n" ); | |||
} | |||
// play the sound | |||
if ( delay > 0f ) { | |||
audioSource.PlayDelayed( delay ); | |||
} else { | |||
audioSource.Play(); | |||
} | |||
return idx; | |||
} | |||
/* | |||
----------------------- | |||
PlayRandomSoundAt() | |||
----------------------- | |||
*/ | |||
static public int PlayRandomSoundAt( Vector3 position, AudioClip[] clips, float volume, EmitterChannel src = EmitterChannel.Any, float delay = 0.0f, float pitch = 1.0f, bool loop = false ) { | |||
if ( ( clips == null ) || ( clips.Length == 0 ) ) { | |||
return -1; | |||
} | |||
int idx = Random.Range( 0, clips.Length ); | |||
return PlaySoundAt( position, clips[idx], volume, src, delay, pitch, loop ); | |||
} | |||
/* | |||
----------------------- | |||
PlaySoundAt() | |||
----------------------- | |||
*/ | |||
static public int PlaySoundAt( Vector3 position, AudioClip clip, float volume = 1.0f, EmitterChannel src = EmitterChannel.Any, float delay = 0.0f, float pitch = 1.0f, bool loop = false ) { | |||
if ( !SoundEnabled ) { | |||
return -1; | |||
} | |||
if ( clip == null ) { | |||
return -1; | |||
} | |||
// check the distance from the local player and ignore sounds out of range | |||
if ( staticListenerPosition != null ) { | |||
if ( ( staticListenerPosition.position - position ).sqrMagnitude > theAudioManager.audioMaxFallOffDistanceSqr ) { | |||
// no chance of being heard | |||
return -1; | |||
} | |||
} | |||
int idx = FindFreeEmitter( src, 0 ); | |||
if ( idx == -1 ) { | |||
// no free emitters - should only happen on very low priority sounds | |||
return -1; | |||
} | |||
SoundEmitter emitter = theAudioManager.soundEmitters[idx]; | |||
// make sure to detach the emitter from a previous parent | |||
emitter.ResetParent( soundEmitterParent.transform ); | |||
emitter.gameObject.SetActive( true ); | |||
// set up the sound emitter | |||
AudioSource audioSource = emitter.audioSource; | |||
ONSPAudioSource osp = emitter.osp; | |||
audioSource.enabled = true; | |||
audioSource.volume = Mathf.Clamp01( theAudioManager.volumeSoundFX * volume ); | |||
audioSource.pitch = pitch; | |||
audioSource.spatialBlend = 0.8f; | |||
audioSource.rolloffMode = AudioRolloffMode.Linear; | |||
audioSource.SetCustomCurve( AudioSourceCurveType.ReverbZoneMix, defaultReverbZoneMix ); | |||
audioSource.dopplerLevel = 0.0f; | |||
audioSource.clip = clip; | |||
audioSource.spread = 0.0f; | |||
audioSource.loop = loop; | |||
audioSource.mute = false; | |||
audioSource.minDistance = theAudioManager.audioMinFallOffDistance; | |||
audioSource.maxDistance = theAudioManager.audioMaxFallOffDistance; | |||
audioSource.outputAudioMixerGroup = AudioManager.EmitterGroup; | |||
// set the play time so we can check when sounds are done | |||
emitter.endPlayTime = Time.time + clip.length + delay; | |||
// cache the default volume for fading | |||
emitter.defaultVolume = audioSource.volume; | |||
// default priority | |||
emitter.priority = 0; | |||
// reset this | |||
emitter.onFinished = null; | |||
// update the sound group limits | |||
emitter.SetPlayingSoundGroup( null ); | |||
// add to the playing list | |||
if ( src == EmitterChannel.Any ) { | |||
theAudioManager.playingEmitters.AddUnique( emitter ); | |||
} | |||
// disable spatialization (by default for regular AudioClips) | |||
if ( osp != null ) { | |||
osp.EnableSpatialization = false; | |||
} | |||
audioSource.transform.position = position; | |||
if ( theAudioManager.verboseLogging ) { | |||
Debug.Log( "[AudioManager] PlaySoundAt() channel = " + idx + " clip = " + clip.name + " volume = " + emitter.volume + " Delay = " + delay + " time = " + Time.time + "\n" ); | |||
} | |||
// play the sound | |||
if ( delay > 0f ) { | |||
audioSource.PlayDelayed( delay ); | |||
} else { | |||
audioSource.Play(); | |||
} | |||
return idx; | |||
} | |||
/* | |||
----------------------- | |||
SetOnFinished() | |||
----------------------- | |||
*/ | |||
public static void SetOnFinished( int emitterIdx, System.Action onFinished ) { | |||
if ( emitterIdx >= 0 && emitterIdx < theAudioManager.maxSoundEmitters ) { | |||
theAudioManager.soundEmitters[emitterIdx].SetOnFinished( onFinished ); | |||
} | |||
} | |||
/* | |||
----------------------- | |||
SetOnFinished() | |||
----------------------- | |||
*/ | |||
public static void SetOnFinished( int emitterIdx, System.Action<object> onFinished, object obj ) { | |||
if ( emitterIdx >= 0 && emitterIdx < theAudioManager.maxSoundEmitters ) { | |||
theAudioManager.soundEmitters[emitterIdx].SetOnFinished( onFinished, obj ); | |||
} | |||
} | |||
/* | |||
----------------------- | |||
AttachSoundToParent() | |||
----------------------- | |||
*/ | |||
public static void AttachSoundToParent( int idx, Transform parent ) { | |||
if ( theAudioManager.verboseLogging ) { | |||
string parentName = parent.name; | |||
if ( parent.parent != null ) { | |||
parentName = parent.parent.name + "/" + parentName; | |||
} | |||
Debug.Log( "[AudioManager] ATTACHING INDEX " + idx + " to " + parentName ); | |||
} | |||
theAudioManager.soundEmitters[idx].ParentTo( parent ); | |||
} | |||
/* | |||
----------------------- | |||
DetachSoundFromParent() | |||
----------------------- | |||
*/ | |||
public static void DetachSoundFromParent( int idx ) { | |||
if ( theAudioManager.verboseLogging ) { | |||
Debug.Log( "[AudioManager] DETACHING INDEX " + idx ); | |||
} | |||
theAudioManager.soundEmitters[idx].DetachFromParent(); | |||
} | |||
/* | |||
----------------------- | |||
DetachSoundsFromParent() | |||
----------------------- | |||
*/ | |||
public static void DetachSoundsFromParent( SoundEmitter[] emitters, bool stopSounds = true ) { | |||
if ( emitters == null ) { | |||
return; | |||
} | |||
foreach ( SoundEmitter emitter in emitters ) { | |||
if ( emitter.defaultParent != null ) { | |||
if ( stopSounds ) { | |||
emitter.Stop(); | |||
} | |||
emitter.DetachFromParent(); | |||
// make sure it's active | |||
emitter.gameObject.SetActive( true ); | |||
} else { | |||
if ( stopSounds ) { | |||
emitter.Stop(); | |||
} | |||
} | |||
} | |||
} | |||
/* | |||
----------------------- | |||
SetEmitterMixerGroup() | |||
----------------------- | |||
*/ | |||
public static void SetEmitterMixerGroup( int idx, AudioMixerGroup mixerGroup ) { | |||
if ( ( theAudioManager != null ) && ( idx > -1 ) ) { | |||
theAudioManager.soundEmitters[idx].SetAudioMixer( mixerGroup ); | |||
} | |||
} | |||
/* | |||
----------------------- | |||
GetActiveSnapshot() | |||
----------------------- | |||
*/ | |||
public static MixerSnapshot GetActiveSnapshot() { | |||
return ( theAudioManager != null ) ? theAudioManager.currentSnapshot : null; | |||
} | |||
/* | |||
----------------------- | |||
SetCurrentSnapshot() | |||
----------------------- | |||
*/ | |||
public static void SetCurrentSnapshot( MixerSnapshot mixerSnapshot ) { | |||
#if UNITY_EDITOR | |||
if ( mixerSnapshot == null || mixerSnapshot.snapshot == null ) { | |||
Debug.LogError( "[AudioManager] ERROR setting empty mixer snapshot!" ); | |||
} else { | |||
Debug.Log( "[AudioManager] Setting audio mixer snapshot: " + ( ( mixerSnapshot != null && mixerSnapshot.snapshot != null ) ? mixerSnapshot.snapshot.name : "None" ) + " Time: " + Time.time ); | |||
} | |||
#endif | |||
if ( theAudioManager != null ) { | |||
if ( ( mixerSnapshot != null ) && ( mixerSnapshot.snapshot != null ) ) { | |||
mixerSnapshot.snapshot.TransitionTo( mixerSnapshot.transitionTime ); | |||
} else { | |||
mixerSnapshot = null; | |||
} | |||
theAudioManager.currentSnapshot = mixerSnapshot; | |||
} | |||
} | |||
/* | |||
----------------------- | |||
BlendWithCurrentSnapshot() | |||
----------------------- | |||
*/ | |||
public static void BlendWithCurrentSnapshot( MixerSnapshot blendSnapshot, float weight, float blendTime = 0.0f ) { | |||
if ( theAudioManager != null ) { | |||
if ( theAudioManager.audioMixer == null ) { | |||
Debug.LogWarning( "[AudioManager] can't call BlendWithCurrentSnapshot if the audio mixer is not set!" ); | |||
return; | |||
} | |||
if ( blendTime == 0.0f ) { | |||
blendTime = Time.deltaTime; | |||
} | |||
if ( ( theAudioManager.currentSnapshot != null ) && (theAudioManager.currentSnapshot.snapshot != null ) ) { | |||
if ( ( blendSnapshot != null ) && ( blendSnapshot.snapshot != null ) ) { | |||
weight = Mathf.Clamp01( weight ); | |||
if ( weight == 0.0f ) { | |||
// revert to the default snapshot | |||
theAudioManager.currentSnapshot.snapshot.TransitionTo( blendTime ); | |||
} else { | |||
AudioMixerSnapshot[] snapshots = new AudioMixerSnapshot[] { theAudioManager.currentSnapshot.snapshot, blendSnapshot.snapshot }; | |||
float[] weights = new float[] { 1.0f - weight, weight }; | |||
theAudioManager.audioMixer.TransitionToSnapshots( snapshots, weights, blendTime ); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} // namespace OVR |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 41cb0f893e9a44e83b09a66c55bd7856 | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: |
@ -0,0 +1,5 @@ | |||
fileFormatVersion: 2 | |||
guid: 02213405caaf04aeea7876974c06fa5a | |||
folderAsset: yes | |||
DefaultImporter: | |||
userData: |
@ -0,0 +1,46 @@ | |||
using UnityEngine; | |||
using UnityEditor; | |||
namespace OVR | |||
{ | |||
/* | |||
----------------------- | |||
AudioImportPostProcessor() | |||
----------------------- | |||
*/ | |||
public class AudioImportPostProcessor : AssetPostprocessor { | |||
static void OnPostprocessAllAssets( string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths ) { | |||
AudioManager audioManager = AudioManager.Instance; | |||
if ( audioManager != null ) { | |||
// find the asset path to the loaded audio manager prefab | |||
#if UNITY_2018_2_OR_NEWER | |||
Object prefabObject = PrefabUtility.GetCorrespondingObjectFromSource(audioManager); | |||
#else | |||
Object prefabObject = PrefabUtility.GetPrefabParent( audioManager ); | |||
#endif | |||
if ( prefabObject != null ) { | |||
string path = AssetDatabase.GetAssetPath( prefabObject ); | |||
// check to see if the AudioManager prefab has been reimported. | |||
// if so, rebuild everything | |||
foreach ( string asset in importedAssets ) { | |||
if ( asset.ToLower() == path.ToLower() ) { | |||
// in the event the audio manager is selected, deselect it first before reloading | |||
Debug.Log( "[AudioManager] AudioManager prefab reloaded: " + path ); | |||
Selection.objects = new Object[0] { }; | |||
// unfortunately even saving the audio manager prefab will trigger this action | |||
//string msg = "The Audio Manager was reloaded. If you are going to be making modifications to the Audio Manager, "; | |||
//msg += "please verify you have the latest version before proceeding. If in doubt, restart Unity before making modifications."; | |||
//EditorUtility.DisplayDialog( "Audio Manager Prefab Reloaded", msg, "OK" ); | |||
// do the actual reload | |||
AudioManager.OnPrefabReimported(); | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} // namespace OVR |
@ -0,0 +1,12 @@ | |||
fileFormatVersion: 2 | |||
guid: 48902580b26e3554d992bad48087eee5 | |||
timeCreated: 1471010515 | |||
licenseType: Pro | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,631 @@ | |||
using UnityEngine; | |||
using UnityEditor; | |||
using System.Collections.Generic; | |||
namespace OVR | |||
{ | |||
/* | |||
----------------------- | |||
AudioManagerInspector | |||
----------------------- | |||
*/ | |||
[CustomEditor(typeof(AudioManager))] | |||
public class AudioManagerInspector : Editor { | |||
private AudioManager audioManager = null; | |||
private string dragDropIdentifier = "MoveSoundFX"; | |||
private GUIStyle customDividerStyle = null; | |||
/* | |||
----------------------- | |||
OnInspectorGUI() | |||
----------------------- | |||
*/ | |||
public override void OnInspectorGUI() { | |||
audioManager = target as AudioManager; | |||
Event e = Event.current; | |||
// draw the default properties | |||
DrawDefaultProperties(); | |||
// draw the categories section | |||
DrawCategories( e ); | |||
serializedObject.Update(); | |||
// draw the sound effects for the selected category | |||
DrawSoundEffects( e ); | |||
serializedObject.ApplyModifiedProperties(); | |||
CreateStyles(); | |||
} | |||
/* | |||
----------------------- | |||
MarkDirty() | |||
----------------------- | |||
*/ | |||
void MarkDirty() { | |||
serializedObject.SetIsDifferentCacheDirty(); | |||
EditorUtility.SetDirty( audioManager ); | |||
} | |||
static private int selectedGroup = 0; | |||
private int nextGroup = -1; | |||
private int editGroup = -1; | |||
private FastList<SoundGroup> soundGroups = new FastList<SoundGroup>(); | |||
private FastList<ItemRect> groups = new FastList<ItemRect>(); | |||
private Rect dropArea = new Rect(); | |||
private bool addSound = false; | |||
private int deleteSoundIdx = -1; | |||
private int dupeSoundIdx = -1; | |||
private bool sortSounds = false; | |||
private bool moveQueued = false; | |||
private int origGroup = -1; | |||
private int origIndex = -1; | |||
private int moveToGroup = -1; | |||
/* | |||
----------------------- | |||
DrawDefaultProperties() | |||
----------------------- | |||
*/ | |||
void DrawDefaultProperties() { | |||
BeginContents(); | |||
if ( DrawHeader( "Default Properties", true ) ) { | |||
EditorGUILayout.BeginVertical( GUI.skin.box ); | |||
EditorGUILayout.PropertyField( serializedObject.FindProperty( "makePersistent" ), new GUIContent( "Don't Destroy on Load" ) ); | |||
EditorGUILayout.PropertyField( serializedObject.FindProperty( "enableSpatializedAudio" ), new GUIContent( "Enable Spatialized Audio" ) ); | |||
EditorGUILayout.PropertyField( serializedObject.FindProperty( "enableSpatializedFastOverride" ), new GUIContent( "Force Disable Reflections" ) ); | |||
EditorGUILayout.PropertyField( serializedObject.FindProperty( "audioMixer" ), new GUIContent( "Master Audio Mixer" ) ); | |||
EditorGUILayout.PropertyField( serializedObject.FindProperty( "defaultMixerGroup" ), new GUIContent( "Pooled Emitter Mixer Group" ) ); | |||
EditorGUILayout.PropertyField( serializedObject.FindProperty( "reservedMixerGroup" ), new GUIContent( "Reserved Emitter Mixer Group" ) ); | |||
EditorGUILayout.PropertyField( serializedObject.FindProperty( "voiceChatMixerGroup" ), new GUIContent( "Voice Chat Mixer Group" ) ); | |||
EditorGUILayout.PropertyField( serializedObject.FindProperty( "verboseLogging" ), new GUIContent( "Verbose Logging" ) ); | |||
EditorGUILayout.PropertyField( serializedObject.FindProperty( "maxSoundEmitters" ), new GUIContent( "Max Sound Emitters" ) ); | |||
EditorGUILayout.PropertyField( serializedObject.FindProperty( "volumeSoundFX" ), new GUIContent( "Default Volume" ) ); | |||
EditorGUILayout.PropertyField( serializedObject.FindProperty( "soundFxFadeSecs" ), new GUIContent( "Sound FX Fade Secs" ) ); | |||
EditorGUILayout.PropertyField( serializedObject.FindProperty( "audioMinFallOffDistance" ), new GUIContent( "Minimum Falloff Distance" ) ); | |||
EditorGUILayout.PropertyField( serializedObject.FindProperty( "audioMaxFallOffDistance" ), new GUIContent( "Maximum Falloff Distance" ) ); | |||
EditorGUILayout.EndVertical(); | |||
serializedObject.ApplyModifiedProperties(); | |||
} | |||
EndContents(); | |||
} | |||
/* | |||
----------------------- | |||
DrawSoundGroupProperties() | |||
----------------------- | |||
*/ | |||
void DrawSoundGroupProperties() { | |||
if ( selectedGroup == -1 ) { | |||
return; | |||
} | |||
SerializedProperty soundGroupsArray = serializedObject.FindProperty( "soundGroupings" ); | |||
if ( selectedGroup >= soundGroupsArray.arraySize ) { | |||
return; | |||
} | |||
SerializedProperty soundGroup = soundGroupsArray.GetArrayElementAtIndex( selectedGroup ); | |||
string soundGroupName = soundGroup.FindPropertyRelative( "name" ).stringValue; | |||
if ( DrawHeader( string.Format( "{0} Properties", soundGroupName ), true ) ) { | |||
EditorGUILayout.BeginVertical( GUI.skin.box ); | |||
EditorGUILayout.PropertyField( soundGroup.FindPropertyRelative( "mixerGroup" ), new GUIContent( "Override Mixer Group", "Leave empty to use the Audio Manager's default mixer group" ) ); | |||
if ( !Application.isPlaying ) { | |||
EditorGUILayout.PropertyField( soundGroup.FindPropertyRelative( "maxPlayingSounds" ), new GUIContent( "Max Playing Sounds Limit", "Max playing sounds for this sound group, 0 = no limit" ) ); | |||
} else { | |||
EditorGUILayout.BeginHorizontal(); | |||
EditorGUILayout.PropertyField( soundGroup.FindPropertyRelative( "maxPlayingSounds" ), new GUIContent( "Max Playing Sounds Limit", "Max playing sounds for this sound group, 0 = no limit" ) ); | |||
// cast to the actual object | |||
int playingSounds = soundGroup.FindPropertyRelative( "playingSoundCount" ).intValue; | |||
EditorGUILayout.LabelField( string.Format( "Playing: {0}", playingSounds ), GUILayout.Width( 80.0f ) ); | |||
EditorGUILayout.EndHorizontal(); | |||
} | |||
EditorGUILayout.PropertyField( soundGroup.FindPropertyRelative( "preloadAudio" ), new GUIContent( "Preload Audio Clips", "Default = No special preloading, Preload = Audio clips are set to 'Preload', Manual Preload = Audio clips are set to not 'Preload'" ) ); | |||
EditorGUILayout.PropertyField( soundGroup.FindPropertyRelative( "volumeOverride" ), new GUIContent( "Volume Override", "All sounds played in this group will have volume scaled by this amount" ) ); | |||
if ( soundGroup.FindPropertyRelative( "volumeOverride" ).floatValue == 0.0f ) { | |||
EditorGUILayout.HelpBox( "With a volumeOverride of 0.0, these sounds will not play!", MessageType.Warning ); | |||
} | |||
EditorGUILayout.EndVertical(); | |||
serializedObject.ApplyModifiedProperties(); | |||
} | |||
} | |||
/* | |||
----------------------- | |||
DrawCategories() | |||
----------------------- | |||
*/ | |||
void DrawCategories( Event e ) { | |||
// do any housework before we start drawing | |||
if ( moveQueued ) { | |||
// make a temp copy | |||
List<SoundFX> origSoundList = new List<SoundFX>( audioManager.soundGroupings[origGroup].soundList ); | |||
SoundFX temp = origSoundList[origIndex]; | |||
List<SoundFX> moveToSoundList = new List<SoundFX>( audioManager.soundGroupings[moveToGroup].soundList ); | |||
// add it to the move to group | |||
moveToSoundList.Add( temp ); | |||
audioManager.soundGroupings[moveToGroup].soundList = moveToSoundList.ToArray(); | |||
// and finally, remove it from the original group | |||
origSoundList.RemoveAt( origIndex ); | |||
audioManager.soundGroupings[origGroup].soundList = origSoundList.ToArray(); | |||
Debug.Log( "> Moved '" + temp.name + "' from " + "'" + audioManager.soundGroupings[origGroup].name + "' to '" + audioManager.soundGroupings[moveToGroup].name ); | |||
MarkDirty(); | |||
moveQueued = false; | |||
} | |||
// switch to the next group | |||
if ( nextGroup > -1 ) { | |||
selectedGroup = nextGroup; | |||
nextGroup = -1; | |||
} | |||
// add a sound | |||
if ( addSound ) { | |||
List<SoundFX> soundList = new List<SoundFX>( audioManager.soundGroupings[selectedGroup].soundList ); | |||
SoundFX soundFX = new SoundFX(); | |||
soundFX.name = audioManager.soundGroupings[selectedGroup].name.ToLower() + "_new_unnamed_sound_fx"; | |||
soundList.Add( soundFX ); | |||
audioManager.soundGroupings[selectedGroup].soundList = soundList.ToArray(); | |||
MarkDirty(); | |||
addSound = false; | |||
} | |||
// sort the sounds | |||
if ( sortSounds ) { | |||
List<SoundFX> soundList = new List<SoundFX>( audioManager.soundGroupings[selectedGroup].soundList ); | |||
soundList.Sort( delegate ( SoundFX sfx1, SoundFX sfx2 ) { return string.Compare( sfx1.name, sfx2.name ); } ); | |||
audioManager.soundGroupings[selectedGroup].soundList = soundList.ToArray(); | |||
MarkDirty(); | |||
sortSounds = false; | |||
} | |||
// delete a sound | |||
if ( deleteSoundIdx > -1 ) { | |||
List<SoundFX> soundList = new List<SoundFX>( audioManager.soundGroupings[selectedGroup].soundList ); | |||
soundList.RemoveAt( deleteSoundIdx ); | |||
audioManager.soundGroupings[selectedGroup].soundList = soundList.ToArray(); | |||
MarkDirty(); | |||
deleteSoundIdx = -1; | |||
} | |||
// duplicate a sound | |||
if ( dupeSoundIdx > -1 ) { | |||
List<SoundFX> soundList = new List<SoundFX>( audioManager.soundGroupings[selectedGroup].soundList ); | |||
SoundFX origSoundFX = soundList[dupeSoundIdx]; | |||
// clone this soundFX | |||
string json = JsonUtility.ToJson( origSoundFX ); | |||
SoundFX soundFX = JsonUtility.FromJson<SoundFX>( json ); | |||
soundFX.name += "_duplicated"; | |||
soundList.Insert( dupeSoundIdx + 1, soundFX ); | |||
audioManager.soundGroupings[selectedGroup].soundList = soundList.ToArray(); | |||
MarkDirty(); | |||
dupeSoundIdx = -1; | |||
} | |||
if ( e.type == EventType.Repaint ) { | |||
groups.Clear(); | |||
} | |||
GUILayout.Space( 6f ); | |||
Color defaultColor = GUI.contentColor; | |||
BeginContents(); | |||
if ( DrawHeader( "Sound FX Groups", true ) ) { | |||
EditorGUILayout.BeginVertical( GUI.skin.box ); | |||
soundGroups.Clear(); | |||
for ( int i = 0; i < audioManager.soundGroupings.Length; i++ ) { | |||
soundGroups.Add( audioManager.soundGroupings[i] ); | |||
} | |||
for ( int i = 0; i < soundGroups.size; i++ ) { | |||
EditorGUILayout.BeginHorizontal(); | |||
{ | |||
if ( i == selectedGroup ) { | |||
GUI.contentColor = ( i == editGroup ) ? Color.white : Color.yellow; | |||
} else { | |||
GUI.contentColor = defaultColor; | |||
} | |||
if ( ( e.type == EventType.KeyDown ) && ( ( e.keyCode == KeyCode.Return ) || ( e.keyCode == KeyCode.KeypadEnter ) ) ) { | |||
// toggle editing | |||
if ( editGroup >= 0 ) { | |||
editGroup = -1; | |||
} | |||
Event.current.Use(); | |||
} | |||
if ( i == editGroup ) { | |||
soundGroups[i].name = GUILayout.TextField( soundGroups[i].name, GUILayout.MinWidth( Screen.width - 80f ) ); | |||
} else { | |||
GUILayout.Label( soundGroups[i].name, ( i == selectedGroup ) ? EditorStyles.whiteLabel : EditorStyles.label, GUILayout.ExpandWidth( true ) ); | |||
} | |||
GUILayout.FlexibleSpace(); | |||
if ( GUILayout.Button( GUIContent.none, "OL Minus", GUILayout.Width(17f) ) ) { // minus button | |||
if ( EditorUtility.DisplayDialog( "Delete '" + soundGroups[i].name + "'", "Are you sure you want to delete the selected sound group?", "Continue", "Cancel" ) ) { | |||
soundGroups.RemoveAt( i ); | |||
MarkDirty(); | |||
} | |||
} | |||
} | |||
EditorGUILayout.EndHorizontal(); | |||
// build a list of items | |||
Rect lastRect = GUILayoutUtility.GetLastRect(); | |||
if ( e.type == EventType.Repaint ) { | |||
groups.Add ( new ItemRect( i, lastRect, null ) ); | |||
} | |||
if ( ( e.type == EventType.MouseDown ) && lastRect.Contains( e.mousePosition ) ) { | |||
if ( ( i != selectedGroup ) || ( e.clickCount == 2 ) ) { | |||
nextGroup = i; | |||
if ( e.clickCount == 2 ) { | |||
editGroup = i; | |||
} else if ( editGroup != nextGroup ) { | |||
editGroup = -1; | |||
} | |||
Repaint(); | |||
} | |||
} | |||
} | |||
// add the final plus button | |||
EditorGUILayout.BeginHorizontal(); | |||
GUILayout.FlexibleSpace(); | |||
if ( GUILayout.Button( GUIContent.none, "OL Plus", GUILayout.Width(17f) ) ) { // plus button | |||
soundGroups.Add( new SoundGroup( "unnamed sound group" ) ); | |||
selectedGroup = editGroup = soundGroups.size - 1; | |||
MarkDirty(); | |||
} | |||
EditorGUILayout.EndHorizontal(); | |||
EditorGUILayout.EndVertical(); | |||
// reset the color | |||
GUI.contentColor = defaultColor; | |||
// the sort and import buttons | |||
EditorGUILayout.BeginHorizontal(); | |||
GUILayout.FlexibleSpace(); | |||
if ( GUILayout.Button( "Sort", GUILayout.Width( 70f ) ) ) { | |||
soundGroups.Sort( delegate( SoundGroup sg1, SoundGroup sg2 ) { return string.Compare( sg1.name, sg2.name ); } ); | |||
MarkDirty(); | |||
} | |||
EditorGUILayout.EndHorizontal(); | |||
// draw a rect around the selected item | |||
if ( ( selectedGroup >= 0 ) && ( selectedGroup < groups.size ) ) { | |||
EditorGUI.DrawRect( groups[selectedGroup].rect, new Color( 1f, 1f, 1f, 0.06f ) ); | |||
} | |||
// finally move the sound groups back into the audio manager | |||
if ( soundGroups.size > 0 ) { | |||
audioManager.soundGroupings = soundGroups.ToArray(); | |||
} | |||
// calculate the drop area rect | |||
if ( ( e.type == EventType.Repaint ) && ( groups.size > 0 ) ) { | |||
dropArea.x = groups[0].rect.x; | |||
dropArea.y = groups[0].rect.y; | |||
dropArea.width = groups[0].rect.width; | |||
dropArea.height = ( groups[groups.size-1].rect.y - groups[0].rect.y ) + groups[groups.size-1].rect.height; | |||
} | |||
} | |||
// draw the sound group properties now | |||
DrawSoundGroupProperties(); | |||
EndContents(); | |||
EditorGUILayout.HelpBox("Create and delete sound groups by clicking + and - respectively. Double click to rename sound groups. Drag and drop sounds from below to the groups above to move them.", MessageType.Info); | |||
} | |||
public class CustomDragData{ | |||
public int originalGroupIndex; | |||
public int originalIndex; | |||
public SerializedProperty originalProperty; | |||
} | |||
public class ItemRect { | |||
public ItemRect( int index, Rect rect, SerializedProperty prop ) { | |||
this.index = index; | |||
this.rect = rect; | |||
this.prop = prop; | |||
} | |||
public int index; | |||
public Rect rect; | |||
public SerializedProperty prop; | |||
} | |||
private FastList<ItemRect> items = new FastList<ItemRect>(); | |||
/* | |||
----------------------- | |||
CreateStyles() | |||
----------------------- | |||
*/ | |||
void CreateStyles() { | |||
if ( customDividerStyle == null ) { | |||
customDividerStyle = new GUIStyle( EditorStyles.label ); | |||
customDividerStyle.normal.background = MakeTex( 4, 4, new Color( 0.5f, 0.5f, 0.5f, 0.25f ) ); | |||
customDividerStyle.margin.right -= 16; | |||
} | |||
} | |||
/* | |||
----------------------- | |||
MakeTex() | |||
----------------------- | |||
*/ | |||
private Texture2D MakeTex( int width, int height, Color col ) { | |||
Color[] pix = new Color[width*height]; | |||
for ( int i = 0; i < pix.Length; i++ ) | |||
pix[i] = col; | |||
Texture2D result = new Texture2D(width, height); | |||
result.SetPixels( pix ); | |||
result.Apply(); | |||
return result; | |||
} | |||
/* | |||
----------------------- | |||
DrawSoundEffects() | |||
----------------------- | |||
*/ | |||
void DrawSoundEffects( Event e ) { | |||
if ( ( selectedGroup < 0 ) || ( audioManager.soundGroupings.Length == 0 ) || ( selectedGroup >= audioManager.soundGroupings.Length ) ) { | |||
return; | |||
} | |||
if ( e.type == EventType.Repaint ) { | |||
items.Clear(); | |||
} else { | |||
CheckStartDrag( e ); | |||
} | |||
BeginContents(); | |||
if ( DrawHeader( "Sound Effects", true ) ) { | |||
GUILayout.Space(3f); | |||
GUILayout.BeginVertical( GUI.skin.box ); | |||
SerializedProperty soundGroupsArray = serializedObject.FindProperty( "soundGroupings" ); | |||
SerializedProperty soundGroup = soundGroupsArray.GetArrayElementAtIndex( selectedGroup ); | |||
SerializedProperty soundList = soundGroup.FindPropertyRelative( "soundList" ); | |||
CreateStyles(); | |||
Rect prevRect = new Rect(); | |||
if ( soundList.arraySize > 0 ) { | |||
// show all the sounds | |||
for ( int i = 0; i < soundList.arraySize; i++ ) { | |||
EditorGUI.indentLevel = 1; | |||
SerializedProperty soundFX = soundList.GetArrayElementAtIndex( i ); | |||
SerializedProperty visToggle = soundFX.FindPropertyRelative( "visibilityToggle" ); | |||
EditorGUILayout.BeginHorizontal( customDividerStyle ); | |||
{ | |||
string soundFXName = soundFX.FindPropertyRelative( "name" ).stringValue; | |||
// save the visibility state | |||
visToggle.boolValue = EditorGUILayout.Foldout( visToggle.boolValue, soundFXName ); | |||
// play button | |||
if ( GUILayout.Button( "\u25BA", GUILayout.Width( 17f ), GUILayout.Height( 16f ) ) ) { | |||
if ( AudioManager.IsSoundPlaying( soundFXName ) ) { | |||
AudioManager.StopSound( soundFXName ); | |||
} else { | |||
AudioManager.PlaySound( soundFXName ); | |||
} | |||
} | |||
} | |||
EditorGUILayout.EndHorizontal(); | |||
if ( visToggle.boolValue ) { | |||
EditorGUILayout.PropertyField( soundFX, true ); | |||
EditorGUILayout.BeginHorizontal(); | |||
GUILayout.FlexibleSpace(); | |||
if ( GUILayout.Button( "Delete FX", GUILayout.Width( Screen.width / 3.0f ) ) ) { | |||
if ( EditorUtility.DisplayDialog( "Delete " + soundFX.displayName, "Are you sure?", "Yes", "No!" ) ) { | |||
deleteSoundIdx = i; | |||
} | |||
} | |||
if ( GUILayout.Button( "Duplicate FX", GUILayout.Width( Screen.width / 3.0f ) ) ) { | |||
dupeSoundIdx = i; | |||
} | |||
GUILayout.FlexibleSpace(); | |||
EditorGUILayout.EndHorizontal(); | |||
GUILayout.Space( 10.0f ); | |||
} | |||
if ( e.type == EventType.Repaint ) { | |||
// GetLastRect() is now returning the last rect drawn in the property drawer, | |||
// not the rect used for the entire SoundFX | |||
Rect curRect = prevRect; | |||
curRect.y = prevRect.y + EditorGUIUtility.singleLineHeight; | |||
Rect lastRect = GUILayoutUtility.GetLastRect(); | |||
curRect.height = ( lastRect.y + lastRect.height ) - curRect.y; | |||
curRect.width = Screen.width; | |||
items.Add( new ItemRect( i, curRect, soundFX ) ); | |||
} | |||
prevRect = GUILayoutUtility.GetLastRect(); | |||
} | |||
} else { | |||
EditorGUILayout.LabelField( " " ); | |||
} | |||
GUILayout.EndVertical(); | |||
GUILayout.Space(3f); | |||
EditorGUILayout.BeginHorizontal(); | |||
GUILayout.FlexibleSpace(); | |||
if ( GUILayout.Button( "Add FX", GUILayout.Width( 70f ) ) ) { | |||
//soundList.InsertArrayElementAtIndex( soundList.arraySize ); | |||
//MarkDirty(); | |||
addSound = true; | |||
} | |||
if ( GUILayout.Button( "Sort", GUILayout.Width( 70f ) ) ) { | |||
sortSounds = true; | |||
} | |||
EditorGUILayout.EndHorizontal(); | |||
} | |||
EndContents(); | |||
UpdateDrag( e ); | |||
} | |||
/* | |||
----------------------- | |||
CheckStartDrag() | |||
----------------------- | |||
*/ | |||
void CheckStartDrag( Event e ) { | |||
if ( ( e.type == EventType.MouseDrag ) && ( e.button == 0 ) ) { | |||
for ( int i = 0; i < items.size; i++ ) { | |||
if ( items[i].rect.Contains( e.mousePosition ) ) { | |||
DragAndDrop.PrepareStartDrag();// reset data | |||
CustomDragData dragData = new CustomDragData(); | |||
dragData.originalGroupIndex = selectedGroup; | |||
dragData.originalIndex = items[i].index; | |||
dragData.originalProperty = items[i].prop; | |||
DragAndDrop.SetGenericData( dragDropIdentifier, dragData ); | |||
DragAndDrop.objectReferences = new Object[0]; | |||
DragAndDrop.StartDrag( dragData.originalProperty.FindPropertyRelative( "name" ).stringValue ); | |||
e.Use(); | |||
} | |||
} | |||
} | |||
} | |||
/* | |||
----------------------- | |||
FindGroupIndex() | |||
----------------------- | |||
*/ | |||
int FindGroupIndex( Event e ) { | |||
for ( int i = 0; i < groups.size; i++ ) { | |||
if ( groups[i].rect.Contains( e.mousePosition ) ) { | |||
return i; | |||
} | |||
} | |||
return -1; | |||
} | |||
/* | |||
----------------------- | |||
UpdateDrag() | |||
----------------------- | |||
*/ | |||
void UpdateDrag( Event e ) { | |||
CustomDragData dragData = DragAndDrop.GetGenericData( dragDropIdentifier ) as CustomDragData; | |||
if ( dragData == null ) { | |||
return; | |||
} | |||
int groupIndex = FindGroupIndex( e ); | |||
switch ( e.type ) { | |||
case EventType.DragUpdated: | |||
if ( ( groupIndex >= 0 ) && ( groupIndex != selectedGroup ) ) { | |||
DragAndDrop.visualMode = DragAndDropVisualMode.Move; | |||
} else { | |||
DragAndDrop.visualMode = DragAndDropVisualMode.Rejected; | |||
} | |||
e.Use(); | |||
break; | |||
case EventType.Repaint: | |||
if ( ( DragAndDrop.visualMode == DragAndDropVisualMode.None ) || | |||
( DragAndDrop.visualMode == DragAndDropVisualMode.Rejected ) ) { | |||
break; | |||
} | |||
if ( groupIndex >= 0 && groupIndex < groups.size ) { | |||
EditorGUI.DrawRect( groups[groupIndex].rect, new Color( 0f, 1f, 0f, 0.1f ) ); | |||
} | |||
break; | |||
case EventType.DragPerform: | |||
DragAndDrop.AcceptDrag(); | |||
// queue the sound FX move | |||
QueueSoundFXMove( dragData.originalGroupIndex, dragData.originalIndex, groupIndex ); | |||
e.Use(); | |||
break; | |||
case EventType.MouseUp: | |||
// in case MouseDrag never occurred: | |||
DragAndDrop.PrepareStartDrag(); | |||
break; | |||
} | |||
} | |||
/* | |||
----------------------- | |||
QueueSoundFXMove() | |||
----------------------- | |||
*/ | |||
void QueueSoundFXMove( int origGroupIndex, int origSoundIndex, int newGroupIndex ) { | |||
moveQueued = true; | |||
origGroup = origGroupIndex; | |||
origIndex = origSoundIndex; | |||
moveToGroup = newGroupIndex; | |||
} | |||
/* | |||
----------------------- | |||
DrawHeader() | |||
----------------------- | |||
*/ | |||
static public bool DrawHeader (string text) { return DrawHeader(text, text, false); } | |||
static public bool DrawHeader (string text, string key) { return DrawHeader(text, key, false); } | |||
static public bool DrawHeader (string text, bool forceOn) { return DrawHeader(text, text, forceOn); } | |||
static public bool DrawHeader( string text, string key, bool forceOn ) { | |||
bool state = EditorPrefs.GetBool(key, true); | |||
GUILayout.Space(3f); | |||
if (!forceOn && !state) GUI.backgroundColor = new Color(0.8f, 0.8f, 0.8f); | |||
GUILayout.BeginHorizontal(); | |||
GUILayout.Space(3f); | |||
GUI.changed = false; | |||
text = "<b><size=11>" + text + "</size></b>"; | |||
if (state) text = "\u25BC " + text; | |||
else text = "\u25B6 " + text; | |||
if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) state = !state; | |||
if (GUI.changed) EditorPrefs.SetBool(key, state); | |||
GUILayout.Space(2f); | |||
GUILayout.EndHorizontal(); | |||
GUI.backgroundColor = Color.white; | |||
if (!forceOn && !state) GUILayout.Space(3f); | |||
return state; | |||
} | |||
/* | |||
----------------------- | |||
BeginContents() | |||
----------------------- | |||
*/ | |||
static public void BeginContents() { | |||
GUILayout.BeginHorizontal(); | |||
GUILayout.Space(4f); | |||
EditorGUILayout.BeginHorizontal(GUILayout.MinHeight(10f)); | |||
GUILayout.BeginVertical(); | |||
GUILayout.Space(2f); | |||
} | |||
/* | |||
----------------------- | |||
EndContents() | |||
----------------------- | |||
*/ | |||
static public void EndContents() { | |||
GUILayout.Space(3f); | |||
GUILayout.EndVertical(); | |||
EditorGUILayout.EndHorizontal(); | |||
GUILayout.Space(3f); | |||
GUILayout.EndHorizontal(); | |||
GUILayout.Space(3f); | |||
} | |||
} | |||
} // namespace OVR |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 9f04a80514947486d9793cab0005447f | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: |
@ -0,0 +1,70 @@ | |||
using UnityEditor; | |||
using UnityEngine; | |||
namespace OVR | |||
{ | |||
/* | |||
----------------------- | |||
MinMaxPropertyDrawer | |||
----------------------- | |||
*/ | |||
[CustomPropertyDrawer (typeof (MinMaxAttribute))] | |||
public class MinMaxPropertyDrawer : PropertyDrawer { | |||
// Provide easy access to the MinMaxAttribute for reading information from it. | |||
MinMaxAttribute minMax { get { return ((MinMaxAttribute)attribute); } } | |||
/* | |||
----------------------- | |||
GetPropertyHeight() | |||
----------------------- | |||
*/ | |||
public override float GetPropertyHeight( SerializedProperty prop, GUIContent label ) { | |||
return base.GetPropertyHeight( prop, label ) * 2f; | |||
} | |||
/* | |||
----------------------- | |||
OnGUI() | |||
----------------------- | |||
*/ | |||
public override void OnGUI( Rect position, SerializedProperty property, GUIContent label ) { | |||
Rect sliderPosition = EditorGUI.PrefixLabel( position, label ); | |||
SerializedProperty min = property.FindPropertyRelative( "x" ); | |||
SerializedProperty max = property.FindPropertyRelative( "y" ); | |||
// draw the range and the reset button first so that the slider doesn't grab all the input | |||
Rect rangePosition = sliderPosition; | |||
rangePosition.y += rangePosition.height * 0.5f; | |||
rangePosition.height *= 0.5f; | |||
Rect contentPosition = rangePosition; | |||
EditorGUI.indentLevel = 0; | |||
EditorGUIUtility.labelWidth = 30f; | |||
contentPosition.width *= 0.3f; | |||
EditorGUI.PropertyField(contentPosition, min, new GUIContent( "Min" ) ); | |||
contentPosition.x += contentPosition.width + 20f; | |||
EditorGUI.PropertyField( contentPosition, max, new GUIContent( "Max" ) ); | |||
contentPosition.x += contentPosition.width + 20f; | |||
contentPosition.width = 50.0f; | |||
if ( GUI.Button( contentPosition, "Reset" ) ) { | |||
min.floatValue = minMax.minDefaultVal; | |||
max.floatValue = minMax.maxDefaultVal; | |||
} | |||
float minValue = min.floatValue; | |||
float maxValue = max.floatValue; | |||
#if UNITY_2017_1_OR_NEWER | |||
EditorGUI.MinMaxSlider( sliderPosition, GUIContent.none, ref minValue, ref maxValue, minMax.min, minMax.max ); | |||
#else | |||
EditorGUI.MinMaxSlider( GUIContent.none, sliderPosition, ref minValue, ref maxValue, minMax.min, minMax.max ); | |||
#endif | |||
// round to readable values | |||
min.floatValue = Mathf.Round( minValue / 0.01f ) * 0.01f; | |||
max.floatValue = Mathf.Round( maxValue / 0.01f ) * 0.01f; | |||
} | |||
} | |||
} // namespace OVR |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 225aed143a64c4a6a93f3a07656ac5cd | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: |
@ -0,0 +1,50 @@ | |||
using UnityEditor; | |||
using UnityEngine; | |||
namespace OVR | |||
{ | |||
/* | |||
----------------------- | |||
MixerSnapshotPropertyDrawer | |||
----------------------- | |||
*/ | |||
[CustomPropertyDrawer( typeof( MixerSnapshot ) )] | |||
public class MixerSnapshotPropertyDrawer : PropertyDrawer { | |||
// Draw the property inside the given rect | |||
public override void OnGUI( Rect position, SerializedProperty property, GUIContent label ) { | |||
// Using BeginProperty / EndProperty on the parent property means that | |||
// prefab override logic works on the entire property. | |||
EditorGUI.BeginProperty( position, label, property ); | |||
// Draw label | |||
position = EditorGUI.PrefixLabel( position, GUIUtility.GetControlID( FocusType.Passive ), label ); | |||
// Don't make child fields be indented | |||
var indent = EditorGUI.indentLevel; | |||
EditorGUI.indentLevel = 0; | |||
EditorGUIUtility.labelWidth = 65; | |||
float width = ( position.width - 15.0f ) / 2.0f; | |||
// Calculate rects | |||
var srcRect = new Rect( position.x, position.y, width + 20, position.height ); position.x += width + 25.0f; | |||
var destRect = new Rect( position.x, position.y, width - 60, position.height ); position.x += width - 60.0f; | |||
var secsRect = new Rect( position.x, position.y, 40, position.height ); | |||
// Draw fields - pass GUIContent.none to each so they are drawn without labels | |||
EditorGUI.PropertyField( srcRect, property.FindPropertyRelative( "snapshot" ), GUIContent.none ); | |||
EditorGUI.PropertyField( destRect, property.FindPropertyRelative( "transitionTime" ), new GUIContent( "Transition" ) ); | |||
EditorGUI.LabelField( secsRect, new GUIContent( "sec(s)" ) ); | |||
// Set indent back to what it was | |||
EditorGUI.indentLevel = indent; | |||
EditorGUI.EndProperty(); | |||
} | |||
} | |||
} // namespace OVR |
@ -0,0 +1,12 @@ | |||
fileFormatVersion: 2 | |||
guid: 82a91f30f2305c14dbfd2cc3c289dc59 | |||
timeCreated: 1472247018 | |||
licenseType: Pro | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,66 @@ | |||
using UnityEngine; | |||
using UnityEditor; | |||
using System.Collections; | |||
namespace OVR | |||
{ | |||
/* | |||
----------------------- | |||
OSPPropsPropertyDrawer | |||
----------------------- | |||
*/ | |||
[CustomPropertyDrawer(typeof(OSPProps))] | |||
public class OSPPropsPropertyDrawer : PropertyDrawer { | |||
static float lineHeight = EditorGUIUtility.singleLineHeight + 2.0f; | |||
static float indent = 32.0f; | |||
// TODO - some day just enumerate these | |||
static string[] props = new string[] { "useFastOverride", "gain", "enableInvSquare", "volumetric" , "invSquareFalloff" }; | |||
static string[] names = new string[] { "Reflections Enabled", "Gain", "Enable Oculus Atten.", "Volumetric", "Range" }; | |||
static int[] lines = new int[] { 1, 1, 1, 1, 2, 2 }; | |||
/* | |||
----------------------- | |||
OnGUI() | |||
----------------------- | |||
*/ | |||
public override void OnGUI( Rect position, SerializedProperty prop, GUIContent label ) { | |||
SerializedProperty playSpatializedProp = prop.FindPropertyRelative("enableSpatialization"); | |||
position.height = lineHeight; | |||
EditorGUI.PropertyField( position, playSpatializedProp ); | |||
if ( playSpatializedProp.boolValue ) { | |||
position.y += lineHeight + 4.0f; | |||
Rect posLine = position; | |||
posLine.x += indent; | |||
posLine.width -= indent; | |||
posLine.height = 1f; | |||
GUI.Box( posLine, "" ); | |||
position.y -= 10.0f; | |||
for ( int i = 0; i < props.Length; i++ ) { | |||
position.y += lineHeight; | |||
position.height = ( lineHeight * lines[i] ); | |||
SerializedProperty sibling = prop.FindPropertyRelative( props[i] ); | |||
EditorGUI.PropertyField( position, sibling, new GUIContent( names[i] ) ); | |||
} | |||
} | |||
} | |||
/* | |||
----------------------- | |||
GetPropertyHeight() | |||
----------------------- | |||
*/ | |||
public override float GetPropertyHeight (SerializedProperty prop, GUIContent label) { | |||
SerializedProperty playSpatializedProp = prop.FindPropertyRelative("enableSpatialization"); | |||
if ( !playSpatializedProp.boolValue ) { | |||
return base.GetPropertyHeight( prop, label ); | |||
} else { | |||
return base.GetPropertyHeight( prop, label ) + ( lineHeight * ( props.Length + 1 ) ) + 16.0f; | |||
} | |||
} | |||
} | |||
} // namespace OVR |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 9fc79251b168140d68851f1e8c283514 | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: |
@ -0,0 +1,67 @@ | |||
using UnityEngine; | |||
using UnityEditor; | |||
using System.Collections; | |||
namespace OVR | |||
{ | |||
/* | |||
----------------------- | |||
SoundFXPropertyDrawer | |||
----------------------- | |||
*/ | |||
[CustomPropertyDrawer(typeof(SoundFX))] | |||
public class SoundFXPropertyDrawer : PropertyDrawer { | |||
static float lineHeight = EditorGUIUtility.singleLineHeight + 2.0f; | |||
static string[] props = new string[] { "name", "playback", "volume", "pitchVariance", "falloffDistance", "falloffCurve", "reverbZoneMix", "spread", "pctChanceToPlay", "priority", "delay", "looping", "ospProps", "soundClips" }; | |||
/* | |||
----------------------- | |||
OnGUI() | |||
----------------------- | |||
*/ | |||
public override void OnGUI( Rect position, SerializedProperty prop, GUIContent label ) { | |||
EditorGUILayout.BeginVertical(); | |||
for ( int i = 0; i < props.Length; i++ ) { | |||
EditorGUI.indentLevel = 2; | |||
SerializedProperty property = prop.FindPropertyRelative( props[i] ); | |||
if ( props[i] == "reverbZoneMix" ) { | |||
EditorGUILayout.BeginHorizontal(); | |||
SerializedProperty reverbCurve = prop.FindPropertyRelative( "reverbZoneMix" ); | |||
EditorGUILayout.PropertyField( reverbCurve, true, GUILayout.Width( Screen.width - 130.0f ) ); | |||
if ( GUILayout.Button( "Reset", GUILayout.Width( 50.0f ) ) ) { | |||
reverbCurve.animationCurveValue = new AnimationCurve( new Keyframe[2] { new Keyframe( 0f, 1.0f ), new Keyframe( 1f, 1f ) } ); | |||
} | |||
EditorGUILayout.EndHorizontal(); | |||
} else { | |||
EditorGUILayout.PropertyField( property, true, GUILayout.Width( Screen.width - 80.0f ) ); | |||
position.y += lineHeight + 4.0f; | |||
if ( props[i] == "falloffCurve" ) { | |||
if ( property.enumValueIndex == (int)AudioRolloffMode.Custom ) { | |||
EditorGUILayout.PropertyField( prop.FindPropertyRelative( "volumeFalloffCurve" ), true, GUILayout.Width( Screen.width - 80.0f ) ); | |||
position.y += lineHeight + 4.0f; | |||
} | |||
} | |||
} | |||
} | |||
EditorGUILayout.EndVertical(); | |||
GUILayout.Space( 5.0f ); | |||
} | |||
/* | |||
----------------------- | |||
GetPropertyHeight() | |||
----------------------- | |||
*/ | |||
public override float GetPropertyHeight (SerializedProperty prop, GUIContent label) { | |||
return base.GetPropertyHeight( prop, label ); | |||
} | |||
} | |||
} // namespace OVR |
@ -0,0 +1,12 @@ | |||
fileFormatVersion: 2 | |||
guid: e791ce392b6937f47b1f7c90c6b402db | |||
timeCreated: 1468857307 | |||
licenseType: Pro | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,62 @@ | |||
using UnityEngine; | |||
using UnityEditor; | |||
using System.Collections; | |||
namespace OVR | |||
{ | |||
/* | |||
----------------------- | |||
SoundFXRefPropertyDrawer | |||
----------------------- | |||
*/ | |||
[CustomPropertyDrawer(typeof(SoundFXRef))] | |||
public class SoundFXRefPropertyDrawer : PropertyDrawer { | |||
static private GUIStyle disabledStyle = null; | |||
/* | |||
----------------------- | |||
OnGUI() | |||
----------------------- | |||
*/ | |||
public override void OnGUI( Rect position, SerializedProperty prop, GUIContent label ) { | |||
int idx = 0; | |||
Rect buttonPosition = position; | |||
buttonPosition.x = position.x + position.width - 40f; | |||
buttonPosition.width = 20f; | |||
position.width = buttonPosition.x - position.x - 2f; | |||
SerializedProperty nameProp = prop.FindPropertyRelative( "soundFXName" ); | |||
if ( AudioManager.GetGameObject() == null ) { | |||
if ( disabledStyle == null ) { | |||
disabledStyle = new GUIStyle(); | |||
disabledStyle.normal.textColor = Color.gray; | |||
} | |||
EditorGUI.LabelField(position, label.text, nameProp.stringValue, disabledStyle ); | |||
} | |||
else { | |||
string[] soundFXNames = AudioManager.GetSoundFXNames( nameProp.stringValue, out idx ); | |||
idx = EditorGUI.Popup( position, label.text, idx, soundFXNames ); | |||
nameProp.stringValue = AudioManager.NameMinusGroup( soundFXNames[idx] ); | |||
// play button | |||
if ( GUI.Button( buttonPosition, "\u25BA" ) ) { | |||
if ( AudioManager.IsSoundPlaying( nameProp.stringValue ) ) { | |||
AudioManager.StopSound( nameProp.stringValue ); | |||
} else { | |||
AudioManager.PlaySound( nameProp.stringValue ); | |||
} | |||
} | |||
buttonPosition.x += 22.0f; | |||
// select audio manager | |||
if ( GUI.Button( buttonPosition, "\u2630" ) ) { | |||
Selection.activeGameObject = AudioManager.GetGameObject(); | |||
} | |||
} | |||
} | |||
} | |||
} // namespace OVR |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 6204bcaba636340b48858c9f10ab9016 | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: |
@ -0,0 +1,26 @@ | |||
using UnityEngine; | |||
namespace OVR | |||
{ | |||
/* | |||
----------------------- | |||
MinMaxAttribute | |||
----------------------- | |||
*/ | |||
public class MinMaxAttribute : PropertyAttribute { | |||
public float minDefaultVal = 1.0f; | |||
public float maxDefaultVal = 1.0f; | |||
public float min = 0.0f; | |||
public float max = 1.0f; | |||
public MinMaxAttribute( float minDefaultVal, float maxDefaultVal, float min, float max ) { | |||
this.minDefaultVal = minDefaultVal; | |||
this.maxDefaultVal = maxDefaultVal; | |||
this.min = min; | |||
this.max = max; | |||
} | |||
} | |||
} // namespace OVR |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 15126f023faf44286a08bdb5bdbdb6e7 | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: |
@ -0,0 +1,433 @@ | |||
using UnityEngine; | |||
using UnityEngine.Audio; | |||
using System.Collections; | |||
namespace OVR | |||
{ | |||
/* | |||
----------------------- | |||
SoundEmitter() | |||
----------------------- | |||
*/ | |||
public class SoundEmitter : MonoBehaviour { | |||
public enum FadeState { | |||
Null, | |||
FadingIn, | |||
FadingOut, | |||
Ducking, | |||
} | |||
// OPTIMIZE | |||
public float volume { get { return audioSource.volume; } set { audioSource.volume = value; } } | |||
public float pitch { get { return audioSource.pitch; } set { audioSource.pitch = value; } } | |||
public AudioClip clip { get { return audioSource.clip; } set { audioSource.clip = value; } } | |||
public float time { get { return audioSource.time; } set { audioSource.time = value; } } | |||
public float length { get { return ( audioSource.clip != null ) ? audioSource.clip.length : 0.0f; } } | |||
public bool loop { get { return audioSource.loop; } set { audioSource.loop = value; } } | |||
public bool mute { get { return audioSource.mute; } set { audioSource.mute = value; } } | |||
public AudioVelocityUpdateMode velocityUpdateMode { get { return audioSource.velocityUpdateMode; } set { audioSource.velocityUpdateMode = value; } } | |||
public bool isPlaying { get { return audioSource.isPlaying; } } | |||
public EmitterChannel channel = EmitterChannel.Reserved; | |||
public bool disableSpatialization = false; | |||
private FadeState state = FadeState.Null; | |||
[System.NonSerialized] | |||
[HideInInspector] | |||
public AudioSource audioSource = null; | |||
[System.NonSerialized] | |||
[HideInInspector] | |||
public SoundPriority priority = SoundPriority.Default; | |||
[System.NonSerialized] | |||
[HideInInspector] | |||
public ONSPAudioSource osp = null; | |||
[System.NonSerialized] | |||
[HideInInspector] | |||
public float endPlayTime = 0.0f; | |||
private Transform lastParentTransform = null; | |||
[System.NonSerialized] | |||
[HideInInspector] | |||
public float defaultVolume = 1.0f; | |||
[System.NonSerialized] | |||
[HideInInspector] | |||
public Transform defaultParent = null; | |||
[System.NonSerialized] | |||
[HideInInspector] | |||
public int originalIdx = -1; | |||
[System.NonSerialized] | |||
[HideInInspector] | |||
public System.Action onFinished = null; | |||
[System.NonSerialized] | |||
[HideInInspector] | |||
public System.Action<object> onFinishedObject = null; | |||
[System.NonSerialized] | |||
[HideInInspector] | |||
public object onFinishedParam; | |||
[System.NonSerialized] | |||
[HideInInspector] | |||
public SoundGroup playingSoundGroup = null; | |||
/* | |||
----------------------- | |||
Awake() | |||
----------------------- | |||
*/ | |||
void Awake() { | |||
// unity defaults to 'playOnAwake = true' | |||
audioSource = GetComponent<AudioSource>(); | |||
if ( audioSource == null ) { | |||
audioSource = gameObject.AddComponent<AudioSource>(); | |||
} | |||
// is the spatialized audio enabled? | |||
if ( AudioManager.enableSpatialization && !disableSpatialization ) { | |||
osp = GetComponent<ONSPAudioSource>(); | |||
if ( osp == null ) { | |||
osp = gameObject.AddComponent<ONSPAudioSource>(); | |||
} | |||
} | |||
audioSource.playOnAwake = false; | |||
audioSource.Stop(); | |||
} | |||
/* | |||
----------------------- | |||
SetPlayingSoundGroup() | |||
----------------------- | |||
*/ | |||
public void SetPlayingSoundGroup( SoundGroup soundGroup ) { | |||
playingSoundGroup = soundGroup; | |||
if ( soundGroup != null ) { | |||
soundGroup.IncrementPlayCount(); | |||
} | |||
} | |||
/* | |||
----------------------- | |||
SetOnFinished() | |||
----------------------- | |||
*/ | |||
public void SetOnFinished( System.Action onFinished ) { | |||
this.onFinished = onFinished; | |||
} | |||
/* | |||
----------------------- | |||
SetOnFinished() | |||
----------------------- | |||
*/ | |||
public void SetOnFinished( System.Action<object> onFinished, object obj ) { | |||
onFinishedObject = onFinished; | |||
onFinishedParam = obj; | |||
} | |||
/* | |||
----------------------- | |||
SetChannel() | |||
----------------------- | |||
*/ | |||
public void SetChannel( int _channel ) { | |||
channel = (EmitterChannel)_channel; | |||
} | |||
/* | |||
----------------------- | |||
SetDefaultParent() | |||
----------------------- | |||
*/ | |||
public void SetDefaultParent( Transform parent ) { | |||
defaultParent = parent; | |||
} | |||
/* | |||
----------------------- | |||
SetAudioMixer() | |||
----------------------- | |||
*/ | |||
public void SetAudioMixer( AudioMixerGroup _mixer ) { | |||
if ( audioSource != null ) { | |||
audioSource.outputAudioMixerGroup = _mixer; | |||
} | |||
} | |||
/* | |||
----------------------- | |||
IsPlaying() | |||
----------------------- | |||
*/ | |||
public bool IsPlaying() { | |||
if ( loop && audioSource.isPlaying ) { | |||
return true; | |||
} | |||
return endPlayTime > Time.time; | |||
} | |||
/* | |||
----------------------- | |||
Play() | |||
----------------------- | |||
*/ | |||
public void Play() { | |||
// overrides everything | |||
state = FadeState.Null; | |||
endPlayTime = Time.time + length; | |||
StopAllCoroutines(); | |||
audioSource.Play(); | |||
} | |||
/* | |||
----------------------- | |||
Pause() | |||
----------------------- | |||
*/ | |||
public void Pause() { | |||
// overrides everything | |||
state = FadeState.Null; | |||
StopAllCoroutines(); | |||
audioSource.Pause(); | |||
} | |||
/* | |||
----------------------- | |||
Stop() | |||
----------------------- | |||
*/ | |||
public void Stop() { | |||
// overrides everything | |||
state = FadeState.Null; | |||
StopAllCoroutines(); | |||
if ( audioSource != null ) { | |||
audioSource.Stop(); | |||
} | |||
if ( onFinished != null ) { | |||
onFinished(); | |||
onFinished = null; | |||
} | |||
if ( onFinishedObject != null ) { | |||
onFinishedObject( onFinishedParam ); | |||
onFinishedObject = null; | |||
} | |||
if ( playingSoundGroup != null ) { | |||
playingSoundGroup.DecrementPlayCount(); | |||
playingSoundGroup = null; | |||
} | |||
} | |||
/* | |||
----------------------- | |||
GetSampleTime() | |||
----------------------- | |||
*/ | |||
int GetSampleTime() { | |||
return audioSource.clip.samples - audioSource.timeSamples; | |||
} | |||
/* | |||
----------------------- | |||
ParentTo() | |||
----------------------- | |||
*/ | |||
public void ParentTo( Transform parent ) { | |||
if ( lastParentTransform != null ) { | |||
Debug.LogError( "[SoundEmitter] You must detach the sound emitter before parenting to another object!" ); | |||
return; | |||
} | |||
lastParentTransform = transform.parent; | |||
transform.parent = parent; | |||
} | |||
/* | |||
----------------------- | |||
DetachFromParent() | |||
----------------------- | |||
*/ | |||
public void DetachFromParent() { | |||
if ( lastParentTransform == null ) { | |||
transform.parent = defaultParent; | |||
return; | |||
} | |||
transform.parent = lastParentTransform; | |||
lastParentTransform = null; | |||
} | |||
/* | |||
----------------------- | |||
ResetParent() | |||
----------------------- | |||
*/ | |||
public void ResetParent( Transform parent ) { | |||
transform.parent = parent; | |||
lastParentTransform = null; | |||
} | |||
/* | |||
----------------------- | |||
SyncTo() | |||
----------------------- | |||
*/ | |||
public void SyncTo( SoundEmitter other, float fadeTime, float toVolume ) { | |||
StartCoroutine( DelayedSyncTo( other, fadeTime, toVolume ) ); | |||
} | |||
/* | |||
----------------------- | |||
DelayedSyncTo() | |||
have to wait until the end of frame to do proper sync'ing | |||
----------------------- | |||
*/ | |||
IEnumerator DelayedSyncTo( SoundEmitter other, float fadeTime, float toVolume ) { | |||
yield return new WaitForEndOfFrame(); | |||
//audio.timeSamples = other.GetSampleTime(); | |||
//audio.time = Mathf.Min( Mathf.Max( 0.0f, other.time - other.length ), other.time ); | |||
audioSource.time = other.time; | |||
audioSource.Play(); | |||
FadeTo( fadeTime, toVolume ); | |||
} | |||
/* | |||
----------------------- | |||
FadeTo() | |||
----------------------- | |||
*/ | |||
public void FadeTo( float fadeTime, float toVolume ) { | |||
//Log.Print( ">>> FADE TO: " + channel ); | |||
// don't override a fade out | |||
if ( state == FadeState.FadingOut ) { | |||
//Log.Print( " ....ABORTED" ); | |||
return; | |||
} | |||
state = FadeState.Ducking; | |||
StopAllCoroutines(); | |||
StartCoroutine( FadeSoundChannelTo( fadeTime, toVolume ) ); | |||
} | |||
/* | |||
----------------------- | |||
FadeIn() | |||
----------------------- | |||
*/ | |||
public void FadeIn( float fadeTime, float defaultVolume ) { | |||
//Log.Print( ">>> FADE IN: " + channel ); | |||
audioSource.volume = 0.0f; | |||
state = FadeState.FadingIn; | |||
StopAllCoroutines(); | |||
StartCoroutine( FadeSoundChannel( 0.0f, fadeTime, Fade.In, defaultVolume ) ); | |||
} | |||
/* | |||
----------------------- | |||
FadeIn() | |||
----------------------- | |||
*/ | |||
public void FadeIn( float fadeTime ) { | |||
//Log.Print( ">>> FADE IN: " + channel ); | |||
audioSource.volume = 0.0f; | |||
state = FadeState.FadingIn; | |||
StopAllCoroutines(); | |||
StartCoroutine( FadeSoundChannel( 0.0f, fadeTime, Fade.In, defaultVolume ) ); | |||
} | |||
/* | |||
----------------------- | |||
FadeOut() | |||
----------------------- | |||
*/ | |||
public void FadeOut( float fadeTime ) { | |||
//Log.Print( ">>> FADE OUT: " + channel ); | |||
if ( !audioSource.isPlaying ) { | |||
//Log.Print( " ... SKIPPING" ); | |||
return; | |||
} | |||
state = FadeState.FadingOut; | |||
StopAllCoroutines(); | |||
StartCoroutine( FadeSoundChannel( 0.0f, fadeTime, Fade.Out, audioSource.volume ) ); | |||
} | |||
/* | |||
----------------------- | |||
FadeOutDelayed() | |||
----------------------- | |||
*/ | |||
public void FadeOutDelayed( float delayedSecs, float fadeTime ) { | |||
//Log.Print( ">>> FADE OUT DELAYED: " + channel ); | |||
if ( !audioSource.isPlaying ) { | |||
//Log.Print( " ... SKIPPING" ); | |||
return; | |||
} | |||
state = FadeState.FadingOut; | |||
StopAllCoroutines(); | |||
StartCoroutine( FadeSoundChannel( delayedSecs, fadeTime, Fade.Out, audioSource.volume ) ); | |||
} | |||
/* | |||
----------------------- | |||
FadeSoundChannelTo() | |||
----------------------- | |||
*/ | |||
IEnumerator FadeSoundChannelTo( float fadeTime, float toVolume ) { | |||
float start = audioSource.volume; | |||
float end = toVolume; | |||
float startTime = Time.realtimeSinceStartup; | |||
float elapsedTime = 0.0f; | |||
while ( elapsedTime < fadeTime ) { | |||
elapsedTime = Time.realtimeSinceStartup - startTime; | |||
float t = elapsedTime / fadeTime; | |||
audioSource.volume = Mathf.Lerp( start, end, t ); | |||
yield return 0; | |||
} | |||
state = FadeState.Null; | |||
} | |||
/* | |||
----------------------- | |||
FadeSoundChannel() | |||
----------------------- | |||
*/ | |||
IEnumerator FadeSoundChannel( float delaySecs, float fadeTime, Fade fadeType, float defaultVolume ) { | |||
if ( delaySecs > 0.0f ) { | |||
yield return new WaitForSeconds( delaySecs ); | |||
} | |||
float start = ( fadeType == Fade.In ) ? 0.0f : defaultVolume; | |||
float end = ( fadeType == Fade.In ) ? defaultVolume : 0.0f; | |||
bool restartPlay = false; | |||
if ( fadeType == Fade.In ) { | |||
if ( Time.time == 0.0f ) { | |||
restartPlay = true; | |||
} | |||
audioSource.volume = 0.0f; | |||
audioSource.Play(); | |||
} | |||
float startTime = Time.realtimeSinceStartup; | |||
float elapsedTime = 0.0f; | |||
while ( elapsedTime < fadeTime ) { | |||
elapsedTime = Time.realtimeSinceStartup - startTime; | |||
float t = elapsedTime / fadeTime; | |||
audioSource.volume = Mathf.Lerp( start, end, t ); | |||
yield return 0; | |||
if ( restartPlay && ( Time.time > 0.0f ) ) { | |||
audioSource.Play(); | |||
restartPlay = false; | |||
} | |||
if ( !audioSource.isPlaying ) { | |||
break; | |||
} | |||
} | |||
if ( fadeType == Fade.Out ) { | |||
Stop(); | |||
} | |||
state = FadeState.Null; | |||
} | |||
} | |||
} // namespace OVR |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: ecd24e91b27c645fc95f6c42115c13cc | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: |
@ -0,0 +1,311 @@ | |||
using UnityEngine; | |||
using UnityEngine.Audio; | |||
namespace OVR | |||
{ | |||
public enum SoundFXNext { | |||
Random = 0, | |||
Sequential = 1, | |||
} | |||
public enum FreqHint { | |||
None = 0, | |||
Wide = 1, | |||
Narrow = 2, | |||
} | |||
public enum SoundPriority { | |||
VeryLow = -2, | |||
Low = -1, | |||
Default = 0, | |||
High = 1, | |||
VeryHigh = 2, | |||
} | |||
[System.Serializable] | |||
public class OSPProps { | |||
public OSPProps() { | |||
enableSpatialization = false; | |||
useFastOverride = false; | |||
gain = 0.0f; | |||
enableInvSquare = false; | |||
volumetric = 0.0f; | |||
invSquareFalloff = new Vector2( 1.0f, 25.0f ); | |||
} | |||
[Tooltip( "Set to true to play the sound FX spatialized with binaural HRTF, default = false")] | |||
public bool enableSpatialization = false; | |||
[Tooltip( "Play the sound FX with reflections, default = false")] | |||
public bool useFastOverride = false; | |||
[Tooltip( "Boost the gain on the spatialized sound FX, default = 0.0")] | |||
[Range( 0.0f, 24.0f )] | |||
public float gain = 0.0f; | |||
[Tooltip("Enable Inverse Square attenuation curve, default = false")] | |||
public bool enableInvSquare = false; | |||
[Tooltip("Change the sound from point source (0.0f) to a spherical volume, default = 0.0")] | |||
[Range(0.0f, 1000.0f)] | |||
public float volumetric = 0.0f; | |||
[Tooltip("Set the near and far falloff value for the OSP attenuation curve, default = 1.0")] | |||
[MinMax ( 1.0f, 25.0f, 0.0f, 250.0f )] | |||
public Vector2 invSquareFalloff = new Vector2( 1.0f, 25.0f ); | |||
} | |||
/* | |||
----------------------- | |||
SoundFX | |||
----------------------- | |||
*/ | |||
[System.Serializable] | |||
public class SoundFX { | |||
public SoundFX() { | |||
playback = SoundFXNext.Random; | |||
volume = 1.0f; | |||
pitchVariance = Vector2.one; | |||
falloffDistance = new Vector2( 1.0f, 25.0f ); | |||
falloffCurve = AudioRolloffMode.Linear; | |||
volumeFalloffCurve = new AnimationCurve( new Keyframe[2] { new Keyframe( 0f, 1.0f ), new Keyframe( 1f, 1f ) } ); | |||
reverbZoneMix = new AnimationCurve( new Keyframe[2] { new Keyframe( 0f, 1.0f ), new Keyframe( 1f, 1f ) } ); | |||
spread = 0.0f; | |||
pctChanceToPlay = 1.0f; | |||
priority = SoundPriority.Default; | |||
delay = Vector2.zero; | |||
looping = false; | |||
ospProps = new OSPProps(); | |||
} | |||
[Tooltip( "Each sound FX should have a unique name")] | |||
public string name = string.Empty; | |||
[Tooltip( "Sound diversity playback option when multiple audio clips are defined, default = Random")] | |||
public SoundFXNext playback = SoundFXNext.Random; | |||
[Tooltip( "Default volume for this sound FX, default = 1.0")] | |||
[Range (0.0f, 1.0f)] | |||
public float volume = 1.0f; | |||
[Tooltip( "Random pitch variance each time a sound FX is played, default = 1.0 (none)")] | |||
[MinMax ( 1.0f, 1.0f, 0.0f, 2.0f )] | |||
public Vector2 pitchVariance = Vector2.one; | |||
[Tooltip( "Falloff distance for the sound FX, default = 1m min to 25m max")] | |||
[MinMax ( 1.0f, 25.0f, 0.0f, 250.0f )] | |||
public Vector2 falloffDistance = new Vector2( 1.0f, 25.0f ); | |||
[Tooltip( "Volume falloff curve - sets how the sound FX attenuates over distance, default = Linear")] | |||
public AudioRolloffMode falloffCurve = AudioRolloffMode.Linear; | |||
[Tooltip( "Defines the custom volume falloff curve")] | |||
public AnimationCurve volumeFalloffCurve = new AnimationCurve( new Keyframe[2] { new Keyframe( 0f, 1.0f ), new Keyframe( 1f, 1f ) } ); | |||
[Tooltip( "The amount by which the signal from the AudioSource will be mixed into the global reverb associated with the Reverb Zones | Valid range is 0.0 - 1.1, default = 1.0" )] | |||
public AnimationCurve reverbZoneMix = new AnimationCurve( new Keyframe[2] { new Keyframe( 0f, 1.0f ), new Keyframe( 1f, 1f ) } ); | |||
[Tooltip( "Sets the spread angle (in degrees) of a 3d stereo or multichannel sound in speaker space, default = 0")] | |||
[Range (0.0f, 360.0f)] | |||
public float spread = 0.0f; | |||
[Tooltip( "The percentage chance that this sound FX will play | 0.0 = none, 1.0 = 100%, default = 1.0")] | |||
[Range (0.0f, 1.0f)] | |||
public float pctChanceToPlay = 1.0f; | |||
[Tooltip( "Sets the priority for this sound to play and/or to override a currently playing sound FX, default = Default")] | |||
public SoundPriority priority = SoundPriority.Default; | |||
[Tooltip( "Specifies the default delay when this sound FX is played, default = 0.0 secs")] | |||
[MinMax ( 0.0f, 0.0f, 0.0f, 2.0f )] | |||
public Vector2 delay = Vector2.zero; // this overrides any delay passed into PlaySound() or PlaySoundAt() | |||
[Tooltip( "Set to true for the sound to loop continuously, default = false")] | |||
public bool looping = false; | |||
public OSPProps ospProps = new OSPProps(); | |||
[Tooltip( "List of the audio clips assigned to this sound FX")] | |||
public AudioClip[] soundClips = new AudioClip[1]; | |||
// editor only - unfortunately if we set it not to serialize, we can't query it from the editor | |||
public bool visibilityToggle = false; | |||
// runtime vars | |||
[System.NonSerialized] | |||
private SoundGroup soundGroup = null; | |||
private int lastIdx = -1; | |||
private int playingIdx = -1; | |||
public int Length { get { return soundClips.Length; } } | |||
public bool IsValid { get { return ( ( soundClips.Length != 0 ) && ( soundClips[0] != null ) ); } } | |||
public SoundGroup Group { get { return soundGroup; } set { soundGroup = value; } } | |||
public float MaxFalloffDistSquared { get { return falloffDistance.y * falloffDistance.y; } } | |||
public float GroupVolumeOverride { get { return ( soundGroup != null ) ? soundGroup.volumeOverride : 1.0f; } } | |||
/* | |||
----------------------- | |||
GetClip() | |||
----------------------- | |||
*/ | |||
public AudioClip GetClip() { | |||
if ( soundClips.Length == 0 ) { | |||
return null; | |||
} else if ( soundClips.Length == 1 ) { | |||
return soundClips[0]; | |||
} | |||
if ( playback == SoundFXNext.Random ) { | |||
// random, but don't pick the last one | |||
int idx = Random.Range( 0, soundClips.Length ); | |||
while ( idx == lastIdx ) { | |||
idx = Random.Range( 0, soundClips.Length ); | |||
} | |||
lastIdx = idx; | |||
return soundClips[idx]; | |||
} else { | |||
// sequential | |||
if ( ++lastIdx >= soundClips.Length ) { | |||
lastIdx = 0; | |||
} | |||
return soundClips[lastIdx]; | |||
} | |||
} | |||
/* | |||
----------------------- | |||
GetMixerGroup() | |||
----------------------- | |||
*/ | |||
public AudioMixerGroup GetMixerGroup( AudioMixerGroup defaultMixerGroup ) { | |||
if ( soundGroup != null ) { | |||
return ( soundGroup.mixerGroup != null ) ? soundGroup.mixerGroup : defaultMixerGroup; | |||
} | |||
return defaultMixerGroup; | |||
} | |||
/* | |||
----------------------- | |||
ReachedGroupPlayLimit() | |||
----------------------- | |||
*/ | |||
public bool ReachedGroupPlayLimit() { | |||
if ( soundGroup != null ) { | |||
return !soundGroup.CanPlaySound(); | |||
} | |||
return false; | |||
} | |||
/* | |||
----------------------- | |||
GetClipLength() | |||
----------------------- | |||
*/ | |||
public float GetClipLength( int idx ) { | |||
if ( ( idx == -1 ) || ( soundClips.Length == 0 ) || ( idx >= soundClips.Length ) || ( soundClips[idx] == null ) ) { | |||
return 0.0f; | |||
} else { | |||
return soundClips[idx].length; | |||
} | |||
} | |||
/* | |||
----------------------- | |||
GetPitch() | |||
----------------------- | |||
*/ | |||
public float GetPitch() { | |||
return Random.Range( pitchVariance.x, pitchVariance.y ); | |||
} | |||
/* | |||
----------------------- | |||
PlaySound() | |||
----------------------- | |||
*/ | |||
public int PlaySound( float delaySecs = 0.0f ) { | |||
playingIdx = -1; | |||
if ( !IsValid ) { | |||
return playingIdx; | |||
} | |||
// check the random chance to play here to save the function calls | |||
if ( ( pctChanceToPlay > 0.99f ) || ( Random.value < pctChanceToPlay ) ) { | |||
if ( delay.y > 0.0f ) { | |||
delaySecs = Random.Range( delay.x, delay.y ); | |||
} | |||
playingIdx = AudioManager.PlaySound( this, EmitterChannel.Any, delaySecs ); | |||
} | |||
return playingIdx; | |||
} | |||
/* | |||
----------------------- | |||
PlaySoundAt() | |||
----------------------- | |||
*/ | |||
public int PlaySoundAt( Vector3 pos, float delaySecs = 0.0f, float volumeOverride = 1.0f, float pitchMultiplier = 1.0f ) { | |||
playingIdx = -1; | |||
if ( !IsValid ) { | |||
return playingIdx; | |||
} | |||
// check the random chance to play here to save the function calls | |||
if ( ( pctChanceToPlay > 0.99f ) || ( Random.value < pctChanceToPlay ) ) { | |||
if ( delay.y > 0.0f ) { | |||
delaySecs = Random.Range( delay.x, delay.y ); | |||
} | |||
playingIdx = AudioManager.PlaySoundAt( pos, this, EmitterChannel.Any, delaySecs, volumeOverride, pitchMultiplier ); | |||
} | |||
return playingIdx; | |||
} | |||
/* | |||
----------------------- | |||
SetOnFinished() | |||
get a callback when the sound is finished playing | |||
----------------------- | |||
*/ | |||
public void SetOnFinished( System.Action onFinished ) { | |||
if ( playingIdx > -1 ) { | |||
AudioManager.SetOnFinished( playingIdx, onFinished ); | |||
} | |||
} | |||
/* | |||
----------------------- | |||
SetOnFinished() | |||
get a callback with an object parameter when the sound is finished playing | |||
----------------------- | |||
*/ | |||
public void SetOnFinished( System.Action<object> onFinished, object obj ) { | |||
if ( playingIdx > -1 ) { | |||
AudioManager.SetOnFinished( playingIdx, onFinished, obj ); | |||
} | |||
} | |||
/* | |||
----------------------- | |||
StopSound() | |||
----------------------- | |||
*/ | |||
public bool StopSound() { | |||
bool stopped = false; | |||
if (playingIdx > -1){ | |||
stopped = AudioManager.StopSound(playingIdx); | |||
playingIdx = -1; | |||
} | |||
return stopped; | |||
} | |||
/* | |||
----------------------- | |||
AttachToParent() | |||
----------------------- | |||
*/ | |||
public void AttachToParent( Transform parent) { | |||
if (playingIdx > -1) { | |||
AudioManager.AttachSoundToParent(playingIdx, parent); | |||
} | |||
} | |||
/* | |||
----------------------- | |||
DetachFromParent() | |||
----------------------- | |||
*/ | |||
public void DetachFromParent() { | |||
if (playingIdx > -1) { | |||
AudioManager.DetachSoundFromParent(playingIdx); | |||
} | |||
} | |||
} | |||
} // namespace OVR |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: b0a1e5e7b5cff46a187b02100f0e4a3c | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: |
@ -0,0 +1,144 @@ | |||
using UnityEngine; | |||
using System.Collections; | |||
namespace OVR | |||
{ | |||
/* | |||
----------------------- | |||
SoundFXRef | |||
just a references to a SoundFX.. all the SoundFX methods are called indirectly from here | |||
----------------------- | |||
*/ | |||
[System.Serializable] | |||
public class SoundFXRef { | |||
public string soundFXName = string.Empty; | |||
private bool initialized = false; | |||
private SoundFX soundFXCached = null; | |||
public SoundFX soundFX { | |||
get { | |||
if ( !initialized ) { | |||
Init(); | |||
} | |||
return soundFXCached; | |||
} | |||
} | |||
public string name { get { return soundFXName; } set { soundFXName = value; Init(); } } | |||
/* | |||
----------------------- | |||
Init() | |||
----------------------- | |||
*/ | |||
void Init() { | |||
// look up the actual SoundFX object | |||
soundFXCached = AudioManager.FindSoundFX( soundFXName ); | |||
if ( soundFXCached == null ) { | |||
soundFXCached = AudioManager.FindSoundFX( string.Empty ); | |||
} | |||
initialized = true; | |||
} | |||
/* | |||
----------------------- | |||
Length() | |||
----------------------- | |||
*/ | |||
public int Length { get { return soundFX.Length; } } | |||
/* | |||
----------------------- | |||
IsValid() | |||
----------------------- | |||
*/ | |||
public bool IsValid { get { return soundFX.IsValid; } } | |||
/* | |||
----------------------- | |||
GetClip() | |||
----------------------- | |||
*/ | |||
public AudioClip GetClip() { | |||
return soundFX.GetClip(); | |||
} | |||
/* | |||
----------------------- | |||
GetClipLength() | |||
----------------------- | |||
*/ | |||
public float GetClipLength( int idx ) { | |||
return soundFX.GetClipLength( idx ); | |||
} | |||
/* | |||
----------------------- | |||
PlaySound() | |||
----------------------- | |||
*/ | |||
public int PlaySound( float delaySecs = 0.0f ) { | |||
return soundFX.PlaySound( delaySecs ); | |||
} | |||
/* | |||
----------------------- | |||
PlaySoundAt() | |||
----------------------- | |||
*/ | |||
public int PlaySoundAt( Vector3 pos, float delaySecs = 0.0f, float volume = 1.0f, float pitchMultiplier = 1.0f ) { | |||
return soundFX.PlaySoundAt( pos, delaySecs, volume, pitchMultiplier ); | |||
} | |||
/* | |||
----------------------- | |||
SetOnFinished() | |||
get a callback when the sound is finished playing | |||
----------------------- | |||
*/ | |||
public void SetOnFinished( System.Action onFinished ) { | |||
soundFX.SetOnFinished( onFinished ); | |||
} | |||
/* | |||
----------------------- | |||
SetOnFinished() | |||
get a callback with an object parameter when the sound is finished playing | |||
----------------------- | |||
*/ | |||
public void SetOnFinished( System.Action<object> onFinished, object obj ) { | |||
soundFX.SetOnFinished( onFinished, obj ); | |||
} | |||
/* | |||
----------------------- | |||
StopSound() | |||
----------------------- | |||
*/ | |||
public bool StopSound() { | |||
return soundFX.StopSound(); | |||
} | |||
/* | |||
----------------------- | |||
AttachToParent() | |||
----------------------- | |||
*/ | |||
public void AttachToParent( Transform parent) | |||
{ | |||
soundFX.AttachToParent( parent); | |||
} | |||
/* | |||
----------------------- | |||
DetachFromParent() | |||
----------------------- | |||
*/ | |||
public void DetachFromParent() | |||
{ | |||
soundFX.DetachFromParent(); | |||
} | |||
} | |||
} // namespace OVR |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 48176edab546a48de9b146105d7c5f47 | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: 02268a883a27b9c4abac4ee978caec4d | |||
folderAsset: yes | |||
timeCreated: 1468506022 | |||
licenseType: Pro | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: b43e7f73d4ffc2545a17b938f63e6bc0 | |||
folderAsset: yes | |||
timeCreated: 1468507225 | |||
licenseType: Pro | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,77 @@ | |||
using UnityEngine; | |||
using UnityEditor; | |||
using System.Collections; | |||
using System.Collections.Generic; | |||
[CustomPropertyDrawer(typeof(InspectorNoteAttribute))] | |||
public class DrawerInspectorNote : DecoratorDrawer | |||
{ | |||
public override void OnGUI( Rect position ) | |||
{ | |||
InspectorNoteAttribute note = attribute as InspectorNoteAttribute; | |||
// our header is always present | |||
Rect posLabel = position; | |||
posLabel.y += 13; | |||
posLabel.x -= 2; | |||
posLabel.height += 13; | |||
EditorGUI.LabelField(posLabel, note.header, EditorStyles.whiteLargeLabel); | |||
// do we have a message too? | |||
if (!string.IsNullOrEmpty(note.message)) | |||
{ | |||
Color color = GUI.color; | |||
Color faded = color; | |||
faded.a = 0.6f; | |||
Rect posExplain = posLabel; | |||
posExplain.y += 15; | |||
GUI.color = faded; | |||
EditorGUI.LabelField(posExplain, note.message, EditorStyles.whiteMiniLabel); | |||
GUI.color = color; | |||
} | |||
Rect posLine = position; | |||
posLine.y += string.IsNullOrEmpty(note.message) ? 30 : 42; | |||
posLine.height = 1f; | |||
GUI.Box(posLine, ""); | |||
} | |||
public override float GetHeight() { | |||
InspectorNoteAttribute note = attribute as InspectorNoteAttribute; | |||
return string.IsNullOrEmpty( note.message ) ? 38 : 50; | |||
} | |||
} | |||
[CustomPropertyDrawer( typeof( InspectorCommentAttribute ) )] | |||
public class DrawerInspectorComment : DecoratorDrawer { | |||
public override void OnGUI( Rect position ) { | |||
InspectorCommentAttribute comment = attribute as InspectorCommentAttribute; | |||
// our header is always present | |||
Rect posLabel = position; | |||
//posLabel.y += 13; | |||
//posLabel.x -= 2; | |||
//posLabel.height += 13; | |||
//EditorGUI.LabelField( posLabel, comment.header, EditorStyles.whiteLargeLabel ); | |||
// do we have a message too? | |||
if ( !string.IsNullOrEmpty( comment.message ) ) { | |||
Color color = GUI.color; | |||
Color faded = color; | |||
faded.a = 0.6f; | |||
Rect posExplain = posLabel; | |||
posExplain.y += 15; | |||
GUI.color = faded; | |||
EditorGUI.LabelField( posExplain, comment.message, EditorStyles.whiteMiniLabel ); | |||
GUI.color = color; | |||
} | |||
} | |||
public override float GetHeight() { | |||
InspectorNoteAttribute note = attribute as InspectorNoteAttribute; | |||
return string.IsNullOrEmpty( note.message ) ? 38 : 50; | |||
} | |||
} |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: f244e745a5bf8412d9d81d43dff35cf5 | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: |
@ -0,0 +1,283 @@ | |||
using UnityEngine; | |||
using System; | |||
using System.Collections; | |||
using System.Collections.Generic; | |||
public class FastList<T> { | |||
/// <summary> | |||
/// Comparison function should return -1 if left is less than right, 1 if left is greater than right, and 0 if they match. | |||
/// </summary> | |||
public delegate int CompareFunc(T left, T right); | |||
public T[] array = null; | |||
public int size = 0; | |||
public FastList () { | |||
} | |||
public FastList(int size) { | |||
if (size > 0) { | |||
this.size = 0; | |||
array = new T[size]; | |||
} | |||
else { | |||
this.size = 0; | |||
} | |||
} | |||
public int Count { | |||
get { return size;} | |||
set { } | |||
} | |||
public T this[int i] { | |||
get { return array[i];} | |||
set { array[i] = value;} | |||
} | |||
//Add item to end of list. | |||
public void Add(T item) { | |||
if (array == null || size == array.Length) { | |||
Allocate(); | |||
} | |||
array[size] = item; | |||
size++; | |||
} | |||
//Add item to end of list if it is unique. | |||
public void AddUnique( T item ) { | |||
if ( array == null || size == array.Length ) { | |||
Allocate(); | |||
} | |||
if ( !Contains( item ) ) { | |||
array[size] = item; | |||
size++; | |||
} | |||
} | |||
//Add items to the end of the list | |||
public void AddRange( IEnumerable<T> items ) { | |||
foreach ( T item in items ) { | |||
Add( item ); | |||
} | |||
} | |||
//Insert item at specified index | |||
public void Insert(int index, T item) { | |||
if (array == null || size == array.Length) { | |||
Allocate(); | |||
} | |||
if (index < size) { | |||
//move things back 1 | |||
for (int i = size; i > index; i--) { | |||
array[i] = array[i-1]; | |||
} | |||
array[index] = item; | |||
size++; | |||
} | |||
else Add(item); | |||
} | |||
//Removes specified item and keeps everything else in order | |||
public bool Remove(T item) { | |||
if (array != null) { | |||
for (int i = 0; i < size; i++) { | |||
if (item.Equals(array[i])) { //found it, push everything up | |||
size--; | |||
for (int j = i; j < size; j++) { | |||
array[j] = array[j+1]; | |||
} | |||
array[size] = default(T); | |||
return true; | |||
} | |||
} | |||
} | |||
return false; | |||
} | |||
//Removes item at specified index while keeping everything else in order | |||
//O(n) | |||
public void RemoveAt(int index) { | |||
if (array != null && size > 0 && index < size) { | |||
size--; | |||
for (int i = index; i < size; i++) { | |||
array[i] = array[i+1]; | |||
} | |||
array[size] = default(T); | |||
} | |||
} | |||
//Removes the specified item from the list and replaces with last item. Return true if removed, false if not found. | |||
public bool RemoveFast(T item) { | |||
if (array != null) { | |||
for (int i = 0; i < size; i++) { | |||
if ( item.Equals( array[i] )) { //found | |||
//Move last item here | |||
if (i < (size - 1)) { | |||
T lastItem = array[size-1]; | |||
array[size-1] = default(T); | |||
array[i] = lastItem; | |||
} else { | |||
array[i] = default(T); | |||
} | |||
size--; | |||
return true; | |||
} | |||
} | |||
} | |||
return false; | |||
} | |||
//Removes item at specified index and replace with last item. | |||
public void RemoveAtFast(int index) { | |||
if (array != null && index < size && index >= 0) { | |||
//last element | |||
if (index == size - 1) { | |||
array[index] = default(T); | |||
} | |||
else { | |||
T lastItem = array[size - 1]; | |||
array[index] = lastItem; | |||
array[size - 1] = default(T); | |||
} | |||
size--; | |||
} | |||
} | |||
//Return whether an item is contained within the list | |||
//O(n) | |||
public bool Contains(T item) { | |||
if (array == null || size <= 0 ) return false; | |||
for (int i = 0; i < size; i++) { | |||
if (array[i].Equals(item)) { return true;} | |||
} | |||
return false; | |||
} | |||
//Returns index of specified item, or -1 if not found. | |||
//O(n) | |||
public int IndexOf(T item) { | |||
if (size <= 0 || array == null) { return -1;} | |||
for (int i = 0; i < size; i++) { | |||
if (item.Equals(array[i])) { return i;} | |||
} | |||
return -1; | |||
} | |||
public T Pop() { | |||
if (array != null && size > 0) { | |||
T lastItem = array[size-1]; | |||
array[size-1] = default(T); | |||
size--; | |||
return lastItem; | |||
} | |||
return default(T); | |||
} | |||
public T[] ToArray() { | |||
Trim(); | |||
return array; | |||
} | |||
public void Sort (CompareFunc comparer) { | |||
int start = 0; | |||
int end = size - 1; | |||
bool changed = true; | |||
while (changed) { | |||
changed = false; | |||
for (int i = start; i < end; i++) { | |||
if (comparer(array[i], array[i + 1]) > 0) { | |||
T temp = array[i]; | |||
array[i] = array[i+1]; | |||
array[i+1] = temp; | |||
changed = true; | |||
} | |||
else if (!changed) { | |||
start = (i==0) ? 0 : i-1; | |||
} | |||
} | |||
} | |||
} | |||
public void InsertionSort(CompareFunc comparer) { | |||
for (int i = 1; i < size; i++) { | |||
T curr = array[i]; | |||
int j = i; | |||
while (j > 0 && comparer(array[j - 1], curr) > 0) { | |||
array[j] = array[j-1]; | |||
j--; | |||
} | |||
array[j] = curr; | |||
} | |||
} | |||
public IEnumerator<T> GetEnumerator() { | |||
if (array != null) { | |||
for (int i = 0; i < size; i++) { | |||
yield return array[i]; | |||
} | |||
} | |||
} | |||
public T Find(Predicate<T> match) { | |||
if (match != null) { | |||
if (array != null) { | |||
for (int i = 0; i < size; i++) { | |||
if (match(array[i])) { return array[i];} | |||
} | |||
} | |||
} | |||
return default(T); | |||
} | |||
//Allocate more space to internal array. | |||
void Allocate() { | |||
T[] newArray; | |||
if (array == null) { | |||
newArray = new T[32]; | |||
} | |||
else { | |||
newArray = new T[Mathf.Max(array.Length << 1, 32)]; | |||
} | |||
if (array != null && size > 0) { | |||
array.CopyTo(newArray, 0); | |||
} | |||
array = newArray; | |||
} | |||
void Trim() { | |||
if (size > 0) { | |||
T[] newArray = new T[size]; | |||
for (int i = 0; i < size; i++) { | |||
newArray[i] = array[i]; | |||
} | |||
array = newArray; | |||
} | |||
else { | |||
array = null; | |||
} | |||
} | |||
//Set size to 0, does not delete array from memory | |||
public void Clear() { | |||
size = 0; | |||
} | |||
//Delete array from memory | |||
public void Release() { | |||
Clear(); | |||
array = null; | |||
} | |||
} |
@ -0,0 +1,12 @@ | |||
fileFormatVersion: 2 | |||
guid: 5ad95fb7eea735748bd34c963525ea21 | |||
timeCreated: 1432749689 | |||
licenseType: Free | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,35 @@ | |||
using UnityEngine; | |||
/* | |||
----------------------- | |||
InspectorNoteAttribute() | |||
----------------------- | |||
*/ | |||
public class InspectorNoteAttribute : PropertyAttribute | |||
{ | |||
public readonly string header; | |||
public readonly string message; | |||
public InspectorNoteAttribute(string header, string message = "") | |||
{ | |||
this.header = header; | |||
this.message = message; | |||
} | |||
} | |||
/* | |||
----------------------- | |||
InspectorCommentAttribute() | |||
----------------------- | |||
*/ | |||
public class InspectorCommentAttribute : PropertyAttribute { | |||
public readonly string message; | |||
public InspectorCommentAttribute( string message = "" ) { | |||
this.message = message; | |||
} | |||
} |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 4616bbe65d311471f8d71174295f4986 | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: da77b29a0418e4596b9a376850379241 | |||
folderAsset: yes | |||
DefaultImporter: | |||
externalObjects: {} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: b7b5af4818686f84f844c1ae9df0f700 | |||
folderAsset: yes | |||
timeCreated: 1466716731 | |||
licenseType: Pro | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: e2c4ef7503877e647b22a4089384f04f | |||
folderAsset: yes | |||
timeCreated: 1466717433 | |||
licenseType: Pro | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,127 @@ | |||
%YAML 1.1 | |||
%TAG !u! tag:unity3d.com,2011: | |||
--- !u!1 &158226 | |||
GameObject: | |||
m_ObjectHideFlags: 0 | |||
m_PrefabParentObject: {fileID: 0} | |||
m_PrefabInternal: {fileID: 100100000} | |||
serializedVersion: 5 | |||
m_Component: | |||
- component: {fileID: 463470} | |||
- component: {fileID: 11437430} | |||
- component: {fileID: 11441414} | |||
m_Layer: 0 | |||
m_Name: LocalAvatar | |||
m_TagString: Untagged | |||
m_Icon: {fileID: 0} | |||
m_NavMeshLayer: 0 | |||
m_StaticEditorFlags: 0 | |||
m_IsActive: 1 | |||
--- !u!4 &463470 | |||
Transform: | |||
m_ObjectHideFlags: 1 | |||
m_PrefabParentObject: {fileID: 0} | |||
m_PrefabInternal: {fileID: 100100000} | |||
m_GameObject: {fileID: 158226} | |||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} | |||
m_LocalPosition: {x: 0, y: 0, z: 0} | |||
m_LocalScale: {x: 1, y: 1, z: 1} | |||
m_Children: [] | |||
m_Father: {fileID: 0} | |||
m_RootOrder: 0 | |||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} | |||
--- !u!114 &11437430 | |||
MonoBehaviour: | |||
m_ObjectHideFlags: 1 | |||
m_PrefabParentObject: {fileID: 0} | |||
m_PrefabInternal: {fileID: 100100000} | |||
m_GameObject: {fileID: 158226} | |||
m_Enabled: 1 | |||
m_EditorHideFlags: 0 | |||
m_Script: {fileID: 11500000, guid: 00f3402a2ea5bff4880c0313515240cd, type: 3} | |||
m_Name: | |||
m_EditorClassIdentifier: | |||
oculusUserID: 0 | |||
Driver: {fileID: 11441414} | |||
EnableBody: 1 | |||
EnableHands: 1 | |||
EnableBase: 0 | |||
EnableExpressive: 1 | |||
RecordPackets: 1 | |||
UseSDKPackets: 1 | |||
PacketSettings: | |||
UpdateRate: 0.033333335 | |||
StartWithControllers: 0 | |||
FirstPersonLayer: | |||
layerIndex: 0 | |||
ThirdPersonLayer: | |||
layerIndex: 0 | |||
ShowFirstPerson: 1 | |||
ShowThirdPerson: 0 | |||
LevelOfDetail: 5 | |||
CombineMeshes: 1 | |||
UseTransparentRenderQueue: 1 | |||
Monochrome_SurfaceShader: {fileID: 4800000, guid: 73f67c4e7bf718b4385aa6b1f8a06591, | |||
type: 3} | |||
Monochrome_SurfaceShader_SelfOccluding: {fileID: 4800000, guid: 69f342b79d37541489919a19cfd8a924, | |||
type: 3} | |||
Monochrome_SurfaceShader_PBS: {fileID: 4800000, guid: 5e52aa58207bbf24d8eb8ec969e9ae88, | |||
type: 3} | |||
Skinshaded_SurfaceShader_SingleComponent: {fileID: 4800000, guid: 36b8b481cf607814a8cec318f0148d63, | |||
type: 3} | |||
Skinshaded_VertFrag_SingleComponent: {fileID: 4800000, guid: c26fc51e445dcfd4db09305d861dc11c, | |||
type: 3} | |||
Skinshaded_VertFrag_CombinedMesh: {fileID: 4800000, guid: 37d2b8298f61cd2469465fc36108675d, | |||
type: 3} | |||
Skinshaded_Expressive_SurfaceShader_SingleComponent: {fileID: 4800000, guid: 93b478e926e46654889c1c20f87f253f, | |||
type: 3} | |||
Skinshaded_Expressive_VertFrag_SingleComponent: {fileID: 4800000, guid: 2fe0ac0c2373ab143a6f21314b785d7d, | |||
type: 3} | |||
Skinshaded_Expressive_VertFrag_CombinedMesh: {fileID: 4800000, guid: 0600fe59b0c043344affd1d1368b9ef2, | |||
type: 3} | |||
Loader_VertFrag_CombinedMesh: {fileID: 4800000, guid: 822f5e641dc5dd54ca9555b727b3277f, | |||
type: 3} | |||
EyeLens: {fileID: 4800000, guid: 8392f54e79937ed4bb1b692a143dc02b, type: 3} | |||
ControllerShader: {fileID: 4800000, guid: 28729c6ae5a33b04cb2f7956f3f3fc01, type: 3} | |||
CanOwnMicrophone: 1 | |||
MouthAnchor: {fileID: 0} | |||
LeftHandCustomPose: {fileID: 0} | |||
RightHandCustomPose: {fileID: 0} | |||
VoiceAmplitude: 0 | |||
EnableMouthVertexAnimation: 0 | |||
--- !u!114 &11441414 | |||
MonoBehaviour: | |||
m_ObjectHideFlags: 1 | |||
m_PrefabParentObject: {fileID: 0} | |||
m_PrefabInternal: {fileID: 100100000} | |||
m_GameObject: {fileID: 158226} | |||
m_Enabled: 1 | |||
m_EditorHideFlags: 0 | |||
m_Script: {fileID: 11500000, guid: ac27124318cf8e84aa7350c2ac1cdb80, type: 3} | |||
m_Name: | |||
m_EditorClassIdentifier: | |||
Mode: 0 | |||
--- !u!114 &11477770 | |||
MonoBehaviour: | |||
m_ObjectHideFlags: 1 | |||
m_PrefabParentObject: {fileID: 0} | |||
m_PrefabInternal: {fileID: 100100000} | |||
m_GameObject: {fileID: 0} | |||
m_Enabled: 1 | |||
m_EditorHideFlags: 0 | |||
m_Script: {fileID: 11500000, guid: 77e19ec58d4a9e844970103e5bd8946a, type: 3} | |||
m_Name: | |||
m_EditorClassIdentifier: | |||
RenderParts: [] | |||
isLeftHand: 1 | |||
--- !u!1001 &100100000 | |||
Prefab: | |||
m_ObjectHideFlags: 1 | |||
serializedVersion: 2 | |||
m_Modification: | |||
m_TransformParent: {fileID: 0} | |||
m_Modifications: [] | |||
m_RemovedComponents: [] | |||
m_ParentPrefab: {fileID: 0} | |||
m_RootGameObject: {fileID: 158226} | |||
m_IsPrefabParent: 1 |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 84c8b8609f9bb434eaf5248f17ff1293 | |||
timeCreated: 1466806466 | |||
licenseType: Pro | |||
NativeFormatImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,114 @@ | |||
%YAML 1.1 | |||
%TAG !u! tag:unity3d.com,2011: | |||
--- !u!1 &143252 | |||
GameObject: | |||
m_ObjectHideFlags: 0 | |||
m_PrefabParentObject: {fileID: 0} | |||
m_PrefabInternal: {fileID: 100100000} | |||
serializedVersion: 5 | |||
m_Component: | |||
- component: {fileID: 496618} | |||
- component: {fileID: 11464902} | |||
- component: {fileID: 11461908} | |||
m_Layer: 0 | |||
m_Name: RemoteAvatar | |||
m_TagString: Untagged | |||
m_Icon: {fileID: 0} | |||
m_NavMeshLayer: 0 | |||
m_StaticEditorFlags: 0 | |||
m_IsActive: 1 | |||
--- !u!4 &496618 | |||
Transform: | |||
m_ObjectHideFlags: 1 | |||
m_PrefabParentObject: {fileID: 0} | |||
m_PrefabInternal: {fileID: 100100000} | |||
m_GameObject: {fileID: 143252} | |||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} | |||
m_LocalPosition: {x: 0, y: 0, z: 0} | |||
m_LocalScale: {x: 1, y: 1, z: 1} | |||
m_Children: [] | |||
m_Father: {fileID: 0} | |||
m_RootOrder: 0 | |||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} | |||
--- !u!114 &11461908 | |||
MonoBehaviour: | |||
m_ObjectHideFlags: 1 | |||
m_PrefabParentObject: {fileID: 0} | |||
m_PrefabInternal: {fileID: 100100000} | |||
m_GameObject: {fileID: 143252} | |||
m_Enabled: 1 | |||
m_EditorHideFlags: 0 | |||
m_Script: {fileID: 11500000, guid: c198a42a3843ca04fa633b60f428ff51, type: 3} | |||
m_Name: | |||
m_EditorClassIdentifier: | |||
Mode: 0 | |||
--- !u!114 &11464902 | |||
MonoBehaviour: | |||
m_ObjectHideFlags: 1 | |||
m_PrefabParentObject: {fileID: 0} | |||
m_PrefabInternal: {fileID: 100100000} | |||
m_GameObject: {fileID: 143252} | |||
m_Enabled: 1 | |||
m_EditorHideFlags: 0 | |||
m_Script: {fileID: 11500000, guid: 00f3402a2ea5bff4880c0313515240cd, type: 3} | |||
m_Name: | |||
m_EditorClassIdentifier: | |||
oculusUserID: 0 | |||
Driver: {fileID: 11461908} | |||
EnableBody: 1 | |||
EnableHands: 1 | |||
EnableBase: 0 | |||
EnableExpressive: 1 | |||
RecordPackets: 0 | |||
UseSDKPackets: 1 | |||
PacketSettings: | |||
UpdateRate: 0.033333335 | |||
StartWithControllers: 0 | |||
FirstPersonLayer: | |||
layerIndex: 0 | |||
ThirdPersonLayer: | |||
layerIndex: 0 | |||
ShowFirstPerson: 0 | |||
ShowThirdPerson: 1 | |||
LevelOfDetail: 3 | |||
CombineMeshes: 1 | |||
UseTransparentRenderQueue: 1 | |||
Monochrome_SurfaceShader: {fileID: 4800000, guid: 73f67c4e7bf718b4385aa6b1f8a06591, | |||
type: 3} | |||
Monochrome_SurfaceShader_SelfOccluding: {fileID: 4800000, guid: 69f342b79d37541489919a19cfd8a924, | |||
type: 3} | |||
Monochrome_SurfaceShader_PBS: {fileID: 4800000, guid: 5e52aa58207bbf24d8eb8ec969e9ae88, | |||
type: 3} | |||
Skinshaded_SurfaceShader_SingleComponent: {fileID: 4800000, guid: 36b8b481cf607814a8cec318f0148d63, | |||
type: 3} | |||
Skinshaded_VertFrag_SingleComponent: {fileID: 4800000, guid: c26fc51e445dcfd4db09305d861dc11c, | |||
type: 3} | |||
Skinshaded_VertFrag_CombinedMesh: {fileID: 4800000, guid: 37d2b8298f61cd2469465fc36108675d, | |||
type: 3} | |||
Skinshaded_Expressive_SurfaceShader_SingleComponent: {fileID: 4800000, guid: 93b478e926e46654889c1c20f87f253f, | |||
type: 3} | |||
Skinshaded_Expressive_VertFrag_SingleComponent: {fileID: 4800000, guid: 2fe0ac0c2373ab143a6f21314b785d7d, | |||
type: 3} | |||
Skinshaded_Expressive_VertFrag_CombinedMesh: {fileID: 4800000, guid: 0600fe59b0c043344affd1d1368b9ef2, | |||
type: 3} | |||
Loader_VertFrag_CombinedMesh: {fileID: 4800000, guid: 822f5e641dc5dd54ca9555b727b3277f, | |||
type: 3} | |||
EyeLens: {fileID: 4800000, guid: 8392f54e79937ed4bb1b692a143dc02b, type: 3} | |||
ControllerShader: {fileID: 4800000, guid: 28729c6ae5a33b04cb2f7956f3f3fc01, type: 3} | |||
CanOwnMicrophone: 1 | |||
MouthAnchor: {fileID: 0} | |||
LeftHandCustomPose: {fileID: 0} | |||
RightHandCustomPose: {fileID: 0} | |||
VoiceAmplitude: 0 | |||
EnableMouthVertexAnimation: 0 | |||
--- !u!1001 &100100000 | |||
Prefab: | |||
m_ObjectHideFlags: 1 | |||
serializedVersion: 2 | |||
m_Modification: | |||
m_TransformParent: {fileID: 0} | |||
m_Modifications: [] | |||
m_RemovedComponents: [] | |||
m_ParentPrefab: {fileID: 0} | |||
m_RootGameObject: {fileID: 143252} | |||
m_IsPrefabParent: 1 |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: 90bf33f968e6bb44ea0208fc82c90a44 | |||
timeCreated: 1468001728 | |||
licenseType: Pro | |||
NativeFormatImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,7 @@ | |||
fileFormatVersion: 2 | |||
guid: 562797c69d851ed4ba23272425436ab6 | |||
folderAsset: yes | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,7 @@ | |||
fileFormatVersion: 2 | |||
guid: 5efa82b7f37ef914c8e36b241d89eaf3 | |||
folderAsset: yes | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,25 @@ | |||
fileFormatVersion: 2 | |||
guid: 0dc1a28a4f6367642b859b703b901f30 | |||
timeCreated: 1516392277 | |||
licenseType: Free | |||
PluginImporter: | |||
serializedVersion: 1 | |||
iconMap: {} | |||
executionOrder: {} | |||
isPreloaded: 0 | |||
isOverridable: 0 | |||
platformData: | |||
Android: | |||
enabled: 1 | |||
settings: | |||
CPU: ARMv7 | |||
Any: | |||
enabled: 0 | |||
settings: {} | |||
Editor: | |||
enabled: 0 | |||
settings: | |||
DefaultValueInitialized: true | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,7 @@ | |||
fileFormatVersion: 2 | |||
guid: 7adeca2b5ccf4302a746d824ae866761 | |||
folderAsset: yes | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,96 @@ | |||
fileFormatVersion: 2 | |||
guid: 6757695d745b8bc419fd41108ba2dec9 | |||
PluginImporter: | |||
externalObjects: {} | |||
serializedVersion: 2 | |||
iconMap: {} | |||
executionOrder: {} | |||
defineConstraints: [] | |||
isPreloaded: 0 | |||
isOverridable: 0 | |||
isExplicitlyReferenced: 0 | |||
validateReferences: 1 | |||
platformData: | |||
- first: | |||
'': Any | |||
second: | |||
enabled: 0 | |||
settings: | |||
Exclude Android: 0 | |||
Exclude Editor: 1 | |||
Exclude Linux: 1 | |||
Exclude Linux64: 1 | |||
Exclude LinuxUniversal: 1 | |||
Exclude OSXUniversal: 1 | |||
Exclude Win: 1 | |||
Exclude Win64: 1 | |||
- first: | |||
Android: Android | |||
second: | |||
enabled: 1 | |||
settings: | |||
CPU: ARM64 | |||
- first: | |||
Any: | |||
second: | |||
enabled: 0 | |||
settings: {} | |||
- first: | |||
Editor: Editor | |||
second: | |||
enabled: 0 | |||
settings: | |||
CPU: AnyCPU | |||
DefaultValueInitialized: true | |||
OS: AnyOS | |||
- first: | |||
Facebook: Win | |||
second: | |||
enabled: 0 | |||
settings: | |||
CPU: AnyCPU | |||
- first: | |||
Facebook: Win64 | |||
second: | |||
enabled: 0 | |||
settings: | |||
CPU: AnyCPU | |||
- first: | |||
Standalone: Linux | |||
second: | |||
enabled: 0 | |||
settings: | |||
CPU: x86 | |||
- first: | |||
Standalone: Linux64 | |||
second: | |||
enabled: 0 | |||
settings: | |||
CPU: x86_64 | |||
- first: | |||
Standalone: LinuxUniversal | |||
second: | |||
enabled: 0 | |||
settings: | |||
CPU: None | |||
- first: | |||
Standalone: OSXUniversal | |||
second: | |||
enabled: 0 | |||
settings: | |||
CPU: AnyCPU | |||
- first: | |||
Standalone: Win | |||
second: | |||
enabled: 0 | |||
settings: | |||
CPU: AnyCPU | |||
- first: | |||
Standalone: Win64 | |||
second: | |||
enabled: 0 | |||
settings: | |||
CPU: AnyCPU | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,7 @@ | |||
fileFormatVersion: 2 | |||
guid: 7be352d6ab8b4db40b701e100dcc1000 | |||
folderAsset: yes | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,8 @@ | |||
fileFormatVersion: 2 | |||
guid: e15cc54b32316d3448de9c9ef2bd7cc1 | |||
folderAsset: yes | |||
DefaultImporter: | |||
externalObjects: {} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
size 7159 |
@ -0,0 +1,121 @@ | |||
fileFormatVersion: 2 | |||
guid: 502d438d2584976448c3cdb146ed836d | |||
TextureImporter: | |||
fileIDToRecycleName: {} | |||
externalObjects: {} | |||
serializedVersion: 9 | |||
mipmaps: | |||
mipMapMode: 0 | |||
enableMipMap: 1 | |||
sRGBTexture: 1 | |||
linearTexture: 0 | |||
fadeOut: 0 | |||
borderMipMap: 0 | |||
mipMapsPreserveCoverage: 0 | |||
alphaTestReferenceValue: 0.5 | |||
mipMapFadeDistanceStart: 1 | |||
mipMapFadeDistanceEnd: 3 | |||
bumpmap: | |||
convertToNormalMap: 0 | |||
externalNormalMap: 0 | |||
heightScale: 0.25 | |||
normalMapFilter: 0 | |||
isReadable: 1 | |||
streamingMipmaps: 0 | |||
streamingMipmapsPriority: 0 | |||
grayScaleToAlpha: 0 | |||
generateCubemap: 6 | |||
cubemapConvolution: 0 | |||
seamlessCubemap: 0 | |||
textureFormat: -1 | |||
maxTextureSize: 2048 | |||
textureSettings: | |||
serializedVersion: 2 | |||
filterMode: -1 | |||
aniso: -1 | |||
mipBias: -100 | |||
wrapU: -1 | |||
wrapV: -1 | |||
wrapW: -1 | |||
nPOTScale: 1 | |||
lightmap: 0 | |||
compressionQuality: 50 | |||
spriteMode: 0 | |||
spriteExtrude: 1 | |||
spriteMeshType: 1 | |||
alignment: 0 | |||
spritePivot: {x: 0.5, y: 0.5} | |||
spritePixelsToUnits: 100 | |||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||
spriteGenerateFallbackPhysicsShape: 1 | |||
alphaUsage: 1 | |||
alphaIsTransparency: 0 | |||
spriteTessellationDetail: -1 | |||
textureType: 0 | |||
textureShape: 1 | |||
singleChannelComponent: 0 | |||
maxTextureSizeSet: 0 | |||
compressionQualitySet: 0 | |||
textureFormatSet: 0 | |||
platformSettings: | |||
- serializedVersion: 2 | |||
buildTarget: DefaultTexturePlatform | |||
maxTextureSize: 1024 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Standalone | |||
maxTextureSize: 1024 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Android | |||
maxTextureSize: 1024 | |||
resizeAlgorithm: 0 | |||
textureFormat: 50 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 1 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Windows Store Apps | |||
maxTextureSize: 1024 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
spriteSheet: | |||
serializedVersion: 2 | |||
sprites: [] | |||
outline: [] | |||
physicsShape: [] | |||
bones: [] | |||
spriteID: | |||
vertices: [] | |||
indices: | |||
edges: [] | |||
weights: [] | |||
spritePackingTag: | |||
pSDRemoveMatte: 0 | |||
pSDShowRemoveMatteOption: 0 | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
size 18737 |
@ -0,0 +1,121 @@ | |||
fileFormatVersion: 2 | |||
guid: b3e87b1024f5fa8408d004b398e7b0c0 | |||
TextureImporter: | |||
fileIDToRecycleName: {} | |||
externalObjects: {} | |||
serializedVersion: 9 | |||
mipmaps: | |||
mipMapMode: 0 | |||
enableMipMap: 1 | |||
sRGBTexture: 1 | |||
linearTexture: 0 | |||
fadeOut: 0 | |||
borderMipMap: 0 | |||
mipMapsPreserveCoverage: 0 | |||
alphaTestReferenceValue: 0.5 | |||
mipMapFadeDistanceStart: 1 | |||
mipMapFadeDistanceEnd: 3 | |||
bumpmap: | |||
convertToNormalMap: 0 | |||
externalNormalMap: 0 | |||
heightScale: 0.25 | |||
normalMapFilter: 0 | |||
isReadable: 1 | |||
streamingMipmaps: 0 | |||
streamingMipmapsPriority: 0 | |||
grayScaleToAlpha: 0 | |||
generateCubemap: 6 | |||
cubemapConvolution: 0 | |||
seamlessCubemap: 0 | |||
textureFormat: -1 | |||
maxTextureSize: 2048 | |||
textureSettings: | |||
serializedVersion: 2 | |||
filterMode: -1 | |||
aniso: -1 | |||
mipBias: -100 | |||
wrapU: -1 | |||
wrapV: -1 | |||
wrapW: -1 | |||
nPOTScale: 1 | |||
lightmap: 0 | |||
compressionQuality: 50 | |||
spriteMode: 0 | |||
spriteExtrude: 1 | |||
spriteMeshType: 1 | |||
alignment: 0 | |||
spritePivot: {x: 0.5, y: 0.5} | |||
spritePixelsToUnits: 100 | |||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||
spriteGenerateFallbackPhysicsShape: 1 | |||
alphaUsage: 1 | |||
alphaIsTransparency: 0 | |||
spriteTessellationDetail: -1 | |||
textureType: 0 | |||
textureShape: 1 | |||
singleChannelComponent: 0 | |||
maxTextureSizeSet: 0 | |||
compressionQualitySet: 0 | |||
textureFormatSet: 0 | |||
platformSettings: | |||
- serializedVersion: 2 | |||
buildTarget: DefaultTexturePlatform | |||
maxTextureSize: 2048 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Standalone | |||
maxTextureSize: 2048 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Android | |||
maxTextureSize: 2048 | |||
resizeAlgorithm: 0 | |||
textureFormat: 50 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 1 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Windows Store Apps | |||
maxTextureSize: 2048 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
spriteSheet: | |||
serializedVersion: 2 | |||
sprites: [] | |||
outline: [] | |||
physicsShape: [] | |||
bones: [] | |||
spriteID: | |||
vertices: [] | |||
indices: | |||
edges: [] | |||
weights: [] | |||
spritePackingTag: | |||
pSDRemoveMatte: 0 | |||
pSDShowRemoveMatteOption: 0 | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
size 2707 |
@ -0,0 +1,121 @@ | |||
fileFormatVersion: 2 | |||
guid: 7d8da3d06466cc04da8c020819170a59 | |||
TextureImporter: | |||
fileIDToRecycleName: {} | |||
externalObjects: {} | |||
serializedVersion: 9 | |||
mipmaps: | |||
mipMapMode: 0 | |||
enableMipMap: 1 | |||
sRGBTexture: 1 | |||
linearTexture: 0 | |||
fadeOut: 0 | |||
borderMipMap: 0 | |||
mipMapsPreserveCoverage: 0 | |||
alphaTestReferenceValue: 0.5 | |||
mipMapFadeDistanceStart: 1 | |||
mipMapFadeDistanceEnd: 3 | |||
bumpmap: | |||
convertToNormalMap: 0 | |||
externalNormalMap: 0 | |||
heightScale: 0.25 | |||
normalMapFilter: 0 | |||
isReadable: 1 | |||
streamingMipmaps: 0 | |||
streamingMipmapsPriority: 0 | |||
grayScaleToAlpha: 0 | |||
generateCubemap: 6 | |||
cubemapConvolution: 0 | |||
seamlessCubemap: 0 | |||
textureFormat: 1 | |||
maxTextureSize: 2048 | |||
textureSettings: | |||
serializedVersion: 2 | |||
filterMode: -1 | |||
aniso: -1 | |||
mipBias: -100 | |||
wrapU: -1 | |||
wrapV: -1 | |||
wrapW: -1 | |||
nPOTScale: 1 | |||
lightmap: 0 | |||
compressionQuality: 50 | |||
spriteMode: 0 | |||
spriteExtrude: 1 | |||
spriteMeshType: 1 | |||
alignment: 0 | |||
spritePivot: {x: 0.5, y: 0.5} | |||
spritePixelsToUnits: 100 | |||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||
spriteGenerateFallbackPhysicsShape: 1 | |||
alphaUsage: 1 | |||
alphaIsTransparency: 0 | |||
spriteTessellationDetail: -1 | |||
textureType: 0 | |||
textureShape: 1 | |||
singleChannelComponent: 0 | |||
maxTextureSizeSet: 0 | |||
compressionQualitySet: 0 | |||
textureFormatSet: 0 | |||
platformSettings: | |||
- serializedVersion: 2 | |||
buildTarget: DefaultTexturePlatform | |||
maxTextureSize: 256 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Standalone | |||
maxTextureSize: 256 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Android | |||
maxTextureSize: 256 | |||
resizeAlgorithm: 0 | |||
textureFormat: 50 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 1 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Windows Store Apps | |||
maxTextureSize: 256 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
spriteSheet: | |||
serializedVersion: 2 | |||
sprites: [] | |||
outline: [] | |||
physicsShape: [] | |||
bones: [] | |||
spriteID: | |||
vertices: [] | |||
indices: | |||
edges: [] | |||
weights: [] | |||
spritePackingTag: | |||
pSDRemoveMatte: 0 | |||
pSDShowRemoveMatteOption: 0 | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,121 @@ | |||
fileFormatVersion: 2 | |||
guid: 9fb4a3be60417d043865e457a9d51e63 | |||
TextureImporter: | |||
fileIDToRecycleName: {} | |||
externalObjects: {} | |||
serializedVersion: 9 | |||
mipmaps: | |||
mipMapMode: 0 | |||
enableMipMap: 1 | |||
sRGBTexture: 0 | |||
linearTexture: 0 | |||
fadeOut: 0 | |||
borderMipMap: 0 | |||
mipMapsPreserveCoverage: 0 | |||
alphaTestReferenceValue: 0.5 | |||
mipMapFadeDistanceStart: 1 | |||
mipMapFadeDistanceEnd: 3 | |||
bumpmap: | |||
convertToNormalMap: 0 | |||
externalNormalMap: 0 | |||
heightScale: 0.25 | |||
normalMapFilter: 0 | |||
isReadable: 1 | |||
streamingMipmaps: 0 | |||
streamingMipmapsPriority: 0 | |||
grayScaleToAlpha: 0 | |||
generateCubemap: 6 | |||
cubemapConvolution: 0 | |||
seamlessCubemap: 0 | |||
textureFormat: -1 | |||
maxTextureSize: 2048 | |||
textureSettings: | |||
serializedVersion: 2 | |||
filterMode: -1 | |||
aniso: -1 | |||
mipBias: -100 | |||
wrapU: -1 | |||
wrapV: -1 | |||
wrapW: -1 | |||
nPOTScale: 1 | |||
lightmap: 0 | |||
compressionQuality: 50 | |||
spriteMode: 0 | |||
spriteExtrude: 1 | |||
spriteMeshType: 1 | |||
alignment: 0 | |||
spritePivot: {x: 0.5, y: 0.5} | |||
spritePixelsToUnits: 100 | |||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||
spriteGenerateFallbackPhysicsShape: 1 | |||
alphaUsage: 1 | |||
alphaIsTransparency: 0 | |||
spriteTessellationDetail: -1 | |||
textureType: 1 | |||
textureShape: 1 | |||
singleChannelComponent: 0 | |||
maxTextureSizeSet: 0 | |||
compressionQualitySet: 0 | |||
textureFormatSet: 0 | |||
platformSettings: | |||
- serializedVersion: 2 | |||
buildTarget: DefaultTexturePlatform | |||
maxTextureSize: 1024 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Standalone | |||
maxTextureSize: 1024 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Android | |||
maxTextureSize: 1024 | |||
resizeAlgorithm: 0 | |||
textureFormat: 50 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 1 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Windows Store Apps | |||
maxTextureSize: 1024 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
spriteSheet: | |||
serializedVersion: 2 | |||
sprites: [] | |||
outline: [] | |||
physicsShape: [] | |||
bones: [] | |||
spriteID: | |||
vertices: [] | |||
indices: | |||
edges: [] | |||
weights: [] | |||
spritePackingTag: | |||
pSDRemoveMatte: 0 | |||
pSDShowRemoveMatteOption: 0 | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
size 28319 |
@ -0,0 +1,121 @@ | |||
fileFormatVersion: 2 | |||
guid: 22a046c12fc7f3c4d98a98add109fa96 | |||
TextureImporter: | |||
fileIDToRecycleName: {} | |||
externalObjects: {} | |||
serializedVersion: 9 | |||
mipmaps: | |||
mipMapMode: 0 | |||
enableMipMap: 1 | |||
sRGBTexture: 0 | |||
linearTexture: 0 | |||
fadeOut: 0 | |||
borderMipMap: 0 | |||
mipMapsPreserveCoverage: 0 | |||
alphaTestReferenceValue: 0.5 | |||
mipMapFadeDistanceStart: 1 | |||
mipMapFadeDistanceEnd: 3 | |||
bumpmap: | |||
convertToNormalMap: 0 | |||
externalNormalMap: 0 | |||
heightScale: 0.25 | |||
normalMapFilter: 0 | |||
isReadable: 1 | |||
streamingMipmaps: 0 | |||
streamingMipmapsPriority: 0 | |||
grayScaleToAlpha: 0 | |||
generateCubemap: 6 | |||
cubemapConvolution: 0 | |||
seamlessCubemap: 0 | |||
textureFormat: -1 | |||
maxTextureSize: 2048 | |||
textureSettings: | |||
serializedVersion: 2 | |||
filterMode: -1 | |||
aniso: -1 | |||
mipBias: -100 | |||
wrapU: -1 | |||
wrapV: -1 | |||
wrapW: -1 | |||
nPOTScale: 1 | |||
lightmap: 0 | |||
compressionQuality: 50 | |||
spriteMode: 0 | |||
spriteExtrude: 1 | |||
spriteMeshType: 1 | |||
alignment: 0 | |||
spritePivot: {x: 0.5, y: 0.5} | |||
spritePixelsToUnits: 100 | |||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||
spriteGenerateFallbackPhysicsShape: 1 | |||
alphaUsage: 1 | |||
alphaIsTransparency: 0 | |||
spriteTessellationDetail: -1 | |||
textureType: 1 | |||
textureShape: 1 | |||
singleChannelComponent: 0 | |||
maxTextureSizeSet: 0 | |||
compressionQualitySet: 0 | |||
textureFormatSet: 0 | |||
platformSettings: | |||
- serializedVersion: 2 | |||
buildTarget: DefaultTexturePlatform | |||
maxTextureSize: 2048 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Standalone | |||
maxTextureSize: 2048 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Android | |||
maxTextureSize: 2048 | |||
resizeAlgorithm: 0 | |||
textureFormat: 50 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 1 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Windows Store Apps | |||
maxTextureSize: 2048 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
spriteSheet: | |||
serializedVersion: 2 | |||
sprites: [] | |||
outline: [] | |||
physicsShape: [] | |||
bones: [] | |||
spriteID: | |||
vertices: [] | |||
indices: | |||
edges: [] | |||
weights: [] | |||
spritePackingTag: | |||
pSDRemoveMatte: 0 | |||
pSDShowRemoveMatteOption: 0 | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
size 5739 |
@ -0,0 +1,121 @@ | |||
fileFormatVersion: 2 | |||
guid: 93a54b3b63bcc6d49b16f6bdb655b940 | |||
TextureImporter: | |||
fileIDToRecycleName: {} | |||
externalObjects: {} | |||
serializedVersion: 9 | |||
mipmaps: | |||
mipMapMode: 0 | |||
enableMipMap: 1 | |||
sRGBTexture: 0 | |||
linearTexture: 0 | |||
fadeOut: 0 | |||
borderMipMap: 0 | |||
mipMapsPreserveCoverage: 0 | |||
alphaTestReferenceValue: 0.5 | |||
mipMapFadeDistanceStart: 1 | |||
mipMapFadeDistanceEnd: 3 | |||
bumpmap: | |||
convertToNormalMap: 0 | |||
externalNormalMap: 0 | |||
heightScale: 0.25 | |||
normalMapFilter: 0 | |||
isReadable: 1 | |||
streamingMipmaps: 0 | |||
streamingMipmapsPriority: 0 | |||
grayScaleToAlpha: 0 | |||
generateCubemap: 6 | |||
cubemapConvolution: 0 | |||
seamlessCubemap: 0 | |||
textureFormat: 1 | |||
maxTextureSize: 2048 | |||
textureSettings: | |||
serializedVersion: 2 | |||
filterMode: -1 | |||
aniso: -1 | |||
mipBias: -100 | |||
wrapU: -1 | |||
wrapV: -1 | |||
wrapW: -1 | |||
nPOTScale: 1 | |||
lightmap: 0 | |||
compressionQuality: 50 | |||
spriteMode: 0 | |||
spriteExtrude: 1 | |||
spriteMeshType: 1 | |||
alignment: 0 | |||
spritePivot: {x: 0.5, y: 0.5} | |||
spritePixelsToUnits: 100 | |||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||
spriteGenerateFallbackPhysicsShape: 1 | |||
alphaUsage: 1 | |||
alphaIsTransparency: 0 | |||
spriteTessellationDetail: -1 | |||
textureType: 1 | |||
textureShape: 1 | |||
singleChannelComponent: 0 | |||
maxTextureSizeSet: 0 | |||
compressionQualitySet: 0 | |||
textureFormatSet: 0 | |||
platformSettings: | |||
- serializedVersion: 2 | |||
buildTarget: DefaultTexturePlatform | |||
maxTextureSize: 256 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Standalone | |||
maxTextureSize: 256 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Android | |||
maxTextureSize: 256 | |||
resizeAlgorithm: 0 | |||
textureFormat: 50 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 1 | |||
androidETC2FallbackOverride: 0 | |||
- serializedVersion: 2 | |||
buildTarget: Windows Store Apps | |||
maxTextureSize: 256 | |||
resizeAlgorithm: 0 | |||
textureFormat: -1 | |||
textureCompression: 1 | |||
compressionQuality: 50 | |||
crunchedCompression: 0 | |||
allowsAlphaSplitting: 0 | |||
overridden: 0 | |||
androidETC2FallbackOverride: 0 | |||
spriteSheet: | |||
serializedVersion: 2 | |||
sprites: [] | |||
outline: [] | |||
physicsShape: [] | |||
bones: [] | |||
spriteID: | |||
vertices: [] | |||
indices: | |||
edges: [] | |||
weights: [] | |||
spritePackingTag: | |||
pSDRemoveMatte: 0 | |||
pSDShowRemoveMatteOption: 0 | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: a082ff1bb115495438c0dbd2a47e2b0f | |||
folderAsset: yes | |||
timeCreated: 1525971172 | |||
licenseType: Free | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,318 @@ | |||
#ifndef AVATAR_UTIL_CG_INCLUDED | |||
#define AVATAR_UTIL_CG_INCLUDED | |||
#include "UnityCG.cginc" | |||
#define SAMPLE_MODE_COLOR 0 | |||
#define SAMPLE_MODE_TEXTURE 1 | |||
#define SAMPLE_MODE_TEXTURE_SINGLE_CHANNEL 2 | |||
#define SAMPLE_MODE_PARALLAX 3 | |||
#define SAMPLE_MODE_RSRM 4 | |||
#define MASK_TYPE_NONE 0 | |||
#define MASK_TYPE_POSITIONAL 1 | |||
#define MASK_TYPE_REFLECTION 2 | |||
#define MASK_TYPE_FRESNEL 3 | |||
#define MASK_TYPE_PULSE 4 | |||
#define BLEND_MODE_ADD 0 | |||
#define BLEND_MODE_MULTIPLY 1 | |||
#ifdef LAYERS_1 | |||
#define LAYER_COUNT 1 | |||
#elif LAYERS_2 | |||
#define LAYER_COUNT 2 | |||
#elif LAYERS_3 | |||
#define LAYER_COUNT 3 | |||
#elif LAYERS_4 | |||
#define LAYER_COUNT 4 | |||
#elif LAYERS_5 | |||
#define LAYER_COUNT 5 | |||
#elif LAYERS_6 | |||
#define LAYER_COUNT 6 | |||
#elif LAYERS_7 | |||
#define LAYER_COUNT 7 | |||
#elif LAYERS_8 | |||
#define LAYER_COUNT 8 | |||
#endif | |||
#define DECLARE_LAYER_UNIFORMS(index) \ | |||
int _LayerSampleMode##index; \ | |||
int _LayerBlendMode##index; \ | |||
int _LayerMaskType##index; \ | |||
fixed4 _LayerColor##index; \ | |||
sampler2D _LayerSurface##index; \ | |||
float4 _LayerSurface##index##_ST; \ | |||
float4 _LayerSampleParameters##index; \ | |||
float4 _LayerMaskParameters##index; \ | |||
float4 _LayerMaskAxis##index; | |||
DECLARE_LAYER_UNIFORMS(0) | |||
DECLARE_LAYER_UNIFORMS(1) | |||
DECLARE_LAYER_UNIFORMS(2) | |||
DECLARE_LAYER_UNIFORMS(3) | |||
DECLARE_LAYER_UNIFORMS(4) | |||
DECLARE_LAYER_UNIFORMS(5) | |||
DECLARE_LAYER_UNIFORMS(6) | |||
DECLARE_LAYER_UNIFORMS(7) | |||
struct VertexOutput | |||
{ | |||
float4 pos : SV_POSITION; | |||
float2 texcoord : TEXCOORD0; | |||
float3 worldPos : TEXCOORD1; | |||
float3 worldNormal : TEXCOORD2; | |||
float3 viewDir : TEXCOORD3; | |||
float4 vertColor : COLOR; | |||
#if NORMAL_MAP_ON || PARALLAX_ON | |||
float3 worldTangent : TANGENT; | |||
float3 worldBitangent : TEXCOORD5; | |||
#endif | |||
}; | |||
float _Alpha; | |||
int _BaseMaskType; | |||
float4 _BaseMaskParameters; | |||
float4 _BaseMaskAxis; | |||
fixed4 _DarkMultiplier; | |||
fixed4 _BaseColor; | |||
sampler2D _AlphaMask; | |||
float4 _AlphaMask_ST; | |||
sampler2D _AlphaMask2; | |||
float4 _AlphaMask2_ST; | |||
sampler2D _NormalMap; | |||
float4 _NormalMap_ST; | |||
sampler2D _ParallaxMap; | |||
float4 _ParallaxMap_ST; | |||
sampler2D _RoughnessMap; | |||
float4 _RoughnessMap_ST; | |||
float4x4 _ProjectorWorldToLocal; | |||
VertexOutput vert(appdata_full v) | |||
{ | |||
VertexOutput o; | |||
UNITY_INITIALIZE_OUTPUT(VertexOutput, o); | |||
o.texcoord = v.texcoord.xy; | |||
o.worldPos = mul(unity_ObjectToWorld, v.vertex); | |||
o.vertColor = v.color; | |||
o.viewDir = normalize(_WorldSpaceCameraPos.xyz - o.worldPos); | |||
o.worldNormal = normalize(mul(unity_ObjectToWorld, float4(v.normal, 0.0)).xyz); | |||
#if NORMAL_MAP_ON || PARALLAX_ON | |||
o.worldTangent = normalize(mul(unity_ObjectToWorld, float4(v.tangent.xyz, 0.0)).xyz); | |||
o.worldBitangent = normalize(cross(o.worldNormal, o.worldTangent) * v.tangent.w); | |||
#endif | |||
o.pos = UnityObjectToClipPos(v.vertex); | |||
return o; | |||
} | |||
#ifndef NORMAL_MAP_ON | |||
#define COMPUTE_NORMAL IN.worldNormal | |||
#else | |||
#define COMPUTE_NORMAL normalize(mul(lerp(float3(0, 0, 1), surfaceNormal, normalMapStrength), tangentTransform)) | |||
#endif | |||
float3 ComputeColor( | |||
VertexOutput IN, | |||
float2 uv, | |||
#if PARALLAX_ON || NORMAL_MAP_ON | |||
float3x3 tangentTransform, | |||
#endif | |||
#ifdef NORMAL_MAP_ON | |||
float3 surfaceNormal, | |||
#endif | |||
sampler2D surface, | |||
float4 surface_ST, | |||
fixed4 color, | |||
int sampleMode, | |||
float4 sampleParameters | |||
) { | |||
if (sampleMode == SAMPLE_MODE_TEXTURE) { | |||
float2 panning = _Time.g * sampleParameters.xy; | |||
return tex2D(surface, (uv + panning) * surface_ST.xy + surface_ST.zw).rgb * color.rgb; | |||
} | |||
else if (sampleMode == SAMPLE_MODE_TEXTURE_SINGLE_CHANNEL) { | |||
float4 channelMask = sampleParameters; | |||
float4 channels = tex2D(surface, uv * surface_ST.xy + surface_ST.zw); | |||
return dot(channels, channelMask) * color.rgb; | |||
} | |||
#ifdef PARALLAX_ON | |||
else if (sampleMode == SAMPLE_MODE_PARALLAX) { | |||
float parallaxMinHeight = sampleParameters.x; | |||
float parallaxMaxHeight = sampleParameters.y; | |||
float parallaxValue = tex2D(_ParallaxMap, TRANSFORM_TEX(uv, _ParallaxMap)).r; | |||
float scaledHeight = lerp(parallaxMinHeight, parallaxMaxHeight, parallaxValue); | |||
float2 parallaxUV = mul(tangentTransform, IN.viewDir).xy * scaledHeight; | |||
return tex2D(surface, (uv * surface_ST.xy + surface_ST.zw) + parallaxUV).rgb * color.rgb; | |||
} | |||
#endif | |||
else if (sampleMode == SAMPLE_MODE_RSRM) { | |||
float roughnessMin = sampleParameters.x; | |||
float roughnessMax = sampleParameters.y; | |||
#ifdef ROUGHNESS_ON | |||
float roughnessValue = tex2D(_RoughnessMap, TRANSFORM_TEX(uv, _RoughnessMap)).r; | |||
float scaledRoughness = lerp(roughnessMin, roughnessMax, roughnessValue); | |||
#else | |||
float scaledRoughness = roughnessMin; | |||
#endif | |||
#ifdef NORMAL_MAP_ON | |||
float normalMapStrength = sampleParameters.z; | |||
#endif | |||
float3 viewReflect = reflect(-IN.viewDir, COMPUTE_NORMAL); | |||
float viewAngle = viewReflect.y * 0.5 + 0.5; | |||
return tex2D(surface, float2(scaledRoughness, viewAngle)).rgb * color.rgb; | |||
} | |||
return color.rgb; | |||
} | |||
float ComputeMask( | |||
VertexOutput IN, | |||
#ifdef NORMAL_MAP_ON | |||
float3x3 tangentTransform, | |||
float3 surfaceNormal, | |||
#endif | |||
int maskType, | |||
float4 layerParameters, | |||
float3 maskAxis | |||
) { | |||
if (maskType == MASK_TYPE_POSITIONAL) { | |||
float centerDistance = layerParameters.x; | |||
float fadeAbove = layerParameters.y; | |||
float fadeBelow = layerParameters.z; | |||
float3 objPos = mul(unity_WorldToObject, float4(IN.worldPos, 1.0)).xyz; | |||
float d = dot(objPos, maskAxis); | |||
if (d > centerDistance) { | |||
return saturate(1.0 - (d - centerDistance) / fadeAbove); | |||
} | |||
else { | |||
return saturate(1.0 - (centerDistance - d) / fadeBelow); | |||
} | |||
} | |||
else if (maskType == MASK_TYPE_REFLECTION) { | |||
float fadeStart = layerParameters.x; | |||
float fadeEnd = layerParameters.y; | |||
#ifdef NORMAL_MAP_ON | |||
float normalMapStrength = layerParameters.z; | |||
#endif | |||
float power = layerParameters.w; | |||
float3 viewReflect = reflect(-IN.viewDir, COMPUTE_NORMAL); | |||
float d = max(0.0, dot(viewReflect, maskAxis)); | |||
return saturate(1.0 - (d - fadeStart) / (fadeEnd - fadeStart)); | |||
} | |||
else if (maskType == MASK_TYPE_FRESNEL) { | |||
float power = layerParameters.x; | |||
float fadeStart = layerParameters.y; | |||
float fadeEnd = layerParameters.z; | |||
#ifdef NORMAL_MAP_ON | |||
float normalMapStrength = layerParameters.w; | |||
#endif | |||
float d = saturate(1.0 - max(0.0, dot(IN.viewDir, COMPUTE_NORMAL))); | |||
float p = pow(d, power); | |||
return saturate(lerp(fadeStart, fadeEnd, p)); | |||
} | |||
else if (maskType == MASK_TYPE_PULSE) { | |||
float distance = layerParameters.x; | |||
float speed = layerParameters.y; | |||
float power = layerParameters.z; | |||
float3 objPos = mul(unity_WorldToObject, float4(IN.worldPos, 1.0)).xyz; | |||
float d = dot(objPos, maskAxis); | |||
float theta = 6.2831 * frac((d - _Time.g * speed) / distance); | |||
return saturate(pow((sin(theta) * 0.5 + 0.5), power)); | |||
} | |||
else { | |||
return 1.0; | |||
} | |||
} | |||
float3 ComputeBlend(float3 source, float3 blend, float mask, int blendMode) { | |||
if (blendMode == BLEND_MODE_MULTIPLY) { | |||
return source * (blend * mask); | |||
} | |||
else { | |||
return source + (blend * mask); | |||
} | |||
} | |||
float4 ComputeSurface(VertexOutput IN) | |||
{ | |||
#if PROJECTOR_ON | |||
float3 projectorPos = mul(_ProjectorWorldToLocal, float4(IN.worldPos, 1.0)).xyz; | |||
if (abs(projectorPos.x) > 1.0 || abs(projectorPos.y) > 1.0 || abs(projectorPos.z) > 1.0) | |||
{ | |||
discard; | |||
} | |||
float2 uv = projectorPos.xy * 0.5 + 0.5; | |||
#else | |||
float2 uv = IN.texcoord.xy; | |||
#endif | |||
fixed4 c = _BaseColor; | |||
IN.worldNormal = normalize(IN.worldNormal); | |||
#if PARALLAX_ON || NORMAL_MAP_ON | |||
float3x3 tangentTransform = float3x3(IN.worldTangent, IN.worldBitangent, IN.worldNormal); | |||
#endif | |||
#ifdef NORMAL_MAP_ON | |||
float3 surfaceNormal = UnpackNormal(tex2D(_NormalMap, TRANSFORM_TEX(uv, _NormalMap))); | |||
#endif | |||
#if PARALLAX_ON || NORMAL_MAP_ON | |||
#ifndef NORMAL_MAP_ON | |||
#define COLOR_INPUTS IN, uv, tangentTransform | |||
#define MASK_INPUTS IN | |||
#else | |||
#define COLOR_INPUTS IN, uv, tangentTransform, surfaceNormal | |||
#define MASK_INPUTS IN, tangentTransform, surfaceNormal | |||
#endif | |||
#else | |||
#define COLOR_INPUTS IN, uv | |||
#define MASK_INPUTS IN | |||
#endif | |||
#define LAYER_COLOR(index) ComputeColor(COLOR_INPUTS, _LayerSurface##index, _LayerSurface##index##_ST, _LayerColor##index, _LayerSampleMode##index, _LayerSampleParameters##index) | |||
#define LAYER_MASK(index) ComputeMask(MASK_INPUTS, _LayerMaskType##index, _LayerMaskParameters##index, _LayerMaskAxis##index##.xyz) | |||
#define LAYER_BLEND(index, c) ComputeBlend(c, LAYER_COLOR(index), LAYER_MASK(index), _LayerBlendMode##index) | |||
c.rgb = LAYER_BLEND(0, c.rgb); | |||
#if LAYER_COUNT > 1 | |||
c.rgb = LAYER_BLEND(1, c.rgb); | |||
#endif | |||
#if LAYER_COUNT > 2 | |||
c.rgb = LAYER_BLEND(2, c.rgb); | |||
#endif | |||
#if LAYER_COUNT > 3 | |||
c.rgb = LAYER_BLEND(3, c.rgb); | |||
#endif | |||
#if LAYER_COUNT > 4 | |||
c.rgb = LAYER_BLEND(4, c.rgb); | |||
#endif | |||
#if LAYER_COUNT > 5 | |||
c.rgb = LAYER_BLEND(5, c.rgb); | |||
#endif | |||
#if LAYER_COUNT > 6 | |||
c.rgb = LAYER_BLEND(6, c.rgb); | |||
#endif | |||
#if LAYER_COUNT > 7 | |||
c.rgb = LAYER_BLEND(7, c.rgb); | |||
#endif | |||
#ifdef VERTALPHA_ON | |||
float scaledValue = IN.vertColor.a * 2.0; | |||
float alpha0weight = max(0.0, 1.0 - scaledValue); | |||
float alpha2weight = max(0.0, scaledValue - 1.0); | |||
float alpha1weight = 1.0 - alpha0weight - alpha2weight; | |||
c.a = _Alpha * c.a * (tex2D(_AlphaMask, TRANSFORM_TEX(uv, _AlphaMask)).r * alpha1weight + tex2D(_AlphaMask2, TRANSFORM_TEX(uv, _AlphaMask2)).r * alpha2weight + alpha0weight) * ComputeMask(MASK_INPUTS, _BaseMaskType, _BaseMaskParameters, _BaseMaskAxis); | |||
#else | |||
c.a = _Alpha * c.a * tex2D(_AlphaMask, TRANSFORM_TEX(uv, _AlphaMask)).r * IN.vertColor.a * ComputeMask(MASK_INPUTS, _BaseMaskType, _BaseMaskParameters, _BaseMaskAxis); | |||
#endif | |||
c.rgb = lerp(c.rgb, c.rgb * _DarkMultiplier, IN.vertColor.r); | |||
return c; | |||
} | |||
#endif |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: 80b6b34e742970d4bb0cdef9c74b04ae | |||
timeCreated: 1525971186 | |||
licenseType: Free | |||
ShaderImporter: | |||
defaultTextures: [] | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,64 @@ | |||
// | |||
// OvrAvatar Simple Avatar Shader | |||
// Uses the Avatar Material Model on the Standard Surface Shader | |||
// | |||
Shader "OvrAvatar/AvatarPBRV2Simple" | |||
{ | |||
Properties | |||
{ | |||
[NoScaleOffset] _MainTex("Color (RGB)", 2D) = "white" {} | |||
[NoScaleOffset] _NormalMap("Normal Map", 2D) = "bump" {} | |||
[NoScaleOffset] _RoughnessMap("Roughness Map", 2D) = "black" {} | |||
} | |||
SubShader | |||
{ | |||
Blend One Zero | |||
Cull Back | |||
CGPROGRAM | |||
#pragma surface surf Standard keepalpha fullforwardshadows | |||
#pragma target 3.0 | |||
#pragma fragmentoption ARB_precision_hint_fastest | |||
#include "UnityCG.cginc" | |||
sampler2D _MainTex; | |||
sampler2D _NormalMap; | |||
sampler2D _RoughnessMap; | |||
struct Input | |||
{ | |||
float2 uv_MainTex; | |||
float2 uv_NormalMap; | |||
float2 uv_RoughnessMap; | |||
float3 viewDir; | |||
float3 worldNormal; INTERNAL_DATA | |||
}; | |||
void surf(Input IN, inout SurfaceOutputStandard o) | |||
{ | |||
#if (UNITY_VERSION >= 20171) | |||
o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex)); | |||
#else | |||
o.Normal = tex2D(_NormalMap, IN.uv_MainTex) * 2.0 - 1.0; | |||
#endif | |||
half4 roughnessTex = tex2D(_RoughnessMap, IN.uv_MainTex); | |||
o.Albedo = tex2D(_MainTex, IN.uv_MainTex); | |||
o.Smoothness = roughnessTex.a; | |||
o.Metallic = roughnessTex.r; | |||
#if !defined(UNITY_COLORSPACE_GAMMA) | |||
o.Albedo = GammaToLinearSpace(o.Albedo); | |||
#endif | |||
o.Albedo = saturate(o.Albedo); | |||
o.Alpha = 1.0; | |||
} | |||
ENDCG | |||
} | |||
Fallback "Diffuse" | |||
} |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: 28729c6ae5a33b04cb2f7956f3f3fc01 | |||
ShaderImporter: | |||
externalObjects: {} | |||
defaultTextures: [] | |||
nonModifiableTextures: [] | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,141 @@ | |||
Shader "OvrAvatar/AvatarSurfaceShader" { | |||
Properties{ | |||
// Global parameters | |||
_Alpha("Alpha", Range(0.0, 1.0)) = 1.0 | |||
_DarkMultiplier("Dark Multiplier", Color) = (0.6, 0.6, 0.6, 1.0) | |||
_BaseColor("Base Color", Color) = (0.0, 0.0, 0.0, 0.0) | |||
_BaseMaskType("Base Mask Type", Int) = 0 | |||
_BaseMaskParameters("Base Mask Parameters", Vector) = (0, 0, 0, 0) | |||
_BaseMaskAxis("Base Mask Axis", Vector) = (0, 1, 0, 0) | |||
_AlphaMask("Alpha Mask", 2D) = "white" {} | |||
_NormalMap("Normal Map", 2D) = "" {} | |||
_ParallaxMap("Parallax Map", 2D) = "" {} | |||
_RoughnessMap("Roughness Map", 2D) = "" {} | |||
// Layer 0 parameters | |||
_LayerSampleMode0("Layer Sample Mode 0", Int) = 0 | |||
_LayerBlendMode0("Layer Blend Mode 0", Int) = 0 | |||
_LayerMaskType0("Layer Mask Type 0", Int) = 0 | |||
_LayerColor0("Layer Color 0", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface0("Layer Surface 0", 2D) = "" {} | |||
_LayerSampleParameters0("Layer Sample Parameters 0", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters0("Layer Mask Parameters 0", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis0("Layer Mask Axis 0", Vector) = (0, 1, 0, 0) | |||
// Layer 1 parameters | |||
_LayerSampleMode1("Layer Sample Mode 1", Int) = 0 | |||
_LayerBlendMode1("Layer Blend Mode 1", Int) = 0 | |||
_LayerMaskType1("Layer Mask Type 1", Int) = 0 | |||
_LayerColor1("Layer Color 1", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface1("Layer Surface 1", 2D) = "" {} | |||
_LayerSampleParameters1("Layer Sample Parameters 1", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters1("Layer Mask Parameters 1", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis1("Layer Mask Axis 1", Vector) = (0, 1, 0, 0) | |||
// Layer 2 parameters | |||
_LayerSampleMode2("Layer Sample Mode 2", Int) = 0 | |||
_LayerBlendMode2("Layer Blend Mode 2", Int) = 0 | |||
_LayerMaskType2("Layer Mask Type 2", Int) = 0 | |||
_LayerColor2("Layer Color 2", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface2("Layer Surface 2", 2D) = "" {} | |||
_LayerSampleParameters2("Layer Sample Parameters 2", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters2("Layer Mask Parameters 2", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis2("Layer Mask Axis 2", Vector) = (0, 1, 0, 0) | |||
// Layer 3 parameters | |||
_LayerSampleMode3("Layer Sample Mode 3", Int) = 0 | |||
_LayerBlendMode3("Layer Blend Mode 3", Int) = 0 | |||
_LayerMaskType3("Layer Mask Type 3", Int) = 0 | |||
_LayerColor3("Layer Color 3", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface3("Layer Surface 3", 2D) = "" {} | |||
_LayerSampleParameters3("Layer Sample Parameters 3", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters3("Layer Mask Parameters 3", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis3("Layer Mask Axis 3", Vector) = (0, 1, 0, 0) | |||
// Layer 4 parameters | |||
_LayerSampleMode4("Layer Sample Mode 4", Int) = 0 | |||
_LayerBlendMode4("Layer Blend Mode 4", Int) = 0 | |||
_LayerMaskType4("Layer Mask Type 4", Int) = 0 | |||
_LayerColor4("Layer Color 4", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface4("Layer Surface 4", 2D) = "" {} | |||
_LayerSampleParameters4("Layer Sample Parameters 4", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters4("Layer Mask Parameters 4", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis4("Layer Mask Axis 4", Vector) = (0, 1, 0, 0) | |||
// Layer 5 parameters | |||
_LayerSampleMode5("Layer Sample Mode 5", Int) = 0 | |||
_LayerBlendMode5("Layer Blend Mode 5", Int) = 0 | |||
_LayerMaskType5("Layer Mask Type 5", Int) = 0 | |||
_LayerColor5("Layer Color 5", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface5("Layer Surface 5", 2D) = "" {} | |||
_LayerSampleParameters5("Layer Sample Parameters 5", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters5("Layer Mask Parameters 5", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis5("Layer Mask Axis 5", Vector) = (0, 1, 0, 0) | |||
// Layer 6 parameters | |||
_LayerSampleMode6("Layer Sample Mode 6", Int) = 0 | |||
_LayerBlendMode6("Layer Blend Mode 6", Int) = 0 | |||
_LayerMaskType6("Layer Mask Type 6", Int) = 0 | |||
_LayerColor6("Layer Color 6", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface6("Layer Surface 6", 2D) = "" {} | |||
_LayerSampleParameters6("Layer Sample Parameters 6", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters6("Layer Mask Parameters 6", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis6("Layer Mask Axis 6", Vector) = (0, 1, 0, 0) | |||
// Layer 7 parameters | |||
_LayerSampleMode7("Layer Sample Mode 7", Int) = 0 | |||
_LayerBlendMode7("Layer Blend Mode 7", Int) = 0 | |||
_LayerMaskType7("Layer Mask Type 7", Int) = 0 | |||
_LayerColor7("Layer Color 7", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface7("Layer Surface 7", 2D) = "" {} | |||
_LayerSampleParameters7("Layer Sample Parameters 7", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters7("Layer Mask Parameters 7", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis7("Layer Mask Axis 7", Vector) = (0, 1, 0, 0) | |||
} | |||
SubShader | |||
{ | |||
Tags | |||
{ | |||
"Queue" = "Transparent" | |||
"RenderType" = "Transparent" | |||
} | |||
Blend SrcAlpha OneMinusSrcAlpha | |||
ZWrite Off | |||
LOD 200 | |||
Pass | |||
{ | |||
Name "FORWARD" | |||
Tags | |||
{ | |||
"LightMode" = "ForwardBase" | |||
} | |||
CGPROGRAM | |||
#pragma only_renderers d3d11 gles3 gles | |||
#pragma vertex vert | |||
#pragma fragment frag | |||
#pragma target 3.0 | |||
#pragma multi_compile PROJECTOR_OFF PROJECTOR_ON | |||
#pragma multi_compile NORMAL_MAP_OFF NORMAL_MAP_ON | |||
#pragma multi_compile PARALLAX_OFF PARALLAX_ON | |||
#pragma multi_compile ROUGHNESS_OFF ROUGHNESS_ON | |||
#pragma multi_compile VERTALPHA_OFF VERTALPHA_ON | |||
#pragma multi_compile LAYERS_1 LAYERS_2 LAYERS_3 LAYERS_4 LAYERS_5 LAYERS_6 LAYERS_7 LAYERS_8 | |||
#include "Assets/Oculus/Avatar/Resources/Materials/AvatarMaterialStateShader.cginc" | |||
float4 frag(VertexOutput IN) : COLOR | |||
{ | |||
return ComputeSurface(IN); | |||
} | |||
ENDCG | |||
} | |||
} | |||
FallBack "Diffuse" | |||
CustomEditor "AvatarMaterialEditor" | |||
} |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: 73f67c4e7bf718b4385aa6b1f8a06591 | |||
timeCreated: 1525971190 | |||
licenseType: Free | |||
ShaderImporter: | |||
defaultTextures: [] | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,79 @@ | |||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' | |||
Shader "OvrAvatar/AvatarSurfaceShaderPBS" { | |||
Properties{ | |||
// Global parameters | |||
_Alpha("Alpha", Range(0.0, 1.0)) = 1.0 | |||
_Albedo("Albedo (RGB)", 2D) = "" {} | |||
_Surface("Metallic (R) Occlusion (G) and Smoothness (A)", 2D) = "" {} | |||
} | |||
SubShader{ | |||
Tags { | |||
"Queue" = "Transparent" | |||
"RenderType" = "Transparent" | |||
} | |||
Pass { | |||
ZWrite On | |||
Cull Off | |||
ColorMask 0 | |||
CGPROGRAM | |||
#pragma vertex vert | |||
#pragma fragment frag | |||
#pragma target 3.0 | |||
#include "UnityCG.cginc" | |||
struct v2f { | |||
float4 position : SV_POSITION; | |||
}; | |||
v2f vert(appdata_full v) { | |||
// Output | |||
v2f output; | |||
output.position = UnityObjectToClipPos(v.vertex); | |||
return output; | |||
} | |||
float4 frag(v2f input) : COLOR { | |||
return 0; | |||
} | |||
ENDCG | |||
} | |||
LOD 200 | |||
CGPROGRAM | |||
// Physically based Standard lighting model, and enable shadows on all light types | |||
#pragma surface surf Standard vertex:vert nolightmap alpha noforwardadd | |||
float _Alpha; | |||
sampler2D _Albedo; | |||
float4 _Albedo_ST; | |||
sampler2D _Surface; | |||
float4 _Surface_ST; | |||
struct Input { | |||
float2 texcoord; | |||
}; | |||
void vert(inout appdata_full v, out Input o) { | |||
UNITY_INITIALIZE_OUTPUT(Input, o); | |||
o.texcoord = v.texcoord.xy; | |||
} | |||
void surf (Input IN, inout SurfaceOutputStandard o) { | |||
o.Albedo = tex2D(_Albedo, TRANSFORM_TEX(IN.texcoord, _Albedo)).rgb; | |||
float4 surfaceParams = tex2D(_Surface, TRANSFORM_TEX(IN.texcoord, _Surface)); | |||
o.Metallic = surfaceParams.r; | |||
o.Occlusion = surfaceParams.g; | |||
o.Smoothness = surfaceParams.a; | |||
o.Alpha = _Alpha; | |||
} | |||
#pragma only_renderers d3d11 gles3 gles | |||
ENDCG | |||
} | |||
FallBack "Diffuse" | |||
} |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: 5e52aa58207bbf24d8eb8ec969e9ae88 | |||
timeCreated: 1525971190 | |||
licenseType: Free | |||
ShaderImporter: | |||
defaultTextures: [] | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,39 @@ | |||
Shader "OvrAvatar/AvatarSurfaceShaderPBSV2" { | |||
Properties { | |||
_AlbedoMultiplier ("Albedo Multiplier", Color) = (1,1,1,1) | |||
_Albedo ("Albedo (RGB)", 2D) = "white" {} | |||
_Metallicness("Metallicness", 2D) = "grey" {} | |||
_GlossinessScale ("Glossiness Scale", Range(0,1)) = 0.5 | |||
} | |||
SubShader { | |||
Tags { "RenderType"="Opaque" } | |||
LOD 200 | |||
CGPROGRAM | |||
// Physically based Standard lighting model, and enable shadows on all light types | |||
#pragma surface surf Standard fullforwardshadows | |||
// Use shader model 3.0 target, to get nicer looking lighting | |||
#pragma target 3.0 | |||
sampler2D _Albedo; | |||
sampler2D _Metallicness; | |||
struct Input { | |||
float2 uv_Albedo; | |||
}; | |||
float _GlossinessScale; | |||
float4 _AlbedoMultiplier; | |||
void surf (Input IN, inout SurfaceOutputStandard o) { | |||
fixed4 c = tex2D (_Albedo, IN.uv_Albedo) * _AlbedoMultiplier; | |||
o.Albedo = c.rgb; | |||
o.Metallic = tex2D (_Metallicness, IN.uv_Albedo).r; | |||
o.Smoothness = _GlossinessScale; | |||
o.Alpha = 1.0; | |||
} | |||
ENDCG | |||
} | |||
FallBack "Diffuse" | |||
} |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: 176faebcc612eb147900defeda2149cb | |||
timeCreated: 1525971187 | |||
licenseType: Free | |||
ShaderImporter: | |||
defaultTextures: [] | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,175 @@ | |||
Shader "OvrAvatar/AvatarSurfaceShaderSelfOccluding" { | |||
Properties{ | |||
// Global parameters | |||
_Alpha("Alpha", Range(0.0, 1.0)) = 1.0 | |||
_DarkMultiplier("Dark Multiplier", Color) = (0.6, 0.6, 0.6, 1.0) | |||
_BaseColor("Base Color", Color) = (0.0, 0.0, 0.0, 0.0) | |||
_BaseMaskType("Base Mask Type", Int) = 0 | |||
_BaseMaskParameters("Base Mask Parameters", Vector) = (0, 0, 0, 0) | |||
_BaseMaskAxis("Base Mask Axis", Vector) = (0, 1, 0, 0) | |||
_AlphaMask("Alpha Mask", 2D) = "white" {} | |||
_NormalMap("Normal Map", 2D) = "" {} | |||
_ParallaxMap("Parallax Map", 2D) = "" {} | |||
_RoughnessMap("Roughness Map", 2D) = "" {} | |||
// Layer 0 parameters | |||
_LayerSampleMode0("Layer Sample Mode 0", Int) = 0 | |||
_LayerBlendMode0("Layer Blend Mode 0", Int) = 0 | |||
_LayerMaskType0("Layer Mask Type 0", Int) = 0 | |||
_LayerColor0("Layer Color 0", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface0("Layer Surface 0", 2D) = "" {} | |||
_LayerSampleParameters0("Layer Sample Parameters 0", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters0("Layer Mask Parameters 0", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis0("Layer Mask Axis 0", Vector) = (0, 1, 0, 0) | |||
// Layer 1 parameters | |||
_LayerSampleMode1("Layer Sample Mode 1", Int) = 0 | |||
_LayerBlendMode1("Layer Blend Mode 1", Int) = 0 | |||
_LayerMaskType1("Layer Mask Type 1", Int) = 0 | |||
_LayerColor1("Layer Color 1", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface1("Layer Surface 1", 2D) = "" {} | |||
_LayerSampleParameters1("Layer Sample Parameters 1", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters1("Layer Mask Parameters 1", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis1("Layer Mask Axis 1", Vector) = (0, 1, 0, 0) | |||
// Layer 2 parameters | |||
_LayerSampleMode2("Layer Sample Mode 2", Int) = 0 | |||
_LayerBlendMode2("Layer Blend Mode 2", Int) = 0 | |||
_LayerMaskType2("Layer Mask Type 2", Int) = 0 | |||
_LayerColor2("Layer Color 2", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface2("Layer Surface 2", 2D) = "" {} | |||
_LayerSampleParameters2("Layer Sample Parameters 2", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters2("Layer Mask Parameters 2", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis2("Layer Mask Axis 2", Vector) = (0, 1, 0, 0) | |||
// Layer 3 parameters | |||
_LayerSampleMode3("Layer Sample Mode 3", Int) = 0 | |||
_LayerBlendMode3("Layer Blend Mode 3", Int) = 0 | |||
_LayerMaskType3("Layer Mask Type 3", Int) = 0 | |||
_LayerColor3("Layer Color 3", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface3("Layer Surface 3", 2D) = "" {} | |||
_LayerSampleParameters3("Layer Sample Parameters 3", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters3("Layer Mask Parameters 3", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis3("Layer Mask Axis 3", Vector) = (0, 1, 0, 0) | |||
// Layer 4 parameters | |||
_LayerSampleMode4("Layer Sample Mode 4", Int) = 0 | |||
_LayerBlendMode4("Layer Blend Mode 4", Int) = 0 | |||
_LayerMaskType4("Layer Mask Type 4", Int) = 0 | |||
_LayerColor4("Layer Color 4", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface4("Layer Surface 4", 2D) = "" {} | |||
_LayerSampleParameters4("Layer Sample Parameters 4", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters4("Layer Mask Parameters 4", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis4("Layer Mask Axis 4", Vector) = (0, 1, 0, 0) | |||
// Layer 5 parameters | |||
_LayerSampleMode5("Layer Sample Mode 5", Int) = 0 | |||
_LayerBlendMode5("Layer Blend Mode 5", Int) = 0 | |||
_LayerMaskType5("Layer Mask Type 5", Int) = 0 | |||
_LayerColor5("Layer Color 5", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface5("Layer Surface 5", 2D) = "" {} | |||
_LayerSampleParameters5("Layer Sample Parameters 5", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters5("Layer Mask Parameters 5", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis5("Layer Mask Axis 5", Vector) = (0, 1, 0, 0) | |||
// Layer 6 parameters | |||
_LayerSampleMode6("Layer Sample Mode 6", Int) = 0 | |||
_LayerBlendMode6("Layer Blend Mode 6", Int) = 0 | |||
_LayerMaskType6("Layer Mask Type 6", Int) = 0 | |||
_LayerColor6("Layer Color 6", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface6("Layer Surface 6", 2D) = "" {} | |||
_LayerSampleParameters6("Layer Sample Parameters 6", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters6("Layer Mask Parameters 6", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis6("Layer Mask Axis 6", Vector) = (0, 1, 0, 0) | |||
// Layer 7 parameters | |||
_LayerSampleMode7("Layer Sample Mode 7", Int) = 0 | |||
_LayerBlendMode7("Layer Blend Mode 7", Int) = 0 | |||
_LayerMaskType7("Layer Mask Type 7", Int) = 0 | |||
_LayerColor7("Layer Color 7", Color) = (1.0, 1.0, 1.0, 1.0) | |||
_LayerSurface7("Layer Surface 7", 2D) = "" {} | |||
_LayerSampleParameters7("Layer Sample Parameters 7", Vector) = (0, 0, 0, 0) | |||
_LayerMaskParameters7("Layer Mask Parameters 7", Vector) = (0, 0, 0, 0) | |||
_LayerMaskAxis7("Layer Mask Axis 7", Vector) = (0, 1, 0, 0) | |||
} | |||
SubShader | |||
{ | |||
Tags | |||
{ | |||
"Queue" = "Transparent" | |||
"RenderType" = "Transparent" | |||
} | |||
Pass | |||
{ | |||
ZWrite On | |||
Cull Off | |||
ColorMask 0 | |||
Offset 1, 1 | |||
CGPROGRAM | |||
#pragma vertex vert | |||
#pragma fragment frag | |||
#pragma target 3.0 | |||
#include "UnityCG.cginc" | |||
struct v2f | |||
{ | |||
float4 position : SV_POSITION; | |||
}; | |||
v2f vert(appdata_full v) | |||
{ | |||
// Output | |||
v2f output; | |||
output.position = UnityObjectToClipPos(v.vertex); | |||
return output; | |||
} | |||
float4 frag(v2f input) : COLOR | |||
{ | |||
return 0; | |||
} | |||
ENDCG | |||
} | |||
Blend SrcAlpha OneMinusSrcAlpha | |||
ZWrite Off | |||
LOD 200 | |||
Pass | |||
{ | |||
Name "FORWARD" | |||
Tags | |||
{ | |||
"LightMode" = "ForwardBase" | |||
} | |||
CGPROGRAM | |||
#pragma only_renderers d3d11 gles3 gles | |||
#pragma vertex vert | |||
#pragma fragment frag | |||
#pragma target 3.0 | |||
#pragma multi_compile PROJECTOR_OFF PROJECTOR_ON | |||
#pragma multi_compile NORMAL_MAP_OFF NORMAL_MAP_ON | |||
#pragma multi_compile PARALLAX_OFF PARALLAX_ON | |||
#pragma multi_compile ROUGHNESS_OFF ROUGHNESS_ON | |||
#pragma multi_compile VERTALPHA_OFF VERTALPHA_ON | |||
#pragma multi_compile LAYERS_1 LAYERS_2 LAYERS_3 LAYERS_4 LAYERS_5 LAYERS_6 LAYERS_7 LAYERS_8 | |||
#include "Assets/Oculus/Avatar/Resources/Materials/AvatarMaterialStateShader.cginc" | |||
float4 frag(VertexOutput IN) : SV_Target | |||
{ | |||
return ComputeSurface(IN); | |||
} | |||
ENDCG | |||
} | |||
} | |||
FallBack "Diffuse" | |||
CustomEditor "AvatarMaterialEditor" | |||
} |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: 69f342b79d37541489919a19cfd8a924 | |||
timeCreated: 1525971190 | |||
licenseType: Free | |||
ShaderImporter: | |||
defaultTextures: [] | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,9 @@ | |||
fileFormatVersion: 2 | |||
guid: 08113db6bc6c49046beb604cc64556ba | |||
folderAsset: yes | |||
timeCreated: 1540579933 | |||
licenseType: Pro | |||
DefaultImporter: | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@ -0,0 +1,86 @@ | |||
// | |||
// OvrAvatar eye lens shader | |||
// | |||
// Generates glint on the eye lens of expressive avatars | |||
// | |||
Shader "OvrAvatar/Avatar_EyeLens" | |||
{ | |||
Properties | |||
{ | |||
_Cube("Cubemap Reflection", CUBE) = "black" {} | |||
_ReflectionIntensity("Reflection Intensity", Range(0.0,1.0)) = 0.2 | |||
_GlintStrength("Glint Strength", Range(0, 10)) = 1.57 | |||
_GlintSpead("Glint Spead", Range(32, 2048)) = 600 | |||
_Alpha("Alpha", Range(0.0,1.0)) = 1.0 | |||
} | |||
SubShader | |||
{ | |||
Tags { "LightMode" = "ForwardBase" "Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True" } | |||
Pass | |||
{ | |||
Blend SrcAlpha OneMinusSrcAlpha | |||
CGPROGRAM | |||
#pragma vertex vert | |||
#pragma fragment frag | |||
#pragma fragmentoption ARB_precision_hint_fastest | |||
#pragma target 3.0 | |||
#include "UnityCG.cginc" | |||
#include "UnityLightingCommon.cginc" | |||
#include "AutoLight.cginc" | |||
samplerCUBE _Cube; | |||
half _ReflectionIntensity; | |||
half _GlintStrength; | |||
half _GlintSpead; | |||
half _Alpha; | |||
struct VertexInput | |||
{ | |||
float4 vertex : POSITION; | |||
float3 normal : NORMAL; | |||
}; | |||
struct VertexOutput | |||
{ | |||
float4 pos : SV_POSITION; | |||
float4 posWorld : TEXCOORD1; | |||
float3 normalDir : TEXCOORD2; | |||
}; | |||
VertexOutput vert(VertexInput v) | |||
{ | |||
VertexOutput o = (VertexOutput)0; | |||
o.normalDir = UnityObjectToWorldNormal(v.normal); | |||
o.posWorld = mul(unity_ObjectToWorld, v.vertex); | |||
o.pos = UnityObjectToClipPos(v.vertex); | |||
return o; | |||
} | |||
float4 frag(VertexOutput i) : COLOR | |||
{ | |||
i.normalDir = normalize(i.normalDir); | |||
half3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz); | |||
half NdotLV = max(0, dot(i.normalDir, normalize(_WorldSpaceLightPos0.xyz + viewDirection))); | |||
half3 spec = pow(NdotLV, _GlintSpead) * _GlintStrength; | |||
// Sample the default reflection cubemap using the reflection vector | |||
half3 viewReflectDirection = reflect(-viewDirection, i.normalDir); | |||
half4 skyData = UNITY_SAMPLE_TEXCUBE(unity_SpecCube0, viewReflectDirection); | |||
// Decode cubemap data into actual color | |||
half3 reflectionColor = DecodeHDR(skyData, unity_SpecCube0_HDR); | |||
half4 finalColor; | |||
finalColor.rgb = reflectionColor.rgb * _ReflectionIntensity; | |||
finalColor.rgb += spec; | |||
finalColor.a = (finalColor.r + finalColor.g + finalColor.b) / 3; | |||
return finalColor; | |||
} | |||
ENDCG | |||
} | |||
} | |||
FallBack "Diffuse" | |||
} |