Шанс выпадение предметов(drop chance) в Unity3d

218
27 августа 2018, 23:30

Сразу говорю, что ответ, скорее всего, лежит у меня перед глазами, но я его, как обычно, не вижу.(А ещё, скорее всего, я запутался xD)
Есть код, в котором есть два массива: Gameobject items(сами предметы) и float dropRate(С каким шансом выпадет предмет). Так вот, мы постоянно генерируем число(float dropchance) от 0 до 1. Если враг умирает, тогда мы хотим, чтобы шанс из dropRate[] определял: какой предмет выпадет. Но я не как не могу сделать так, чтобы выпадал именно определенный предмет из items[]. Выпадают сразу все вещи из items[]. Да-да, понимаю, что это связано с циклом foreach, но как бы его изменить, чтобы выпадала та вещь, которая мне нужна?

using System.Collections;
using UnityEngine;
using System.Collections.Generic;
public class Drop : MonoBehaviour {
    public GameObject[] items;
    public int a;
    public float[] dropRate;
    public float dropchance;
    public bool killed = false;
    public float expdropped;
    private GameObject Player;
    // Use this for initialization
    void Start () {
        Player = GameObject.FindGameObjectWithTag("Player");
        a = items.Length;
    }
    // Update is called once per frame
    private void Update()
    {
        dropchance = Random.Range(0f, 1f);
        Debug.Log(dropchance);
    }
    void LateUpdate()
    {
        Debug.Log(killed);
        if (killed)
        {
            killed = false;
            Player.GetComponent<Expirience>().exp += expdropped;
            Vector3 SpawnPoint = transform.position;
            if (items != null) {
                //if (dropchance <= dropRate)
                {
                    for(a=0; a < dropRate.Length;a++) {
                        Debug.Log(dropRate[a]);
                        if (dropRate[a] >= dropchance) {
                            foreach (GameObject item in items)
                            {
                                if (item != null)
                                {
                                    Instantiate(item, SpawnPoint, Quaternion.identity);
                                }
                            }
                        }
                    }
                }
            }
            Destroy(gameObject);
        }
    }
}

Answer 1

Сделайте принудительный выход из цикла путем вызова break;

var itemDropped = false;
for(a=0; a < dropRate.Length;a++)
{
    Debug.Log(dropRate[a]);
    if (dropRate[a] >= dropchance) {
        foreach (GameObject item in items)
        {
            if (item != null)
            {
                Instantiate(item, SpawnPoint, Quaternion.identity);
                itemDropped = true;
            }
            if(itemDropped) break;
        }
    }
    if(itemDropped) break;
}

UPD: еще раз внимательно прочитал ваш код- foreach (GameObject item in items). Данный цикл у вас заставляет выпадать все предметы из списка. Чтобы выбрать только определенные предметы следует сделать такой цикл:

foreach (GameObject item in items)
{
    if (item != null && item.dropChance == dropRate[a] )
    {
        Instantiate(item, SpawnPoint, Quaternion.identity);
    }
}

UPD2: В таком случае вам вообще не нужен foreach:

if (dropRate[a] - dropchance <= 0.05 && -0.05 <= dropRate[a] - dropchance) {
    if (items[a] != null)
    {
        Instantiate(item, SpawnPoint, Quaternion.identity);
    }
}
READ ALSO
Unity, посмотреть туда, куда смотрит камера

Unity, посмотреть туда, куда смотрит камера

Есть скрипт для оружияМы пускаем рейкаст, и когда попадаем им, смотрим на точку попадения

194
Проверка значения на &ldquo;старость&rdquo;

Проверка значения на “старость”

Есть переменнаяОна в бесконечном цикле выдаёт значения типа:

184
Не перебирает адреса в базе правильно

Не перебирает адреса в базе правильно

Я составил скрипт, который перебирает адреса в моей таблице и отмечает отправленные

187
Как передать данные с laravel в react компонент

Как передать данные с laravel в react компонент

Мне нужно передать данные с blade (с бд данные) в react компонентГде-то я прочитал, что можно передать так:

291