使用组件控制物体
博客专区 > LIndieGS 的博客 > 博客详情
使用组件控制物体
LIndieGS 发表于11个月前
使用组件控制物体
  • 发表于 11个月前
  • 阅读 2
  • 收藏 0
  • 点赞 0
  • 评论 0

【腾讯云】买域名送云解析+SSL证书+建站!>>>   

原文链接:https://docs.unity3d.com/Manual/ControllingGameObjectsComponents.html

     在Unity中,你能使用监视器(Inspector)来改变组件的属性。所以,例如,改变Transform(变化) 组件的position(位置)的值就会引起组件位置的改变。类似的,你可以改变着色器(Render)材质(Material)的颜色或刚体(Rigidbody)的质量,使物体的外观和行为有一个合适的效果。在多数情况下,脚本也是通过改变物体的属性来操控物体的。不同的是,脚本能改变随着时间的推进逐步改变属性值,或响应一个来自玩家的输入。通过在正确的时间改变,创建和销毁物体,任何种类的玩法(gameplay)都能被实现。

访问组件

      最简单、最常见的情况是一个脚本需要访问挂在同一物体上的其他组件。一个组件实际上是一个类的实例(instance)。因此第一步就是获取一个你想要执行的组件实例的引用。GetComponent()函数可以实现这个功能。典型地,你想指定这个组件对象给一个变量,在C#中,可以通过下面的语句实现这件事情。

void Start () {
    Rigidbody rb = GetComponent<Rigidbody>();
}

     一旦你建立了一个组件实例的引用,你就能设置它的属性值。甚至你可以在Inspector中改变它。

void Start () {
    Rigidbody rb = GetComponent<Rigidbody>();
    
    // Change the mass of the object's Rigidbody.
    rb.mass = 10f;
}

     一个额外的特性是可以调用组件实例中的函数。(这个特性不能在Inspector中实现)

void Start () {
    Rigidbody rb = GetComponent<Rigidbody>();
    
    // Add a force to the Rigidbody.
    rb.AddForce(Vector3.up * 10f);
}

 

    值得注意的是:你不能有超过一个自定义脚本挂在同一个对象上。如果你需要访问来自另一个对象上脚本,你通常可以使用GetComponent()函数,只需要在尖括号里包括脚本类的类名(或文件名),去指定你想要的组件的类型。

    如果你企图去获取这个物体上并不存在的组件,那么GetComponent()函数会返回一个null(空);如果你尝试改变任何在空对象中的值,你将会在运行时得到一个空引用错误。

访问其他对象

    尽管它们有时能独立执行,但对于脚本来说,访问其他对象是很普通的。比如,创建一个跟踪玩家的敌人可能需要知道玩家的位置。Unity提供了许多的不同的方法检索其他对象,每一个都适用于特定的情况。

用变量链接对象

    找到相关物体最直接的方法是在脚本中添加一个GameObject的变量(声明为public):

public class Enemy : MonoBehaviour {
    public GameObject player;
    
    // Other variables and functions...
}

    和其他变量一样,这个GameObject的变量也能在监视器里看到。

    你可以从场景(Scene)或层级(Hierarchy)中拖进一个物体。GetComponent()函数和组件访问变量就能在这个物体上使用,所以你可以使用如下代码:

public class Enemy : MonoBehaviour {
    public GameObject player;
    
    void Start() {
        // Start the enemy ten units behind the player character.
        transform.position = player.transform.position - Vector3.forward * 10f;
    }
}

    另外,如果在你的脚本中声明一个公有的组件型变量,你能拖进任何一个挂有你想访问组件的物体。它会直接访问物体的这个组件,而不是访问这个物体本身。

public Transform playerTransform;

    当你在处理某些对象会一直和其他对象有联系时,通过变量链接对象是最有效的手段。你可以使用数组变量来链接多个同类型的物体,但是这种链接必须在编辑游戏是就设定好,而不能在游戏运行时去设定。在游戏运行时,用这种方法来定位一个对象是很方便的。Unity提供了两种基础的方法来实现这件事情,如下所述。

寻找子物体

    有时,在一个游戏场景中会使用许多同类型的物体。比如敌人,路标和障碍。这可能需要被一个特殊的脚本追踪,这个脚本能指导这些物体,或对它们有一些反应。(比如:所有的路标都需要被一个寻路脚本访问)。使用变量去连接这些脚本是可行的,但是它会使设计过程非常繁琐,如果每一个新路标都被拖进一个变量。同样地,如果一个路标被删除,就不得不为这个路标移除所有变量的引用。为了避免这件事情,通常安排这一组对象为同一个父级的子级。这些子对象就可以使用父级的Transform组件去访问。(因为所有的GameObject都隐含一个Transform组件)。

using UnityEngine;

public class WaypointManager : MonoBehaviour {
    public Transform[] waypoints;
    
    void Start() {
        waypoints = new Transform[transform.childCount];
        int i = 0;
        
        foreach (Transform t in transform) {
            waypoints[i++] = t;
        }
    }
}

   这非常有用,当一个对象有一个子对象,这个子对象在游玩过程中能被随时添加和移除。游戏中,捡起或丢弃武器就是一很好的例子。

通过名字或标签来寻找物体

    你能在场景层级的任何地方定位一个物体,只要你有一些识别它们的信息。单个物体能通过名字去访问,这就要用到GameObject.Find()函数:

GameObject player;

void Start() {
    player = GameObject.Find("MainHeroCharacter");
}

    一个物体或是物体的集合也可以被它们的标签(tag)定位,可以使用GameObject.FindWithTag()和GameObject.FindGameObjectsWithTag()函数:

GameObject player;
GameObject[] enemies;

void Start() {
    player = GameObject.FindWithTag("Player");
    enemies = GameObject.FindGameObjectsWithTag("Enemy");
}

 

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 0
博文 9
码字总数 6421
×
LIndieGS
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: