A collection of problems encountered in Unity development


1. Unity package Android frame rate is limited

After Unity packages Android, the default is up to 30 frames. This is Unity's official description of the frame rate limit: Application.targetFrameRate
mentioned that for Android, you need to set two places: 1) QualitySettings.vSyncCount; 2) targetFrameRate;

  1. QualitySettings.vSyncCount
    Open Buile Settings —> Player Settings —> Quality —> VSync count set to Don't Sync
    insert image description here

  2. targetFrameRate
    is added in the project Start() Application.targetFrameRate = 60;to set the frame rate to 60. If the machine cannot reach the frame rate of 60, it will run at the maximum frame rate. If set to -1, it will run at the platform's default frame rate.
    insert image description here
    insert image description here

2. There is no sound when Unity packs Android

Search the Asset Store for "Android Native Audio".
insert image description here
After adding it into the project project, you can see that there are two PDFs in it. This is the tutorial:

  1. ANA Music: For long music, such as BGM;
  2. Android Native Audio: For short music, such as gunshot sound effects;

insert image description here
Take the ANA Music instructions here, and you can see that the usage methods are very clear.
ANA Music's life cycle:
insert image description here
ANA Music's use case:
insert image description here
  It's very simple to use, just get the music ID of the music first, and then call the ANAMusic.play() function to play the music.

Game initialization:

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

Start playing music:

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

  Here I divide the environment into Android platform and other platforms. If the current environment is Android, use ANAMusic.play() to play music, otherwise use AudioSource to play.
insert image description here

3. Unity package Android and bluetooth module HC-05 communication

  We need to enable Unity to call the mobile phone BLE to connect and communicate with the Bluetooth module. Search for "Arduino Bluetooth Plugin" in the Asset Store and download it, or download it from this link: [Unity Android Bluetooth Plugin ]

Import the plug-in into the project, this Arduino Unity Plugin file is the use document. The
insert image description here
use of the plug-in is described in detail in the document:
insert image description here
first, some configuration is required, and then the Plugins folder in the plug-in needs to be moved to the same level as BluetoothAPI Location.
(If the platform is PC or IOS, etc., there are more detailed operation instructions in the document)

Establishing a connection:
insert image description here
  In this figure, there are more detailed steps on how to establish a Bluetooth connection, and Scripts/manager.csthere are detailed use cases in :
insert image description here

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. The first is to define the name of the Bluetooth module we need to connect "HC-05", and then get the instance through this name;
  2. Then add a series of events (defined in the cs file);
  3. Print the devices that the mobile phone has been paired with (Notice: If you want to connect a Bluetooth module, you need to pair it first, so for those Bluetooth modules that cannot be paired, it is not suitable for connecting with the mobile phone);
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;
	}
}

  This is also Scripts/manager.csthe code in that draws a button to bluetoothHelperconnect to the previously defined .
insert image description here

4. Unity plays animation

First import the resources of the fbx animation model:
insert image description here
then you can move the resources of the animation model to the Resources folder in the project, and the resources in this folder can be obtained directly in the code, which is very convenient.
insert image description here
It can be seen that this animation model has four animations, which are idle, left_hook, left_straight, and left_swing (the animation frame number, addition and deletion can be operated in the right Inspector sidebar).

Then get the resources in the Resources folder in the code and play the animation:

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.csDefine animation playback methods in :

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

insert image description here

5. Scene jump

This part of the code refers to "Unity 3D Game Development (2nd Edition)" P393 Scene Management

Unity provides synchronous switching and asynchronous switching:

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

First create a cs file SceneLoadManager.csand type the following code:

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

The above code finally needs to monitor the loading progress and call it at the end of loading. Once you get the loading progress, you can display it on the UI.

Then create a new scene New Scene:
insert image description here
then click File > Build Settings...
insert image description here
then click Add Open Scenes (Notice: This action needs to be performed on the premise of opening a new scene, New Scene),
insert image description here
and you can see that the current New Scene is added
insert image description here
. Switching to a new scene will automatically uninstall the old scene. Type the following code in the cs file that needs to be jumped:
(required 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);
	}
}

Jump scene:

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

insert image description here

6. Using Buttons

First create Button in Canvas
insert image description here
and then create a StartScene.csfile

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

Then create an empty object in Canvas, name it UIManager: Attach a file
insert image description here
to the object , and bind the three Button , , StartScene.csdefined in the file to three buttons respectively: then OK, click the three buttons will trigger , and Different responses to specific trigger buttons in the functionbutton_startbutton_settingbutton_quit
insert image description here
OnClick()
insert image description here

Guess you like

Origin blog.csdn.net/weixin_40973138/article/details/124317652