以下两个代码之间有什么区别吗:
if(Physics.Raycast(transform.position , transform.TransformDirection(Vector3.forward), out hit)){
RaycastHit hit;
targetDistance = hit.distance;
Physics.Raycast(transform.position , transform.TransformDirection(Vector3.forward), out hit;
.........
这不仅仅是一个简单的声明,是吗?我知道if(sth(等于if(sth==true(。但是,我认为没有必要在这里使用if。这个问题让我很困惑。请帮助详细解释。谢谢
首先:在您的第一个代码段中,在已经有Physics.Raycast(..., out hit)
之后声明RaycastHit hit;
将是编译器错误;(
Physics.Raycast
返回布尔
如果光线与碰撞器相交,则为True,否则为false。
所以Raycast本身的执行方式不!没有区别。。。是否使用方法的返回值取决于您。。。
但是如果没有if
检查,hit
中的值可能是不完整的/无效的/根本没有设置,并且您会遇到试图继续的异常。。。
这里的线索RaycastHit
是一个struct
!与class
类型不同,它不能是null
,但总是有一些默认值。
你不能检查,例如
Physics.Raycast(transform.position, transform.forward, out var hit);
if(hit != null) // not possible!
{
...
}
因此,虽然有些值可能表明它是无效的,比如hit.collider
或hit.gameObject
(基本上是所有引用类型属性(,但其他值本身也是结构或其他值类型,因此它们总是包含一个值。。这是无效的,尽管类似于例如hit.point
(默认为Vector3.zero
(、hit.distance
(默认为0f
(等(基本上所有值类型属性(。
因此,为了确保在使用存储在hit
中的值之前确实命中了一些内容,您可以使用bool
返回值来检查hit
是否实际包含有效数据。
通常,当您使用out
关键字时,您会让方法返回bool
,以指示out
参数是否已成功填充。
作为解释,让我们看看这个使用out
:的例子(也许不是最好的,但我无法想出更具解释性的东西(
bool FindObject(string name, out GameObject obj)
{
if(string.isNullOrWhiteSpace(name))
{
obj = null;
return false;
}
obj = GameObject.Find(name);
return obj; // true if obj exists
}
当然,现在你可以使用类似的东西
FindObject("", out var obj);
obj.transform.position = Vector3.zero;
但它总是会抛出一个异常!
因此,你更想检查它是否真的成功了
if(FindObject("abc", out var obj)
{
obj.transform.position = Vector3.zero;
}
注意,不是
transform.TransformDirection(Vector3.forward)
你应该简单地使用
transform.forward
来自Unity文档:
如果投射的光线与对撞机相交,则Raycast(…(将返回true。
因此,您代码的第一个版本中的内部块:
if(Physics.Raycast(transform.position , transform.TransformDirection(Vector3.forward), out hit)){
RaycastHit hit;
targetDistance = hit.distance;
}
将仅在投射的光线击中碰撞器时执行。
代码的第二个版本将始终执行,因为之前没有任何条件。
不管怎样,如果这是你问题的焦点,那么在这两种情况下都会播放雷。