Unity基础 之 生命周期函数(二)

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战markdown

一,鼠标交互

1.1 函数描述

几个函数ide

  1. OnMouseEnter: 鼠标进入时调用一次
  2. OnMouseOver: 鼠标停留(通过)时一直调用
  3. OnMouseExit: 鼠标退出时调用一次
  4. OnMouseDown: 鼠标按下时调用一次
  5. OnMouseDrag: 鼠标拖拽(按住)时一直调用
  6. OnMouseUp: 鼠标抬起时调用一次

实际使用:使用时通常都是成对使用函数

  1. OnMouseEnter,OnMouseOver,OnMouseExit 一组。好比模拟选中状态:鼠标进入时物体变色,鼠标退出时再变回来。
  2. OnMouseDown,OnMouseDrag,OnMouseUp 一组。好比射击游戏:鼠标按下拖拽时调整方向,抬起时发射子弹。
  3. 当鼠标按下并停留在当前游戏对象上时,OnMouseOver,OnMouseDrag会同时触发。

检测原理post

  1. 只能检测当前脚本挂载的游戏对象。
  2. 当前游戏对象须要有碰撞体。
  3. 不能有其余物体(UI)遮挡到此游戏对象。
  • 总结为一局话就是:OnMouseXXX的原理是经过鼠标的射线检测来判断鼠标当前位置是否碰到了挂载脚本游戏对象的碰撞体。

勾选IsTrigger:测试

  若须要不检测勾选IsTrigger的碰撞体,Edit => Project Settings => Physics中的Queries Hit Triggers,将这个✅ 取消,便可不触发勾选IsTrigger的。【注意:默认是✅ 勾选状态,不须要触发则取消勾选】 ui


1.2 示例解析

  场景中建立一个Cube,将其位置调整在摄像机先显示便可【示例中调整位置(0,0,-1),缩放为(3,3,3)】。spa

测试功能:code

  • 鼠标进入\退出,触发Cube颜色变化
  • 鼠标移动到Cube上,触发旋转
  • 鼠标在Cube按下并拖拽,触发Cube跟随移动
  • 鼠标抬起Cube回归到原来位置

建立并挂载到Cube代码以下:orm

using UnityEngine;

public class OnMouseXXXTest : MonoBehaviour
{
    #region 鼠标相关

    // 鼠标和Collider(碰撞体)之间的触发
    
    // 鼠标进入
    private void OnMouseEnter()
    {
        Debug.Log("OnMouseEnter 鼠标进入...");
        GetComponent<MeshRenderer>().material.color = Color.blue;
    }
    
    // 鼠标停留
    private void OnMouseOver()
    {
        transform.Rotate(Vector3.up * 50 * Time.deltaTime);
    }

    // 鼠标退出
    private void OnMouseExit()
    {
        Debug.Log("OnMouseExit 鼠标退出...");
        GetComponent<MeshRenderer>().material.color = Color.green;
    }

    // 鼠标按下
    private void OnMouseDown()
    {
        Debug.Log("OnMouseDown 鼠标按下...");
    }

    // 鼠标拖动
    private void OnMouseDrag()
    {
        Vector3 target = Input.mousePosition;
        target.z = Mathf.Abs(Camera.main.transform.position.z);
        transform.localPosition = Camera.main.ScreenToWorldPoint(target);
    }

    // 鼠标抬起
    private void OnMouseUp()
    {
        Debug.Log("OnMouseUp 鼠标抬起...");
        transform.localPosition = new Vector3(0, 0, -1);
    }

    #endregion
}
复制代码

测试效果: 对象


二,碰撞检测

2.1 函数描述

碰撞函数

  1. OnCollisionEnter: 进入碰撞时触发一次。
  2. OnCollisionStay: 在碰撞体中停留时每帧触发一次。
  3. OnCollisionExit: 离开碰撞体时触发一次。

触发函数

  1. OnTriggerEnter: 进入碰撞体时触发一次。
  2. OnTriggerStay: 在碰撞体中停留时每帧触发一次。
  3. OnTriggerExit: 离开碰撞体是触发一次。

PS:上面这六个方法,还有对应2D碰撞体的六个方法(如:OnCollisionEnter2D) 函数后面添加2D接口,触发条件和使用方式和3D一致。 使用时注意碰撞体和检测函数同步接口,即用2D碰撞体必须用2D函数。

函数执行条件

  1. 两个物体须要都有碰撞体(Collider)组件。
  2. 检测方(挂载脚本物体)须要有刚体(Rigidbody)组件。
  3. Collider上都不勾选IsTrigger(有一方勾选则执行触发函数)。

2.2 示例解析

在一例上继续操做,在Cube上添加Rigidbody组件,并取消勾选Use Gravity 属性(避免其受到重力影响)。

而后再建立两个Cube,位置大小随意能在Game视图看到就行。将其中一个BoxCollider的IsTrigger 属性勾选 ✅ 上。这样就能够一个用来测试碰撞,一个用来测试触发了。

将代码添加到OnMouseXXXTest类中,添加内容以下:

#region 碰撞,触发检测

// 在方法名后加上2D(如:OnCollisionEnter2D), 便可触发2D碰撞体对应函数
// 进入碰撞时触发
private void OnCollisionEnter(Collision other)
{
    Debug.Log("开始碰撞..." + other.collider.gameObject.name);
    other.collider.GetComponent<MeshRenderer>().material.color = Color.black;
}

// 在碰撞体中停留时每帧触发一次
private void OnCollisionStay(Collision other)
{
    Debug.Log("持续碰撞中..." + other.collider.gameObject.name);
    other.collider.GetComponent<MeshRenderer>().material.color = Color.red;
}

// 离开碰撞体时触发
private void OnCollisionExit(Collision other)
{
    Debug.Log("碰撞结束..." + other.collider.gameObject.name);
    other.collider.GetComponent<MeshRenderer>().material.color = Color.white;
}

// 碰撞体勾选is Trigger 选项: 取消碰撞器,开启触发器
// 进入碰撞体时触发
private void OnTriggerEnter(Collider other)
{
    Debug.Log("触发开始...");
    other.transform.GetComponent<MeshRenderer>().material.color = Color.black;
}

// 在碰撞体中触发
private void OnTriggerStay(Collider other)
{
    Debug.Log("持续触发中...");
    other.transform.GetComponent<MeshRenderer>().material.color = Color.yellow;
}

// 离开碰撞体是触发
private void OnTriggerExit(Collider other)
{
    Debug.Log("触发结束...");
    other.transform.GetComponent<MeshRenderer>().material.color = Color.white;
}
#endregion
复制代码

运行后获得以下效果:


三,应用程序

3.1 函数描述

三个函数

  1. OnApplicationPause: 检测到暂停的帧结束 --> 切换到后台和回来时调用。
  2. OnApplicationFocus: 当屏幕 得到/失去 焦点时调用
  3. OnApplicationQuit: 当程序退出时调用。

实际应用

  1. OnApplicationPause: 游戏中止保存数据/游戏继续数据初始化。

  2. OnApplicationFocus: 失去焦点关闭背景音乐/得到焦点继续播放音乐。

  3. OnApplicationQuit: 在移动端大退时也会对调用,但不会触发上面两个方法。


3.2 示例解析

使用时将下面代码复制到须要处理检测逻辑的部分便可:

#region Application 应用程序

// 检测到暂停的帧结束时调用,有效地在正常帧更新之间
private void OnApplicationPause(bool pauseStatus)
{
    Debug.Log("OnApplicationPause ... " + pauseStatus);
    if (pauseStatus) // 切换到后台时执行
    {
    }
    else // 切换到前台执行一次
    {
    }
}

// 当屏幕 得到/失去 焦点时调用
private void OnApplicationFocus(bool hasFocus)
{
    Debug.Log("OnApplicationFocus ... " + hasFocus);
    if (hasFocus) // 得到焦点 -- 切换到前台
    {
    }
    else // 失去焦点
    {
    }
}

// 当程序退出时调用 -- Application.Quit();触发,不会触发上面两个方法
private void OnApplicationQuit()
{
    Debug.Log("OnApplicationQuit ... ");
}
复制代码

由下图能够看到执行逻辑:当我点击Hierarchy面板时触发失去焦点,再次点击Game视图则触发了得到焦点

Unity 官方图解: 图解

相关文章
相关标签/搜索