Unity开发遇到的问题集合


1. Unity打包安卓帧率受限

Unity打包安卓之后默认是最高30帧,这是Unity官方对于帧率限制的说明:Application.targetFrameRate
里面提到,对于安卓而言,需要设置两个地方:1)QualitySettings.vSyncCount;2)targetFrameRate;

  1. QualitySettings.vSyncCount
    打开Buile Settings —> Player Settings —> Quality —> VSync count 设为Don’t Sync
    在这里插入图片描述

  2. targetFrameRate
    在项目Start()中添加Application.targetFrameRate = 60;将帧率设置为60,如果由于机器无法达到60的帧率,那将会以最大的帧率运行。若设置为-1,将按照平台默认的帧率运行。
    在这里插入图片描述
    在这里插入图片描述

2. Unity打包安卓没有声音

Asset Store搜索“Android Native Audio”。
在这里插入图片描述
添加进项目工程里面后,可以看到里面有两个PDF,这就是使用教程了:

  1. ANA Music:针对长音乐,例如BGM;
  2. Android Native Audio:针对短音乐,例如开枪音效;

在这里插入图片描述
在此拿ANA Music 说明,可以看到里面对于使用方法都说得很清楚了。
ANA Music 的生命周期:
在这里插入图片描述
ANA Music 的用例:
在这里插入图片描述
  使用方法非常简单啊,只需要先获取音乐的musicID,然后通过调用ANAMusic.play() 函数就可以实现音乐播放了。

游戏初始化:

/*===== 游戏音乐 =====*/
this.musicBlocks = FadedMusic.data.blocks;	//方块数据
this.totalBlocks = this.musicBlocks.Length;	//数据量大小
#if UNITY_ANDROID && !UNITY_EDITOR
this.musicID = ANAMusic.load("car.ogg");
#else
this.music = this.gameObject.AddComponent<AudioSource>();
this.music.clip = ResMgr.Instance.GetAssetCache<AudioClip>(FadedMusic.soundUrl);	//获取音乐资源
#endif
/*===== 开始游戏 =====*/
this.gameStart();

开始播放音乐:

/* 开始游戏 */
private void gameStart() {
    
    
#if UNITY_ANDROID && !UNITY_EDITOR
	ANAMusic.play(this.musicID);
#else
	this.music.Play();					//播放音乐
#endif
	this.musicStartTime = Time.time;	//记录游戏开始的时间戳
	this.FPS_time = Time.time;
}

  在此我将环境分为安卓平台和其他平台两种,如果当前是安卓环境,则使用ANAMusic.play() 播放音乐,不然则使用AudioSource 进行播放。
在这里插入图片描述

3. Unity打包安卓与蓝牙模块HC-05通讯

  我们需要实现Unity调用手机BLE与蓝牙模块进行连接通讯,Asset Store 搜索“Arduino Bluetooth Plugin”并下载,或者在这个链接进行下载:【Unity安卓蓝牙插件

将该插件导入项目中,这个Arduino Unity Plugin 文件就是使用文档
在这里插入图片描述
文档里面对于插件的使用做了较为详细的说明:
在这里插入图片描述
首先就是需要进行一些配置,然后需要将插件中的Plugins 文件夹移到与BluetoothAPI 同级位置。
(如果平台是PC或者IOS等,文档中有更加详细的操作指示)

建立连接:
在这里插入图片描述
  在这张图中对于如何建立蓝牙连接都给了较为详细的步骤,并且在Scripts/manager.cs 中有详细的用例:
在这里插入图片描述

void Start () {
    
    
	deviceName = "HC-05"; //bluetooth should be turned ON;
	try{
    
    	
		bluetoothHelper = BluetoothHelper.GetInstance(deviceName);
		bluetoothHelper.OnConnected += OnConnected;
		bluetoothHelper.OnConnectionFailed += OnConnectionFailed;
		bluetoothHelper.OnDataReceived += OnMessageReceived; //read the data

		bluetoothHelper.setTerminatorBasedStream("\n"); //delimits received messages based on \n char

        LinkedList<BluetoothDevice> ds = bluetoothHelper.getPairedDevicesList();

        foreach(BluetoothDevice d in ds)
            Debug.Log($"{d.DeviceName} {d.DeviceAddress}");
	}
	catch (Exception ex){
    
    
		sphere.GetComponent<Renderer>().material.color = Color.yellow;
		Debug.Log (ex.Message);
		text.text = ex.Message;
	}
}
  1. 首先就是定义了我们需要连接的蓝牙模块的名称"HC-05",然后通过这个名称获取instance;
  2. 接着添加了一系列的事件(cs文件中有定义);
  3. 打印手机已经配对过的设备(注意:如果想要连接一个蓝牙模块,需要先与其配对,所以对于那些无法配对的蓝牙模块,就不适合与手机进行连接);
void OnGUI()
{
    
    
	if(bluetoothHelper!=null)
		bluetoothHelper.DrawGUI();
	else 
	return;

	if(!bluetoothHelper.isConnected())
	if(GUI.Button(new Rect(Screen.width/2-Screen.width/10, Screen.height/10, Screen.width/5, Screen.height/10), "Connect"))
	{
    
    
		if(bluetoothHelper.isDevicePaired())
			bluetoothHelper.Connect (); // tries to connect
		else
			sphere.GetComponent<Renderer>().material.color = Color.magenta;
	}
}

  这也是Scripts/manager.cs 中的代码,绘制一个按键用以对前面定义的bluetoothHelper 进行连接。
在这里插入图片描述

4. Unity播放动画

首先导入fbx 动画模型的资源:
在这里插入图片描述
然后可以将动画模型的资源移动到项目中的Resources 文件夹中,该文件夹中的资源可以直接在代码中获取,非常方便。
在这里插入图片描述
可以看到,这个动画模型有四个动画,分别为idle、left_hook、left_straight、left_swing(动画帧数、增添和删减可以在右侧Inspector 边栏中进行操作)。

然后在代码中对Resources 文件夹中的资源进行获取并播放动画:

void Start(){
    
    
	var obj_fist = Resources.Load("fist");				//获取拳套资源
	this.fist = Instantiate(obj_fist) as GameObject;	//实例化对象
	this.fist.name = obj_fist.name;
	this.fist.AddComponent<Punch>();					//链接脚本
}

void OnGUI(){
    
    
	/* 绘制拳击按键 */
	if(GUI.Button(new Rect(Screen.width/2+Screen.width/10*3, Screen.height/5, Screen.width/5, Screen.height/10), "LS")){
    
    
		Punch.LeftStraight();
	}
	if(GUI.Button(new Rect(Screen.width/2+Screen.width/10*3, Screen.height/10*3, Screen.width/5, Screen.height/10), "LW")){
    
    
		Punch.LeftSwing();
	}
	if(GUI.Button(new Rect(Screen.width/2+Screen.width/10*3, Screen.height/5*2, Screen.width/5, Screen.height/10), "LH")){
    
    
		Punch.LeftHook();
}

Punch.cs 中定义动画播放的方法:

private static new Animation animation;

void Start(){
    
    
    animation = GetComponent<Animation>();
    }
}

public static void LeftStraight(){
    
    
    animation.Play("left_straight");
}
public static void LeftSwing(){
    
    
    animation.Play("left_swing");
}
public static void LeftHook(){
    
    
    animation.Play("left_hook");
}

在这里插入图片描述

5. 场景跳转

该部分代码参考《Unity 3D游戏开发(第2版)》P393 场景管理

Unity提供同步切换和异步切换:

//同步切换场景
SceneManager.LoadScene("sceneName");
//异步切换场景
SceneManager.LoadSceneAsync("sceneName");

首先创建一个cs文件SceneLoadManager.cs,并键入以下代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

public class SceneLoadManager : MonoBehaviour
{
    
    
    static AsyncOperation m_AsyncOperation;
    static UnityAction<float> m_Progress;

    //加载场景
    //name 场景名,progress回调加载进度,finish 回调加载场景结束
    static public void LoadScene(string name, UnityAction<float>progress, UnityAction finish){
    
    
        new GameObject("#SceneLoadManager#").AddComponent<SceneLoadManager>();
        m_AsyncOperation = SceneManager.LoadSceneAsync(name, LoadSceneMode.Single);
        m_Progress = progress;

        //加载完毕后抛出事件
        m_AsyncOperation.completed += delegate(AsyncOperation obj){
    
    
            finish();
            m_AsyncOperation = null;
        };
    }

    // Update is called once per frame
    void Update()
    {
    
    
        if(m_AsyncOperation != null){
    
    
            //抛出加载进度
            if(m_Progress != null){
    
    
                m_Progress(m_AsyncOperation.progress);
                m_Progress = null;
            }
        }
    }
}

上述代码最后需要监听加载进度,并在加载结束的地方进行调用。拿到加载进度,就可以在UI 上个显示。

然后创建一个新的场景New Scene
在这里插入图片描述
然后点击File > Build Settings…
在这里插入图片描述
接着点击Add Open Scenes(注意:此动作需要在打开新场景New Scene 的前提下进行)
在这里插入图片描述
就可以看到当前的New Scene 添加进来了
在这里插入图片描述
切换新场景会自动卸载老场景,如果需要在跳转场景时禁止卸载初始化的游戏对象,可以在需要进行跳转的cs 文件中键入以下代码:
(需要using UnityEngine.SceneManagement;

void Start(){
    
    
	//禁止切换场景时卸载初始化的游戏对象
	GameObject[]InitGameObjects = GameObject.FindObjectsOfType<GameObject>();
	foreach(GameObject go in InitGameObjects){
    
    
		if(go.transform.parent == null)
			GameObject.DontDestroyOnLoad(go.transform.root);
	}
}

跳转场景:

//加载场景
SceneLoadManager.LoadScene("New Scene", delegate(float progress){
    
    
	Debug.LogFormat("加载进度:{0}", progress);
}, delegate(){
    
    
	Debug.Log("加载结束");
});

在这里插入图片描述

6. 使用Button

首先在Canvas 中创建Button
在这里插入图片描述
然后创建一个StartScene.cs 文件

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class StartScene : MonoBehaviour
{
    
    
    public Button button_start;
    public Button button_setting;
    public Button button_quit;

    // Start is called before the first frame update
    void Awake() {
    
    
        button_start.onClick.AddListener(delegate(){
    
    
            OnClick(button_start.gameObject);
        });

        button_setting.onClick.AddListener(delegate(){
    
    
            OnClick(button_setting.gameObject);
        });

        button_quit.onClick.AddListener(delegate(){
    
    
            OnClick(button_quit.gameObject);
        });
    }

    // Update is called once per frame
    void OnClick(GameObject go)
    {
    
    
        if(go == button_start.gameObject) {
    
    
            Debug.Log("button_start");
        } else if(go == button_setting.gameObject) {
    
    
            Debug.Log("button_setting");
        } else if(go == button_quit.gameObject) {
    
    
            Debug.Log("button_quit");
            GetExit();
        }
    }

    public void GetExit()//退出运行
    {
    
    
#if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;//用于退出运行
#else
        Application.Quit();
#endif
    }
}

然后在Canvas 中创建一个空物体,命名为UIManager
在这里插入图片描述
为该物体附上StartScene.cs文件,并将文件中定义的三个Button button_startbutton_settingbutton_quit分别绑定三个按键:
在这里插入图片描述
如此便OK了,点击三个按键都会触发OnClick(),并在函数中对具体的触发按键进行不同的相应
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_40973138/article/details/124317652