1.为什么使用Android的API播放音乐,unity3d本身是有播放音乐的api的?
在Android低端机上音乐延迟明显,对于节奏感强的游戏这就是致命的问题,而Android的soundpool正好解决了这一问题
2.怎么制作jar包?
可以参考我的上一篇文章(https://blog.csdn.net/qq_14931305/article/details/82591314)这里只做简单的总结:
- build.gradle中 apply plugin: 'com.android.application'修改成apply plugin: 'com.android.library'
- build.gradle中删除 applicationId "com.*******.****"
- 重新build项目(点击build---->Rebuild project)
- 查找生成的项目aar包,找到项目存放的位置myproject---->build---->outputs---->aar---->myproject.aar
- myproject.aar修改成myproject.zip
- myproject.zip解压
- 找到classes.jar包,这就是你需要的jar包,为了区别其他的jar包最好把jar包的名字修改一下,如果有资源文件记得把资源文件也要放到unity3d中
3.下面要说的就是soundpool的代码
代码奉上之前我们需要做的是把音乐文件放到我们的res---->assets---->mysound文件夹下,此处的mysound文件夹是自己新建的,为了区别其他的资源文件,此文件夹下放得都是要提供给unity3d的音乐文件,有人问:为什么不放在raw下面,原因是api提供2个方法 :
getAssets().openFd("mysound/"+soundName),//可以通过soundName找到对应的资源文件
String[] arr =context.getResources().getAssets().list("mysound");//可以对mysound文件夹下的音乐文件实现所有的预加载,现用现加载有点慢,我们可以提前加载,用到的时候可以通过音乐名字直接播放音乐,记得最后关闭的时候释放一下预加载的资源。
具体代码如下:
package com.gamestar.nativesoundpool;
import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.util.Log;
import java.io.IOException;
import java.util.HashMap;
public class JavaSoundPool {
private final static int Max_Stream = 8;
private SoundPool _pool;
private HashMap<String, Integer> mSoundIDMap;
JavaSoundPool(){
if( android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
_pool = new SoundPool(Max_Stream, AudioManager.STREAM_MUSIC, 0);
}else{
SoundPool.Builder builder = new SoundPool.Builder();
builder.setAudioAttributes(new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_GAME)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).build());
builder.setMaxStreams(Max_Stream);
_pool = builder.build();
}
mSoundIDMap = new HashMap<>();
}
public int load(Context context, String soundName) {
// TODO Auto-generated method stub
try {
int soundId =_pool.load(context.getAssets().openFd("mysound/"+soundName),0);
mSoundIDMap.put(soundName.substring(0,soundName.indexOf(".")), soundId);
Log.e("UnityAndroidPlugin","soundId= "+soundId);
return soundId;
} catch (IOException e) {
e.printStackTrace();
Log.e("UnityAndroidPlugin","异常"+soundName);
return 0;
}
}
public void unload(String soundName) {
Integer soundId = mSoundIDMap.get(soundName);
if(soundId != null) {
_pool.unload(soundId);
mSoundIDMap.remove(soundName);
}
}
public int play(String soundName, float volume, float speed) {
Integer soundID = mSoundIDMap.get(soundName);
if(soundID != null) {
return _pool.play(soundID, volume, volume, 0, 0, speed);
}else {
Log.e("UnityAndroidPlugin","soundID为空 "+soundName);
}
return -1;
}
public void release() {
_pool.release();
mSoundIDMap.clear();
}
}
package com.gamestar.nativesoundpool;
import android.content.Context;
import android.util.SparseArray;
import android.util.SparseIntArray;
import java.util.HashMap;
/**
* SoundPoolManager
*/
public class SoundPoolManager{
static private SoundPoolManager instance = null;
/**
* Key is Sound Type defined by ourselves
*/
private HashMap<String, JavaSoundPool> mSoundPoolMap;
private SoundPoolManager() {
mSoundPoolMap = new HashMap<>();
}
public static SoundPoolManager getInstance() {
if(instance == null) {
instance = new SoundPoolManager();
}
return instance;
}
JavaSoundPool getSoundPoolByName(String instrumentName) {
if(mSoundPoolMap == null) {
return null;
}
JavaSoundPool soundPool = mSoundPoolMap.get (instrumentName);
if(soundPool == null) {
soundPool = new JavaSoundPool();
mSoundPoolMap.put(instrumentName, soundPool);
}
return soundPool;
}
void removeSoundPoolByName(String instrumentName) {
if(mSoundPoolMap == null) {
return;
}
JavaSoundPool soundPool = mSoundPoolMap.get(instrumentName);
if(soundPool != null) {
soundPool.release();
mSoundPoolMap.remove(instrumentName);
}
}
}
package com.gamestar.nativesoundpool;
import android.app.Activity;
import android.content.Context;
import java.io.IOException;
public class UnityAndroidPlugin {
static boolean createSoundPool(String soundPoolName) {
JavaSoundPool soundPool = SoundPoolManager.getInstance().getSoundPoolByName(soundPoolName);
if(soundPool == null) {
return false;
}else{
return true;
}
}
static void loadSound(final Context context, final String soundPoolName) {
new Thread(new Runnable() {
@Override
public void run() {
try {
String[] arr =context.getResources().getAssets().list("mysound");
for (String name:arr){
JavaSoundPool soundPool = SoundPoolManager.getInstance().getSoundPoolByName(soundPoolName);
soundPool.load(context, name);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
static int playSound(String soundPoolName, String soundName) {
JavaSoundPool soundPool = SoundPoolManager.getInstance().getSoundPoolByName(soundPoolName);
return soundPool.play(soundName, 1.0f, 1.0f);
}
static void releaseSoundPool(String soundPoolName) {
SoundPoolManager.getInstance().removeSoundPoolByName(soundPoolName);
}
}
4.Unity3D调用:
- 复制资源文件到unity3d中,在unity3d中asset下新建一个Plugins文件夹,一个Android文件夹,一个assets文件夹,一个bin文件夹,将音乐文件拷贝到mysound文件夹下,jar包放在bin下
- 调用jar包的代码
AndroidJavaObject m_activity = new AndroidJavaObject("com.gamestar.nativesoundpool.UnityAndroidPlugin"); //预加载所有assets/mysound文件夹下的音乐文件 m_activity.CallStatic<bool>("createSoundPool", SOUNDPOOLNAME); //播放指定歌曲 m_activity.CallStatic<int>("playSound", SOUNDPOOLNAME, soundName); //释放资源 m_activity.CallStatic("releaseSoundPool", GameController.SOUNDPOOLNAME);