国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

刨根問底U3D---Vector3 你到底是蔬菜呢還是水果呢?

2019-11-17 02:27:22
字體:
來源:轉載
供稿:網(wǎng)友

刨根問底U3D---Vector3 你到底是蔬菜呢還是水果呢?

事情的起因還是因為一段代碼,因為在做一個2D TileBase的游戲 所以需要有一個簡單的 Tile坐標到世界坐標的變換

public static Vector3 GetTileWorldPosByTileIndex(int _tileIndexX, int _tileIndexY , Vector3 _result){    if(_result == null)    {        _result = new Vector3();    }    _result.x = TileConst.TILE_WIDTH * _tileIndexX;    _result.y = TileConst.TILE_HEIGHT * _tileIndexY;    _result.z = 0;    return _result;}

代碼邏輯很簡單,特殊的地方就是后面?zhèn)魅氲腣ector3,因為函數(shù)會被經(jīng)常調用 所以不想每次都New出來一個新的Vector3. OK 運行..

Warning CS0472: The result of comparing value type `UnityEngine.Vector3' with null is `false'Unreachable code detected

WTF?! 哪里錯了? Vector3 居然不能和null 判等? 嘿經(jīng)過我一通測試 果真發(fā)現(xiàn)一些問題

來看如下的代碼

public class Test01 : MonoBehaviour{    void Start ()    {        int inputInt = 500;        int outputInt = SetIntWithRandom (inputInt);        Debug.Log (inputInt);    }        public  int SetIntWithRandom(int _input)    {        _input = Random.Range(-300,300);        return _input;    }}

這段應該很簡單,弄出來一個int 類型然后傳入函數(shù)內(nèi)部, 然后在Log出來 看看是否有發(fā)生改變。 Ok 運行

Log結果 500,

說明沒有發(fā)生任何改變。 也就是說 int 類型的變量是 傳值不是傳址的

再換下一組

public class Test01 : MonoBehaviour{    void Start ()    {        int[] inputIntArray = new int[2];        inputIntArray [0] = 500;        int[] outputIntArray = SetIntArrayWithRandom (inputIntArray);        Debug.Log (inputIntArray [0]);    }        public int[] SetIntArrayWithRandom(int[] _inputIntArray)    {        _inputIntArray[0] = Random.Range(-300,300);        return _inputIntArray;    }}

Log結果 -89 發(fā)生改變. 對于Array來說 是傳址不是傳值的.

Ok 來看 Vector3

public class Test01 : MonoBehaviour{    void Start ()    {        Vector3 inputV3 = new Vector3 ();        inputV3.x = 500;        Vector3 outputV3 =SetV3ValueWithRandom (inputV3);        Debug.Log (inputV3.x);    }        public Vector3 SetV3ValueWithRandom (Vector3 _result)    {        _result.x = Random.Range (-300, 300);        return _result;    }}

Log結果 500.

也就是說呢, 雖然Vector3 初始化時候 需要用New 操作符, 但是Vector3 卻是一個基礎類型 和 float,int 一樣

之前有很多類似的地方都是想節(jié)約內(nèi)存不每次進行new操作,于是類中做了一個引用,然后函數(shù)時候將引用傳過去。

Vector3 inputV3 = new Vector3 ();inputV3 =SetV3ValueWithRandom (inputV3)

現(xiàn)在看來,其實一點都沒有省...

這個也解釋了 為什么再給 transfrom的position賦值時候不能

transform.position.x = 100; 這樣去做 會報錯說

Error CS1612: Cannot modify a value type return value of `UnityEngine.Transform.position'. Consider storing the value in a temporary variable (CS1612)

我又做了幾個相關的測試,實在懶得寫了 :) 就把相關結果說一下吧(有興趣可以私聊哈)

1· 每次去New Vector3 對性能開銷大么?

PRofile了一下, 在一個Update里面 循環(huán)去new 10w個 Vector3, CPU和內(nèi)存都沒有任何的波動.

vod Update(){    Vector3 tmp;    for(int i=0 ; i<100000;i++)    {        Vector3 tmp = new Vector3();        tmp.x = Random.Range (-300, 300);    }    transform.position = tmp}

也就是完全把它當int來看就好了,雖然使用的是New操作符 總感覺 要有很大動靜似的...

vod Update(){    int tmp;    for(int i=0 ; i<100000;i++)    {        tmp = Random.Range (-300, 300);    }}

2· 雖然開銷很小 但是我還是想類中保留一個引用,然后不用每次去New出來 應該怎么做?

直接在函數(shù)的參數(shù)中改為ref即可, 感覺ref是C# 中很變態(tài)的東西 int啊 float啊什么的 都能ref (之前接觸到得As3,java是不行的 從C++上面繼承來的特性吧 這個應該是)

public static void GetTileWorldPosByTileIndex(int _tileIndexX, int _tileIndexY , ref Vector3 _result){    _result.x = TileConst.TILE_WIDTH * _tileIndexX;    _result.y = TileConst.TILE_HEIGHT * _tileIndexY;    _result.z = 0;}

3· 注意一下 Nullable Type

可以看下這篇文章 http://unitypatterns.com/nullable-types/

兩個問題,一個是說

Vector3 tmp;Debug.Log(tmp.x) //  這里會有結果,結果是0

也就是說 Vector3 在沒有new操作時候 是有默認值的 和 布爾默認值是false, int默認值是0 一個道理

第二個 如果不希望這樣的話 那就要使用 牛逼操作符 問號..

Vector3? tmp;if(tmp.HasValue){    Debug.Log(tmp.Value);}

在Vector3后面加一個問號 將其轉變?yōu)镹ullable Type 然后就可以用HasValue判斷是否有值 然后用 xxx.Value獲得這個值了

OK 繼續(xù)搞游戲去了..

Best

Eran

PS: 寫完以后被各種大神教育了一下,Struct問題 呵呵

其實Vector3是一個Struct 所以才有這種特性,如果有興趣可以看下MSDN

https://msdn.microsoft.com/en-us/library/aa288471%28v=vs.71%29.aspx

摘錄一段:

Structs vs. Classes

Structs may seem similar to classes, but there are important differences that you should be aware of. First of all, classes are reference types and structs are value types. By using structs, you can create objects that behave like the built-in types and enjoy their benefits as well.

Heap or Stack?

When you call the New Operator on a class, it will be allocated on the heap. However, when you instantiate a struct, it gets created on the stack. This will yield performance gains. Also, you will not be dealing with references to an instance of a struct as you would with classes. You will be working directly with the struct instance. Because of this, when passing a struct to a method, it's passed by value instead of as a reference.


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 晋中市| 普兰店市| 江北区| 鄂托克前旗| 伊宁市| 洪泽县| 搜索| 安塞县| 沾益县| 文昌市| 南开区| 张掖市| 天津市| 普格县| 华蓥市| 郸城县| 霍山县| 星子县| 铜山县| 平利县| 金山区| 甘南县| 堆龙德庆县| 连云港市| 崇州市| 天镇县| 林西县| 商丘市| 韶关市| 博白县| 丹巴县| 巨鹿县| 同江市| 潞西市| 武城县| 苗栗市| 垣曲县| 黑水县| 景宁| 洪洞县| 通山县|