Как я могу требовать, чтобы общедоступная переменная (Prefab) имела определенный компонент (RigidBody) в UNITY? - PullRequest
0 голосов
/ 27 марта 2019

Я пытаюсь реализовать "Стрелять" MonoBehaviour.Я хочу, чтобы он сделал что-то очень простое, он должен принять Prefab как «Input» (пока он хранится в публичной переменной «снаряд»), а затем просто создать его и добавить силу Forward к его RigidBody (относительнообъект, к которому он прикреплен, например, к танку).

Однако я не хочу, чтобы моя игра вылетала, если я случайно вставил префаб без RigidBody.(На самом деле было бы здорово, если бы он даже не позволял мне добавлять префабы без RigidBodies в качестве метательных снарядов).

Я пытался использовать атрибут «RequireComponent», но похоже, что он работает только дляклассы.Есть ли способ сделать это, не проверяя, есть ли у снаряда RigidBody каждый раз, когда я хочу его выстрелить?

Я попробовал код, приведенный ниже, но он выдает ошибку, говорящую, что я не могу установитьRigidBody как GameObject.Это понятно, но у меня заканчиваются идеи.

public class Shoot : MonoBehaviour
{

    public Rigidbody projectile;
    public float firePower = 5f;

    public void Fire()
    {
        GameObject projectileInstance = Instantiate(projectile) as GameObject;
        //maybe add some particles/smoke effect
        projectile.GetComponent<Rigidbody>().AddForce(firePower * transform.forward);
    }
}

Ответы [ 4 ]

1 голос
/ 28 марта 2019

Вы можете добавить нужные компоненты во время выполнения, например:

    // First check if there is no rigidbody component on the object
    if (!currentPrefab.GetComponent<Rigidbody>()){
        // Add the Rigidbody component
        currentPrefab.AddComponent<Rigidbody>();

        // You can also add a collider here if you want collisions
        var bc = currentPrefab.AddComponent<BoxCollider>();

        // And you'll have to calculate the new collider's bounds
        Renderer[] r = t.GetComponentsInChildren<Renderer>();
        for(var i=0; i<r.length; i++) {
            bc.bounds.Encapsulate(r[i].bounds);
        }
    }
1 голос
/ 27 марта 2019

Вы можете проверить префаб, чтобы увидеть, есть ли в нем компонент Rigidbody, например:

if (currentPrefab.GetComponent<Rigidbody>()){

    // Do something

}

Метод GameObject.GetComponent () вернет значение null, если тип, введенный вами в качестве параметра, отсутствует.

0 голосов
/ 28 марта 2019

Другие здесь уже дали вам несколько примеров того, как вы будете делать это во время выполнения, однако я бы порекомендовал вам добавить [RequireComponent(typeof(RigidBody))] к вашему классу снарядов (если он у вас есть).

Все, что вы делаете, это каждый раз, когда вы присоединяете свой компонент к gameObject. Unity автоматически добавляет необходимые компоненты, не влияя на производительность вашей игры во время выполнения. Просто добавьте это к объявлению класса в вашем сценарии снаряда.

Однако вам необходимо вручную назначить компоненты через инспектора или GetComponent. Но это гарантирует, что к вашему объекту прикреплены нужные компоненты.

Вам нужен какой-то сценарий на ваших снарядах, чтобы это сработало. Поэтому, если у вас его нет, вам следует использовать другой вариант, указанный здесь.

Документацию можно найти здесь , если вы заинтересованы.

0 голосов
/ 28 марта 2019

Я полагаю, вы уже записали трек. Вы просто должны исправить свою ошибку, выполнив следующее:

public Rigidbody projectile;
public float firePower = 5f;

public void Fire()
{
    if( projectile == null )
    {
         Debug.LogError( "You forgot to provide a projectile prefab");
         return;
    }
    Rigidbody projectileInstance = Instantiate(projectile) as Rigidbody;
    projectileInstance.AddForce(firePower * transform.forward);
}

Однако, при использовании этого метода вы не можете требовать, чтобы в сборном было несколько компонентов. Если вам это нужно, то используйте метод, указанный в других ответах.

...