脚本动态拼接地板

脚本动态拼接地板

       这里开始笔记的第一节,关于教程制作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()方法等等较为常用

 

最后结果如下:
 
(动态更改结果如图所示,当然数值可以自己进一步修改)

 

演示图:

 

 

posted @ 2021-11-05 11:15  hhhei!  阅读(96)  评论(0编辑  收藏  举报