2015年11月3日 星期二

Unity 紅外線瞄準器

程式碼內附著三種標記方式
大家有興趣可以試試看

使用時,須建立一個空的GameObject,並將此Script拖曳至空的GameObject。
以及把需要當作貼片(模擬成紅外線光圈)的圓形薄片物體拖曳給此Script的Pointer。
貼片請自行設計,可用圓柱物體並將厚度設為0.01即可。



using UnityEngine;
using System.Collections;
using UnityEditor;

public class LaserProject : MonoBehaviour {

    public GameObject pointer;
    private Light spotlight;
    private LineRenderer lineRenderer;

    public enum ProjectTypes {SpotLightTangent, SpotLightNormal, PatchObject};
    public ProjectTypes projectTypes;

    //是否顯示光線
    public bool showLight = true;
    //光源移動離目標距離
    private float minDistance = 1f;
    //定義一個Vector3,用來儲存物件原點位置
    private Vector3 originalPosition;
    //從螢幕射出的光線
    private Ray rayFromCam;
    //沿著螢幕射線慢慢移動的光線
    private Ray ray;

    //a RaycastHit variable, to gather informartion about the ray's collision  
    private RaycastHit hitFromCam, hit;
    
    //用來索引端點
    private int index = 0;


    // Use this for initialization
    void Awake () {

        if (projectTypes != ProjectTypes.PatchObject)
        {
            //取得燈光物件
            spotlight = gameObject.GetComponent();
            spotlight.enabled = false;
            //貼圖設為看不見
            pointer.active = false;

        }

        //紀錄原點位置
        originalPosition = transform.position;

        if (showLight) //顯示光線
        { 
            //添加LineRenderer組件
            lineRenderer = gameObject.AddComponent();
            //設置材質
            lineRenderer.material = new Material(Shader.Find("Particles/Additive"));
            //設置顏色
            lineRenderer.SetColors(Color.white, Color.white);
            //設置寬度
            lineRenderer.SetWidth(0.01f, 0.05f);
            //設置起點與終點,若不設置終點會自動產生線段
            lineRenderer.SetPosition(0, originalPosition);
            lineRenderer.SetPosition(1, originalPosition);
        }

    }
 
 // Update is called once per frame
 void Update () {

        if (Input.GetMouseButton(0)) //點擊左鍵
        {
            if (projectTypes != ProjectTypes.PatchObject)
                spotlight.enabled = false;  //關閉光源


            //從攝像機發出到點擊坐標的射線
            rayFromCam = Camera.main.ScreenPointToRay(Input.mousePosition);
            
            // 如果有射到物體
            if (Physics.Raycast(rayFromCam, out hitFromCam))  
            {
                //取得投影點與對應物體名稱
                //Debug.Log("" + hitFromCam.point.x + ", " + hitFromCam.point.y + ", " + hitFromCam.point.z);
                //GameObject gameObj = hitFromCam.collider.gameObject;
                //Debug.Log("click object name is " + gameObj.name);
                
                Vector3 direction = hitFromCam.point - originalPosition;
                ray = new Ray(originalPosition, direction);
                
                //發射一條100個單位長的射線
                if (Physics.Raycast(ray.origin, ray.direction, out hit, 100))
                {

                    if (showLight)
                    {
                        //獲取LineRenderer組件
                        lineRenderer = GetComponent();
                        lineRenderer.SetPosition(index + 1, hit.point);
                    }

                    //計算距離
                    float distance = Vector3.Distance(originalPosition, hit.point);
                    //Debug.Log("normal  " + hit.normal);

                    switch (projectTypes)
                    {
                        //1. 光源移動到沿射線距離物件minDistance上
                        case ProjectTypes.SpotLightTangent:
                            if (distance > minDistance)
                            {
                                transform.LookAt(hit.point);
                                spotlight.spotAngle = 60;
                                spotlight.range = minDistance * 2;
                                spotlight.transform.position =
                                    Vector3.MoveTowards(originalPosition, hit.point, distance - minDistance);
                                spotlight.enabled = true;
                            }
                            else
                                spotlight.enabled = false;
                            break;

                        //2. 光源移動至法向量上
                        case ProjectTypes.SpotLightNormal:
                            if (distance > minDistance)
                            {
                                transform.LookAt(hit.point);
                                spotlight.spotAngle = 70;
                                spotlight.range = minDistance * 3;
                                spotlight.transform.position = hit.point + hit.normal * minDistance;
                                spotlight.enabled = true;
                            }
                            else
                                spotlight.enabled = false;
                            break;

                        //3.使用半透明物件作為標示物
                        case ProjectTypes.PatchObject:
                            pointer.transform.position = hit.point;
                            pointer.transform.rotation =
                                Quaternion.FromToRotation(pointer.transform.up, hit.normal) * pointer.transform.rotation;
                            break;

                        default:
                            break;

                    }
                    
                }
            }
           
        }

    }
    
}

沒有留言:

張貼留言