• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Unity spadający obiekt w stylu kodu Matrix'a

Object Storage Arubacloud
0 głosów
266 wizyt
pytanie zadane 20 marca 2020 w C# przez Sic Dyskutant (8,510 p.)

Witam,

Zależy mi na tym, aby stworzyć obiekt spadający od górnej części ekranu do dolnej ( start- y = 190, stop- y = -224). Obiekt ten po uzyskaniu końcowej granicy (stop) powinien wrócić ponownie na pozycje y równiej 190 jednak pozycja x powinna być losowa. Opcje grawitacji uzyskałem dzięki "Rigidbody2D". Obiekt oczywiście spada jednak nie pojawia się on ponownie na wskazanie pozycji.

Próbowałem zrobić to za pomocą utworzenia nowej pozycja Vecto2 oraz podjąłem probłem stworzenia nowego obiektu na pozycji (nic nie spowodowało pojawienia się obiektu ponownie w górnej części ekranu)

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

public class SquareBackground : MonoBehaviour
{
    public GameObject fallingSquare;
    public Rigidbody2D falling;

    // Update is called once per frame
    void Update()
    {
        Vector2 fallDownPos = fallingSquare.transform.position;

        fallDownPos = falling.position;

        fallDownPos.y = 190;
        if (fallingSquare.transform.position.y == -224)
        {
            //fallDownPos = new Vector2(Random.Range(-284, 234), 190);

            fallDownPos = new Vector2(Random.Range(-284, 234), 190);
            falling.MovePosition(fallDownPos);
        }
    }
}

Ostateczną próbą było wykorzystanie "MovePosiotion" z klasy "Rigidbody2D".

Proszę o podpowiedź dotyczącą możliwości przeniesienia(lub utworzenia) na wybranej pozycji po osiągnięciu y == -224.

1 odpowiedź

0 głosów
odpowiedź 20 marca 2020 przez bergman Obywatel (1,600 p.)
Jeśli przesuwasz o jakis y nie zawsze obiekt wyąduje na wysokości y == -224 .Tam powinno byc mniejsze bądź równe
komentarz 21 marca 2020 przez Sic Dyskutant (8,510 p.)

Zasugerowałem się tym co napisałeś @bergman, po części dało to pozytywny rezultat. W momencie osiągnięcia odpowiedniej wartości dla y. Obiekt zaczyna zmieniać pozycje o różnych wartościach x.

Pojawia się inny problem, którego nie mogę rozwiązać i nie jest on dla mnie do końca jasne, mianowicie w momencie osiągnięcia wartości y umieszczonej w warunku. Obiekt pojawia się w miejscu losowym dla x, jednak Y pozostaje ten sam (~-224). Nie cofa się do wartości podanej przy tworzeniu nowej pozycja (~190).

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

public class SquareBackground : MonoBehaviour
{
    public GameObject fallingSquare;
    public Rigidbody2D falling;

    // Update is called once per frame
    void Update()
    {
        Vector2 fallDownPos = fallingSquare.transform.position;
        Quaternion fallDownRot = falling.transform.rotation;
        fallDownPos = falling.position;

        fallDownPos.y = 190;
        for (int i = 0; i < 10; i++)
        {
            if (fallingSquare.transform.position.y <= -224)
            {
                //fallingSquare = new GameObject();
                fallDownPos = new Vector2(Random.Range(-284, 234), 190);
                falling.MovePosition(fallDownPos);
            }
        }
    }
}

Dla upewnienia się modyfikowałem się do utworzenia lub klonowania obiektu (GameObject), jak również rezygnując z klasy RigidBody2D.

Co może być nie tak w obecnej sytuacji ?

komentarz 21 marca 2020 przez bergman Obywatel (1,600 p.)
edycja 21 marca 2020 przez bergman
Xxx
komentarz 22 marca 2020 przez Sic Dyskutant (8,510 p.)

Problemem tej sytuacjia nie jest x, a y.

Za każdym razem gdy próbuje zmienić wartość nowe Y, obiekt pojawia się w tej samej wartości zachowuje zupełnie inaczej jak X. Przykład ( po zmianie wartości):

fallDownPos = new Vector2(Random.Range(30.0f, 34.0f), Random.Range(0f,1.0f));

X pojawia się dokładnie tam gdzie powinnien, jednak Y cały cas w tym samym miejscu- nie wiele powyżej wartości wprowadzonej w warunku.

komentarz 24 marca 2020 przez Sic Dyskutant (8,510 p.)

Znalazłem interesujący kod, które częściowo wykonuje to na czym mi zależy:

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

public class SquareBackground : MonoBehaviour
{
    [SerializeField]
    private float xLimit;

    [SerializeField] // zależy od ilości obiektów- wartości pozycji x
    private float[] xPosition;

    [SerializeField] // tablica obiektów 
    private GameObject[] squaresFalling;

    [SerializeField]
    private Wave[] wave; // obiekty klasy Wave

    private float currentTime;

    List<float> remainingPositions = new List<float>();
    private int waveIndex;
    float xPos = 0;
    int rand;

    void Start()
    {
        currentTime = 0;
        remainingPositions.AddRange(xPosition);
    }

    void Update()
    {
        //int r = Random.Range(0, 1);
        //var yPos = squaresFalling[r].transform.position.y;
        //if (yPos == -224)
        SelectWave(); // powoduje utworzenie klona w odpowiedniej pozycji 
}

    void fallObject(float xPos)
    {
        int r = Random.Range(0, 1); // rodzaje obiektów (ich ilość)
        GameObject fallObject = Instantiate(squaresFalling[r], new Vector3(xPos, transform.position.y, 0), Quaternion.identity);
    }

    void SelectWave()
    {
        remainingPositions = new List<float>();
        remainingPositions.AddRange(xPosition);

        waveIndex = Random.Range(0, wave.Length);

        currentTime = wave[waveIndex].delayTime;

        if (wave[waveIndex].spawnAmount == 1)
            xPos = Random.Range(-xLimit, xLimit);
        else if(wave[waveIndex].spawnAmount > 1)
        {
            rand = Random.Range(0, remainingPositions.Count);
            xPos = remainingPositions[rand];
            remainingPositions.RemoveAt(rand);
        }

        for(int i = 0; i < wave[waveIndex].spawnAmount; i++)
        {
            fallObject(xPos);
            rand = Random.Range(0, remainingPositions.Count);
            xPos = remainingPositions[rand];
            remainingPositions.RemoveAt(rand);
        }
    }
}

[System.Serializable]
public class Wave
{
    public float delayTime;
    public float spawnAmount;
}

Uzależniony jest od ilości obiektów, które oczywiści mogę dodać w każdej chwili. Zależy mi wciąż, aby po osiągnięciu przez obiekt odpowiedniej pozycji y cofał się do wartości początkowe.

Istnieje w tym kodzie jednak dość spory problem, ilość tworzonych obiektów jest ogromna co powoduje całkowite przeciążenie aplikacji.

Czy mogłby prosić o pomoc w modyfikacji kodu ?

komentarz 28 marca 2020 przez Sic Dyskutant (8,510 p.)
edycja 28 marca 2020 przez Sic

@bergman,

Polegając na jednym z poradników zmodyfikowałem kod, częściowo wszystko działa prawidłowo, jednak wciąż mam problem z warunkiem dotyczącym wartości y (próbowałem na wiele sposobów, mimo to nie chce on wrócić na początkową pozycje i spadać od nowa!).

Oto kod:

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

public class SquareBackground : MonoBehaviour
{
    [SerializeField]
    private float xLimit;

    [SerializeField] // zależy od ilości obiektów- wartości pozycji x
    private float[] xPosition;

    [SerializeField]
    private Wave[] wave; // obiekty klasy Wave

    private float currentTime;

    List<float> remainingPositions = new List<float>();
    private int waveIndex;
    float xPos = 0;
    int rand;

    void Start()
    {
        currentTime = 0;
        remainingPositions.AddRange(xPosition);
    }

    void Update()
    {
        if(transform.position.y == -224)
        { 
            SelectWave(); 
            fallObject(xPos);
        }
    }

    void fallObject(float xPos)
    {
        int r = 0;
        string objectName = "";
        if (r == 0)
            objectName = "fallSquare";

        GameObject fallingObject = PollingObjects.instance.GetPooledObject(objectName);
        fallingObject.transform.position = new Vector3(xPos, transform.position.y, 0);
        fallingObject.SetActive(true);
    }

    void SelectWave()
    {
        remainingPositions = new List<float>();
        remainingPositions.AddRange(xPosition);

        waveIndex = Random.Range(0, wave.Length);

        currentTime = wave[waveIndex].delayTime;

        if (wave[waveIndex].spawnAmount == 1)
            xPos = Random.Range(-xLimit, xLimit);
        else if(wave[waveIndex].spawnAmount > 1)
        {
            rand = Random.Range(0, remainingPositions.Count);
            xPos = remainingPositions[rand];
            remainingPositions.RemoveAt(rand);
        }

        for(int i = 0; i < wave[waveIndex].spawnAmount; i++)
        {
            fallObject(xPos);
            rand = Random.Range(0, remainingPositions.Count);
            xPos = remainingPositions[rand];
            remainingPositions.RemoveAt(rand);
        }
    }
}

[System.Serializable]
public class Wave
{
    public float delayTime;
    public float spawnAmount;
}

Klasa "PollingObjects", która występuje w linii numer 45 odpowiada za klonowanie obiektu. Tylko że tworząc kopie pojawiają się w zupełnie innej pozycji niż zostaje to podane w parametrach.

W obecnej sytuacji skupiam się na dwóch funkcjach- pierwszą z nich jest Update(), a drugą fallObject(float).

Wciąż zależy mi na tym samym celu- obiekt po osiągnięciu pozycji y -224 powinien wrócić, lub jego kopia na początkowe miejsce i ponownie spadać.

Podobne pytania

0 głosów
0 odpowiedzi 111 wizyt
pytanie zadane 8 stycznia 2021 w C# przez ShockWave Bywalec (2,350 p.)
0 głosów
1 odpowiedź 106 wizyt
pytanie zadane 18 czerwca 2020 w C# przez Szyszka Gaduła (3,490 p.)
0 głosów
1 odpowiedź 99 wizyt
pytanie zadane 22 kwietnia 2020 w C# przez Mariner Nowicjusz (140 p.)

92,575 zapytań

141,424 odpowiedzi

319,649 komentarzy

61,960 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...