Unity (C #) — как мне выделить GameObject, обнаруживаемый Raycast в системе уничтожения / возрождения

#c# #unity3d #raycasting

#c# #unity3d #raycasting

Вопрос:

Я пытаюсь создать уничтоженный gameobject, подождать x секунд, возродить систему gameobject. У меня есть 2 сценария, и я удаляю, а затем создаю его снова. Я хочу использовать несколько одинаковых сборных под названием «Breakable», но у меня есть только тот, который я собираюсь уничтожить. Подобно играм, таким как Minecraft, aim и только нацеленный на блок уничтожается.

Сценарий 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

Комментарии:

1. Код выглядит очень аккуратно! Просто чтобы было ясно, в чем проблема на данный момент ???? : O

2. @Fattie Когда я добавляю второй «хрупкий» сборный элемент в игру, я разбиваю один, он ломает их оба, потому что у них одинаковое имя и тег. Я хочу иметь возможность использовать одно и то же имя и теги для нескольких одинаковых сборных, но иметь только тот, на который я смотрю непосредственно, чтобы быть сломанным. Как мне это сделать? если это имеет смысл

3. Аааа! это просто!

Ответ №1:

К счастью, это просто и просто в Unity!

Вы этого не делаете:

 breakableObject = GameObject.Find("Breakable");
 

Хорошая новость в том, что приведение скажет вам, какой объект вы поразили! Здорово, да?

Это в основном:

 hit.collider.gameObject
 

Вы можете использовать hit.collider.gameObject.name в отладке.Войдите для удобства.

Это так просто!

Обратите внимание, что затем (если вам это нужно) получите свой компонент для этого объекта с помощью чего-то вроде .GetComponent<YourBreakishBlock>() … легко.

Обратите внимание, что вы можете ПРОВЕРИТЬ, является ли объект одним из объектов «YourBreakishBlock», просто проверив, присутствует ли этот компонент.

Примечание. просто погуглите что-то вроде «unity physics raycast out hit, какой объект был поражен?» для бесконечных примеров,

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!"); }
}
 

Теперь поместите это на НЕКОТОРЫЕ кубы, но НЕ на ДРУГИЕ кубы.

В вашем коде ray:

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

а затем проверьте это:

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

Теперь запустите приложение и попробуйте указать на различные кубы!

Комментарии:

1. Вау, это невероятно просто xD Я действительно не понимаю, что делает часть .getcomponent, потому что я этому еще не научился! Теперь мне нужно выяснить, как поместить блок обратно в то же место, а не там, где находится позиция prefabs!

2. Куда мне поместить каждый из них, извините? Мозг сейчас работает на половинной скорости! В какие сценарии они будут входить?

3. подождите, у меня получилось! Итак, могу ли я использовать какую-либо форму getcomponent для определения положения куба, передать его в сценарий возрождения, а затем установить такую позицию ?! omg ИЛИ получить весь объект и передать этот точный объект (который будет соответствовать его положению) в respawner !?

4. У меня это работает! Теперь они работают индивидуально!!!! ОГРОМНОЕ вам СПАСИБО!

5. да, оба ваших утверждения ВЕРНЫ!!!! Кстати, получить позицию так просто!! hit.collider.gameObject.transform.position !!!