如何在圆周生成等距点位,解决Unity圆形网格tile放置抖动问题
问题排查与修复方案
核心问题
你的实现思路本身是可行的,出现抖动、偏移问题是代码存在三处逻辑疏漏:
- 量化步长计算顺序错误:原代码计算周长
circumference时使用的是上一帧的radius值,而非当前帧的目标圈层半径,导致角度量化步长和当前圈层不匹配,触发提前偏移。 - 角度范围处理异常:
Mathf.Atan2返回的角度范围是[-π, π](对应-180°~180°),在正负角度交界的0°位置会出现359°到1°的跳变,直接取整会导致判定逻辑混乱,出现抖动。 - 非整数tile数量问题:原代码计算出的每层tile数量可能为小数,无法保证tile严格等距排列,会出现累积偏移。
修复后代码
customGrid.cs
using UnityEngine; public class customGrid : MonoBehaviour { [SerializeField] private Camera mainCamera; [SerializeField] private LayerMask layerMask; public GameObject structure; Vector3 truePos; public int maxLayers = 1; public int minLayers = 0; public float objectSize = 1.5f; void LateUpdate() { Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out RaycastHit raycastHit, float.MaxValue, layerMask)) { // 先计算当前鼠标点的角度和距离 float angleRadian = Mathf.Atan2(raycastHit.point.x, raycastHit.point.z); float cursorDistanceFromOrigin = Vector3.Distance(Vector3.zero, new Vector3(raycastHit.point.x, 0, raycastHit.point.z)); // 计算目标圈层半径 float objectDistanceFromOrigin = Mathf.Floor(cursorDistanceFromOrigin / objectSize) * objectSize; var maxDistance = objectSize * maxLayers; var minDistance = objectSize * minLayers; float radius = Mathf.Clamp(objectDistanceFromOrigin, minDistance, maxDistance); if (radius < 1) return; // 基于当前半径计算角度量化步长,强制tile数量为整数 var circumference = 2 * Mathf.PI * radius; int tileCount = Mathf.RoundToInt(circumference / objectSize); float quantization = 360f / tileCount; // 角度归一化到0~360度,避免跨0度跳变 var degree = angleRadian * Mathf.Rad2Deg; if (degree < 0) degree += 360f; degree = Mathf.Round(degree / quantization) * quantization; angleRadian = degree * Mathf.Deg2Rad; truePos.x = Mathf.Sin(angleRadian) * radius; truePos.y = 0; truePos.z = Mathf.Cos(angleRadian) * radius; RepositionObject(); } } private void RepositionObject() { structure.transform.position = truePos; var dir = truePos - Vector3.zero; dir = Vector3.Normalize(dir); structure.transform.rotation = Quaternion.LookRotation(dir); } }
可选优化
如果需要相邻圈层的tile严格对齐,可以将每层的tile数量设置为第一层tile数量的整数倍,避免层与层之间的错位。
内容的提问来源于stack exchange,提问作者Abcd
相关产品推荐
相关产品推荐

