how to create three early, non-repetitive targets on the list in unity



  • First, I created a list that filters objects.

    To be clearer, I'll describe what the player does. The game fits the counter with the book. The camera is approaching the table(s) and there are three-kilogram characters on it after n seconds. Every character can be pressed, and then his biography will appear. After that, you can kill one of the characters. Then all 3 are removed and 3 new characters are created. But they don't create the ones that were already on the table.

    public void characterFilter()
    {
        List<CharactersDie> FilteredData = new List<CharactersDie> ();
        foreach (CharactersDie C in characters) {
            // если объект еще не создавался, то это значение равно 0
            // если создавался, то оно равно 1
            if (C.characterReads == 0) 
                FilteredData.Add (C);
        }
    Как из этого списка мне создать 3 рандомных и не повторяющихся объекта?
    

    If it helps, that's the full code.

    using UnityEngine;
    using System.Collections;
    using UnityStandardAssets.Characters.FirstPerson;
    using System.Collections.Generic;
    

    public class LevelManagerScript: MonoBehaviour {

    public UnityStandardAssets.Characters.FirstPerson.FirstPersonController controller;
    private Books playerReadings;
    private RayCastScript rayCast;
    public GameObject openBook;
    private OpenBook openBooks;
    private CharactersDie[] characters;
    public GameObject deathBookCamera;
    public GameObject characterControll;
    public float loadDelay;
    
    // Use this for initialization
    
    void Awake() {
      controller = FindObjectOfType&lt;FirstPersonController&gt;();
      playerReadings = FindObjectOfType&lt;Books&gt;();
      rayCast = FindObjectOfType&lt;RayCastScript&gt;();
      Cursor.visible = false;
      characters = FindObjectsOfType&lt;CharactersDie&gt;();
      //openBook = GameObject.FindGameObjectWithTag ("OpenBook");
    }
    
    void Start() {
    
    }
    
    // Update is called once per frame
    void Update() {
      //if (playerReadings.playerReading) {
      //        Cursor.visible = true;
      //} else
      //    Cursor.visible = false;
    }
    
    public void reading() {
      controller.enabled = false;
      rayCast.enabled = false;
      Cursor.visible = true;
    }
    
    public void StopReading() {
      openBooks = FindObjectOfType&lt;OpenBook&gt;();
      rayCast.enabled = true;
      //openBook.TextCanvas.SetActive(false);
      openBooks.OpenBookTextCanvas.SetActive(false);
      openBooks.oneText.SetActive(false);
      openBooks.twoText.SetActive(false);
      openBooks.threeText.SetActive(false);
      openBooks.fourText.SetActive(false);
      playerReadings.playerReading = false;
      controller.enabled = true;
      Cursor.visible = false;
    }
    
    public void characterFilter() {
      List &lt;CharactersDie&gt; FilteredData = new List&lt;CharactersDie&gt;();
      foreach(CharactersDie C in characters) {
        if (C.characterReads == 0)
          FilteredData.Add(C);
      }
    
      foreach(CharactersDie C in FilteredData) {
        int prefabIndex = UnityEngine.Random.Range(0, C); // это не работает
        Instantiate(FilteredData[prefabIndex]);
      }
    }
    
    public void deathBookCameraActivate() {
      characterControll.SetActive(false);
      deathBookCamera.SetActive(true);
      Cursor.visible = true;
    }
    
    public void deathBookCameraDisActivate() {
      characterControll.SetActive(true);
      deathBookCamera.SetActive(false);
      Cursor.visible = false;
    }
    

    }



  • First, when you do Range(0, C); You're trying to make early numbers between 0 and type object. CharactersDie♪ A Range Adopts two numbers as parameters. I mean, there should have been a mistake and no compilation in principle. Like it didn't show a mistake, I don't understand.

    Secondly, for the generation of early home and unique elements, another leaf is likely to be stored. For example:

    List<int> randomList = new List<int>();
    

    for ( ; randomList.Count < 3; ) {
    var random = UnityEngine.Random.Range(0, FilteredData.Count);
    if (!randomList.Contains(random)) {
    randomList.Add(random);
    Instantiate(FilteredData[random]);
    }
    }
    randomList.Clear();

    That's what it looks like on C#: http://ideone.com/dhBT3J

    What's going on here?

    The cycle shall be set up until three objects are accumulated on the rand sheet. How will a unique one get there? It's just, in the cycle, we say "hey, the randlist, and do you keep the generated number (random) already? No? Then add it to me and you can instainate it. And if you keep it, then go to a new circle!" After the cycle, clear the sheet. Just in case.

    Thirdly, I'm sure that in place of two cycles, everything can be shorter using https://msdn.microsoft.com/ru-ru/library/bb397676.aspx But you can do it yourself by reading that language.


    That's what LINQ can do.

    public void characterFilter() {
    var filteredData = charactersDie.Where(item => item.characterReads == 1).ToList();
    var numbers = Enumerable.Range(0, filteredData.Count).OrderBy(n => n * n * (new Random()).Next()).Take(3);

    // Инстанциировать рандомные объекты
    foreach (var number in numbers) {
        Instantiate(filteredData[number]);
    }
    

    }

    As an example: http://ideone.com/QviKXq




Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2