刨根问底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 = ;
return _result;
}
代码逻辑很简单,特殊的地方就是后面传入的Vector3,因为函数会被经常调用 所以不想每次都New出来一个新的Vector3. OK 运行..
Warning CS0472: The result of comparing value type `UnityEngine.Vector3' with null is `false'
Unreachable code detected
WTF?! 哪里错了? Vector3 居然不能和null 判等? 嘿经过我一通测试 果真发现一些问题
来看如下的代码
public class Test01 : MonoBehaviour
{
void Start ()
{
;
int outputInt = SetIntWithRandom (inputInt);
Debug.Log (inputInt);
}
public int SetIntWithRandom(int _input)
{
_input = Random.Range(-,);
return _input;
}
}
这段应该很简单,弄出来一个int 类型然后传入函数内部, 然后在Log出来 看看是否有发生改变。 Ok 运行
Log结果 500,
说明没有发生任何改变。 也就是说 int 类型的变量是 传值不是传址的
再换下一组
public class Test01 : MonoBehaviour
{
void Start ()
{
];
inputIntArray [] = ;
int[] outputIntArray = SetIntArrayWithRandom (inputIntArray);
Debug.Log (inputIntArray []);
}
public int[] SetIntArrayWithRandom(int[] _inputIntArray)
{
_inputIntArray[] = Random.Range(-,);
return _inputIntArray;
}
}
Log结果 -89 发生改变. 对于Array来说 是传址不是传值的.
Ok 来看 Vector3
public class Test01 : MonoBehaviour
{
void Start ()
{
Vector3 inputV3 = new Vector3 ();
inputV3.x = ;
Vector3 outputV3 =SetV3ValueWithRandom (inputV3);
Debug.Log (inputV3.x);
}
public Vector3 SetV3ValueWithRandom (Vector3 _result)
{
_result.x = Random.Range (-, );
return _result;
}
}
Log结果 500.
也就是说呢, 虽然Vector3 初始化时候 需要用New 操作符, 但是Vector3 却是一个基础类型 和 float,int 一样
之前有很多类似的地方都是想节约内存不每次进行new操作,于是类中做了一个引用,然后函数时候将引用传过去。
Vector3 inputV3 = new Vector3 (); inputV3 =SetV3ValueWithRandom (inputV3)
现在看来,其实一点都没有省...
这个也解释了 为什么再给 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里面 循环去new 10w个 Vector3, CPU和内存都没有任何的波动.
vod Update()
{
Vector3 tmp;
; i<;i++)
{
Vector3 tmp = new Vector3();
tmp.x = Random.Range (-, );
}
transform.position = tmp
}
也就是完全把它当int来看就好了,虽然使用的是New操作符 总感觉 要有很大动静似的...
vod Update()
{
int tmp;
; i<;i++)
{
tmp = Random.Range (-, );
}
}
2· 虽然开销很小 但是我还是想类中保留一个引用,然后不用每次去New出来 应该怎么做?
直接在函数的参数中改为ref即可, 感觉ref是C# 中很变态的东西 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 = ;
}
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后面加一个问号 将其转变为Nullable Type 然后就可以用HasValue判断是否有值 然后用 xxx.Value获得这个值了
OK 继续搞游戏去了..
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.
刨根问底U3D---Vector3 你到底是蔬菜呢还是水果呢?的更多相关文章
- JS or C#?不存在的脚本之争
前言: 又来到了周末,小匹夫也终于有了喘口气写写博客的时间和精力.话说周五的下午,小匹夫偶然间晃了一眼蛮牛的QQ群,又看到了一个Unity3D开发中老生长谈的问题,“我的开发语言究竟是选择JavaSc ...
- Cpu Gpu 内存 显存 数据流
[精]从CPU架构和技术的演变看GPU未来发展 http://www.pcpop.com/doc/0/521/521832_all.shtml 显存与纹理内存详解 http://blog.csdn.n ...
- unity3D用什么语言开发好?
unity3D用什么语言开发好? 一.总结 一句话总结:选c# 同时U3D团队也会把支持的重心转移到C#,也就是说文档和示例以及社区支持的重心都在C#,C#的文档会是最完善的,C#的代码实例会是最详细 ...
- Java泛型使用的简单介绍
目录 一. 泛型是什么 二. 使用泛型有什么好处 三. 泛型类 四. 泛型接口 五. 泛型方法 六. 限定类型变量 七. 泛型通配符 7.1 上界通配符 7.2 下界通配符 7.3 无限定通配符 八. ...
- 9102 IT人保持记忆力及健康的方法
做技术时间久了,我们会发现有的时候我们会感觉记忆力衰减太快,前脚刚忙完的事或者刚做完计划任务没多久就遗忘了,或者是以前轻车熟入的方法死活都记不起来了,亦或者之前学习一门技术很快就掌握真谛,现在即便花N ...
- Study 5 —— CSS概述
CSS(Cascading Style Sheet)称为层叠样式表,也可以称为CSS样式表或样式表,其文件扩展名为.css,CSS是用于增强或控制网页样式,并允许将样式信息与网页内容分离的一种标记性语 ...
- 金字塔原理(Pyramid Principle)
什么是金字塔原理?简单来说,金字塔原理就是“中心论点---分论点---支撑论据”这样的一个结构. 图片摘自:http://www.woshipm.com/pmd/306704.html 人类通常习惯于 ...
- Android使用Mono c#分段列表视图
下载source code - 21.7 KB 你想知道如何把多个ListView控件放到一个布局中,但是让它们在显示时表现正确吗 多个列表项?你对它们正确滚动有问题吗?这个例子将向你展示如何组合单独 ...
- u3d中的向量 vector3 vector2
Vector3(x,y,z)x代表左右,y代表上下,z代表前后 Vector3.magnitude 长度 计算两点之间的距离 .如果只给了一点的话.算出的长度其实就是和Vector3.zero点之间 ...
随机推荐
- JavaScript进阶篇
组团,并给团取个名(如何创建数组) 使用数组之前首先要创建,而且需要把数组本身赋至一个变量.好比我们出游,要组团,并给团定个名字“云南之旅”. 创建数组语法: var myarray=new Arra ...
- 去掉inline-block元素默认间距的几种方法
方法1:使用负margin值一般是-3px,部分浏览器可能不同,不太推荐使用. 方法2:去掉多余空格将元素紧挨着写去掉多余空格,但降低了可读性. 方法3:使用font-size:0在外层父元素加上fo ...
- iOS 电话在后台运行时,我的启动图片被压缩
一,经历 <1> 第一感觉是启动图片没有设置好,长度设置小了.但是和网上说的正确方式相比,没什么差别. <2> 害怕是控制器影响的,又新建了一个项目,来检验启动图片是否设置成功 ...
- 20145330Java程序设计第三次实验
20145330<Java程序设计>第三次实验报告 实验三 敏捷开发与XP实践 实验内容 1.使用git上传代码 2.使用git实现代码开发实践 3.实现代码的重载 实验步骤 使用git上 ...
- 分模块创建maven项目(二)
1.新建Parent项目,MavenProject 2.新建子模块项目,MavenProject 右击项目名 --> NEW --> other 结果,在parent上运行会打出两个包,一 ...
- [转]as3事件流机制彻底理解
题记: 看过网上一些as3事件流的教程,觉得大多都讲得不甚清楚,让人不能直观的理解事件流.而这篇教程以将事件流过程比喻成捕鱼过程,形象简单. 在此基础上对于as3事件流总算有了全面的理解.事件流机制说 ...
- 如何打印出lua里table的内容
不像开发as3时用fb有强大的断点调试功能,一般lua开发不用什么高级的ide,貌似也没有适合的,就直接用sublime.exvim等文本编辑器,直接编译运行看结果.所以不能很方便的知道变量值,特别是 ...
- 多态(Java)
一.多态 1.什么是多态? 解析:不同的对象对于同一个操作,做出的响应不同 具有表现多种形态的能力的特征 2.使用多态的优点 解析:为了实现统一调用 一个小例子:<父类类型作为参数> 父类 ...
- Odoo Website 替换 Summernote 为第三方富文本编辑器
随着用odoo的人越来越多,奇葩的需求也是越来越多.... 这不,有同学就想替换掉website forum里边的summernote控件,花了点时间研究了一下,先说结论:替换是可行的. 先上替换之后 ...
- 数位DP bzoj1026
1026: [SCOI2009]windy数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 5809 Solved: 2589[Submit][Sta ...