协同程序
协同程序,即在主程序运行时同时开启另一段逻辑处理,来协同当前程序的执行。换句话说,开启协同程序就是开启一个线程。
协同程序的开启与终止
在Unity3D中,使用MonoBehaviour.StartCoroutine方法即可开启一个协同程序,也就是说该方法必须在MonoBehaviour或继承于MonoBehaviour的类中调用。
在Unity3D中,使用StartCoroutine(string methodName)和StartCoroutine(IEnumerator routine)都可以开启一个线程。区别在于使用字符串作为参数可以开启线程并在线程结束前终止线程,相反使用IEnumerator 作为参数只能等待线程的结束而不能随时终止(除非使用StopAllCoroutines()方法);另外使用字符串作为参数时,开启线程时最多只能传递一个参数,并且性能消耗会更大一点,而使用IEnumerator 作为参数则没有这个限制。
在Unity3D中,使用StopCoroutine(string methodName)来终止一个协同程序,使用StopAllCoroutines()来终止所有可以终止的协同程序,但这两个方法都只能终止该MonoBehaviour中的协同程序。
例:
这个例子将执行Do,但是do函数之后的print指令会立刻执行.
- <span style="font-size:18px;">Do ();
- Console.WriteLine("This is printed immediately");
- IEnumerator Do ()
- {
- Console.WriteLine("Do now");
- yield return new WaitForSeconds (2);
- Console.WriteLine("Do 2 seconds later");
- }
- <span style="font-size:18px;">// 启动协程
- yield return StartCoroutine("Do");
- Console.WriteLine("Also after 2 seconds");
- Console.WriteLine ("这个print将在Do协程执行完以后显示。");
- IEnumerator Do ()
- {
- Console.WriteLine("Do now");
- yield return new WaitForSeconds (2);
- Console.WriteLine("Do 2 seconds later");
- }
查看 YieldInstruction , WaitForSeconds , WaitForFixedUpdate , Coroutine and MonoBehaviour.StartCoroutine 可以获得更多使用yield的信息.
yield return可以看做是一种特殊的return,会返回到父类继续执行,但是yield return后面的类型或方法会有一个执行条件,当条件满足时会回调包含yield的子函数,
- void Start () {
- print("Starting:" + Time.time);
- StartCoroutine(WaitAnPrint(2.0F));
- print("Before WaiAndPrint:" + Time.time);
- }
- IEnumerator WaitAndPrint(float waitTime)
- {
- yield return new WaitForSeconds(waitTime);
- print("WaitAndPrint:" + Time.time);
- }
射线
射线是3D世界中一个点向一个方向发射无终点的线。在unity3d中我们发射的射线一旦与其他的碰撞器发生碰撞,射线将停止发射。在游戏制作过程中我们可以通过判断射线是否发生了碰撞,并且可以判断射线和谁发生了碰撞。应用范围非常广泛,如射击类游戏中用它来判断是否射中目标。
Ray.origin:射线起点
Ray.direction:射线的方向
步骤:
1.创建一条射线的方法Ray (origin : Vector3, direction : Vector3)
2.Origin是射线的起点,dire我们要想在游戏中发射一条射线,必须要有两个元素,一个起始点,一个方向。
ction是射线的方向。
3.首先在场景中创建一个CUBE,创建一个c#文件,并输入如下代码:
void Update ()
{
//定义一条射线,起点为Vector3.zero终点为物体坐标
Ray ray=new Ray(Vector3.zero,transform.position);
//定义一个光线投射碰撞
RaycastHit hit;
//发射射线长度为100
Physics.Raycast(ray,out hit,100);
//在Scene中生成这条射线,起点为射线的起点,终点为射线与物体的碰撞点
Debug.DrawLine(ray.origin,hit.point);
}
Debug.DrawLine()方法只在Scene视图中才可以看到
下面我们通过一个实例来看一下怎么判断射线与游戏物体之间的碰撞,并如何获得碰撞后的信息。
首先在场景中创建一个地面,然后制作一个Prefab里面包含一个Cube。然后在场景中添加一盏灯光,把脚本放在摄像机上面。
场景制作完成,我们想完成的功能是当我们用鼠标点击地面,在我们点击地面的位置生成Prefab的实例,就像种豆子一样。
public Transform explosion;
void Update ()
{
//获取鼠标点击事件
if(Input.GetMouseButtonDown(0))
{
//定义一条射线
Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
//如果射线发生碰撞
if(Physics.Raycast (ray, out hit, 100))
{
Transform theClonedExplosion; //实例化物体
//hit.point为碰撞点的坐标
theClonedExplosion =Instantiate(explosion, hit.point, transform.rotation)as Transform;
}
}
}
更多精彩关注:http://www.gopedu.com/