Unity学习-GameObject常用API

712 阅读6分钟

一.引言

熟悉了Unity的使用后,下面就是熟悉它提供的一些和脚本交互相关的API,以及一些重要组件

二.脚本获取API

在游戏开发中,肯定会存在游戏物体之间的交互,这个交互其实就是通过挂载它身上的脚本进行的,所以获取到它身上的脚本就很关键

  1. 挂载脚本内部提供的重要成员
    • 获取依附的GameObject
      this.gameObject.name
    • 获取依附的GameObject的位置信息
           //得到对象位置信息
          print(this.transform.position);//位置
          print(this.transform.eulerAngles);//角度
          print(this.transform.lossyScale);//缩放大小
          //这种写法和上面是一样的效果 都是得到依附的对象的位置信息
          //this.gameObject.transform
      
    • 获取脚本是否激活
      this.enabled = false;
    • 获取别的脚本对象 依附的gameobject和 transform位置信息
          // 定义一个域用于保存指定的游戏物体
          public Lesson3 otherLesson3;
          print(otherLesson3.gameObject.name);
          print(otherLesson3.transform.position);
      
  2. 获取脚本的重要方法
    • 得到自己挂载的单个脚本
          //根据脚本名获取
          //获取脚本的方法 如果获取失败 就是没有对应的脚本 会默认返回空
          Lesson3_Test t = this.GetComponent("Lesson3_Test") as Lesson3_Test;
          print(t);
          //根据Type获取
          t = this.GetComponent(typeof(Lesson3_Test)) as Lesson3_Test;
          print(t);
          //根据泛型获取 建议使用泛型获取 因为不用二次转换
          t = this.GetComponent<Lesson3_Test>();
          if( t != null )
          {
              print(t);
          }
      
    • 得到自己挂载的多个脚本
          Lesson3[] array = this.GetComponents<Lesson3>();
          print(array.Length);
          List<Lesson3> list = new List<Lesson3>();
          this.GetComponents<Lesson3>(list);
          print(list.Count);
      
    • 得到子对象挂载的脚本(它默认也会找自己身上是否挂载该脚本)
          //函数是有一个参数的 默认不传 是false 意思就是 如果子对象失活 是不会去找这个对象上是否有某个脚本的
          //如果传true 及时 失活 也会找
          //得子对象 挂载脚本 单个
          t = this.GetComponentInChildren<Lesson3_Test>(true);
          print(t);
          //得子对象 挂载脚本 多个
      
          Lesson3_Test[] lts = this.GetComponentsInChildren<Lesson3_Test>(true);
          print(lts.Length);
      
          List<Lesson3_Test> list2 = new List<Lesson3_Test>();
          this.GetComponentsInChildren<Lesson3_Test>(true, list2);
          print(list2.Count);
      
    • 得到父对象挂载的脚本(它默认也会找自己身上是否挂载该脚本)
          t = this.GetComponentInParent<Lesson3_Test>();
          print(t);
          lts = this.GetComponentsInParent<Lesson3_Test>();
          print(lts.Length);
          //它也有list的 省略不写了 和上面是一样的套路
      
    • 尝试获取脚本
          Lesson3_Test l3t;
          //提供了一个更加安全的 获取单个脚本的方法 如果得到了 会返回true
          //然后在来进行逻辑处理即可
          if(this.TryGetComponent<Lesson3_Test>(out l3t))
          {
              //逻辑处理
          }
      

三.GameObject相关API

下列的获取操作都是在Mono脚本中进行的

  1. 基本成员变量
        //名字
        print(this.gameObject.name);
        this.gameObject.name = "Lesson4DIY改名";
        print(this.gameObject.name);
        //是否激活
        print(this.gameObject.activeSelf);
        //是否是静态
        print(this.gameObject.isStatic);
        //层级
        print(this.gameObject.layer);
        //标签
        print(this.gameObject.tag);
        //transform
        //this.transform 通过Mono去得到的依附对象的GameObject的位置信息
        //他们得到的信息是一样 都是依附的GameObject的位置信息
        print(this.gameObject.transform.position);
    
  2. GameObject中的静态方法
    • 创建自带几何体
          /只要得到了一个GameObject对象 我就可以得到它身上挂在的任何脚本信息
          //通过obj.GetComponent来得去
          GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
          obj.name = "DIY创建的立方体";
      
    原始类型还有很多,比如球,圆柱等,上面只展示立方体
    • 查找对象
      查找对象有两个API,共同点是无法找到失活的对象,只能找到激活的对象,并且如果场景中存在多个满足条件的对象,我们无法准确确定找到的是谁,随机返回一个
          //通过对象名查找
          //这个查找效率比较低下  因为他会在场景中的所有对象去查找
          //没有找到 就会返回null
          GameObject obj2 = GameObject.Find("DIY");
          if( obj2 != null )
          {
              print(obj2.name);
          }
          else
          {
              print("没有找到对应对象");
          }
          //通过tag来查找对象
          //GameObject obj3 = GameObject.FindWithTag("Player");
          //该方法和上面这个方法 效果一样 只是名字不一样而已
          GameObject obj3 = GameObject.FindGameObjectWithTag("Player");
          if (obj3 != null)
          {
              print("根据tag找的对象" + obj3.name);
          }
          else
          {
              print("根据tag没有找到对应对象");
          }
      
      目前得到某个游戏物体有两种方式:
      1. public从外部面板拖入,进行关联
      2. 通过API去找,上面展示了查找单个对象的方法,查找多个对象同理,只是方法名不同
      //通过tag找到多个对象
      //它也是 只能找到 激活对象 无法找到失活对象
      GameObject[] objs = GameObject.FindGameObjectsWithTag("Player");
      print("找到tag为Player对象的个数" + objs.Length);
      
      另外再补充一个方法,用的比较少,遍历效率很低
      // 这个不是获取某个游戏物体,而是获取某个Mono脚本,当然可以间接地访问到与之关联的游戏物体
      Lesson4 o = GameObject.FindObjectOfType<Lesson4>();
      print(o.gameObject.name);
      
      注:查找对象相关是用的比较少的方法是GameObject父类Object提供的方法,Unity里面的Object不是指的万物之父object,Unity里的Object命名空间在UnityEngine中的Object类,是集成万物之父的一个自定义类,C#中的Object命名空间是在System中的
    • 实例化对象(克隆对象)的方法
      实例化(克隆)对象它的作用是根据一个GameObject对象创建出一个和它一模一样的对象,通常用于实例化一个预制体
      //准备用来克隆的对象
      //1.直接是场景上的某个对象
      //2.可以是一个预设体对象
      public GameObject myObj;  // 既然是公共的域,Inspector面板中直接拖入即可
      GameObject obj5 = GameObject.Instantiate(myObj);
      
    • 删除对象的方法
          GameObject.Destroy(myObj2);
          //第二个参数 代表延迟几秒钟删除
          GameObject.Destroy(obj5, 5);
          //Destroy不仅可以删除对象 还可以删除脚本
          //GameObject.Destroy(this);
      
      删除对象有两种作用:
      1. 删除指定的一个游戏对象
      2. 删除一个指定的脚本对象 注:Destroy方法不会马上移除对象,是给这个对象加了一个移除标识,般情况下,会在下一帧时把这个对象移除并从内存中移除,如果想立即删除可以使用GameObject.DestroyImmediate(myObj);
    • 切换场景时,让某个游戏物体不删除
      默认情况,换场景时,场景中对象都会被自动删除掉
      GameObject.DontDestroyOnLoad(this.gameObject);
      
    注:上述的方法都是在Mono脚本类中进行调用的,可以直接省略GameObject,直接调用即可
  3. GameObject中的成员方法
    • 创建空物体
      new一个GameObject就是在创建一个空物体
          GameObject obj6 = new GameObject();
          GameObject obj7 = new GameObject("DIY创建的空物体");
          // 创建游戏物体的同时,给它挂载指定类型的脚本
          GameObject obj8 = new GameObject("顺便加脚本的空物体", typeof(Lesson2),typeof(Lesson1));
      
    • 为对象添加脚本
      继承MOnoBehavior的脚本是不能够去new,如果想要动态的添加继承MonoBehavior的脚本 在某一个对象上,直接使用GameObject提供的方法即可
          Lesson1 les1 = obj6.AddComponent(typeof(Lesson1)) as Lesson1;
          //用泛型更方便
          Lesson2 les2 = obj6.AddComponent<Lesson2>();
          //通过返回值 可以得到加入的脚本信息
          //来进行一些处理
      
    • 标签比较
          if(this.gameObject.CompareTag("Player"))
          {
              print("对象的标签 是 Player");
          }
          if(this.gameObject.tag == "Player")
          {
              print("对象的标签 是 Player");
          }
      
    • 设置激活失活
      false 失活
      true 激活
          obj6.SetActive(false);
          obj7.SetActive(false);
          obj8.SetActive(false);
      
    • 无关紧要的方法,了解即可
          //通过广播或者发送消息的形式 让自己或者别人 执行某些行为方法
      
          //通知自己 执行什么行为
          //命令自己 去执行这个TestFun这个函数 会在自己身上挂在的所有脚本去找这个名字的函数
          //它会去找到 自己身上所有的脚本 有这个名字的函数去执行
          this.gameObject.SendMessage("TestFun");
          this.gameObject.SendMessage("TestFun2", 199);
      
          //广播行为 让自己和自己的子对象执行
          //this.gameObject.BroadcastMessage("函数名");
      
          //向父对象和自己发送消息 并执行
          //this.gameObject.SendMessageUpwards("函数名");
      
      广播用的很少,了解即可,有的时候可能会有用,比如挂载的很多脚本都有一个同名的方法,就可以通过广播进行调用 代码链接