赞
踩
在 Unity 开发中,射线检测是一个非常重要的功能,广泛应用于碰撞检测、物理交互等场景。合理选择和使用射线检测方法,不仅可以提高检测的准确性,还能显著优化性能。
今天在学习中突然想到游戏中频繁的使用射线,GC 也会大量产生
Physics.Raycast
而不是 Physics.RaycastAll
。NonAlloc
版本以减少垃圾回收和内存分配。LayerMask
过滤不必要的碰撞体,提高检测效率。Tip: 主体是就是在频繁使用射线检测时候,使用避免GC的方法等等去实现减少GC
- if (Physics.Raycast(origin, direction, out RaycastHit hitInfo, maxDistance, layerMask))
- {
- // 处理碰撞
- }
- RaycastHit[] hits = Physics.RaycastAll(origin, direction, maxDistance, layerMask);
- foreach (RaycastHit hit in hits)
- {
- // 处理每个碰撞
- }
- if (Physics.SphereCast(origin, radius, direction, out RaycastHit hitInfo, maxDistance, layerMask))
- {
- // 处理碰撞
- }
- if (Physics.SphereCast(origin, radius, direction, out RaycastHit hitInfo, maxDistance, layerMask))
- {
- // 处理碰撞
- }
- RaycastHit[] hits = Physics.SphereCastAll(origin, radius, direction, maxDistance, layerMask);
- foreach (RaycastHit hit in hits)
- {
- // 处理每个碰撞
- }
- RaycastHit[] results = new RaycastHit[10];
- int hitCount = Physics.SphereCastNonAlloc(origin, radius, direction, results, maxDistance, layerMask);
- for (int i = 0; i < hitCount; i++)
- {
- RaycastHit hit = results[i];
- // 处理每个碰撞
- }
- if (Physics.CapsuleCast(point1, point2, radius, direction, out RaycastHit hitInfo, maxDistance, layerMask))
- {
- // 处理碰撞
- }
- RaycastHit[] hits = Physics.CapsuleCastAll(point1, point2, radius, direction, maxDistance, layerMask);
- foreach (RaycastHit hit in hits)
- {
- // 处理每个碰撞
- }
- RaycastHit[] results = new RaycastHit[10];
- int hitCount = Physics.CapsuleCastNonAlloc(point1, point2, radius, direction, results, maxDistance, layerMask);
- for (int i = 0; i < hitCount; i++)
- {
- RaycastHit hit = results[i];
- // 处理每个碰撞
- }
- using UnityEngine;
-
- public interface IRaycastManager
- {
- int Raycast(Vector3 origin, Vector3 direction, float maxDistance, LayerMask layerMask, out RaycastHit[] results);
- }
- using UnityEngine;
- using System.Collections.Generic;
-
- public class RaycastManager : MonoBehaviour, IRaycastManager
- {
- private List<RaycastHit[]> raycastHitPools;
- private int poolSize = 10; // 池的大小
- private int maxResults = 10; // 每个数组可以存储的最大结果数
-
- void Start()
- {
- // 初始化对象池
- raycastHitPools = new List<RaycastHit[]>(poolSize);
- for (int i = 0; i < poolSize; i++)
- {
- raycastHitPools.Add(new RaycastHit[maxResults]);
- }
- }
-
- public int Raycast(Vector3 origin, Vector3 direction, float maxDistance, LayerMask layerMask, out RaycastHit[] results)
- {
- // 从对象池中获取一个预分配的数组
- results = GetRaycastHitArrayFromPool();
-
- // 使用 NonAlloc 方法进行射线检测
- int hitCount = Physics.RaycastNonAlloc(origin, direction, results, maxDistance, layerMask);
-
- // 返回检测到的碰撞体数量
- return hitCount;
- }
-
- private RaycastHit[] GetRaycastHitArrayFromPool()
- {
- // 简单实现:循环使用池中的数组
- RaycastHit[] resultArray = raycastHitPools[0];
- raycastHitPools.RemoveAt(0);
- raycastHitPools.Add(resultArray);
- return resultArray;
- }
-
- // 调试时绘制射线
- void OnDrawGizmos()
- {
- Gizmos.color = Color.red;
- Gizmos.DrawLine(transform.position, transform.position + transform.forward * 10);
- }
- }
- using UnityEngine;
-
- public class TestRaycast : MonoBehaviour
- {
- private IRaycastManager raycastManager;
- public LayerMask layerMask;
- public float maxDistance = 100f;
-
- void Start()
- {
- // 获取 RaycastManager 组件
- raycastManager = GetComponent<RaycastManager>();
- }
-
- void Update()
- {
- // 射线起点和方向
- Vector3 origin = transform.position;
- Vector3 direction = transform.forward;
-
- // 使用自定义射线检测方法
- int hitCount = raycastManager.Raycast(origin, direction, maxDistance, layerMask, out RaycastHit[] results);
-
- // 处理检测结果
- for (int i = 0; i < hitCount; i++)
- {
- RaycastHit hit = results[i];
- Debug.Log("Hit: " + hit.collider.name);
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。