【问题标题】:Using volume buttons on Android in Unity3d在 Unity3d 中使用 Android 上的音量按钮
【发布时间】:2016-12-06 15:38:46
【问题描述】:

我正在尝试在 Android 上的 unity3d 游戏中使用音量按钮。不幸的是,我看不到任何与将音量映射为 KeyCode 相关的内容,因此在我看来,Unity3d 没有此功能。有没有一种更隐蔽的方法?有没有办法解决这个问题?它的应用是在按下音量按钮时简单地发送一个 UDP 数据包,因此它不需要与 Unity3d 应用程序本身交互。可能是一个可以处理它的后台进程?我只是想要关于遵循路径的建议,因为我不想浪费时间为我的解决方案寻找错误的树。提前致谢!

【问题讨论】:

    标签: android unity3d


    【解决方案1】:

    另一种方法是使用电话音量(好的,这是一种解决方法^^)。如果音量增加,那么音量按钮“UP”被按下。或者,如果音量减小,则表示按下了音量按钮“DOWN”。 要访问电话音量,我使用了这个 stackoverflow 答案: Unity3D: is it possible to check the volume of both Android and iPhone devices?

    这是我的android解决方案(我没有能力处理ios,但我想前面的答案提供了一些线索):

    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<AndroidJavaObject>("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<AndroidJavaObject>("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<VolumeListener> 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<int>("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();
            }
        }
    
    }
    

    我在 samsung note 4 上对其进行了测试。在使用 SamsungGear Input 的 VR 模式下也可以使用。希望它可以为某人服务。

    编辑:

    如果音量最小或最大,此解决方案将不起作用。所以你必须在之前将音量设置在最小和最大音量之间。

    //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<int>("getStreamMaxVolume", 3);
        }
        else
        {
            return 1;
        }
    }
    

    在那里找到了获取最大音量的方法:

    Android: how to play music at maximum possible volume?

    【讨论】:

      【解决方案2】:

      我认为您不能将控件映射到 Unity 中的音量按钮(使用键码)。这些按钮由系统操作系统控制,无论如何映射任何东西都是个坏主意。

      但是,您可以映射到 Android 触摸按钮。我相信后面是Keycode.Escape,菜单是Keycode.Menu

      【讨论】:

      • 在 android 中使用音量按钮通常是一个好主意 - 例如相机就是这样做的,电子书阅读器也是如此。
      【解决方案3】:

      我猜您询问音量按钮是因为您的应用被三星拒绝了?具体来说,由于缺乏对三星相机音量按钮和三星 Homesync 的支持,您向三星提交的应用程序将失败。最简单的解决方法是在提交游戏时简单地取消选择对这两项的支持。如果您在三星仪表板中切换到高级模式,您可以选择/取消选择您支持/不支持的每个设备。只需在提交应用时取消选择所有三星相机条目并取消选择三星 Homesync。

      【讨论】:

        【解决方案4】:

        您可以将您的应用构建为 android studio/eclipse 项目并修改 UnityPlayerActivity(参见:Extending the UnityPlayerActivity Java Code

        然后您可以使用此 SO 答案中描述的音量键:Android - Volume Buttons used in my application

        从 Activity 到 unity3d 上下文的通信示例:

        UnityPlayer.UnitySendMessage("TheNameOfYourGameObject", "PublicMethodInThatGameObject", "StringArgument");
        

        请注意,有传言称,如果按钮行为发生变化,三星(而非 Google)将不接受应用程序进入其商店。

        此外,如果用户仍然能够更改应用的音量,那将是很好的用户体验。

        【讨论】:

          猜你喜欢
          • 2013-12-13
          • 2019-03-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多