本文通过实验梳理第一周训练营视频中所提到的知识点,便于大家复习巩固,也便于自己日后查阅。视频内容主要分为三个部分:
-
MonoBehavior的执行顺序
-
碰撞事件
-
鼠标事件
配合视频使用效果更佳。
代码下载地址: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");
}
}
测试结果如下图