c# - b\w if(raycast....) 和单独的 raycast 的任何区别
问题描述
以下两个代码之间有什么区别:
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 。这个问题让我很困惑。请帮忙详细解释一下。谢谢
解决方案
First of all: In your first snippet declaring RaycastHit hit;
after already having Physics.Raycast(..., out hit)
would be a compiler error ;)
Physics.Raycast
returns a bool
True if the ray intersects with a Collider, otherwise false.
So execution wise of the Raycast itself No! There is no difference ... it is up to you whether you use return values of methods or not ...
BUT without the if
check the value in hit
might be incomplete/invalid/not set at all and you would get exceptions trying to go on ...
The clue here RaycastHit
is a struct
! So different to a class
type it can not be null
but always has some default values.
You can not check e.g.
Physics.Raycast(transform.position, transform.forward, out var hit);
if(hit != null) // not possible!
{
...
}
So while some of the values might indicate it is invalid like hit.collider
or hit.gameObject
(basically all reference type properties) others again are structs or other value types themselves so they contain always a value .. which is not valid though like e.g. hit.point
(would by default be Vector3.zero
), hit.distance
(would be default be 0f
) etc (basically all value type properties).
Therefore to be sure you actually have hit something before using the values stored in hit
you use the bool
return value to check whether hit
actually contains valid data or not.
Usually always when you use the out
keyword you let your method return bool
for indicating whether the out
parameter was successfully filled or not.
As explanation let's just look at this example (maybe not the best but I couldn't come up with something more explanatory) using 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
}
Now ofcourse you could use something like
FindObject("", out var obj);
obj.transform.position = Vector3.zero;
but it will always throw an exception!
Therefore you rather want to check whether it actually succeeded
if(FindObject("abc", out var obj)
{
obj.transform.position = Vector3.zero;
}
Note btw that instead of
transform.TransformDirection(Vector3.forward)
you should rather simply use
transform.forward
推荐阅读
- laravel - How to OrderBy HasManyThrough Relation 特定列
- processing - P3D 草图在 Python 处理模式下不起作用
- r - 如何修剪r中的向量?
- java - 更改 ID 字符串后 Java 性能严重下降
- sql-server - SQL Server - 多个客户的同一张表
- android - Java,Android - 当设备设置为深色主题时,应用程序在首次启动应用程序时以深色模式打开
- r - 如何通过在 R 中重复其值来扩展向量以匹配另一个向量?
- javascript - 使用 webpack 响应延迟加载模块
- ruby-on-rails - 使用 react 和 json 将图像上传到 rails
- python - 如何在 `setup.py` 中设置 bin 脚本入口点?