Unity 3D GridLayoutGroup3D 让子物体对齐,调整子物体间距

Unity 3D GridLayoutGroup3D 让子物体对齐,调整子物体间距

效果

请添加图片描述

介绍

GridLayoutGroup3D 脚本是一个用于在 Unity 3D 编辑器中创建 3D 网格布局的实用工具。主要用于在 Unity 编辑器中提供一种可视化的方式来设置和调整子物体的位置,同时支持删除脚本时将物体恢复原位。

源码:

#if UNITY_EDITOR
using UnityEditor.SceneManagement;
#endif
using System.Collections.Generic;
using UnityEngine;public class GridLayoutGroup3D : MonoBehaviour
{
#if UNITY_EDITORpublic Vector3 matrixInterval = new Vector3(0.25f, 0.25f, 0.25f);public Vector3Int matrixSize = new Vector3Int(3, 3, 3);public Color matrixColor = new Color(255 / 225f, 225 / 225f, 0, 100 / 255f);public float radius = 0.1f;private int ChildIndex = 0;public List<Location> locations = new List<Location>();//子物体间隔public Vector3 MatrixInterval{get => matrixInterval; set{matrixInterval = value;UnityEditor.EditorApplication.QueuePlayerLoopUpdate();}}//矩阵大小public Vector3Int MatrixSize{get => matrixSize; set{matrixSize = value;UnityEditor.EditorApplication.QueuePlayerLoopUpdate();}}public float Radius{get => radius; set{radius = value;UnityEditor.EditorApplication.QueuePlayerLoopUpdate();}}public Color MatrixColor{get => matrixColor; set{matrixColor = value;UnityEditor.EditorApplication.QueuePlayerLoopUpdate();}}private void OnDrawGizmosSelected(){DrawAndSetLocation();}public void DrawAndSetLocation(){ChildIndex = 0;int MatrixSizeX = Mathf.Abs(MatrixSize.x);int MatrixSizeY = Mathf.Abs(MatrixSize.y);int MatrixSizeZ = Mathf.Abs(MatrixSize.z);//刷新子物体位置for (int j = 0; j < MatrixSizeY; j++){for (int z = 0; z < MatrixSizeZ; z++){for (int i = 0; i < MatrixSizeX; i++){Vector3 CurLoc = new Vector3(MatrixSize.x > 0 ? i : -i,MatrixSize.y > 0 ? j : -j,MatrixSize.z > 0 ? -z : z);Vector3 Location = new Vector3(CurLoc.x * MatrixInterval.x,CurLoc.y * MatrixInterval.y,CurLoc.z * MatrixInterval.z);if (ChildIndex < transform.childCount){if (transform.GetChild(ChildIndex).localPosition != Location){transform.GetChild(ChildIndex).localPosition = Location;EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());}}Gizmos.color = MatrixColor;Gizmos.matrix = transform.localToWorldMatrix;Gizmos.DrawCube(Location, Radius * Vector3.one);ChildIndex++;}}}}public void CopyInfo(){if (locations.Count == 0){foreach (var item in GetComponentsInChildren<Transform>()){locations.Add(new Location(item.name, item.position, item.rotation));}}}public string PasteInfo(){Transform[] transforms = GetComponentsInChildren<Transform>();if (transforms.Length != locations.Count){return "子物体数量不对等!停止赋值!";}for (int i = 0; i < transforms.Length; i++){if (transforms[i].name == locations[i].name){transforms[i].position = locations[i].position;transforms[i].rotation = locations[i].rotation;}else{return "子物体" + locations[i].name + "有变动!停止赋值!";}}return "赋值成功!";}public class Location{public string name;public Vector3 position;public Quaternion rotation;public Location(string name, Vector3 position, Quaternion rotation){this.name = name;this.position = position;this.rotation = rotation;}}
#endif
}

编辑器扩展(美化面板)

记得放到Editor文件夹下

using UnityEditor;
using UnityEngine;[CustomEditor(typeof(GridLayoutGroup3D)), CanEditMultipleObjects]
public class Editor_GridLayoutGroup3D : Editor
{private GridLayoutGroup3D gridLayoutGroup3D;// Start is called before the first frame updateprivate void OnEnable(){gridLayoutGroup3D = target as GridLayoutGroup3D;gridLayoutGroup3D.CopyInfo();}public override void OnInspectorGUI(){gridLayoutGroup3D.MatrixInterval = EditorGUILayout.Vector3Field("子物体间隔", gridLayoutGroup3D.MatrixInterval);GUILayout.Space(10);gridLayoutGroup3D.MatrixSize = EditorGUILayout.Vector3IntField("矩阵大小", gridLayoutGroup3D.MatrixSize);GUILayout.Space(10);GUILayout.BeginHorizontal();GUILayout.Label("矩阵显示调节:");gridLayoutGroup3D.MatrixColor = EditorGUILayout.ColorField(gridLayoutGroup3D.MatrixColor);GUILayout.Space(10);float MaxValue = Mathf.Max(new float[3] { gridLayoutGroup3D.MatrixInterval.x, gridLayoutGroup3D.MatrixInterval.y, gridLayoutGroup3D.MatrixInterval.z });gridLayoutGroup3D.Radius = EditorGUILayout.Slider(gridLayoutGroup3D.Radius,0.01f, MaxValue/2);GUILayout.EndHorizontal();if (gridLayoutGroup3D.MatrixSize.y==0|| gridLayoutGroup3D.MatrixSize.x==0|| gridLayoutGroup3D.MatrixSize.z==0){EditorGUILayout.HelpBox("矩阵大小,最小值为1", MessageType.Info);}GUILayout.Space(10);if (GUILayout.Button("移除并恢复")){if (EditorUtility.DisplayDialog("警告!", "这将使当前的子物体恢复到开始状态。", "是的", "手滑了~")){Debug.Log(gridLayoutGroup3D.PasteInfo());DestroyImmediate(gridLayoutGroup3D);}}}
}

代码解释

1. 基本信息

// 使用 UNITY_EDITOR 指令确保这些代码仅在编辑器模式下运行
#if UNITY_EDITOR
using UnityEditor.SceneManagement;
#endif
using System.Collections.Generic;
using UnityEngine;public class GridLayoutGroup3D : MonoBehaviour
{// ...(省略其他代码)
}
  • 在这里,我们通过 #if UNITY_EDITOR 确保包含的代码仅在 Unity 编辑器中运行。

2. 字段和属性

public Vector3 matrixInterval = new Vector3(0.25f, 0.25f, 0.25f);
public Vector3Int matrixSize = new Vector3Int(3, 3, 3);
public Color matrixColor = new Color(255 / 225f, 225 / 225f, 0, 100 / 255f);
public bool isDrawGizmos = true;
public float radius = 0.1f;
private int ChildIndex = 0;
public List<Location> locations = new List<Location>();

这些字段和属性用于在 Unity 编辑器中设置参数。

  • matrixInterval 是一个三维向量,表示子物体之间的间隔。
  • matrixSize 是一个三维整数向量,表示矩阵的大小。
  • matrixColor 是一个颜色,表示绘制 Gizmos 的颜色。
  • radius 表示 Gizmos 的大小。
  • locations 是一个存储子物体位置信息的列表。

3. 方法

	private void OnDrawGizmosSelected(){DrawAndSetLocation();}public void DrawAndSetLocation(){ChildIndex = 0;int MatrixSizeX = Mathf.Abs(MatrixSize.x);int MatrixSizeY = Mathf.Abs(MatrixSize.y);int MatrixSizeZ = Mathf.Abs(MatrixSize.z);//刷新子物体位置for (int j = 0; j < MatrixSizeY; j++){for (int z = 0; z < MatrixSizeZ; z++){for (int i = 0; i < MatrixSizeX; i++){Vector3 CurLoc = new Vector3(MatrixSize.x > 0 ? i : -i,MatrixSize.y > 0 ? j : -j,MatrixSize.z > 0 ? -z : z);Vector3 Location = new Vector3(CurLoc.x * MatrixInterval.x,CurLoc.y * MatrixInterval.y,CurLoc.z * MatrixInterval.z);if (ChildIndex < transform.childCount){if (transform.GetChild(ChildIndex).localPosition != Location){transform.GetChild(ChildIndex).localPosition = Location;EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());}}Gizmos.color = MatrixColor;Gizmos.matrix = transform.localToWorldMatrix;Gizmos.DrawCube(Location, Radius * Vector3.one);ChildIndex++;}}}}
  • OnDrawGizmosSelected 是 Unity 编辑器中的一个回调方法,用于在选择物体时绘制 Gizmos。
  • DrawAndSetLocation 方法用于刷新子物体的位置并在 Unity 编辑器中绘制 Gizmos。它通过循环遍历矩阵的每个位置,将子物体放置在相应的位置。

4. 位置信息容器

public class Location
{public string name;public Vector3 position;public Quaternion rotation;public Location(string name, Vector3 position, Quaternion rotation){this.name = name;this.position = position;this.rotation = rotation;}
}

Demo下载地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/323878.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode(39)组合总和⭐⭐

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选取 。如…

iview 选择框远程搜索 指定筛选的参数

问题&#xff1a;开启了filterable之后&#xff0c;选择框是允许键盘输入的&#xff0c;但是会对选择列表进行过滤&#xff0c;如果不想使用再次过滤&#xff0c;可以试下下面这个方法。 场景&#xff1a;输入加密前的关键字筛选&#xff0c;选择框显示加密后的数据 说明一&a…

simulink代码生成(九)—— 串口显示数据(纸飞机联合调试)

纸飞机里面的协议是固定的&#xff0c;必须按照协议配置&#xff1b; &#xff08;1&#xff09;使用EasyHEX协议&#xff0c;测试int16数据类型 测试串口发出的数据是否符合&#xff1f; 串口接收数据为&#xff1a; 打开纸飞机绘图侧&#xff1a; &#xff08;1&#xff09…

MINCO+汽车

对于环境中的静态障碍物&#xff0c;我们构造几何自由空间来约束自我车辆的完整模型以保证安全。 对于动态障碍物&#xff0c;我们使用凸多边形来覆盖其形状。 然后&#xff0c;我们约束小车与障碍物多边形在每一时刻的符号距离[1]的下界近似&#xff0c;以保证小车的安全。 …

软件测试基础理论学习-常见软件开发模型

瀑布模型 背景 瀑布模型的概念最早在1970年由软件工程师Winston W. Royce在其论文《Managing the Development of Large Software Systems》中提出。Royce虽然没有明确提出“瀑布模型”这个术语&#xff0c;但他描述了一种线性的、阶段性的开发流程&#xff0c;各个阶段之间具…

从零学Java - 面向对象 abstract

面向对象 abstract 文章目录 面向对象 abstract1.什么是抽象?1.1 生活中的抽象 2.抽象类2.1 不该被创建对象的类2.2 抽象类的语法2.3 抽象类的作用2.4 抽象类的特点 3.抽象方法3.1 不该被实现的方法3.2 抽象方法的语法3.3 抽象方法的特点 4.总结4.1 抽象类4.2 抽象方法 1.什么…

人生重开模拟器

前言&#xff1a; 人生重开模拟器是前段时间非常火的一个小游戏&#xff0c;接下来我们将一起学习使用c语言写一个简易版的人生重开模拟器。 网页版游戏&#xff1a; 人生重开模拟器 (ytecn.com) 1.实现一个简化版的人生重开模拟器 &#xff08;1&#xff09; 游戏开始的时…

3190个文件!10GB大小!看3D WEB轻量引擎HOOPS Communicator如何高性能读取?

前言&#xff1a; HOOPS Communicator是专为在云端和Web上构建工程应用程序的3D开发工具包。它针对Web工作流、浏览器和工程图形进行了优化。研发小组花了20多年的时间来研发HOOPS Visualize&#xff08;本地3D可视化引擎&#xff09;&#xff0c;他们在这些工作中积累了大量计…

vue3学习 【2】vite起步和开发工具基本配置

vite的简介 官方文档 刚起步学习&#xff0c;所以我们只需要按照官方文档的入门流程即可。推荐阅读一下官网的为什么使用vite vite目前需要的node版本是18&#xff0c;可以参考上一篇文章的安装nvm&#xff0c;用来进行多版本的node管理。 vite安装与使用 npm create vitela…

Python基础篇: 环境安装

Python基础环境使用 一&#xff1a;运行环境Anaconda介绍1、Anaconda搭建1.1、下载方式1.2、安装1.3、验证是否安装成功 2、管理python环境2.1、列出所有环境2.2、创建环境2.3、进入指定虚拟环境2.4、离开虚拟环境2.5、删除虚拟环境 3、依赖管理3.1、安装依赖3.2、卸载依赖3.3、…

Android linphone-android sdk设置语音编码问题

1.遇到的问题 今天遇到linphone-android sdk需要解决语音编码问题&#xff0c;需要指定编码。查了下配置&#xff0c;里面没有发现类似的配置。 ## Start of factory rc # This file shall not contain path referencing package name, in order to be portable when app is r…

uni-app 前后端调用实例 基于Springboot 上拉分页实现

锋哥原创的uni-app视频教程&#xff1a; 2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中...共计23条视频&#xff0c;包括&#xff1a;第1讲 uni…