写在前面
【Unity API】系列!记录实现效果一路上遇到的Unity API,仅作个人学习记录。
在Unity里写工具时,总有场景需要用到两点发出射线求交的函数,Unity提供了一些API方便我们使用!例如最近在实现一个光晕效果的工具:
脚本里就用到了
官方手册:UnityEngine.Ray - Unity 脚本 API
关于射线的是一整个struct,首先是通过发出点origin+射线方向确定一个Struct Ray:
//
// 摘要:
// Representation of rays.
public struct Ray : IFormattable
{
//
// 摘要:
// Creates a ray starting at origin along direction.
//
// 参数:
// origin:
//
// direction:
public Ray(Vector3 origin, Vector3 direction);
//
// 摘要:
// The origin point of the ray.
public Vector3 origin { get; set; }
//
// 摘要:
// The direction of the ray.
public Vector3 direction { get; set; }
//
// 摘要:
// Returns a point at distance units along the ray.
//
// 参数:
// distance:
public Vector3 GetPoint(float distance);
//
// 摘要:
// Returns a formatted string for this ray.
//
// 参数:
// format:
// A numeric format string.
//
// formatProvider:
// An object that specifies culture-specific formatting.
public override string ToString();
//
// 摘要:
// Returns a formatted string for this ray.
//
// 参数:
// format:
// A numeric format string.
//
// formatProvider:
// An object that specifies culture-specific formatting.
public string ToString(string format);
//
// 摘要:
// Returns a formatted string for this ray.
//
// 参数:
// format:
// A numeric format string.
//
// formatProvider:
// An object that specifies culture-specific formatting.
public string ToString(string format, IFormatProvider formatProvider);
}
[Unity]教程------Ray(射线)的基本使用这个文章详细写了怎么通过射线检测碰撞物体。
再看看实现光晕,首先需要计算光晕方向
Ray ray = new Ray(m_GameCamera.transform.position, position);
然后Raycast(后面会提到)进行射线遮挡判断
if(Physics.Raycast(ray, out hit))
{
...
}
官方手册:Physics-Raycast - Unity 脚本 API
public static bool Raycast (Vector3 origin, Vector3 direction, float maxDistance= Mathf.Infinity, int layerMask= DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction= QueryTriggerInteraction.UseGlobal);
文档中对这个API的描述为:向场景中的所有碰撞体投射一条射线,该射线起点为 /origin/,朝向 /direction/,长度为 /maxDistance/
返回的值:返回的是一个bool变量,如果射线检测道碰撞机就返回true,否则返回false
RaycastHit hit;
// Does the ray intersect any objects excluding the player layer
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity, layerMask))
{
Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.yellow);
Debug.Log("Did Hit");
}
else
{
Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * 1000, Color.white);
Debug.Log("Did not Hit");
}
[NativeHeaderAttribute("Modules/Physics/RaycastHit.h")]
[NativeHeaderAttribute("Runtime/Interfaces/IRaycast.h")]
[NativeHeaderAttribute("PhysicsScriptingClasses.h")]
[UsedByNativeCodeAttribute]
public struct RaycastHit
{
//
// 摘要:
// The Collider that was hit.
public Collider collider { get; }
//
// 摘要:
// Instance ID of the Collider that was hit.
public int colliderInstanceID { get; }
//
// 摘要:
// The impact point in world space where the ray hit the collider.
public Vector3 point { get; set; }
//
// 摘要:
// The normal of the surface the ray hit.
public Vector3 normal { get; set; }
//
// 摘要:
// The barycentric coordinate of the triangle we hit.
public Vector3 barycentricCoordinate { get; set; }
//
// 摘要:
// The distance from the ray's origin to the impact point.
public float distance { get; set; }
//
// 摘要:
// The index of the triangle that was hit.
public int triangleIndex { get; }
//
// 摘要:
// The uv texture coordinate at the collision location.
public Vector2 textureCoord { get; }
//
// 摘要:
// The secondary uv texture coordinate at the impact point.
public Vector2 textureCoord2 { get; }
//
// 摘要:
// The Transform of the rigidbody or collider that was hit.
public Transform transform { get; }
//
// 摘要:
// The Rigidbody of the collider that was hit. If the collider is not attached to
// a rigidbody then it is null.
public Rigidbody rigidbody { get; }
//
// 摘要:
// The ArticulationBody of the collider that was hit. If the collider is not attached
// to an articulation body then it is null.
public ArticulationBody articulationBody { get; }
//
// 摘要:
// The uv lightmap coordinate at the impact point.
public Vector2 lightmapCoord { get; }
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Use textureCoord2 instead. (UnityUpgradable) -> textureCoord2")]
public Vector2 textureCoord1 { get; }
}
其中,RaycastHit也是一个围绕Raycast定义的结构体,感觉每个定义了Raycast的脚本都会定义个RaycastHit再给他out出来(即使后面不用到),感觉应该是个固定的、不能更改的写法吧。
Unity学习之Physic.Raycast(射线检测)个人理解分享这篇博客演示了碰撞检测的应用。