天天看點

Unity 射線檢測,子彈、飛彈、手雷

射線的用途很廣泛,本文講述射線在槍戰遊戲中炮彈的射線使用。

檢測步驟

1.執行個體化一根射線

參數1:射線起點

參數2:射線方向

2.用步驟1産生的射線進行檢測

參數1:步驟1執行個體化的射線

參數2:射線檢測碰撞到傳回的碰撞資料

參數3:檢測最遠距離

參數4:檢測的層級

子彈

public ProjectileData projectileData;//子彈攜帶資料類(方向,速度等),看官請自定義
internal LayerMask layerMask = (1 << 0) | (1 << 1) ; //子彈擊中層級(敵人,建築等),看官請自定義
internal RaycastHit rayCastHit;
internal Ray ray;

void Update()
    {
        //射線檢測
        ray = new Ray(gameObject.transform.position, projectileData.direction);
        if (Physics.Raycast(ray, out rayCastHit, (projectileData.speed * Time.deltaTime) + 0.1f, layerMask)) 
        {
			//擊中處理
            Destroy();
        }
        else
        {
        	//子彈運動
            gameObject.transform.position += projectileData.direction * (projectileData.speed * Time.deltaTime);
        }

        //子彈存活時間
        projectileData.lifetime -= Time.deltaTime;
        if (projectileData.lifetime <= 0) Destroy();
    }
           

飛彈

void Update()
    {
        //射線檢測
        ray = new Ray(gameObject.transform.position, projectileData.direction);
        if (Physics.Raycast(ray, out rayCastHit, (projectileData.speed * Time.deltaTime) + 0.1f, layerMask))
        {
        	//擊中處理
            Explode();
        }
        else
        {
        	//飛彈追随
            if (projectileData.target != null)
            {
                projectileData.endPosition = projectileData.target.transform.position;
            }
            Quaternion sourceRotation = gameObject.transform.rotation;
            gameObject.transform.LookAt(projectileData.endPosition);
            gameObject.transform.Rotate(90, 0, 0);
            Quaternion endRotation = gameObject.transform.rotation;
            gameObject.transform.rotation = Quaternion.Slerp(sourceRotation, endRotation, 5f * Time.deltaTime);
            projectileData.direction = gameObject.transform.up;

            gameObject.transform.position += projectileData.direction * (projectileData.speed * Time.deltaTime);
        }
        
		//子彈存活時間
        projectileData.lifetime -= Time.deltaTime;
        if (projectileData.lifetime <= 0) Destroy();
    }
           

手雷

void Update()
    {
        if (Data.pause) return;
        deltaTime = Time.deltaTime;
        lifeTime -= deltaTime;
        float speed = gameObject.GetComponent<Rigidbody>().velocity.magnitude * Time.fixedDeltaTime + 0.3f;
        ray = new Ray(gameObject.transform.position, gameObject.GetComponent<Rigidbody>().velocity.normalized);
        if (Physics.Raycast(ray, speed, layerMask))
        {
            Explode();
        }
        else if (lifeTime <= 0)
        {
            Explode();
        }
    }
           

寫在最後

Unity提供很多重寫射線檢測Raycast函數,可以根據需要靈活運用

[ExcludeFromDocs]
public static bool Raycast(Ray ray, out RaycastHit hitInfo);
[ExcludeFromDocs]
public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance);
[ExcludeFromDocs]
public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance, int layerMask);
[ExcludeFromDocs]
public static bool Raycast(Ray ray, float maxDistance, int layerMask);
public static bool Raycast(Ray ray, out RaycastHit hitInfo, [Internal.DefaultValue("Mathf.Infinity")] float maxDistance, [Internal.DefaultValue("DefaultRaycastLayers")] int layerMask, [Internal.DefaultValue("QueryTriggerInteraction.UseGlobal")] QueryTriggerInteraction queryTriggerInteraction);
[ExcludeFromDocs]
public static bool Raycast(Ray ray);
//
// 摘要:
//     Same as above using ray.origin and ray.direction instead of origin and direction.
//
// 參數:
//   ray:
//     The starting point and direction of the ray.
//
//   maxDistance:
//     The max distance the ray should check for collisions.
//
//   layerMask:
//     A that is used to selectively ignore colliders when casting a ray.
//
//   queryTriggerInteraction:
//     Specifies whether this query should hit Triggers.
//
// 傳回結果:
//     True when the ray intersects any collider, otherwise false.
public static bool Raycast(Ray ray, [Internal.DefaultValue("Mathf.Infinity")] float maxDistance, [Internal.DefaultValue("DefaultRaycastLayers")] int layerMask, [Internal.DefaultValue("QueryTriggerInteraction.UseGlobal")] QueryTriggerInteraction queryTriggerInteraction);
[ExcludeFromDocs]
public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo);
[ExcludeFromDocs]
public static bool Raycast(Ray ray, float maxDistance);
[ExcludeFromDocs]
[RequiredByNativeCode]
public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance, int layerMask);
public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance, int layerMask, QueryTriggerInteraction queryTriggerInteraction);
[ExcludeFromDocs]
public static bool Raycast(Vector3 origin, Vector3 direction);
//
// 摘要:
//     Casts a ray, from point origin, in direction direction, of length maxDistance,
//     against all colliders in the Scene.
//
// 參數:
//   origin:
//     The starting point of the ray in world coordinates.
//
//   direction:
//     The direction of the ray.
//
//   maxDistance:
//     The max distance the ray should check for collisions.
//
//   layerMask:
//     A that is used to selectively ignore Colliders when casting a ray.
//
//   queryTriggerInteraction:
//     Specifies whether this query should hit Triggers.
//
// 傳回結果:
//     True if the ray intersects with a Collider, otherwise false.
public static bool Raycast(Vector3 origin, Vector3 direction, [Internal.DefaultValue("Mathf.Infinity")] float maxDistance, [Internal.DefaultValue("DefaultRaycastLayers")] int layerMask, [Internal.DefaultValue("QueryTriggerInteraction.UseGlobal")] QueryTriggerInteraction queryTriggerInteraction);
[ExcludeFromDocs]
public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance);
[ExcludeFromDocs]
public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance, int layerMask);
[ExcludeFromDocs]
public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance);
           

繼續閱讀