gameObject.renderer.enabled
//是控制一個物體是否在屏幕上渲染或顯示 而物體實際還是存在的 只是想當於隱身 而物體本身的碰撞體還依然存在的
GameObject.Destroy()
//表示移除物體或物體上的組件 代表銷毀該物體 實際上該物體的內存並沒有立即釋放 而是在你下下個場景中槽釋放內存資源,就是你a場景中Destroy了 一般是在c場景中才真正釋放該物體的內存資源(這是我的體會 不知道理解錯誤沒)
gameObject.active
//是否在場景中停用該物體 在你gameObject.active =false中 則你在場景中用find找不到該物體
//如果該物體有子物體 你要用SetActiveRecursively(false) 來控制是否在場景中停用該物體(遞歸的)
我們要介紹是銷毀物體Destroy()
1 using UnityEngine; 2 using System.Collections; 3 4 public class acc : MonoBehaviour { 5 6 // Use this for initialization 7 public Transform Q; 8 int speed=50; 9 void Start () { 10 11 } 12 13 // Update is called once per frame 14 void Update () { 15 float x = Input.GetAxis("Horizontal") * Time.deltaTime * speed;//左右移動 16 float z = Input.GetAxis("Vertical") * Time.deltaTime * speed;// 前後移動 17 //主攝像機物體 移動 18 transform.Translate(x,0,z); 19 20 if(Input.GetKeyDown(KeyCode.Mouse0)) 21 { 22 23 //實列化子彈 24 Transform n = Instantiate(Q) as Transform; 25 //發射子彈的位置為物體的位置 26 n.position = transform.position; 27 28 Vector3 f = transform.TransformDirection(Vector3.forward); 29 n.gameObject.rigidbody.AddForce(f*3000); 30 Destroy(n.gameObject,5); 31 //Destroy(n.gameObject); 32 //Destroy(gameObject); 33 } 34 35 36 } 37 }
5秒後 銷毀物體
Destroy(n.gameObject,5);
立即銷毀物體
Destroy(n.gameObject);
如果文件綁定在物體上用
Destroy(gameObject);
來銷毀物體
Unity資源內存申請和釋放
GameObject, Transform, Mesh, Texture, Material, Shader, Script和各種其他Assets。
IEnumerator LoadResources()
{
// 清除干淨以免影響測試結果
Resources.UnloadUnusedAssets();
// 等待5秒以看到效果
yield return new WaitForSeconds(5.0f);
// 通過Resources.Load加載一個資源
GameObject tank = Resources.Load("Role/Tank") as GameObject;
yield return new WaitForSeconds(0.5f);
// Instantiate一個資源出來
GameObject tankInst = GameObject.Instantiate(tank, Vector3.zero, Quaternion.identity) as GameObject;
yield return new WaitForSeconds(0.5f);
// Destroy一個資源
GameObject.Destroy(tankInst);
yield return new WaitForSeconds(0.5f);
//釋放無用資源
tank = null;
Resources.UnloadUnusedAssets();
yield return new WaitForSeconds(0.5f);
}
執行結果如下:
下面是統計結果:
從這裡我們得出如下結論:
若沒有調用Resources.UnloadUnusedAssets,則結果如下:
統計結果如下:
得出如下結論: 如果不手動執行Resources.UnloadUnusedAssets,則多余的Mesh,Material和Object不會主動釋放。
代碼如下:
IEnumerator LoadAssets(string path)
{
// 清除干淨以免影響測試結果
Resources.UnloadUnusedAssets();
// 等待5秒以看到效果
yield return new WaitForSeconds(5.0f);
// 創建一個WWW類
WWW bundle = new WWW(path);
yield return bundle;
yield return new WaitForSeconds(0.5f);
// AssetBundle.Load一個資源
Object obj = bundle.assetBundle.Load("tank");
yield return new WaitForSeconds(0.5f);
// Instantiate一個資源出來
GameObject tankInst = Instantiate(obj) as GameObject;
yield return new WaitForSeconds(0.5f);
// Destroy一個資源
GameObject.Destroy(tankInst);
yield return new WaitForSeconds(0.5f);
// Unload Resources
bundle.assetBundle.Unload(false);
yield return new WaitForSeconds(0.5f);
// 釋放無用資源
//obj = null;
//Resources.UnloadUnusedAssets();
yield return new WaitForSeconds(0.5f);
}
執行結果如下: 統計結果如下:
得出如下結論: 通過WWW Load AssetBundle的方式加載一個資源時會自動加載相應的Mesh,Texture和Material,而通過Resouces.Load方式進行加載只會加載Mesh信息。因此通過AssetBundle方式加載後Instantiate一個資源的內存消耗較小,本例中AssetBundle.Load增加了2.5M的內存,而Instantiate增加了1.1M的內存。相比較Resources.Load後Instantiate的內存增量要小很多。
代碼如下:
IEnumerator InstResources()
{
Resources.UnloadUnusedAssets();
yield return new WaitForSeconds(5.0f);
GameObject inst = GameObject.Instantiate(tank, Vector3.zero, Quaternion.identity) as GameObject;
yield return new WaitForSeconds(1f);
GameObject.Destroy(inst);
yield return new WaitForSeconds(1f);
//釋放無用資源
tank = null;
Resources.UnloadUnusedAssets();
yield return new WaitForSeconds(1f);
}
執行結果如下:
統計結果如下:
得出結論如下: 通過靜態綁定的方式各種資源的加載順序和Resources.Load的方式是一樣的,一個GameObject創建時,其Component中靜態綁定的GameObject只會加載Mesh信息,只有當該GameObject Instantiate出來之後才會加載Texture和Material信息。
加載資源的過程可以分為兩個階段,第一階段是使用Resources.Load或者AssetBundle.Load加載各種資源,第二階段是使用GameObject.Instantiate克隆出一個新的GameObject。 Load的資源類型包括GameObject, Transform, Mesh, Texture, Material, Shader和Script等各種資源,但是Resources.Load和AssetBundle.Load是有區別的。 使用Resources.Load的時候在第一次Instantiate之前,相應的Asset對象還沒有被創建,直到第一次Instantiate時才會真正去讀取文件創建這些Assets。它的目的是實現一種OnDemand的使用方式,到該資源真正使用時才會去創建這些資源。 而使用AssetBundle.Load方法時,會直接將資源文件讀取出來創建這些Assets,因此第一次Instantiate的代價會相對較小。 上述區別可以幫助我們解釋為什麼發射第一發子彈時有明顯的卡頓現象的出現。
然後我們再來了解一下Instantiate的過程。Instantiate的過程是一個對Assets進行Clone(復制)和引用相結合的過程,Clone的過程需要申請內存存放自己的數據,而引用的過程只需要直接一個簡單的指針指向一個已經Load的資源即可。例如Transform是通過Clone出來的,Texture和TerrainData是通過引用復制的,而Mesh,Material,PhysicalMaterial和Script是Clone和引用同時存在的。以Script為例,Script分為代碼段和數據段,所有需要使用該Script的GameObject使用的代碼是一樣的,而大家的數據有所區別,因此對數據段需要使用Clone的方式,而對代碼段需要使用引用的方式來復制。 因此Load操作其實Load一些數據源出來,用於創建新對象時被Clone或者被引用。
然後是銷毀資源的過程。當Destory一個GameObject或者其他實例時,只是釋放實例中那些Clone出來的Assets,而並不會釋放那些引用的Assets,因為Destroy不知道是否有其他人在引用這些Assets。等到場景中沒有任何物體引用到這些Assets之後,它們就會成為UnusedAssets,此時可以通過Resources.UnloadUnusedAssets來進行釋放。AssetBundle.Unload(false)不行,因為它只會釋放文件的內存鏡像,不會釋放資源;AssetBunde.Unload(true)也不行,因為它是暴力的釋放,可能有其他對象在引用其中的Assets,暴力釋放可能導致程序錯誤。 另外需要注意,系統在加載新場景時,所有的內存對象都會被自動銷毀,這包括了Resources.Load加載的Assets, 靜態綁定的Assets,AssetBundle.Load加載的資源和Instantiate實例化的對象。但是AssetBundle.Load本身的文件內存鏡像(用於創建各種Asset)不會被自動銷毀,這個必須使用AssetBundle.Unload(false)來進行主動銷毀。推薦的做法是在加載完資源後立馬調用AssetBunble.Unload(false)銷毀文件內存鏡像。 下圖可以幫助理解內存中的Asset和GameObject的關系。
520 520小說 小說520 小說520 5200 小說5200 5200小說 5200小說網
www.520books.com
http://www.cnblogs.com/goodchenqing/
http://blog.sina.com.cn/goodchenqing
http://goodchenqing.bokee.com/
http://blog.csdn.net/abc288abcd/article/category/2786567