Unity-基本函数用法

1.常用组件

组件 作用
Transform 存储个处理游戏对象的位置、旋转和缩放
Mesh Filter 显示网格
Rigidbody 刚体,使物体能在物理控制下运动
Collider 碰撞器,和刚体一起来是游戏对象发生碰撞
Renderer 渲染器,使物体在屏幕上显示出来
Audio Source 音频源,在场景中可以播放音频剪辑
Animation 播放指定的动画剪辑
Animator 通过动画控制器设置角色上的行为
Script 定义自定义功能和各种交互操作
Particle System 用于创作烟雾,气流,火焰,瀑布,喷泉等效果

2.常用周期事件

事件方法 说明
Awake 唤醒事件,在脚本实例被创建时调用,只执行一次
OnEnable 启用事件,在每次激活脚本时调用
Start 开始事件,用于游戏对象或游戏场景的初始化,在场景被加载时调用,只执行一次
FixedUpdate 固定更新事件,0.02秒执行一次。所有物理组件相关的更新都在这个事件中处理。
Update 更新事件,每帧执行一次
LateUpdate 延迟更新,每帧执行一次,在Update事件之后执行。和相机有关的更新一般都放在这。
OnGUI 用来绘制交互界面,每帧会调用多次
OnDisable 禁用事件,取消脚本的激活状态后调用
OnDestroy 当前脚本被销毁时调用

如下输出,各函数的调用次数。
在这里插入图片描述
3.向量

二维向量Vector2 方法
down Vector2(0,-1)
left Vector2(-1,0)
one Vector2(1,1)
right Vector2(1,0)
up Vector2(0,1)
zero Vector2(0,0)
magnitude 返回向量长度
normalized 单位化向量,长度变为 1,方向不变
        //静态变量.类名来调用
        print(Vector2.down);
        print(Vector2.up);
        print(Vector2.left);
        print(Vector2.right);
        print(Vector2.zero);
        print(Vector2.one);

        //创建向量
        Vector2 a = new Vector2(4,5);
        Vector2 b = new Vector2(1,3);

        //返回向量长度
        print(a.magnitude);
        print(b.magnitude);

        //返回单位化向量,原向量不变
        print(a.normalized);
        print(a.x + "," + a.y);
        print(b.normalized);
        print(b.x + "," +b.y);

        //对向量进行单位化,原向量改变
        a.Normalize();
        print(a.x + "," + a.y);

        //输出两个向量之间的距离
        print(Vector2.Distance(a, b));

        //输出两向量之间的角度
        print(Vector2.Angle(a, b));
三维向量Vector3 方法
back Vector3(0,0,-1)
down Vector3(0,0,-1)
forward Vector3(0,0,1)
left Vector3(-1,0,0)
one Vector3(1,1,1)
right Vector3(1,0,0)
up Vector3(0,1,0)
zero Vector3(0,0,0)
Angle 两向量的夹角
Cross 叉乘,满足左手法则,结果为一个向量
Dot 点乘,结果为一个值
MoveTowards 由当前位置匀速移动到目标位置
Slerp 对长度和角度进行插值,用于对象的转向,比较平滑
+,-,*,/,!=,== 相关运算

4.键盘和鼠标输入

相关方法 说明
Input.GetKey() 按下某键,持续返回true
Input.GetKeyDown 按下某键的一瞬间,返回true
Input.GetKeyUp 松开某键的一瞬间,返回true
Input.GetMouseButton(0) 持续检测是否按鼠标左键(针对鼠标左中右键,三个方法同)
Input.GetMouseButtonDown(1) 检测是否按下了右键,检测一次
Input.GetMouseButtonUp(2) 检测是否按下了鼠标中键[参数左键(0),右键(1),中键(2) ]
Input.GetButton 持续检测
Input.GetButtonDown 检测是否按下,检测一次
Input.GetButtonUp 检测是否松开,检测一次
Input.GetAxis 获取虚拟轴,返回-1到1之间的浮点数,有渐变效果
Input.GetAxisRow 返回-1,0,1三个值,没有渐变效果
OnMouseDrag 当鼠标拖动(获取鼠标的行为事件,不针对左中右键,下同)
OnMuseDown 当鼠标按下
OnMouseUp 当鼠标抬起
OnMouseEnter 当鼠标进入
OnMuseExit 当鼠标退出
OnMuseOver 当鼠标经过
               //获取键盘的输入,检测按下和松开。
        if(Input.GetKey(KeyCode.A))
            print("GetKey:A");
        if(Input.GetKeyDown(KeyCode.A))
            print("GetkeyDown:A");
        if(Input.GetKeyUp(KeyCode.A))
            print("GetKeyUp:A");

        //检测鼠标右键状态
        if (Input.GetMouseButton(1))
            print("Mouse right");
        if (Input.GetMouseButtonDown(1))
            print("Mouse right down");
        if (Input.GetMouseButtonUp(1))
            print("Mouse right up");

获取按钮和虚拟轴:
通过Edit–>Project Setting–>Input Manager–>Axes打开,可以查看相关配置信息。如Fire1的配置如下。按下鼠标左键(Mouse 0)和按下左边的Ctrl都会响应。
在这里插入图片描述

        //检测按钮Fire1状态
        if (Input.GetButton("Fire1"))
            print("Button Fire1");
        if (Input.GetButtonDown("Fire1"))
            print("Button Fire1 Down");

获取虚拟轴,按下左右的方向键或者a、d键,输入虚拟轴的值。
在这里插入图片描述

        //获取虚拟轴的状态
        //一般用来控制物体的左右,前后移动或者旋转
        float h1 = Input.GetAxis("Horizontal");
        print(h1);

        float h2= Input.GetAxisRaw("Horizontal");
        print(h2);

改变一个游戏对象的颜色。

    private void OnMouseEnter()
    {
        gameObject.GetComponent<MeshRenderer>().material.color = Color.red;
    }
    private void OnMouseExit()
    {
        gameObject.GetComponent<MeshRenderer>().material.color = Color.white;
    }

5.Time类及其成员变量
通过Time类可以获取和时间有光的信息,用来计算帧速率,调整时间流逝的速度等。

成员变量 功能
Time 游戏开始到现在的时间( 秒)
deltaTime 上一帧消耗的时间
fixedTime 最近FixedUpdate已经开始的时间,该时间从游戏开始计算
fixedDeltaTime 物理引擎和FixedUpdate更新时间间隔
timeScale 时间流逝速度比例。可以用来制作慢动作特效
frameCount 已渲染的帧总数
smoothDeltaTime Time.deltaTime的平滑淡出
timeSinceLevelLoad 此帧的开始时间,从关卡加载完成开始计算
maximumDeltaTime 一帧的最大耗费时间
realtimeSinceStartup 游戏开始到现在经历的真实时间,该时间不会受timeScale的影响
captureFramerate 固定帧设置
        print("Time.time:" + Time.time);
        print("Time.deltaTime:" + Time.deltaTime);
        print("Time.fixedDeltaTime:" + Time.fixedDeltaTime);
        print("Time.fixedTime:" + Time.fixedTime);
        print("Time.timeScale:" + Time.timeScale);
    //通过计时器来控制Cube的状态
    private float time = 3.0f;
    
    //运行时在Unity面板上设置值
    public float speed;
    public float rotaeSpeed;
    
    private void Update()
    {
        time -= Time.deltaTime;
        if(time<=0)
        {
            time = 3.0f;
            //处理逻辑,该属性取反,禁用时,不渲染。
            GetComponent<MeshRenderer>().enabled = !GetComponent<MeshRenderer>().enabled;
        }

        //控制物体每秒移动多少米
        transform.Translate(Vector3.right * Time.deltaTime*speed);

        //控制物体每秒旋转的角度
        transform.Rotate(Vector3.up * Time.deltaTime * rotaeSpeed);

        //通过按键来控制时间流速的大小
        if (Input.GetKeyDown(KeyCode.Q))
            Time.timeScale = 10.0f;
        if (Input.GetKeyDown(KeyCode.P))
            Time.timeScale =0.0f;
    }

6.预制体
预制体:Perfab,预先准备好的物体,可以重复使用,是Unity中很重要的资源。

预制体的创建方法:

  • 手动创建:从Hierachy面板用鼠标拖拽游戏物体到Asserts资源文件夹中;
  • 脚本动态创建:Instantiate(Prefabs,transform.position,transform.rotation);
    在这里插入图片描述
  • 可以置入多个场景中,也可以多次置入一个场景中。
  • 在场景中添加一个Prefab,即实例化了一个预制体对象。
  • 所有的Prefab实例都是一个Prefab的原型克隆,运行中生成的对象会有Clone的标记。
  • 只要原型发生变化,所有的Prefabs都会发生变化。

创建游戏对象的三种方法:

  • 通过GameObject构造函数创建游戏对象,生成一个空的游戏对象。
    GameObject g=new GameObject(“g”);
  • 通过CreatePrimitive方法创建原型的游戏模型。GameObject.CreatePrimitive(Primitive.Cube);
  • 通过Instantiate方法创建游戏对象。
    克隆预制体;
    克隆普通的游戏对象;
    Instantiate(Prefabs,transform.position,transform.rotation);
    public GameObject CubePrefab;
    private GameObject g2;
    GameObject g1;
    void Start()
    {
        g1= new GameObject("g1");

        GameObject.CreatePrimitive(PrimitiveType.Cube);

        Vector3 pos = new Vector3(-1f, 2f, 0f);
        //使用as将Instantiate的返回值转化为GameObject类型
        g2=Instantiate(CubePrefab, pos, Quaternion.identity) as GameObject;

        print(g2.name);
    }

运行前将准备好的预制体赋值给CubePrefab,如下:
在这里插入图片描述
结果如图:
在这里插入图片描述
游戏对象的销毁:

  • 现在销毁一个对象,GameObject.Destroy(Object);
  • 延迟销毁一个对象,GameObject.Destroy(Object obj,float time);
  • 销毁游戏物体时将销毁该物体所有组件和子物体。
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.D))
        {
            GameObject.Destroy(g2);
            GameObject.Destroy(g1, 5f);
        }
    }

7.查找物体
若物体没激活,则通过名称和标签查不到,通过路径和和根据父物体可以查到。

方法 说明
GameObject.Find() 可通过名称全局查找或根据路径查找子对象
GameObject.Find(“Cube”).transform.GetChild(0) 通过父物体查找子物体
FindWithTag/FindGameObjectWithTag/FindGameObjectsWithTag 通过标签名查找

在这里插入图片描述

        GameObject go1=GameObject.Find("s");
        print(go1.name);

        Transform tf1= transform.Find("g1/s");
        print(tf1);

        Transform tf2=GameObject.Find("g1").transform.GetChild(0);
        print(tf2);
		
		//设置s和g2的标签为Player;
        GameObject go2=GameObject.FindGameObjectWithTag("Player");
        print(go2);

        GameObject[] gArray = GameObject.FindGameObjectsWithTag("Player");
        print(gArray.Length);
        print(gArray[0].name);

8.启用和禁用

函数 功能
SetActive 参数true为启用,false为禁用
activeSelf 父物体禁用,自身未禁用,则返回true
activeInHierarchy 父物体禁用,则返回false
 	public GameObject Cube;
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.D))
        {
            Cube.SetActive(false);
            print(Cube.activeSelf);
            print(Cube.activeInHierarchy);
        }
        if (Input.GetKeyDown(KeyCode.A))
        {
            Cube.SetActive(true);
            print(Cube.activeSelf);
            print(Cube.activeInHierarchy);
        }
    }

获取组件信息
在这里插入图片描述

void Start()
    {
        BoxCollider box= gameObject.GetComponent<BoxCollider>();
        box.size *= 3;

        //获取脚本组件
        s c=gameObject.GetComponent<s>();
        c.name = "txy";
        c.print();
    }

组价的启用和禁用

	void Update()
    {
        //组件的添加和删除
        if(Input.GetKeyDown(KeyCode.A))
        {
            gameObject.AddComponent<Rigidbody>();
        }
        if (Input.GetKeyDown(KeyCode.D))
        {
            GameObject.Destroy(gameObject.GetComponent<Rigidbody>());
        }


        //组件的启用和禁用
        if (Input.GetKeyDown(KeyCode.E))
        {
            gameObject.GetComponent<BoxCollider>().enabled = true;
        }
        if (Input.GetKeyDown(KeyCode.F))
        {
            gameObject.GetComponent<BoxCollider>().enabled =false ;
        }
    }

移动物体

    void Update()
    {
        //控制物体的移动
        //1.通过改变位置信息,添加一个增量,来持续改变位置信息
        transform.position += new Vector3(Time.deltaTime * 0.5f,0, 0);

        //2.通过transform.Translate来移动,默认朝自身坐标系方向运动,可以设置为朝世界坐标系
       transform.Translate(Vector3.right * Time.deltaTime * 0.5f,Space.World);

        //3.通过Vector3.Lerp方法,通过插值,运动为先快后慢
        Vector3 target = new Vector3(4f, 3f, 2f);
        transform.position=Vector3.Lerp(transform.position, target, Time.deltaTime);

        //4.通过Vector3.MoveTowards方法,匀速移动,z增量为Time.deltaTime
        transform.position = Vector3.MoveTowards(transform.position, target, Time.deltaTime);

	    //5.通过A,S,D,W键来控制物体的移动;虚拟轴的值正负来控制移动的方向
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        transform.Translate(Vector3.right * h * Time.deltaTime);
        transform.Translate(Vector3.forward * v * Time.deltaTime);
    }
    

物体的旋转

  void Start()
    {
    	//欧拉角与四元素介绍
        //获取物体的欧拉角
        print(transform.eulerAngles);

        //获取四元数
        print(transform.rotation);

        //四元素与欧拉角的相互转换
        print(transform.rotation.eulerAngles);//四元数-->欧拉角
        print(Quaternion.Euler(transform.eulerAngles));// 欧拉角-- > 四元数
    }

    // Update is called once per frame
    void Update()
    {
        //1.使用transform.Rolate方法,y轴每秒旋转30度
        transform.Rotate(Vector3.up * Time.deltaTime * 30);

        //2.使用四元数的乘法来实现,在其基础上y轴旋转5度;
        Quaternion q1 = transform.rotation;
        Vector3 vd = new Vector3(0, 5, 0);
        Quaternion q2 = Quaternion.Euler(vd);
        if(Input.GetKeyDown(KeyCode.R))
        {
            transform.rotation=q1* q2;
        }   
    }

Invoke相关方法

函数 功能
Invoke(string funname,float time) 调用函数。多少秒后执行函数funname,只会调用一次
InvokeRepeating(string ,float,float) 重复调用函数。多少秒后执行某个函数,并且以后每个多少秒都会执行该函数一次
CancelInvoke 取消这个脚本中的所有Invoke调用
CancelInvoke(string fun) 取消某个函数的Invoke调用
IsInvokeing(string ) 判断某个函数是否在等待调用
void Start()
    {
        //调用函数CreateBox,延迟两秒
       // Invoke("CreateBox", 2f);
        InvokeRepeating("CreateBox", 4f, 2f);
    }

    // Update is called once per frame
    void Update()
    {
        bool r = IsInvoking("CreateBox");
        print(r);

        if(Input.GetKeyDown(KeyCode.D))
        {
             //CancelInvoke();
            CancelInvoke("CreateBox");
        }
    }
    void CreateBox()
    {
        print("生成物体");
    }
}

9.协成
协成:协成程序,即主程序在运行的同时开启另外一段出路逻辑。
协成方法与普通方法的区别:

  • 调用普通方法,会等这个普通方法执行完,然后在继续向下执行;
  • 调用协成方法,可以不用等这个方法执行完就继续向下执行;

协成方法的定义:

  • 返回值类型是IEnumerator,方法体中使用yield return返回,可以返回空。
  • 使用yield语句可以暂停协成的执行,yield return的返回值决定了什么时候恢复协成的执行。
例子 说明
yield return null/数字/字符串 暂停协成,下一帧在继续执行,用来延迟一帧执行
yield return new WaitForSeconds(2f) 暂停协成,2秒后再往下执行
yield return StartCoroutine(“Funname”) 暂停协成,启动协成Funname,执行完后再继续往下执行
yeild new WaitForFixedUpdate() 暂停协成,等下一次调用FixedUpdate方法是在继续执行下去
    void Start()
    {
        //普通方法
        print("任务1");
        print("任务2");
        //print("任务3");
        //开启协成
        StartCoroutine("Task3");
        print("任务4");
    }
    //定义协成
    IEnumerator Task3()
    {
        yield return new WaitForSeconds(2f);
        print("任务3");
    }

结果
在这里插入图片描述

    void Update()
    {
        //停止协成
        if(Input.GetKeyDown(KeyCode.Space))
        {
            StopCoroutine("Task3");
        }
    }

10.物理引擎
具有刚体组件的物体,满足物理规律,具有碰撞体的物体能进行碰撞检测。
在这里插入图片描述

  • Mass表示物体的重量
  • Drag:空气阻力
  • Angular Drag:角阻力,受到扭曲时的空气阻力
  • Use Gravity:使用重力
    private Rigidbody r;
    // Start is called before the first frame update
    void Start()
    {
        r = gameObject.GetComponent<Rigidbody>();

    }

    // Update is called once per frame
    void Update()
    {
        //刚体移动
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        r.MovePosition(r.position + transform.right * h * Time.deltaTime * 2f);
        r.MovePosition(r.position + transform.forward * v * Time.deltaTime * 2f);
    }

碰撞事件检测方法

函数 功能
OnCollisionEnter(Collision) 当碰撞开始时,调用该方法一次
OnCollisionExit(Collision) 当碰撞结束时,调用该方法一次
OnCollisionStay(Collision) 当碰撞进行中是,持续调用该方法
    private void OnCollisionEnter(Collision collision)
    {
        print("Enter"+collision.gameObject.name);
    }
    private void OnCollisionExit(Collision collision)
    {
        print("Enter" + collision.gameObject.name);
    }
    private void OnCollisionStay(Collision collision)
    {
        print("Enter" + collision.gameObject.name);
    }

碰撞检测条件

  • 两个物体接触并发生碰撞
  • 运动物体必须带有碰撞体Collider和刚体Rigidbody
  • 另一个物体必须至少带有碰撞体Collider

触发器事件

  • 触发器:将碰撞组件属性面板上的“Is Trigger”勾选,当前物体的碰撞体就变成了了触发器。
  • 触发器事件:当一个刚体控制的物体进入另一个物体的触发器范围内,就是触发事件。
  • 用途:不与目标物体发生碰撞(接触),而是进入目标物体的触发范围,就执行特定操作。

触发器检测条件:

  • 运动物体必须带有碰撞体Collider和刚体Rigidbody;
  • 另一个物体至少带有碰撞体Collider;
  • 其中一个物体勾选Is Trigger;
private void OnTriggerEnter(Collider other)
    {
        if(other.name !="Plane")
        {
            print(other.gameObject.name);
            print(other.name);
        }
    }
    private void OnTriggerExit(Collider other)
    {
        if (other.name != "Plane")
        {
            print(other.gameObject.name);
            print(other.name);
        }
    }

    private void OnTriggerStay(Collider other)
    {
        if (other.name != "Plane")
        {
            print(other.gameObject.name);
            print(other.name);
        }
    }

物理射线

  • 从一个点往一个方向发射,该射线与场景中的物体的碰撞体组件碰撞,射线即结束。
  • 由于射线可以与物理组件Collider交互,所以也称之为“物理射线”;

物理射线检测方法:

  • 通过摄像机创建射线
    Camera.main:指的是tag设置为MainCamera的摄像机的组件Camera的引用;
    ScreenPointToRay(Vector3):摄像机组件的下的方法,屏幕点转化为射线,返回一个Ray类型的射线。
    Input.mousePosition:鼠标所在的位置,Vector3类型;
  • 检测射线与其他物体的碰撞
    RaycastHit:一个结构体,存储射线的碰撞信息;
    Physics.Raycast(Ray,out RaycastHit):检测射线,碰撞返回true,否则返回false;第一个参数为需要检测的射线,第二个参数存储碰撞信息。
    private Ray ray;
    private RaycastHit hit;
    void Update()
    {
        if(Input.GetMouseButtonDown(0))
        {
            //获取摄像机,创建一条射线,方向为摄像机到鼠标点击的位置
            ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        }

        //碰撞检测,通过结构体hit和返回关键字out返回碰撞信息
        if(Physics.Raycast(ray, out hit))
        {
            //把碰撞的物体销毁
            GameObject.Destroy(hit.collider.gameObject);
        }
    }

附:
学习至中国大学mooc-Unity2D游戏程序设计

发布了126 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/TxyITxs/article/details/104130605