Unity (C#) - 如何在销毁/重生系统中挑选出被 Raycast 检测到的 GameObject

Posted

技术标签:

【中文标题】Unity (C#) - 如何在销毁/重生系统中挑选出被 Raycast 检测到的 GameObject【英文标题】:Unity (C#) - How do I single out GameObject being detected by Raycast in a destroy / respawn system 【发布时间】:2021-04-27 12:25:36 【问题描述】:

我正在尝试制作一个 Destroy 游戏对象,等待 x 秒,重新生成游戏对象系统。我有 2 个脚本,我正在破坏然后再次实例化它。我想使用多个名为“Breakable”的相同预制件,但只有一个我打算被摧毁的预制件。类似于 Minecraft 之类的游戏,瞄准并且只有瞄准的方块会被摧毁。

BlockBreakItem 脚本:

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

public class BlockBreakItem : MonoBehaviour

    RaycastHit hit;
    int layerMask = 1;
    public GameObject breakableObject;
    public bool isObjectDestoryed = false;

    public int score = 0;

    // Update is called once per frame
    void Update()
    
        breakableDetection();
    

    void breakableDetection()
    
        Ray rayLocation = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(rayLocation, out hit, 1000, layerMask))
        
            print("Detected");
            if (Input.GetKey(KeyCode.Mouse0))
            
                
                breakableObject = GameObject.Find("Breakable");
                Destroy(breakableObject);
                isObjectDestoryed = true;
                
                score = score +1 ;
            
        
    

RespawnBrokenObject 脚本:

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

public class RespawnBrokenObject : MonoBehaviour

    private BlockBreakItem BlockBreakItem;
    public GameObject breakablePrefab;

    // Start is called before the first frame update
    void Start()
    
        BlockBreakItem = GameObject.FindObjectOfType<BlockBreakItem>();
    

    // Update is called once per frame
    void Update()
    
        if (BlockBreakItem.isObjectDestoryed == true)
        
            Invoke("respawnObject", 5.0f);
            BlockBreakItem.isObjectDestoryed = false;
        
    

    void respawnObject()
    
        GameObject tempObjName = Instantiate(breakablePrefab);
        
        tempObjName.name = breakablePrefab.name;
        BlockBreakItem.breakableObject = tempObjName;
    

我希望代码不要太乱!一直担心听不懂xD

【问题讨论】:

代码看起来很整洁!只是要清楚,目前有什么问题???? :O @Fattie 当我在游戏中添加第二个“Breakable”预制件时,我破坏了一个,它破坏了它们,因为它们具有相同的名称和标签。我希望能够为多个相同的预制件使用相同的名称和标签,但只有我正在直接查看的那个被破坏。我该怎么做?如果这有意义 啊!很简单! 【参考方案1】:

幸运的是,它在 Unity 中既简单又基本!

你不要这样做:

breakableObject = GameObject.Find("Breakable");

好消息是演员会告诉你你击中了什么物体!太好了,嗯?

基本上是:

hit.collider.gameObject

为方便起见,您可以在 Debug.Log 中使用 hit.collider.gameObject.name

就这么简单!

然后请注意(如果需要)使用 .GetComponent&lt;YourBreakishBlock&gt;()... 之类的方式将组件放在该对象上。

请注意,您可以检查对象是否命中,是否是“YourBreakishBlock”对象之一,只需检查该组件是否存在。

请注意,只需在 Google 上搜索类似“unity 物理射线投射命中,哪个物体被击中?”举不胜举的例子,

https://forum.unity.com/threads/getting-object-hit-with-raycast.573982/https://forum.unity.com/threads/changing-properties-of-object-hit-with-raycast.538819/

等等

--

制作这个简单的类:

public class ExamplePutThisOnACube: MonoBehavior

public void SAYHELLO()  Debug.Log("hello!"); 

现在把它放在一些立方体上,而不是放在其他立方体上。

在你的光线代码中:

ExamplePutThisOnACube teste =
  hit.collider.gameObject.GetComponent<ExamplePutThisOnACube>();

然后检查一下:

if (teste != null)  teste.SAYHELLO(); 

现在运行应用程序并尝试指向各种立方体!

【讨论】:

哇,这太容易了 xD 我真的不明白 .getcomponent 部分的作用,因为我还没有学过!现在我需要弄清楚如何将块放回原处而不是预制件的位置! 我应该把他们每个人都放在哪里对不起?大脑现在正在半速工作!他们会进入哪些脚本? 等我搞定了!那么我可以使用某种形式的 getcomponent 来获取被点击的立方体的位置,将它传递给 respawn 脚本,然后像这样设置位置吗?! omg 或者获取整个对象并将那个确切的对象(将与它的位置一起出现)传递给重生者!? 我成功了!他们现在单独工作!!!!非常感谢! 是的,你的两个陈述都是正确的!!!!顺便说一句,获得职位就这么容易! hit.collider.gameObject.transform.position !!!

以上是关于Unity (C#) - 如何在销毁/重生系统中挑选出被 Raycast 检测到的 GameObject的主要内容,如果未能解决你的问题,请参考以下文章

如何在脚本中仅使用游戏对象启用 Unity C# 中的部件/组件

Unity:如何通过网络销毁游戏对象?

公共静态 Dictionary<String,GameObject> 中的游戏对象在 Unity 中的场景更改时被销毁

unity3d 怎么检测碰撞?比如主角碰撞到物体之后销毁被撞到的物体

在 Unity 中销毁实例化游戏对象的问题

如何在 C# 中销毁对象 [重复]