प्रौद्योगिकी साझेदारी

एकता--किरण अन्वेषण--RayCast

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

एकता–किरण अन्वेषण–RayCast

1.रेडियोग्राफिक परीक्षणस्य अर्थः

किरणपरिचयः नामनुसारं किरणस्य उपयोगेन ज्ञायते यत् सः कस्मिंश्चित् वस्तु/बहुवस्तूनाम् उपरि आघातं करोति वा इति ज्ञातुं शक्नोति

रेडियोग्राफिकपरीक्षणस्य द्वौ भागौ भवतः : १. किरणाःतथाअन्वेषणम्

2. रेडियोग्राफिकपरीक्षणस्य उपयोगः कुत्र कर्तुं शक्यते ?

  1. शूटिंग् क्रीडा
    • खिलाडी लक्ष्यीकरणं शूटिंग् च : खिलाडयः दृष्टिरेखा शत्रुणा अन्येन वा लक्ष्येण सह च्छेदनं करोति वा इति ज्ञायते ।
    • गोलीप्रक्षेपवक्रता तथा प्रभावाः : गोलिकानां उड्डयनमार्गस्य प्रहारप्रभावस्य च अनुकरणं कुर्वन्तु।
  2. अन्तरक्रिया तथा UI
    • माउस् क्लिक् डिटेक्शन् : खिलाड्यस्य माउस् क्लिक् गेम ऑब्जेक्ट् अथवा UI एलिमेण्ट् इत्यनेन सह प्रतिच्छेदं करोति वा इति अन्वेष्टुम् ।
    • टचस्क्रीन्-अन्तर्क्रिया : खिलाडयः स्पर्शः मोबाईल-यन्त्रे विशिष्टं क्रीडा-तत्त्वं प्रतिच्छेदयति वा इति अन्वेष्टुम् ।
  3. वर्णनियन्त्रकाः एआइ च
    • दृष्टिपरिचयः : एनपीसी अथवा शत्रवः एकस्य निश्चितपरिधिमध्ये खिलाडयः अन्यपात्राणि वा ज्ञायन्ते ।
    • टकरावपरिहारः : एआइ-पात्राणि गमनसमये टकरावस्य परिहाराय किरण-परिचयस्य उपयोगं कुर्वन्ति ।
  4. आभासीयवास्तविकता (VR) तथा संवर्धितवास्तविकता (AR)
    • नेत्रं वा हस्तं वा अनुसरणं : VR मध्ये खिलाड्यस्य दृष्टिः अथवा हस्तस्य स्थितिं ज्ञापयन्तु।
    • वस्तुपरस्परक्रिया : एआर मध्ये आभासीवस्तुभिः सह खिलाडी प्रतिच्छेदनं करोति वा इति अन्वेषणम् ।

3.एकतायां किरणः

दैनन्दिनजीवने बहुषु स्थानेषु किरणाः दृश्यन्ते, यथाटॉर्च,ppt लेजर पृष्ठ घुमाव कलम, किङ्ग्यु वर्षाणां मध्येसाइक्लोप्स

किरणे आरम्भबिन्दुः, दिशा, दूरं च भवति यथा- १. origin , direction तथाdistance

भौतिकशास्त्रे किरणस्य दूरं अनन्तं भवति, अतः भौतिककिरणस्य केवलम् एकः आरम्भबिन्दुः एकदिशा च भवति क्रीडायां किरणस्य अधिकतमं दूरं अपि तन्त्रेण सीमितं भवति 1000.0 मीटर् निम्नलिखितम् अस्ति A description of Ray.

एकतायां रे एकः संरचना अस्तिorigin, direction तथाGetPoint.अर्थात् किरणस्य सह निश्चितदूरे स्थितस्य बिन्दुस्य आरम्भबिन्दुः, दिशा च स्थितिः च एकतायां किरणस्य कोडः अस्ति

using System;

namespace UnityEngine
{
    public struct Ray : IFormattable
    {        
        public Ray(Vector3 origin, Vector3 direction);
        public Vector3 origin { get; set; } // 起点(向量)
        public Vector3 direction { get; set; }// 方向(向量)
        public Vector3 GetPoint(float distance);// 沿着射线一定距离的点(向量)
        public override string ToString();
        public string ToString(string format);
        public string ToString(string format, IFormatProvider formatProvider);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

३.१ किरणानाम् निर्माणम्

उपर्युक्तसङ्केतस्य अनुसारं द्रष्टुं शक्यते यत् Ray constructor इत्यस्य उपयोगेन प्रत्यक्षतया किरणस्य निर्माणं कर्तुं शक्यते, यथा-

Ray ray = new Ray(Vector3.zero, Vector3.forward); // 射线的起点 + 射线的方向
  • 1

उपर्युक्तसङ्केतस्य अनुसारं वयं द्रष्टुं शक्नुमः यत् किरणस्य आरम्भबिन्दुः एकतायां (0,0,0) विश्वनिर्देशाङ्कानां उत्पत्तिः भवति, किरणस्य दिशा च विश्वनिर्देशाङ्कानां अग्रे दिशा भवति

३.२ किरणाः कथं प्रदर्शयितव्याः

यथार्थतः अस्माकं लेजर-सूचकः टॉर्चः च द्रष्टुं शक्यते, परन्तु Unity इत्यस्मिन् किरणाः अदृश्याः सन्ति अतः यदि वयं किरणाः प्रदर्शयितुम् इच्छामः तर्हि वयं यत् पद्धतयः उपयोक्तुं शक्नुमः तत् अस्ति ।

  • उपयुञ्जताम्‌Debug.DrawRay()प्रदर्शन किरण
  • उपयुञ्जताम्‌LineRendererघटकः किरणं आकर्षयति

4.एकतायां किरणपरिचयः

केवलं किरणानाम् निर्माणं प्रदर्शनं वा करणं वा हस्ते साधनं धारयित्वा साधनं विना कार्यं कर्तुं तुल्यम् ।

वस्तुनिरीक्षणार्थं किरणानाम् उपयोगः कथं भवति।

सम्यक् चिन्तयन्तु : अस्माकं दैनन्दिनजीवने अस्माकं लेजर-सूचकाः वा टॉर्च-प्रकाशाः भित्तिस्थाने प्रकाश-बिन्दवः प्रदर्शयितुं शक्नुवन्ति वा लेजर-प्रकाशं उत्सर्जयित्वा कस्मिंश्चित् स्थानं प्रकाशयितुं वा शक्नुवन्ति एतेन ज्ञायते यत् भित्तिः सह अन्तरक्रियां कर्तुं शक्यते, अन्येषु शब्देषु, किरणेन सह टकरावः भवति the object/ वस्तु ज्ञाता अस्ति वा इति निर्धारयितुं Unity मध्ये निम्नलिखित API उपयुज्यताम् ।

४.१रेकैट् कार्यम्

// 基础版API
public static bool Raycast(Ray ray);

public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance, int layerMask);
public static bool Raycast(Ray ray, out RaycastHit hitInfo);
public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance);
                           
// 常用版API
public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance, int layerMask);
                           
public static bool Raycast(Ray ray, float maxDistance);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

किरणपरिचयस्य उपयोगाय भवद्भिः...Physicsपुस्तकालयः, यस्मिन् भौतिकशास्त्रेण सम्बद्धाः स्थिरकार्यं भवति

उपर्युक्तानि अतिभारितानि कार्याणि दृष्ट्वा वयं प्रायः न जानीमः यत् कस्य उपयोगः कर्तव्यः वस्तुतः येषां कृते बहुविधाः पैरामीटर् सन्ति तेषां कृते वयं वास्तवतः आवश्यकतानुसारं भिन्नानि अतिभारितानि पैरामीटर्स् उपयुञ्ज्महे ।

प्रथमं एपिआइ इत्यस्य मूलभूतं संस्करणं पश्यन्तु public static bool Raycast(Ray ray); return value इत्यस्य अनुसारं वयं यत् ज्ञातुं शक्नुमः तत् अस्ति यत् किरणः कस्मिंश्चित् वस्तुनः आघातं करोति वा यदि न मारयति तर्हि सः false इति प्रत्यागच्छति ।

4.2HitInfo संरचना

अन्यस्मिन् एपिआइ-मध्ये किरण-परिचयःpublic static bool Raycast(Ray ray, out RaycastHit hitInfo);अत्र एकः अपि पैरामीटर् अस्तिhitInfo

hitInfo पैरामीटर् किरणेन आहतस्य वस्तुनः सूचनासंरचना अस्ति संरचना तुल्यकालिकरूपेण विशाला अस्ति, यस्य अर्थः अस्ति यत् अस्मिन् अधिकानि सूचनानि सन्ति यथा Unreal Engine इत्यस्मिन् किरणपरिचयेन आहतस्य वस्तुनः परिणामः ।FHitResult) समानाः सन्ति

  • वस्तुसूचना, सर्वाणि सूचनानि परिवर्तनद्वारा प्राप्तुं शक्यन्ते
  • हिट बिन्दु सूचना

वस्तुनः सूचनां प्राप्तुं सुलभं भवति: यथा वस्तुनः नाम, वस्तुनः transfrom घटकः, वस्तुनः Tag...

हिट्-बिन्दुस्य सूचनां प्राप्नुवन्तु, अर्थात् यत्र किरणः वस्तुं प्रहरति तस्य बिन्दुस्य (hit point) सूचनां प्राप्नुवन्तु: यथा बिन्दुस्य निर्देशांकाः,सामान्य(सामान्य), सामान्य विमान, के बिन्दुशिखरवर्णः

निम्नलिखितम् अस्तिRaycastHitसंरचनासूचना, सामान्यतया प्रयुक्तेषु टिप्पण्यानि योजिताः सन्ति, यथाlightmapCoordते प्रकाशमानचित्रनिर्देशाङ्काः सन्ति, येषां उपयोगः प्रतिपादनार्थं भवति ।

namespace UnityEngine
{
    public struct RaycastHit
    {
        public Collider collider { get; }						// 碰撞器
        public int colliderInstanceID { get; }
        public Vector3 point { get; set; }						// 击中的点(命中点)
        public Vector3 normal { get; set; }						// 命中点的法线
        public Vector3 barycentricCoordinate { get; set; }		 // 重心坐标
        public float distance { get; set; }						// 命中点距离射线起点的距离
        public int triangleIndex { get; }
        public Vector2 textureCoord { get; }
        public Vector2 textureCoord2 { get; }
        public Transform transform { get; }						// Transform组件
        public Rigidbody rigidbody { get; }						// 刚体组件
        public ArticulationBody articulationBody { get; }
        public Vector2 lightmapCoord { get; }
        public Vector2 textureCoord1 { get; }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

इत्यर्थःHitInfoवयं यत् वस्तु मारयामः तस्य विषये सूचनां रक्षति, वयं एतां सूचनां अधिकानि कार्याणि कर्तुं उपयोक्तुं शक्नुमः

४.३ स्तरमास्कः

एकतायां, २.layerMask भौतिक-सङ्घर्षं, किरण-कास्टिंग्, किरण-परिचयम् इत्यादीनां कार्याणां नियन्त्रणार्थं प्रयुक्तं वस्तु-स्तर-चयन-तन्त्रम् अस्ति ।सेट् कृत्वाlayerMask, एतेषु कार्येषु के स्तराः समाविष्टाः वा बहिष्कृताः वा इति निर्दिष्टुं शक्नुवन्ति ।

सामान्यतया उपयुज्यमानं किरणपरिचय एपिआइ प्रति पुनः गच्छन्तु public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance, int layerMask);मध्यं।

उपरिष्टाद् API मध्ये maxDistance इति किरणस्य दूरी इति वक्तुं नावश्यकता वर्ततेMathf.Infinityअस्मिन् एपिआइ मध्ये एकः पैरामीटर् layerMask अपि अस्ति, यत् लेयर मास्क अस्ति ।

Unity इत्यस्मिन् game objects इत्यस्य भेदं कर्तुं वयं tags योजयित्वा अर्थात् Tags इत्यस्य भेदं कर्तुं शक्नुमः तथापि Tags इत्येतत् अधिकं कष्टप्रदं भवति, तथा च हस्तेन टङ्कणकाले त्रुटिः कर्तुं सुलभम् अस्ति । तत्सह, यतः इदं स्ट्रिंग् अस्ति , Unity इत्यस्य तलभागे गणनायां वेगः किञ्चित् मन्दः भवति ।

Unity इत्यस्मिन् layerMask इत्यस्मिन् ३२ स्तराः सन्ति, येषु केचन पूर्वमेव प्रणाल्याः उपयुज्यन्ते, यथाPlayerस्तर, UIस्तराः अद्यापि बहवः स्तराः सन्ति येषां उपयोगः प्रणाल्याः न भवति ततः वयं स्तराः योजयितुं शक्नुमः ततः क्रीडायाः वस्तुषु बालश्रमस्तरं योजयित्वा वर्गीकरणं कर्तुं शक्नुमः ।

कथं लेयर योजयितव्यम्?भवता कस्यापि वस्तुनः Inspector panel इत्यत्र Layer नुदन्तु, ततः क्लिक् कुर्वन्तुAddLayer इतितत् एव, ततः परिवर्तनीयानां वस्तूनाम् कृते स्तरं हस्तचलितरूपेण निर्दिशन्तु ।

एकता_रेकास्ट_जोडस्तर

Layer इत्येतत् मैन्युअल् रूपेण योजयित्वा कथं तस्य उपयोगः करणीयः ।

अस्तिpublic static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance, int layerMask);मध्यंlayereMaskवयं ज्ञातवन्तः यत् एतेन कintपूर्णाङ्कस्य प्रकारः तथापि वयं प्रत्यक्षतया संख्याः पूरयितुं न शक्नुमः, पूरणनियमाः shift operations इत्यस्य उपयोगं कुर्वन्ति,

layerMask कथं पूरयितव्यम्:

  1. Layer Mask मूल्यं प्राप्नुत

    • प्रत्येकं स्तरस्य तत्सम्बद्धं पूर्णाङ्कमूल्यं भवति, 0 तः आरभ्य । यथा, पूर्वनिर्धारितस्तरस्य (Default) मूल्यं 0 भवति, UI स्तरस्य च प्रायः 5 भवति ।
    • विशिष्टस्तरस्य कृते layerMask निर्मातुं भवान् उपयोक्तुं शक्नोति 1 << LayerMask.NameToLayer("LayerName") . एतेन अस्य स्तरस्य कृते layerMask इत्यस्य प्रतिनिधित्वं कृत्वा पूर्णाङ्कमूल्यं प्रत्यागच्छति ।
  2. बहुस्तरं संयोजयन्तु

    • यदि भवान् बहुस्तरं संयोजयितुम् इच्छति तर्हि bitwise OR operator इत्यस्य उपयोगं कर्तुं शक्नोति | . उदाहरणतया,layerMask = LayerMask.GetMask("Layer1", "Layer2") एकं layerMask निर्मितं भविष्यति, यत्र "Layer1" "Layer2" च सन्ति ।
  3. स्तरं बहिष्कृत्य

    • लेयरं बहिष्कृत्य प्रथमं सर्वाणि लेयर्स् युक्तं मास्कं निर्मातुं शक्नुवन्ति ततः bitwise XOR ऑपरेटर् इत्यस्य उपयोगं कर्तुं शक्नुवन्ति ^ विशिष्टस्तरं बहिष्कृत्य । उदाहरणतया,layerMask = ~LayerMask.GetMask("ExcludeLayer")
  4. लेयरं पश्यन्तु

    • निर्दिष्टे layerMask मध्ये कश्चन वस्तु अस्ति वा इति परीक्षितुं भवान् उपयोक्तुं शक्नोति layerMask.value & (1 << gameObject.layer) . यदि परिणामः 0 नास्ति तर्हि वस्तु layerMask मध्ये अस्ति इति अर्थः ।
    // 示例代码
    // 创建一个包含Layer1和Layer2的layerMask
    int layerMask = LayerMask.GetMask("Layer1", "Layer2");
    
    // 排除Layer3
    layerMask = ~LayerMask.GetMask("Layer3");
    
    // 使用layerMask进行射线检测
    RaycastHit hit;
    if (Physics.Raycast(ray, out hit, maxDistance, layerMask))
    {
        // 处理射线击中的对象
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

5.किरणपरिचय कोड

निम्नलिखितः कोडः अस्ति यः hitInfo पैरामीटर् विना तथा च hitInfo पैरामीटर् इत्यस्य उपयोगं करोति:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RayCast : MonoBehaviour
{
    /
    // 构建一条射线 : 射线产生的起始点 + 射线的方向.
    private Ray ray1 = new Ray(Vector3.zero, Vector3.forward);
    // 射线距离
    private float rayDistance = 100.0f;
   
    // 击中的判定结果
    bool hitResult = false;
    // 射线击中的物体
    private RaycastHit hitInfo;

    void Start()
    {
        // 不含有hitInfo的函数
        bool result1 = Physics.Raycast(Vector3.zero + new Vector3(0,0,10), Vector3.forward, 1000.0f, 1 << LayerMask.NameToLayer("Default"), QueryTriggerInteraction.UseGlobal);
        if (result1)
        {
            Debug.Log("射线击中物体");
        }
        // 含有hitInfo的函数
		hitResult =  Physics.Raycast(ray1, out hitInfo, rayDistance, 1 << LayerMask.NameToLayer("Default"), QueryTriggerInteraction.UseGlobal);
        if (hitResult == true)
        {
            print(hitInfo.collider.name);
            print(hitInfo.transform);
            print(hitInfo.point);
        }
    }       
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

6.किरण अलार्म

घूर्णनशीलं लेजरसूचकं कार्यान्वितुं किरणपरिचयस्य उपयोगं कुर्वन्तु यदा वस्तुनः सम्मुखीभवति तदा किरणदीर्घता न्यूनीभवति, किरणस्य आकर्षणस्य आवश्यकता भवति ।

आवश्यकं कौशलम् : रे डिटेक्शन + रोटेशन + LineRender

निम्नलिखितः संहिता अस्ति

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotateRay : MonoBehaviour
{
    // LinerRender组件
    private LineRenderer lineRenderer = null;

    // 构建一条射线 : 射线产生的起始点 + 射线的方向.
    private Ray ray = new Ray(Vector3.zero, Vector3.forward);
    // 射线距离
    private float rayDistance = 1000.0f;
    // 击中的判定结果
    bool hitResult = false;
    // 射线击中的物体
    private RaycastHit hitInfo;

    void Start()
    {
        // 添加线条绘制组件
        lineRenderer = this.gameObject.AddComponent<LineRenderer>();
        InitLineRenderer(lineRenderer);

        // 设置射线的起点和方向
        ray.origin = this.transform.position;
        ray.direction = this.transform.forward;
    }

    // Update is called once per frame
    void Update()
    {
        // 重新设置射线的位置
        ray.origin = this.transform.position;
        ray.direction = this.transform.forward;

        // 旋转游戏对象 -- 每秒旋转60°
        Quaternion quaternion = Quaternion.AngleAxis(60f * Time.deltaTime, this.transform.up);
        this.transform.rotation *= quaternion;        

        // 判断击中的物体
        hitResult =  Physics.Raycast(ray, out hitInfo, rayDistance, 1 << LayerMask.NameToLayer("Default"), QueryTriggerInteraction.UseGlobal);
        if (hitResult == true)
        {
            print(hitInfo.collider.name);
        }
        // 显示并更新射线
        UpdateLineRendererByRay(lineRenderer, ray, hitResult,hitInfo, rayDistance);
    }

    /// <summary>
    /// 初始化线条渲染组件
    /// </summary>
    void InitLineRenderer(LineRenderer lineRenderer)
    {
        // lineRenderer = this.gameObject.AddComponent<LineRenderer>();
        lineRenderer.positionCount = 2;
        lineRenderer.startWidth = 0.2f;
        lineRenderer.endWidth = 0.2f;
        lineRenderer.startColor = Color.red;
        lineRenderer.endColor = Color.green;
    }

    /// <summary>
    /// 击中物体的时候修改射线的长度
    /// </summary>
    /// <param name="lineRenderer">lineRenderer组件</param>
    /// <param name="ray">射线</param>
    /// <param name="hitResult">是否命中物体</param>
    /// <param name="hitInfo">命中物体信息</param>
    /// <param name="rayDistance">射线距离</param>
    void UpdateLineRendererByRay(LineRenderer lineRenderer,Ray ray, bool hitResult, RaycastHit hitInfo, float rayDistance)
    {
        if (lineRenderer == null || lineRenderer.positionCount < 2)
        {
            Debug.Log("LineRender组件不可以使用");
            return;
        }

        // 修改起点位置
        lineRenderer.SetPosition(0, ray.origin);
        // 修改终点位置
        if (hitResult == true)
        {
            lineRenderer.SetPosition(1, hitInfo.point);
        }
        else 
        {
            lineRenderer.SetPosition(1, ray.GetPoint(rayDistance));
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93

अनुकूलित कोड

using UnityEngine;

public class RotateRay : MonoBehaviour
{
    private LineRenderer lineRenderer;
    private Ray ray;
    private float rayDistance = 1000.0f;
    private RaycastHit hitInfo;

    void Start()
    {
        lineRenderer = this.gameObject.AddComponent<LineRenderer>();
        InitLineRenderer(lineRenderer);
        ray = new Ray(Vector3.zero, Vector3.forward);
    }

    void Update()
    {
        UpdateRayPosition();
        RotateObject();
        PerformRaycast();
        UpdateLineRenderer();
    }

    void InitLineRenderer(LineRenderer lineRenderer)
    {
        lineRenderer.positionCount = 2;
        lineRenderer.startWidth = 0.2f;
        lineRenderer.endWidth = 0.2f;
        lineRenderer.startColor = Color.red;
        lineRenderer.endColor = Color.green;
    }

    void UpdateRayPosition()
    {
        ray.origin = this.transform.position;
        ray.direction = this.transform.forward;
    }

    void RotateObject()
    {
        Quaternion rotation = Quaternion.AngleAxis(60f * Time.deltaTime, this.transform.up);
        this.transform.rotation *= rotation;
    }

    void PerformRaycast()
    {
        int layerMask = 1 << LayerMask.NameToLayer("Default");
        hitInfo = new RaycastHit(); // 初始化hitInfo,避免未击中时的错误
        Physics.Raycast(ray, out hitInfo, rayDistance, layerMask, QueryTriggerInteraction.UseGlobal);
    }

    void UpdateLineRenderer()
    {
        if (lineRenderer == null || lineRenderer.positionCount < 2)
        {
            Debug.LogError("LineRenderer component is not available or not properly initialized.");
            return;
        }

        lineRenderer.SetPosition(0, ray.origin);
        lineRenderer.SetPosition(1, hitInfo.collider != null ? hitInfo.point : ray.GetPoint(rayDistance));
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

प्रतिपादनानि यथा

एकता_रेकास्ट.gif

7. विशेषप्रभावं जनयितुं माउस् क्लिक् कुर्वन्तु

using UnityEngine;

public class  CameraRay: MonoBehaviour
{
    // 射线距离
    private float rayDistance = 1000.0f;
    // 特效Prefab--外部可以自定义特效
    public GameObject effectPrefab;

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            // 从摄像机发出一条射线
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hitInfo;

            // 如果射线击中了指定层级的物体
            if (Physics.Raycast(ray, out hitInfo, rayDistance, LayerMask.GetMask("Wall")))
            {
                // 生成特效 --格局法线来计算特效位置
                GameObject effectObject = Instantiate(effectPrefab, hitInfo.point, Quaternion.LookRotation(hitInfo.normal));
                // 销毁特效,参数为延迟时间
                Destroy(effectObject, EffectPrefab.GetComponent<ParticleSystem>().main.duration);
            }
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29