Unity墙体放置脚本问题:如何循环列表对象计算柱体间距?
解决Unity墙体放置脚本的立柱循环距离计算问题
我来帮你搞定这个立柱之间生成墙体的逻辑问题~先梳理下你当前代码的核心问题:你的AdjustWalls方法里只固定取了列表里的第一个立柱作为previousPost,这显然没法实现和所有已有立柱(或者上一个立柱)的距离判断,下面给你两种符合需求的解决方案,按需选择:
方案1:新立柱与所有已有立柱判断距离(适合任意位置的立柱自动连墙)
这个方案会在每次新增立柱后,遍历所有已经放置的立柱,只要新立柱和某根已有立柱的距离足够近,就自动在两者之间生成墙体:
首先修改你的代码,替换掉原来的AdjustWalls和Distance方法,新增一个专门生成墙体的方法:
[SerializeField] private GameObject wall; [SerializeField] private GameObject post; [SerializeField] private float wallPlacementThreshold = 10f; // 可在Inspector调整的距离阈值 private List<GameObject> posts = new List<GameObject>(); private void Update() { GetInput(); Debug.Log(posts.Count); } private void AdjustWalls() { // 取刚添加的新立柱 GameObject newPost = posts[posts.Count - 1]; // 遍历所有已有的旧立柱(排除刚添加的这个) foreach (GameObject existingPost in posts.Take(posts.Count - 1)) { float distance = Vector3.Distance(newPost.transform.position, existingPost.transform.position); // 距离足够近时生成墙体(注意这里是<=阈值,你原来的>是逻辑反了) if (distance <= wallPlacementThreshold) { InstantiateWallBetween(newPost, existingPost); Debug.Log("Wall placed between posts"); } } } // 专门处理墙体的实例化、位置、旋转和缩放 private void InstantiateWallBetween(GameObject postA, GameObject postB) { // 墙体位置设为两个立柱的中点 Vector3 wallPos = Vector3.Lerp(postA.transform.position, postB.transform.position, 0.5f); // 墙体朝向两个立柱的连线方向 Vector3 direction = postB.transform.position - postA.transform.position; Quaternion wallRot = Quaternion.LookRotation(direction); // 如果你墙体模型是横向的,可能需要调整旋转让它竖直(根据你的模型调整) wallRot *= Quaternion.Euler(90, 0, 0); // 实例化墙体 GameObject newWall = Instantiate(wall, wallPos, wallRot); // 调整墙体长度刚好适配两个立柱的距离 float wallLength = direction.magnitude; newWall.transform.localScale = new Vector3(newWall.transform.localScale.x, newWall.transform.localScale.y, wallLength); // 给墙体设置父物体,方便管理 newWall.transform.parent = transform; } private void AddPosts() { GameObject newPost = Instantiate(post, gridSnap(getWorldPoint()), Quaternion.identity); posts.Add(newPost); newPost.transform.parent = transform; AdjustWalls(); } private void GetInput() { if (Input.GetKeyDown(KeyCode.Q)) // 建议用KeyCode枚举代替字符串,更可靠 { AddPosts(); } } // 你的gridSnap和getWorldPoint方法保持不变 private Vector3 gridSnap(Vector3 point) { // 你的网格对齐逻辑 return point; } private Vector3 getWorldPoint() { // 你的获取世界点逻辑 return Vector3.zero; }
方案2:仅与上一个放置的立柱判断距离(适合连续放置的线性墙体)
如果你的需求是只有连续放置的立柱之间才生成墙体(比如画一条连续的墙),那逻辑更简单,只需要和列表里的倒数第二个立柱比较:
private void AdjustWalls() { // 至少有2根立柱才需要判断 if (posts.Count >= 2) { GameObject newPost = posts[posts.Count - 1]; GameObject lastPost = posts[posts.Count - 2]; float distance = Vector3.Distance(newPost.transform.position, lastPost.transform.position); if (distance <= wallPlacementThreshold) { InstantiateWallBetween(newPost, lastPost); Debug.Log("Wall placed between last two posts"); } } }
关键优化点说明
- 把距离阈值做成了可序列化变量
wallPlacementThreshold,不用改代码就能在Unity编辑器里调整; - 移除了冗余的
currentPost和previousPost变量,直接从列表中取对应的立柱,避免变量混乱; - 修复了你原来逻辑中
Distance() > 10的错误(需求是距离近才生成墙,应该是<=阈值); - 新增的
InstantiateWallBetween方法专门处理墙体的位置、旋转和缩放,让墙体刚好贴合两个立柱,避免错位。
内容的提问来源于stack exchange,提问作者Siegebreaker
相关产品推荐
相关产品推荐

