脚本动态拼接地板
脚本动态拼接地板
这里开始笔记的第一节,关于教程制作fps.microgame游戏的内容,由于本人水平十分有限,笔记主要是给自己做知识储备和整理用的,如需使用,则自酌其中的笔记内容,不合理之处肯定存在,希望一起指正、学习。
全套视频教程及源码获取 添加WX:coco-zhaoxi 发送B0418。
具体方法:
1、首先导入相应场景资源,在Hierarchy窗口里添加预制体HoveBot。
2、将RootObject文件夹里的OBJBasic_Floor拖进hierarchy视图中,命名一个空物体,取名groundfloor,将该预制体拖进空物体下进行,现在我们可以在groundfloor的组件里添加脚本来动态拼接其子物体地板。
3、新建一个C#脚本,脚本自己命名好后点击进入编辑,这里使用的编辑器是visual studio 2019版本。
4、 编辑脚本如下所示:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Ryun : MonoBehaviour { public Vector3 cellcount = Vector3.zero;//声明并初始化cellcount为zero(与地板数量相关的3D矢量),在控制面板修改相应参数 public Vector3 floorsize = Vector3.zero;//声明并初始化单个地板的长宽向量为zero,在控制面板修改相应参数 public List<Transform> floortransform = new List<Transform>();//声明并实例化一个transform类型的泛型集合,用于动态储存地板的数量 // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } [ContextMenu("floor lay out")]//保证能在游戏未运行时动态修改(调用此函数) private void floorlayout() { floortransform.Clear();//每次修改前清空之前的内容 var childrentransforms = this.GetComponentsInChildren<Transform>();//声明并实例化一个局部变量childrentransforms,返回当前实例化transform集合通过GetcomponentsInchildren<>函数调用的一系列组件 for (int i = 1; i < childrentransforms.Length; i++) { if (childrentransforms[i].gameObject.CompareTag("floor")) { floortransform.Add(childrentransforms[i]);//利用list的Add()方法动态加载子组件,这个对后续修改起到了决定性作用 } } int currentindex = 0;//list集合的下标索引 for (int x=0 ; x < cellcount.x; x++) { for (int z = 0; z < cellcount.z; z++) { Vector3 newpos = new Vector3(x * floorsize.x, 0, z * floorsize.z); floortransform[currentindex].position= newpos;//将每次修改好的newpos结果返回给指定的floortransform元素的位置矢量 currentindex++;//每次循环结果加1 } } } }
具体说明:
5、声明一个Vector3类型的公有变量,名为cellcount,初始化为zero,用于记录动态加载的地板数量; 6、声明一个同样类型的公有变量,名为floorsize,初始化为zero,用于动态记录单个地板的长宽高; 7、声明一个泛型变量(后面有关于它的补充),以Transform类型为参数,命名为floortransform//并将该类下定义好的childrentransforms[i]中的游戏对象添加进去。(这是后面的过程) 8、由于我们是对场景做动态改变,故在外面声明一个私有的无返回值的函数,命名为floorlayout(),由于我们需要在游戏未运行的时候能调用该方法,ContextMenu()能实现这一点,具体可参考unity官方的中文文档。 9、在函数体内隐式声明一个变量,为方便识别,命名为childrentransforms,并利用GetComponentsInChildren<>赋予其含Transform组件下的所有子物体组件。 {GetComponentsInChildren<>:用于返回 GameObject 或其任何子项中类型为Transform的所有组件;Unity 以递归方式在子 GameObject上搜索组件。这意味着它还包含目标GameObject的子GameObject以及所有后续子GameObject。} 由于将找到的所有组件均返回到 List results 中,故书写: childrentransforms.Length;childrentransforms[i]就能很好理解其缘由。 10、通过for循环,这里注意由于不能包含groundfloor故在添加子对象的时候将变量索引值初始化为i=1,利用Add()方法将这些录入。 11、介于后续可能需要修改。故在每次调用方法前将floortransform里的对象清除,这里用了Clear()方法。 12、利用双重for循环改变每个子物体的世界坐标的位置: 13、先声明并实例化一个Vector3类型的位置坐标,关于坐标点的位置变化自己思考。 Vector3 newpos = new Vector3(x * floorsize.x, 0, z * floorsize.z); 循环前先写一个 int currentindex = 0; 其中 floortransform[currentindex].position= newpos; :将每次定义好的newpos赋予给当前的floortransform下的childrentransforms对象;一次内部循环结束后自增currentindex。
<补>
1、childrentransforms[i].gameObject.CompareTag("floor")
理解为:获取当前transform组件所在的gameobject,并利用gameobject下的CompareTag()方法找到标签为floor的游戏对象,这是为了防止将不需要的子对象添加进floortransfrom的缘故
2、标签需要自己在游戏对象的Inspectors窗口的tab选项里添加并修改。
3、声明一个泛型变量的格式:
List<数据类型> 变量名=new list<数据类型>();
List泛型集合的常用方法:
Add()方法
Contains()方法
Remove()方法
ToArray()方法等等较为常用
最后结果如下:
(动态更改结果如图所示,当然数值可以自己进一步修改)
演示图: