Una colección de problemas encontrados en el desarrollo de Unity


1. La velocidad de fotogramas de Android empaquetada en Unity es limitada

Después de que Unity empaqueta Android, el valor predeterminado es hasta 30 fotogramas. Esta es la descripción oficial de Unity del límite de velocidad de fotogramas: Application.targetFrameRate mencionó
que para Android, debe establecer dos lugares: 1) QualitySettings.vSyncCount, 2) targetFrameRate;

  1. QualitySettings.vSyncCount
    Abra Configuración Buile —> Configuración del reproductor —> Calidad —> Recuento de VSync establecido en No sincronizar
    inserte la descripción de la imagen aquí

  2. targetFrameRate
    se agrega en el proyecto Start() Application.targetFrameRate = 60;para establecer la velocidad de fotogramas en 60. Si la máquina no puede alcanzar la velocidad de fotogramas de 60, se ejecutará a la velocidad de fotogramas máxima. Si se establece en -1, se ejecutará a la velocidad de fotogramas predeterminada de la plataforma.
    inserte la descripción de la imagen aquí
    inserte la descripción de la imagen aquí

2. No hay sonido cuando Unity empaqueta Android

Busque en la tienda de recursos "Android Native Audio".
inserte la descripción de la imagen aquí
Después de agregarlo al proyecto del proyecto, puede ver que hay dos archivos PDF en él. Este es el tutorial:

  1. ANA Music: para música larga, como BGM;
  2. Android Native Audio: para música corta, como efectos de sonido de disparos;

inserte la descripción de la imagen aquí
Tome las instrucciones de ANA Music aquí y verá que los métodos de uso son muy claros.
Ciclo de vida de ANA Music:
inserte la descripción de la imagen aquí
caso de uso de ANA Music:
inserte la descripción de la imagen aquí
  es muy simple de usar, solo obtenga primero la identificación de la música y luego llame a la función ANAMusic.play() para realizar la reproducción de música.

Inicialización del juego:

/*===== 游戏音乐 =====*/
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();

Empezar a reproducir música:

/* 开始游戏 */
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;
}

  Aquí divido el entorno en plataforma Android y otras plataformas. Si el entorno actual es Android, use ANAMusic.play() para reproducir música, de lo contrario, use AudioSource para reproducir.
inserte la descripción de la imagen aquí

3. Paquete Unity Android y módulo bluetooth Comunicación HC-05

  Necesitamos permitir que Unity llame al teléfono móvil BLE para conectarse y comunicarse con el módulo Bluetooth. Busque "Arduino Bluetooth Plugin" en la tienda de activos y descárguelo, o descárguelo desde este enlace: [Unity Android Bluetooth Plugin ]

Importe el complemento al proyecto, este archivo Arduino Unity Plugin es el documento de uso. El
inserte la descripción de la imagen aquí
uso del complemento se describe en detalle en el documento:
inserte la descripción de la imagen aquí
primero, se requiere alguna configuración y luego la carpeta Complementos en el complemento. es necesario moverlo al mismo nivel que la ubicación de BluetoothAPI.
(Si la plataforma es PC o IOS, etc., hay instrucciones de operación más detalladas en el documento)

Establecimiento de una conexión:
inserte la descripción de la imagen aquí
  en esta figura, hay pasos más detallados sobre cómo establecer una conexión Bluetooth, y Scripts/manager.cshay casos de uso detallados en:
inserte la descripción de la imagen aquí

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. Lo primero es definir el nombre del módulo Bluetooth que necesitamos conectar "HC-05", y luego obtener la instancia a través de este nombre;
  2. Luego agregue una serie de eventos (definidos en el archivo cs);
  3. Imprimir los dispositivos con los que se ha emparejado el teléfono móvil (Aviso: si desea conectar un módulo Bluetooth, primero debe emparejarlo, por lo que para aquellos módulos Bluetooth que no se pueden emparejar, no es adecuado para conectar con el teléfono móvil);
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;
	}
}

  Este es también Scripts/manager.csel código en el que se dibuja un botón para bluetoothHelperconectarse al previamente definido.
inserte la descripción de la imagen aquí

4. Unity reproduce animación

Primero importe los recursos del modelo de animación fbx:
inserte la descripción de la imagen aquí
luego puede mover los recursos del modelo de animación a la carpeta Recursos en el proyecto, y los recursos en esta carpeta se pueden obtener directamente en el código, lo cual es muy conveniente.
inserte la descripción de la imagen aquí
Se puede ver que este modelo de animación tiene cuatro animaciones, que son inactiva, gancho izquierdo, recto izquierdo y oscilación izquierda (el número de cuadro de animación, la adición y la eliminación se pueden operar en la barra lateral derecha del Inspector).

Luego obtenga los recursos en la carpeta Recursos en el código y reproduzca la animación:

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.csDefina los métodos de reproducción de animación en :

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");
}

inserte la descripción de la imagen aquí

5. Salto de escena

Esta parte del código hace referencia a "Unity 3D Game Development (2nd Edition)" P393 Gestión de escena

Unity proporciona conmutación síncrona y conmutación asíncrona:

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

Primero cree un archivo cs SceneLoadManager.csy escriba el siguiente código:

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;
            }
        }
    }
}

El código anterior finalmente necesita monitorear el progreso de la carga y llamarlo al final de la carga. Una vez que obtenga el progreso de carga, puede mostrarlo en la interfaz de usuario.

Luego cree una nueva escena New Scene:
inserte la descripción de la imagen aquí
luego haga clic en Archivo > Configuración de compilación...
inserte la descripción de la imagen aquí
luego haga clic en Agregar escenas abiertas (Aviso: Esta acción debe realizarse bajo la premisa de abrir una nueva escena, Nueva escena),
inserte la descripción de la imagen aquí
y puede ver que se agrega la Nueva escena actual
inserte la descripción de la imagen aquí
. Al cambiar a una nueva escena, se desinstalará automáticamente la escena anterior. Escriba el siguiente código en el cs archivo que necesita ser saltado:
(requerido 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);
	}
}

Escena de salto:

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

inserte la descripción de la imagen aquí

6. Uso de botones

Primero cree el botón en Canvas
inserte la descripción de la imagen aquí
y luego cree un StartScene.csarchivo

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
    }
}

A continuación, cree un objeto vacío en Canvas, asígnele un nombre UIManager: adjunte un archivo
inserte la descripción de la imagen aquí
al objeto y vincule los tres botones , StartScene.csdefinidos en el archivo a tres botones respectivamente: luego haga clic en Aceptar, haga clic en los tres botones y se activarán diferentes respuestas a un activador específico botones en la funciónbutton_startbutton_settingbutton_quit
inserte la descripción de la imagen aquí
OnClick()
inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_40973138/article/details/124317652
Recomendado
Clasificación