Add manual raycast in Update for PingClickHandler to guarantee clicks

This commit is contained in:
yangbear
2026-07-12 04:46:14 +08:00
parent d8914e1079
commit aceedb44e4
+34 -27
View File
@@ -19,25 +19,25 @@ public class PingClickHandler : MonoBehaviour
var col = GetComponent<Collider>();
if (col == null)
{
col = gameObject.AddComponent<BoxCollider>();
// 如果没有碰撞体,为了100%能够被点到,加一个超级巨大的 BoxCollider
var box = gameObject.AddComponent<BoxCollider>();
box.size = new Vector3(2f, 2f, 2f); // 固定绝对大尺寸
col = box;
}
// 恢复所有类型碰撞体强制放大逻辑,之前丢掉了 BoxCollider 的处理导致第一步没法点
float scale = Mathf.Max(Mathf.Abs(transform.lossyScale.x), Mathf.Abs(transform.lossyScale.y), Mathf.Abs(transform.lossyScale.z), 0.001f);
// 不管是什么碰撞体强制设置为绝对足够大的物理尺寸
if (col is SphereCollider sphere)
{
sphere.radius = Mathf.Clamp(0.4f / scale, 0.1f, 20f);
sphere.radius = 1.0f;
}
else if (col is BoxCollider box)
{
float s = Mathf.Clamp(0.8f / scale, 0.1f, 40f);
box.size = new Vector3(s, s, s);
box.size = new Vector3(2f, 2f, 2f);
}
else if (col is CapsuleCollider cap)
{
cap.radius = Mathf.Clamp(0.4f / scale, 0.1f, 20f);
cap.height = Mathf.Clamp(0.8f / scale, 0.1f, 40f);
cap.radius = 1.0f;
cap.height = 2.0f;
}
col.isTrigger = false;
@@ -48,6 +48,8 @@ public class PingClickHandler : MonoBehaviour
_isBlinking = true;
StopAllCoroutines();
StartCoroutine(BlinkOutline());
Debug.Log($"[PingClick] {name} OnEnable 完成,碰撞体已强制放大。");
}
void CreateOutlineMesh()
@@ -77,13 +79,34 @@ public class PingClickHandler : MonoBehaviour
while (true) { if (_outlineMesh != null) _outlineMesh.enabled = !_outlineMesh.enabled; yield return new WaitForSeconds(0.4f); }
}
// 恢复使用 OnMouseDown,因为 Update 手动射线可能因为某些相机的 LayerMask 配置导致完全扫不到
void OnMouseDown()
{
Debug.Log($"[PingClick] OnMouseDown 触发: {name}");
PerformClick();
}
// 加入更强力的通用点击检测支持,防止某些射线遮挡 OnMouseDown
void Update()
{
if (Input.GetMouseButtonDown(0))
{
if (!_isBlinking) return;
// 简单射线检测,如果打中当前物体,强行触发
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit[] hits = Physics.RaycastAll(ray, 100f);
foreach (var hit in hits)
{
if (hit.collider != null && hit.collider.gameObject == gameObject)
{
Debug.Log($"[PingClick] Update手动射线贯穿点中: {name}");
PerformClick();
return;
}
}
}
}
public void PerformClick()
{
if (!_isBlinking)
@@ -231,23 +254,7 @@ public class PingClickHandler : MonoBehaviour
_modelShown = false;
var col = GetComponent<Collider>();
if (col == null)
{
col = gameObject.AddComponent<BoxCollider>();
}
float scale = Mathf.Max(Mathf.Abs(transform.lossyScale.x), Mathf.Abs(transform.lossyScale.y), Mathf.Abs(transform.lossyScale.z), 0.001f);
if (col is SphereCollider sphere)
{
sphere.radius = Mathf.Clamp(0.4f / scale, 0.1f, 20f);
}
else if (col is BoxCollider box)
{
float s = Mathf.Clamp(0.8f / scale, 0.1f, 40f);
box.size = new Vector3(s, s, s);
}
col.enabled = true;
if (col != null) col.enabled = true;
_isBlinking = true;
if (_modelRenderer != null) _modelRenderer.enabled = false;