博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实现一个简单的Unity3D三皮卡——3D Picking (1)
阅读量:5129 次
发布时间:2019-06-13

本文共 3729 字,大约阅读时间需要 12 分钟。

3D Picking 其原理是从摄像机位置到空间发射的射线。基于光线碰到物体回暖。

 

这里我们使用了触摸屏拿起触摸,鼠标选择相同的原理,仅仅是可选API不同。

unity3D官网Manual里找到下面Input内容:

当中有段样例程序:

Following is an example script which will shoot a ray whenever the user taps on the screen:

var particle : GameObject;function Update () {    for (var touch : Touch in Input.touches) {        if (touch.phase == TouchPhase.Began) {            // Construct a ray from the current touch coordinates            var ray = Camera.main.ScreenPointToRay (touch.position);            if (Physics.Raycast (ray)) {                // Create a particle if hit                Instantiate (particle, transform.position, transform.rotation);            }        }  }}

var ray = Camera.main.ScreenPointToRay (touch.position);            if (Physics.Raycast (ray))
这两句代码是关键代码,我们从这里入手。

查找ScreenPointToRay文档:

节选文档中主要描写叙述和一段样例

ScreenPointToRay(position);

Returns a ray going from camera through a screen point.

using UnityEngine;using System.Collections;public class Example : MonoBehaviour {    void Update() {        Ray ray = camera.ScreenPointToRay(new Vector3(200, 200, 0));        Debug.DrawRay(ray.origin, ray.direction * 10, Color.yellow);    }}

上面的Debug.DrawRay留着后面调试时使用,能够看到发射的射线。

 

接下来Camera.main.ScreenPointToRay中的Camera.main是什么意思呢,查找Camera.main

static  main; 

The first enabled camera tagged "MainCamera" (Read Only).

 

unity新建一个project后,默认的一个main Camera

查找.Raycast文档。

文档内容非常多。当中有一个

static bool Raycast(origin, direction, hitInfo, float distance = Mathf.Infinity, int layerMask = DefaultRaycastLayers);

红色的两个參数我们后面将会用到,在查看hitInfo,

http://docs.unity3d.com/Documentation/ScriptReference/RaycastHit.html

 

至此。我们能够实现一个简单的Picking了,创建sphere, plane, Direction Light,和一个Empty GameObject取名GameController。并新建一个脚本与其绑定。

打开GameController.cs。输入下面代码:

using UnityEngine;using System.Collections;public class GameController : MonoBehaviour{	void Update () 	{		if(Input.touchCount == 1)		{			Ray ray = Camera.main.ScreenPointToRay (Input.GetTouch(0).position);			Debug.DrawRay (ray.origin, ray.direction * 10, Color.yellow);  // ray needs a origin, and a dir			if(Physics.Raycast(ray, 10))				Debug.Log("Hit something");		}	}}

在移动设备上使用Unity remote,用手触摸屏幕,将会看到一道黄线,若触摸到小球Sphere或地面Plane后。可看到在Console中有Hit something信息,即射线击中了物体。

以下我们想分别选中物体。即仅仅picking小球而忽略地面plane。查看Layer文档:

当中讲的非常仔细。关键就是要新建Tags和设定layerMask

 

打开Edit,选择Project Settings->Tags and Layers

Layer 8输入PlayerLayer 9输入Background

将Sphere 和 PlaneLayer 设为对应的层

改动GameController.cs

using UnityEngine;using System.Collections;public class GameController : MonoBehaviour{	void Update () 	{		if(Input.touchCount == 1)		{			Ray ray = Camera.main.ScreenPointToRay (Input.GetTouch(0).position);						int playersLayerMask = 1 << 8;						RaycastHit hit;			if(Physics.Raycast(ray, out hit, Mathf.Infinity, playersLayerMask))			{				Debug.DrawLine(ray.origin, hit.point, Color.yellow);			// line needs two points			}		}	}}

此时,仅仅有当我们触摸到Sphere时才绘制黄色射线提示,因为设置了LayerMask射线将忽略Plane

以下我们尝试当射线击中Spheres时绘制黄色提示线,先击中Sphere后击中Plane时绘制红色提示线。

改动GameController.cs

using UnityEngine;using System.Collections;public class GameController : MonoBehaviour{	void Update () 	{		if(Input.touchCount == 1)		{			Ray ray = Camera.main.ScreenPointToRay (Input.GetTouch(0).position);						int playersLayerMask = 1 << 8;			int backgroundLayerMask = 1 << 9;						RaycastHit hit;			if(Physics.Raycast(ray, out hit, Mathf.Infinity, playersLayerMask))			{				Debug.DrawLine(ray.origin, hit.point, Color.yellow);			// line needs two points								RaycastHit groundHit;				if(Physics.Raycast(ray, out groundHit, Mathf.Infinity, backgroundLayerMask))				{					Debug.DrawLine(ray.origin, groundHit.point, Color.red);									}			}		}	}}

点击Play,效果例如以下,

版权声明:本文博客原创文章,博客,未经同意,不得转载。

转载于:https://www.cnblogs.com/mengfanrong/p/4717337.html

你可能感兴趣的文章
springboot No Identifier specified for entity的解决办法
查看>>
浅谈 unix, linux, ios, android 区别和联系
查看>>
51nod 1428 活动安排问题 (贪心+优先队列)
查看>>
Solaris11修改主机名
查看>>
latex for wordpress(一)
查看>>
如何在maven工程中加载oracle驱动
查看>>
Flask 系列之 SQLAlchemy
查看>>
aboutMe
查看>>
【Debug】IAR在线调试时报错,Warning: Stack pointer is setup to incorrect alignmentStack,芯片使用STM32F103ZET6...
查看>>
一句话说清分布式锁,进程锁,线程锁
查看>>
FastDFS使用
查看>>
服务器解析请求的基本原理
查看>>
[HDU3683 Gomoku]
查看>>
下一代操作系统与软件
查看>>
[NOIP2013提高组] CODEVS 3287 火车运输(MST+LCA)
查看>>
Python IO模型
查看>>
DataGridView的行的字体颜色变化
查看>>
局域网内手机访问电脑网站注意几点
查看>>
[Serializable]的应用--注册码的生成,加密和验证
查看>>
Android-多线程AsyncTask
查看>>