I am attempting to use the volume buttons in a unity3d game on Android. Unfortunately I can\'t see anything pertaining to volume being mapped as a KeyCode, so it seems to me tha
Another approach is to use phone volume (Ok, it's a workaround^^). If the volume increase, so the volume button "UP" was pressed. Or, if the volume decrease, it means that the volume button "DOWN" was pressed. To access phone volume i used this stackoverflow answer: Unity3D: is it possible to check the volume of both Android and iPhone devices?
Here is my solution for android (I didn't had the competence to deal with ios, but I guess the previous answer is giving some clues):
public static class Common {
private static AndroidJavaObject s_mainActivity = null;
private static AndroidJavaObject s_androidAudioManager = null;
public static AndroidJavaObject GetAndroidAudioManager()
{
if (s_androidAudioManager == null)
{
s_androidAudioManager = GetMainActivity().Call("getSystemService", "audio");
}
return s_androidAudioManager;
}
public static AndroidJavaObject GetMainActivity()
{
if (s_mainActivity == null)
{
var unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
s_mainActivity = unityPlayerClass.GetStatic("currentActivity");
}
return s_mainActivity;
}
public static bool IsRunningOnAndroid()
{
#if UNITY_ANDROID && !UNITY_EDITOR
return true;
#else
return false;
#endif
}
}
using UnityEngine;
using System.Collections.Generic;
public interface VolumeListener
{
void OnVolumeUp();
void OnVolumeDown();
}
public abstract class VolumeListenerGO : MonoBehaviour, VolumeListener
{
public abstract void OnVolumeUp();
public abstract void OnVolumeDown();
}
public class VolumeButton : MonoBehaviour {
public bool m_bGetVolumeFromPhone = true;
//for non gameobject listener
public List m_vVolumeListener = null;
//for gameobject listener (easier to edit in scene mode)
public VolumeListenerGO[] m_vVolumeListenerGO = null;
private float m_fPrevVolume = -1;
private bool m_bShutDown = false;
//quick access to reference
private static VolumeButton s_instance = null;
public static VolumeButton Get()
{
return s_instance;
}
//Get phone volume if running or android or application volume if running on pc
//(or wanted by user)
public float GetVolume()
{
if(m_bGetVolumeFromPhone && Common.IsRunningOnAndroid())
{
AndroidJavaObject audioManager = Common.GetAndroidAudioManager();
return audioManager.Call("getStreamVolume", 3);
}
else
{
return AudioListener.volume;
}
}
//set phone or application volume (according if running on android or if user want application volume)
public void SetVolume(float a_fVolume)
{
if (m_bGetVolumeFromPhone && Common.IsRunningOnAndroid())
{
AndroidJavaObject audioManager = Common.GetAndroidAudioManager();
audioManager.Call("setStreamVolume", 3, (int)a_fVolume, 0);
}
else
{
AudioListener.volume = a_fVolume;
}
}
private void ResetVolume()
{
SetVolume(m_fPrevVolume);
}
void Start () {
s_instance = this;
PowerOn();
}
void OnVolumeDown()
{
if (m_vVolumeListener != null)
{
foreach (VolumeListener listener in m_vVolumeListener)
{
listener.OnVolumeDown();
}
}
if (m_vVolumeListenerGO != null)
{
foreach (VolumeListener listener in m_vVolumeListenerGO)
{
listener.OnVolumeDown();
}
}
}
void OnVolumeUp()
{
if (m_vVolumeListener != null)
{
foreach (VolumeListener listener in m_vVolumeListener)
{
listener.OnVolumeUp();
}
}
if (m_vVolumeListenerGO != null)
{
foreach (VolumeListener listener in m_vVolumeListenerGO)
{
listener.OnVolumeUp();
}
}
}
//If user want to change volume, he has to mute this script first
//else the script will interpret this has a user input and resetvolume
public void ShutDown()
{
m_bShutDown = true;
}
//to unmute the script
public void PowerOn()
{
m_bShutDown = false;
//get the volume to avoid interpretating previous change (when script was muted) as user input
m_fPrevVolume = GetVolume();
}
// Update is called once per frame
void Update () {
if (m_bShutDown)
return;
float fCurrentVolume = GetVolume();
float fDiff = fCurrentVolume - m_fPrevVolume;
//if volume change, compute the difference and call listener according to
if(fDiff < 0)
{
ResetVolume();
OnVolumeDown();
}
else if(fDiff > 0)
{
ResetVolume();
OnVolumeUp();
}
}
}
I tested it on samsung note 4. Work also in VR mode with SamsungGear Input. Hope it can serve to someone.
EDIT:
This solution doesn't work if volume is minimum or maximum. So you have to set volume somewhere between minimum and maximum volume before.
//to unmute the script
public void PowerOn()
{
m_bShutDown = false;
//get the volume to avoid interpretating previous change (when script was muted) as user input
m_fPrevVolume = GetVolume();
//if volume is set to max, reduce it -> if not, there will be no detection for volume up
if (m_fPrevVolume == GetMaxVolume())
{
--m_fPrevVolume;
SetVolume(m_fPrevVolume);
}
}
//Get max volume phone
public float GetMaxVolume()
{
if (m_bGetVolumeFromPhone && Common.IsRunningOnAndroid())
{
AndroidJavaObject audioManager = Common.GetAndroidAudioManager();
return audioManager.Call("getStreamMaxVolume", 3);
}
else
{
return 1;
}
}
Method for getting max volume was found there:
Android: how to play music at maximum possible volume?