unity3D 从摄像机发射射线,检测画线

原创 2013年12月03日 10:20:16

                最近做项目的时候,有一个需要从摄像机发出一条射线,当射线检测到有碰撞物体的时候,点击鼠标左键开始画线。我是创立了一个平板drawing,当然Cube什么的也是可以的。

                c#脚本代码,将这个脚本拖到摄像机里,然后拖拽材质到画线材质,拖拽碰撞体到脚本那里即可以。

                代码脚本:

using UnityEngine;
using System.Collections;

public class test : MonoBehaviour {

    //-----------划线所能够用到材质
     public Material lineMaterial  ;
	//
      int maxPoints = 5000;
      //全局变量的定义方法
     public static float lineWidth = 4.0f;
	 int minPixelMove = 2;	// Must move at least this many pixels per sample for a new segment to be recorded
     public Vector2[] linePoints;
     private VectorLine  line ;
     private int  lineIndex = 0;
      private   Vector2   previousPosition;
      private int  sqrMinPixelMove ;
      private bool canDraw = false;
    //记录当下画板的位置,判断平板是否平移等
      public Vector3 boardPosition;
      public GameObject board;
	//记录当下画板的大小,判断画板是否缩放等	
	 public Vector3 boardScale;	
	//初始化平板的大小与位置
	void IntializeScaleAndPosition()
	{
		boardPosition=Camera.mainCamera.WorldToScreenPoint(board.transform.position);
	    boardScale=board.transform.localScale;
		
	}
	// 初始化
	void Start () {
        linePoints = new Vector2[maxPoints];
        line = new VectorLine("DrawnLine", linePoints,lineMaterial, lineWidth, LineType.Continuous);
        sqrMinPixelMove = minPixelMove * minPixelMove;
		IntializeScaleAndPosition();
	}
	// Update is called once per frame
	void Update () {
        Vector2 mousePos = Input.mousePosition;
		//当画板移动时,将所有的点按照统一方向移动相同的距离
		//当前画板的位置
	   Vector3 currentBoardPositon=Camera.mainCamera.WorldToScreenPoint(board.transform.position);
		
		//画板的移动距离
		Vector3  moveDistance=currentBoardPositon-boardPosition;
		
	    if(moveDistance.x!=0||moveDistance.y!=0)
		{
			//将所有的画下的点都平移
			for(int i=0;i<linePoints.Length;i++)
			{
			Vector2 dis=new Vector2(moveDistance.x,moveDistance.y);
			linePoints[i]+=dis;
			}
			//销毁当前画下的线
		    Vector.DestroyLine(ref line);
			
			//距离平移后,所有的点的位置已经重新获得,重新画下新的线
			
			 line = new VectorLine("DrawnLine", linePoints, lineMaterial, lineWidth, LineType.Continuous);
			 line.minDrawIndex = 1;
	         line.maxDrawIndex = lineIndex;
		    Vector.DrawLine(line);
			
		}	
		boardPosition=Camera.mainCamera.WorldToScreenPoint(board.transform.position);
        //平板的缩放操作,对平板进行缩放,同时画出的线也要能够实现缩放。
		//检测平板是否已经开始缩放
		float currentScale=board.transform.localScale.x;
		float scaleFactor=currentScale/(boardScale.x);
		//Debug.Log("scaleFactor "+scaleFactor+" currentScale "+currentScale+" boardScale "+boardScale.x);
		boardScale=board.transform.localScale;
	    if(scaleFactor!=1||scaleFactor!=1)
		{	
			// 求出画板中心的位置
		    Vector3 boardPostionToSceern=Camera.mainCamera.WorldToScreenPoint(board.transform.position);
			
			  //当平板缩放时,所有的点都要同比例缩放。
			for(int i=0;i<linePoints.Length;i++)
			{
			Vector3 pointPositon=new Vector3(linePoints[i].x,linePoints[i].y,0);
			Vector3 PointToCenterDistance=(pointPositon-boardPostionToSceern)*scaleFactor;
			linePoints[i]=new Vector2((boardPostionToSceern+PointToCenterDistance).x,(boardPostionToSceern+PointToCenterDistance).y);
			}		
			//销毁当前画下的线
		    Vector.DestroyLine(ref line);
			//画板缩放后,所有的点的位置已经重新获得,重新画下新的线
			 line = new VectorLine("DrawnLine", linePoints, lineMaterial, lineWidth, LineType.Continuous);
			 line.minDrawIndex = 1;
	         line.maxDrawIndex = lineIndex;
		    Vector.DrawLine(line);	
		}
		//从摄像头发出一条射线
		Ray ray=Camera.mainCamera.ScreenPointToRay(Input.mousePosition);
	    RaycastHit hit;
		if(Physics.Raycast(ray,out hit,1000))
		{	
		//检测到物体时才开始画
		if(hit.transform.gameObject.name=="drawing")
		{		
		    if (Input.GetMouseButtonDown(0))
	        {
	          //  Vector.ZeroPointsInLine(line);
	           // line.minDrawIndex = lineIndex;
	          //  Vector.DrawLine(line);
	           // linePoints[lineIndex] = mousePos;
	            previousPosition  = mousePos;
	            lineIndex++;
	            linePoints[lineIndex] = mousePos;
	            canDraw = true;
	        }
	        else if (Input.GetMouseButton(0) && (mousePos - previousPosition).sqrMagnitude > sqrMinPixelMove && canDraw)
	        {
	            previousPosition = linePoints[++lineIndex] = mousePos;
	            line.minDrawIndex = lineIndex - 1;
	            line.maxDrawIndex = lineIndex;
	            if (lineIndex >= maxPoints - 1) canDraw = false;
	            Vector.DrawLine(line);
	        }				
		}	
	}

                 
版权声明:本文为博主原创文章,未经博主允许不得转载。

Unity3d 发射射线Ray

Ray Camera.main.ScreenPointToRay(Vector3 pos)   返回一条射线Ray从摄像机到屏幕指定一个点 Ray Camera.main.ViewportPoi...

Physics.Raycast和Ray(射线)的理解

在游戏中,我们常常要用到鼠标来控制物体的移动或是鼠标拾取某个物体。还有射击游戏里,子弹打中靶子......这些都需要Physics.Raycast和ray。可见他们的重要性。 首先说说射线; 射线...
  • ElyXiao
  • ElyXiao
  • 2016年03月12日 16:25
  • 7249

Unity实现画线条功能

废话不多说,今天实现一个用LineRender组件实现画图的功能。网上已有相关博文,感觉步骤有些模糊,今天就整理出来供大家学习 第一步:创建一个空对象,为其添加LineRender组件。 ...

Unity图片变灰的方式

http://www.tuicool.com/articles/Vruuqme
  • sgnyyy
  • sgnyyy
  • 2014年05月13日 15:20
  • 10180

billboard公告板技术与perlin噪声的实现

一、billboard公告板技术1.简介在游戏中经常会遇到使用一张2D贴图来代替3D物体的情况,比如我们可以绘制一个2D的太阳贴图来代替3D的太阳模型,再比如使用2D的灌木、花草贴图来代替其复杂的3D...

Unity3D【脚本】点击物体后屏幕放大 - (射线、坐标的转换、摄像机的移动和改变属性)

using UnityEngine; using System.Collections; public class DParaticle : MonoBehaviour { //摄像机 pu...

[Unity3D]射线碰撞检测+LayerMask的使用

射线:射线是3D世界中一个点向一个方向发射的一条无终点的线,在发射轨迹中与其他物体发生碰撞时,它将停止发射 。用途:在unity中射线应用范围比较广, 多用于碰撞检测(如:子弹飞行是否击中目标)、角色...

Unity3D,(2)射线检测与EventSystem判断UI点击

按照传统的做法,EventSystem用做UI的事件处理,射线检测用做非UI碰撞的判断,但需要手动添加Collider。EventSystem使用了,GraphicRaycaster组件来检测UI元素...

[Unity3D]射线碰撞检测+LayerMask的使用

[Unity3D]射线碰撞检测+LayerMask的使用 转射线:射线是3D世界中一个点向一个方向发射的一条无终点的线,在发射轨迹中与其他物体发生碰撞时,它将停止发射 。 用途:在unity中射线应...

Unity3D的射线检测Physics.Raycast

Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo); Camera.main.ScreenPointToRay()
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:unity3D 从摄像机发射射线,检测画线
举报原因:
原因补充:

(最多只允许输入30个字)