zoukankan      html  css  js  c++  java
  • Unity 学习(三)—— 编写脚本

    创建和编写脚本

    Unity 支持 C#和能兼容编译 DLL的 .Net语言来编写脚本。

    创建脚本

    Assets -> Create -> C# Script

    解析脚本文件

    Unity 默认使用 VS打开 脚本文件,你也可以通过 Unity -> Preferences来选择你想要打开的编辑器。
    初始文件的内容如下所示:

    using UnityEngine;
    using System.Collections;
    
    public class MainPlayer : MonoBehaviour {
    
        // Use this for initialization
        void Start () {
        
        }
        
        // Update is called once per frame
        void Update () {
        
        }
    }
    

    脚本文件通过实现继承内置 MonoBehaviour类来完成与unity内部工作的连接。你可以认为这个类是一种实现方案,这个方案创建了一个与 GameObject相关的组件类型。每次你将脚本组件与 GameObject联系起来,它就通过实现方案产生一个物体的新实例。类的名字取自创建文件时提供的名称。类名与文件名必须一致,以确保脚本组件能与 GameObject关联。
    Update 函数是你用于处理 GameObject帧更新的地方;它应该包括移动,动作触发和用户输入相应,以及在 gameplay期间需要根据时间推移来解决的任何事件。为保证 Update函数能够工作,你需要在所有游戏动作发生前构建变量、读取首选项以及和其他 GameObjects建立连接。Start 函数将会在 gameplay开始前由 Unity调用,因此你需要在这里做一些初始化。

    控制 GameObject

    在脚本与 GameObject相关联之前,脚本代码并不会被激活。你可以通过拖动脚本 asset到层级面板的 GamObject或到已选中的 GameObject的 Inspector上来产生关联。
    关联起来后,脚本会在你按下 Play运行这个游戏是开始工作。你可以尝试下下面的开始函数:

    // Use this for initialization
    void Start () 
    {
        Debug.Log("I am alive!");
    }
    

    你可以在 Console窗口那看到打印出来的信息。(Window -> Console)

    变量和 Inspector

    就像其他组件也有一些可在 Inspector中编辑一样,你也可以让你的脚本在 Inspector中编辑。

    using UnityEngine;
    using System.Collections;
    
    public class MainPlayer : MonoBehaviour 
    {
        public string myName;
        
        // Use this for initialization
        void Start () 
        {
            Debug.Log("I am alive and my name is " + myName);
        }
    }
    

    上面的代码在 Inspector创建了一个可编辑域“My Name”。

    按下 Play,你会看到:

    在 C#,你必须将变量声明为 public才能在 Inspector中看到它。

    使用 Component控制 GameObject

    脚本也可以通过修改 Component属性来操纵 GameObjects。它与 Inspector的区别在于:脚本可以随着时间推移来改变属性值或响应用户的输入。

    访问 Component

    最简单常见的情况是脚本需要访问关联到此 GameObject的其他组件。实际上,一个组件就是一个类的实例,因此,第一步就是获得你需要的 Component的引用。GetComponent 函数可以做到这个。如下所示:

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

    一旦你获得了一个 Component实例的引用,你就可以设置你想要的属性值了。

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

    在 Inspector中有一个额外的特性可能不可用,那就是调用 Component实例的函数。

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

    需要注意的是,你不能用多个定制化脚本关联一个同一个 object。如果你需要在另一个脚本中访问某个脚本,你可以使用 GetComponent且只使用这个脚本类的名字(即文件名)来指定你想要的 Component类型。
    如果你尝试检索一个未添加到 GameObject上的 Component,那么 GetComponent会返回 null;所以如果你试图去改变一个 null对象的值,你会得到一个 null reference error。

    访问其他 objects

    虽然 objects的分开操作的,但对于脚本来说,与其他 objects保持联系也是十分常见的。比如说,一个正在跟踪的敌人需要知道玩家的位置。Unity提供了许多不同的方式来检索其他 objects,每种方式都有实用的场景。

    通过变量链接 GameObject

    找到相关的 GameObject的最直接的方式是为脚本添加一个 public的 GameObject变量:

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

    这个变量在 Inspector是可见的:

    现在你可以从场景或层级面板中拖动一个 object并分配到这个变量上。GetComponent函数和 Component访问变量对于这个 object来说是可用的,因此你可以使用下面的这段代码:

    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的 Component类型的变量,你可以拖动任何一个拥有此 Component的 GameObject到这。这会直接访问这个 Component而不是 GameObject自身。

    public Transform playerTransform;
    

    寻找 child GameObjects

    有时,一个游戏场景会使用大量的相同类型的 GameObjects,如敌人,导航点和障碍物。这些都需要通过一个特殊的脚本跟踪它们,这个脚本起到监督和响应它们的作用(例如,所有的导航点应该可被一个路径搜索脚本所用)。使用变量来链接这些 GameObjects是可行的,但是,如果每个导航点都要被拖到脚本的一个变量中,是十分繁琐的。同样的,如果一个导航点被删除,就必须要去移除这个变量所引用的遗失的 GameObject,这会十分麻烦。对于这种情况,尝试通过将它们变为一个 parent GameObject的 children往往是更为可行的方案。使用 parent的 Transform组件能检索到 child GameObject(因为所有的 GameObjects隐式地都会有一个 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;
            }
        }
    }
    
  • 相关阅读:
    Windows10内置Linux子系统安装及C++编程环境配置
    在iOS平台上使用gtest进行单元测试
    【转载】Android7.0以前和7.0以后开启闪光灯的方式
    C++11 move记录
    决策树
    生成MTLLibrary
    【转载】3D显示技术
    vector::insert和std::copy
    Visual Studio 2017 + CMake + CUDA
    词嵌入向量WordEmbedding
  • 原文地址:https://www.cnblogs.com/qing2019/p/12716104.html
Copyright © 2011-2022 走看看