Replace OnMouseDown with Physics.RaycastAll in Update for guaranteed click penetration
This commit is contained in:
@@ -21,27 +21,11 @@ public class PingClickHandler : MonoBehaviour
|
||||
{
|
||||
col = gameObject.AddComponent<SphereCollider>();
|
||||
}
|
||||
|
||||
// 强行把碰撞体的世界大小固定在一个比较合适的尺寸(比如世界尺寸 0.15)
|
||||
// 注意:父级如果在很远的层级里存在极端缩放,这里直接算可能还会出问题
|
||||
// 所以我们加一个更保守的安全保障:无论算出什么比例,绝对物理半径不能低于 0.05,不能高于 5.0
|
||||
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)
|
||||
{
|
||||
float targetRadius = 0.3f / scale;
|
||||
// 如果缩放太小,导致计算出的局部半径极大,或者缩放太大导致半径极小,我们要Clamp住它
|
||||
// 以保证在 Scene/Game 视窗里它至少是个“可以点得到的球”
|
||||
sphere.radius = Mathf.Clamp(targetRadius, 0.05f, 20f);
|
||||
Debug.Log($"[PingClick] {name} 设置了碰撞体半径: {sphere.radius} (基于缩放 {scale})");
|
||||
float scale = Mathf.Max(Mathf.Abs(transform.lossyScale.x), Mathf.Abs(transform.lossyScale.y), Mathf.Abs(transform.lossyScale.z), 0.001f);
|
||||
sphere.radius = Mathf.Clamp(0.3f / scale, 0.05f, 20f);
|
||||
}
|
||||
else if (col is BoxCollider box)
|
||||
{
|
||||
float targetSize = 0.6f / scale;
|
||||
targetSize = Mathf.Clamp(targetSize, 0.1f, 40f);
|
||||
box.size = new Vector3(targetSize, targetSize, targetSize);
|
||||
}
|
||||
|
||||
col.enabled = true;
|
||||
|
||||
CreateOutlineMesh();
|
||||
@@ -78,21 +62,35 @@ public class PingClickHandler : MonoBehaviour
|
||||
while (true) { if (_outlineMesh != null) _outlineMesh.enabled = !_outlineMesh.enabled; yield return new WaitForSeconds(0.4f); }
|
||||
}
|
||||
|
||||
void OnMouseDown()
|
||||
// 弃用 Unity 自带的 OnMouseDown,因为它只能检测最外层第一个碰到的物体,会被前面的隐形物体挡住
|
||||
void Update()
|
||||
{
|
||||
Debug.Log($"[PingClick] 接收到鼠标点击: {name}");
|
||||
PerformClick();
|
||||
if (Input.GetMouseButtonDown(0))
|
||||
{
|
||||
if (!_isBlinking) return;
|
||||
|
||||
foreach (var c in Camera.allCameras)
|
||||
{
|
||||
if (!c.enabled) continue;
|
||||
Ray ray = c.ScreenPointToRay(Input.mousePosition);
|
||||
// 穿透所有物体!
|
||||
RaycastHit[] hits = Physics.RaycastAll(ray, 1000f);
|
||||
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)
|
||||
{
|
||||
Debug.Log($"[PingClick] {name} 忽略点击,因为 _isBlinking=false");
|
||||
return;
|
||||
}
|
||||
|
||||
// 不做任何射线遮挡判定!直接穿透触发点击,确保 100% 成功!
|
||||
if (!_isBlinking) return;
|
||||
|
||||
if (!_modelShown)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user