unity3D 從攝像機(jī)發(fā)射射線,檢測畫線

最近做項目的時候,有一個需要從攝像機(jī)發(fā)出一條射線,當(dāng)射線檢測到有碰撞物體的時候,點(diǎn)擊鼠標(biāo)左鍵開始畫線。我是創(chuàng)立了一個平板drawing,當(dāng)然Cube什么的也是可以的。
c#腳本代碼,將這個腳本拖到攝像機(jī)里,然后拖拽材質(zhì)到畫線材質(zhì),拖拽碰撞體到腳本那里即可以。
代碼腳本(附有注釋):
<pre><code>
using UnityEngine;
using System.Collections;

public class test : MonoBehaviour {

//-----------劃線所能夠用到材質(zhì)  
 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;  
//記錄當(dāng)下畫板的位置,判斷平板是否平移等  
  public Vector3 boardPosition;  
  public GameObject board;  
//記錄當(dāng)下畫板的大小,判斷畫板是否縮放等     
 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;  
    //當(dāng)畫板移動時,將所有的點(diǎn)按照統(tǒng)一方向移動相同的距離
   //當(dāng)前畫板的位置  
   Vector3 currentBoardPositon=Camera.mainCamera.WorldToScreenPoint(board.transform.position);  
      
    //畫板的移動距離  
    Vector3  moveDistance=currentBoardPositon-boardPosition;  
      
    if(moveDistance.x!=0||moveDistance.y!=0)  
    {  
        //將所有的畫下的點(diǎn)都平移  
        for(int i=0;i<linePoints.Length;i++)  
        {  
        Vector2 dis=new Vector2(moveDistance.x,moveDistance.y);  
        linePoints[i]+=dis;  
        }  
        //銷毀當(dāng)前畫下的線  
        Vector.DestroyLine(ref line);  
          
        //距離平移后,所有的點(diǎn)的位置已經(jīng)重新獲得,重新畫下新的線  
          
         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);  
    //平板的縮放操作,對平板進(jìn)行縮放,同時畫出的線也要能夠?qū)崿F(xiàn)縮放。  
    //檢測平板是否已經(jīng)開始縮放  
    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);  
          
          //當(dāng)平板縮放時,所有的點(diǎn)都要同比例縮放。  
        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);  
        }         
        //銷毀當(dāng)前畫下的線  
        Vector.DestroyLine(ref line);  
        //畫板縮放后,所有的點(diǎn)的位置已經(jīng)重新獲得,重新畫下新的線  
         line = new VectorLine("DrawnLine", linePoints, lineMaterial, lineWidth, LineType.Continuous);  
         line.minDrawIndex = 1;  
         line.maxDrawIndex = lineIndex;  
        Vector.DrawLine(line);    
    }  
    //從攝像頭發(fā)出一條射線  
    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);  
        }                 
    }     
}  

</code></pre>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在我們的游戲開發(fā)過程中,有一個很重要的工作就是進(jìn)行碰撞檢測。例如在射擊游戲中子彈是否擊中敵人,在RPG游戲中是否撿...
    壹米玖坤閱讀 24,822評論 0 17
  • Unity3D塔防開發(fā)流程 配置環(huán)境及場景搭建 編程語言:C#,略懂些許設(shè)計模式,如果不了解設(shè)計模式,BUG Mo...
    Grape_葡萄閱讀 3,106評論 1 3
  • 本文來源于兩年前我的一篇CSDN博客。CSDN博客本來就沒寫多少,現(xiàn)在也基本是到簡書上混了。所以各位大大請自覺繞過...
    曉夢蟬君閱讀 42,924評論 5 12
  • 0x00 前言 剛開始寫這篇文章的時候選了一個很土的題目。。?!禪nity3D優(yōu)化全解析》。因?yàn)檫@是一篇臨時起意才...
    楊夏MX閱讀 2,391評論 2 11
  • 無論是碰撞檢測還是觸發(fā)檢測,他們都基于Collider組件。兩個游戲?qū)ο蟀l(fā)生碰撞時,碰撞器可以產(chǎn)生系統(tǒng)默認(rèn)的碰撞產(chǎn)...
    S_H_C閱讀 3,135評論 0 3

友情鏈接更多精彩內(nèi)容