网龙暑期训练营第一周:MonoBehavior函数执行顺序、碰撞与鼠标事件

本文通过实验梳理第一周训练营视频中所提到的知识点,便于大家复习巩固,也便于自己日后查阅。视频内容主要分为三个部分:

  1. MonoBehavior的执行顺序

  2. 碰撞事件

  3. 鼠标事件

配合视频使用效果更佳。

代码下载地址:https://download.csdn.net/download/s1314_jhc/10570792 (群共享中也有)

1.MonoBehavior的执行顺序

执行顺序的流程图如下,通过代码实际测试情况对图中顺序进行验证。

测试代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Diagnostics;
public class MonoTest : MonoBehaviour
{
    // Awake is called when the script instance is being loaded
    public void Awake()
    {
        DoLog();
    }
    //// Use this for initialization
    void Start()
    {
        DoLog();
    }
    //// Update is called once per frame
    void Update()
    {
        DoLog();
    }
    //// This function is called every fixed framerate frame, if the MonoBehaviour is enabled
    void FixedUpdate()
    {
        DoLog();
    }
    //// LateUpdate is called every frame, if the Behaviour is enabled
    void LateUpdate()
    {
        DoLog();
    }
    void OnGUI()
    {
        DoLog();
    }
    void Reset()
    {
        DoLog();
    }
    void OnDisable()
    {
        DoLog();
    }
    void OnDestroy()
    {
        DoLog();
    }
    public static void DoLog()        //获取当前调用的方法名
    {
        StackTrace st = new StackTrace(true);
        StackFrame stackFrame = st.GetFrame(1);
        //var callInfo = string.Format("{0}:{1}.{2}",stackFrame.GetFileName(),stackFrame.GetFileLineNumber(),stackFrame.GetMethod().Name);
        var callInfo = stackFrame.GetMethod().Name.ToString();
        DoLog(callInfo);
    }
    public static void DoLog(string szMsg, params object[] args)
    {
        string log = string.Format("[{0}]{1}", DateTime.Now.ToString("HH:mm:ss.ffff"), string.Format(szMsg, args));
        UnityEngine.Debug.Log(log);
    }
}

将代码脚本挂载在Camera下,执行后结果如下图所示。

图中可得,Awake()与Start()的执行顺序最靠前,在两个Update()之间穿插了许多个的FixedUpdate(),LateUpdate()在Update()执行之后调用。并在销毁时调用OnDisable()和OnDestroy(),顺序与流程图中一致。

2.碰撞功能

本节实现视频中提到的碰撞事件,碰撞事件的介绍如下图

在场景中添加几个Cube,挂载上Move脚本控制移动。脚本代码如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour {
    private float translateTimer ;
    private BoxCollider coll;
    private Rigidbody rigid;
        // Use this for initialization
        void Start () {
        coll = GameObject.Find("Plane").GetComponent<BoxCollider>();    //找到BoxCollider和Rigidbody
        //coll = this.GetComponent<BoxCollider>();
        rigid = this.GetComponent<Rigidbody>();
        translateTimer = 3f;
        }
        
        // Update is called once per frame
        void Update () {
                if(Input.GetKey(KeyCode.W))    //控制移动
                {
                        transform.Translate(Vector3.up * Time.deltaTime * 1);
                }
                //向下运动——S
                if(Input.GetKey(KeyCode.S))
                {
                        transform.Translate(Vector3.down * Time.deltaTime * 1);
                }
                //向左运动——A
                if(Input.GetKey(KeyCode.A))
                {
                        transform.Translate(Vector3.left * Time.deltaTime * 1);
                }
                //向右运动——D
                if (Input.GetKey(KeyCode.D))
                {
                        transform.Translate(Vector3.right * Time.deltaTime * 1);
                }
        if (coll != null)    
        {
            if (coll.isTrigger)    
                StopAllCoroutines();
            else
                StartCoroutine(OnTranslateMoveTime());
        }
        else
        {
            Debug.Log("无法找到collider");
        }
        }
    IEnumerator OnTranslateMoveTime()
    {
        yield return new WaitForSeconds(translateTimer);
        rigid.useGravity = false;
        transform.Translate(Vector3.up * Time.deltaTime * 1);
    }
    void OnCollisionEnter(Collision other)
    {
        Debug.Log("发生碰撞,调用OnCollisionEnter");
    }
    void OnCollisionStay(Collision other)
    {
        Debug.Log("正在碰撞,调用OnCollisionStay");
    }
    void OnCollisionExit(Collision other)
    {
        Debug.Log("结束碰撞,调用OnCollisionExit");
    }
    void OnTriggerEnter(Collider other)
    {
        Debug.Log("与触发器产生碰撞,调用OnTriggerEnter");
    }
    void OnTriggerStay(Collider other)
    {
        Debug.Log("正在与触发器进行碰撞,调用OnTriggerStay");
    }
    void OnTriggerExit(Collider other)
    {
        Debug.Log("结束与触发器的碰撞,调用OnTriggerExit");
    }
}

首先测试刚体之间的碰撞,添加MoveTest和Plane两个Cube,给它们添加上BoxCollider,为了方便测试,给MoveTest添加上BoxCollider,开启重力(Use Gravity)

运行时可以看到MoveTest小球与Plane发生碰撞的过程中,效果如下

控制台的输出为

接下来模拟碰撞器与触发器的碰撞情况

将Plane中的isTrigger勾选,并取消MoveTest中RigidBody的UseGravity,改为手动操作MoveTest的移动(W,A,S,D),二者由发生碰撞到相互离开时,控制台的输出如下

注意:此时即使MoveTest组件中含有刚体,也只触发OnTrigger事件。

3.鼠标事件

鼠标常用事件如下

将场景中的小球MouseTest作为鼠标事件的测试。为其添加脚本MouseTest,代码如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseTest : MonoBehaviour {
    void OnMouseDown()
    {
        Debug.Log("鼠标按下,调用OnMouseDown");
    }
    void OnMouseUp()
    {
        Debug.Log("鼠标抬起,调用OnMouseUp");
    }
    void OnMouseEnter()
    {
        Debug.Log("鼠标进入collider范围,调用OnMouseEnter");
    }
    void OnMouseExit()
    {
        Debug.Log("鼠标移出collider范围,调用OnMouseEnter");
    }
}

测试结果如下图

猜你喜欢

转载自blog.csdn.net/s1314_JHC/article/details/81271413