2 सवाल: अगला दृश्य लोड नहीं हो रहा है

पर बनाया गया सवाल Wed, May 8, 2019 12:00 AM

मेरी समस्या यह है कि जब सभी दुश्मनों को मार दिया जाता है, जिसे लोड किया जाना चाहिए, लोड नहीं हो रहा है। मैंने बिल्ड सेटिंग में दृश्य जोड़ा (इसमें 3 का सूचकांक है) लेकिन यह अभी भी लोड नहीं हो रहा है। मेरे द्वारा बनाई गई स्क्रिप्ट एक खाली वस्तु से जुड़ी है और सीधे स्प्राइट से जुड़ी नहीं है (क्या यह ठीक है?)। क्या कोई मुझे बता सकता है कि दृश्य लोड क्यों नहीं हो रहा है? धन्यवाद।

यह छवि आपको EnemySpawner खाली ऑब्जेक्ट इंस्पेक्टर को दिखाने के लिए है यहां छवि विवरण दर्ज करें

दुश्मन दुश्मन स्क्रिप्ट:

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

public class EnemySpawner : MonoBehaviour {

[SerializeField] GameObject EnemyPreFab;
[SerializeField] int MaxEnemies = 30;
[SerializeField] float EnemySpawnTime = 1.00001f;
[SerializeField] GameObject FirstWaypoint;
int CurrentNumOfEnemies = 0;
public LevelManager myLevelManager;
public int maximumnumberofhits = 0;
int timesEnemyHit;



IEnumerator SpawningEnemies()
{
    while(CurrentNumOfEnemies <= MaxEnemies)
    {
        GameObject Enemy = Instantiate(EnemyPreFab, this.transform.position, Quaternion.identity);
        CurrentNumOfEnemies++;
        yield return new WaitForSeconds(EnemySpawnTime);
    }
}

void Start()
{
    StartCoroutine(SpawningEnemies());
    timesEnemyHit = 0;
    if (this.gameObject.tag == "EnemyHit")
    {
        CurrentNumOfEnemies++;
    }


}

void OnCollisionEnter2D()
{
    timesEnemyHit++;
    if (timesEnemyHit == maximumnumberofhits)
    {
        CurrentNumOfEnemies--;
        Destroy(this.gameObject);
    }

    if (CurrentNumOfEnemies == 0)
    {
        myLevelManager.LoadLevel("NextLevelMenu");
        Debug.Log("LevelLoaded");
    }
   }

}

LevelManger स्क्रिप्ट:

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

public class LevelManager : MonoBehaviour {
 public void LoadLevel(string name)
 {
    print("Level loading requested for" + name);
    SceneManager.LoadScene(name);
  }
}

शत्रु-निवारण स्क्रिप्ट:

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

public class EnemyShooting : MonoBehaviour {


[SerializeField] float EnemyLaserSpeed = 10f;
[SerializeField] float EnemyLaserFireTime;
[SerializeField] GameObject LaserBulletEnemyPreFab;
[SerializeField] int MaxNumberOfHits = 1;
int CurrentNumberOfHits = 0;
Coroutine FireCoroutine;

void OnTriggerEnter2D(Collider2D collider)
{
    if(collider.gameObject.tag == "PlayerLaser")
    {
        if(CurrentNumberOfHits < MaxNumberOfHits)
        {
            CurrentNumberOfHits++;
            Destroy(collider.gameObject);
            Score.ScoreValue += 2;//The user will be rewarded 1 point
        }
    }
}



void DestroyEnemy()
{
    if(CurrentNumberOfHits >= MaxNumberOfHits)
    {
        Destroy(gameObject);
    }
}

private void Fire()
{
    FireCoroutine = StartCoroutine(ShootContinuously());
}

void BecomeVisible()
{
    Fire();
}

IEnumerator ShootContinuously()
{
    while (true)
    {
        GameObject LaserBulletEnemy = Instantiate(LaserBulletEnemyPreFab, this.transform.position, Quaternion.identity) as GameObject;
        LaserBulletEnemy.GetComponent<Rigidbody2D>().velocity = new Vector2(0, EnemyLaserSpeed);
        EnemyLaserFireTime = Random.Range(0.5f, 0.9f);
        yield return new WaitForSeconds(EnemyLaserFireTime);
    }
}
// Use this for initialization
void Start () {

    BecomeVisible();
}

// Update is called once per frame
void Update () {

    DestroyEnemy();

   }
}

EnemyPathing स्क्रिप्ट:

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

public class EnemyPathing : MonoBehaviour {
[SerializeField] List<Transform> WayPoints;
[SerializeField] float EnemyMovingSpeed = 5f;
int WayPointIndex = 0; 

void EnemyMoving()
{
    if (WayPointIndex <= WayPoints.Count - 1)
    {
        var TargetedPosition = WayPoints[WayPointIndex].transform.position; //The position of where the enemy needs to go
        TargetedPosition.z = 0f;
        var MoveThisFrame = EnemyMovingSpeed * Time.deltaTime;
        transform.position = Vector2.MoveTowards(this.transform.position, TargetedPosition, MoveThisFrame);

        if(transform.position == TargetedPosition)
        {
            WayPointIndex++;
        }
    }

    else
    {
        Destroy(gameObject);
    }
}
// Use this for initialization
void Start () {

    transform.position = WayPoints[WayPointIndex].transform.position;

}

// Update is called once per frame
void Update () {

    EnemyMoving();

 }
}
    
1
  1. कृपया MyLevelManager के कोड को जोड़ें। :)
    2019-05-08 12: 11: 47Z
  2. क्या आपको कोई अपवाद मिल रहा है? क्या आपने यह सत्यापित करने के लिए अपने कोड में Debug.Log() डालने का प्रयास किया है कि लोडलेवल कोड ट्रिगर हो रहा है?
    2019-05-08 12: 12: 34Z
  3. स्तरीय प्रबंधक की स्क्रिप्ट जोड़ी गई है और मैंने अभी अभी डिबग.लॉग जोड़ा है लेकिन कुछ भी नहीं छाप रहा है कि यह लोड है
    2019-05-08 12: 18: 05Z
  4. धन्यवाद, कृपया @ एंड्रिया का उत्तर देखें, मुझे लगता है कि यह आपके मुद्दे को हल करने के लिए एक मार्ग पर स्थापित होगा। Btw, कि LevelManager को एक GameObject को असाइन करने की आवश्यकता नहीं है क्योंकि यह एक GameObject के रूप में कुछ भी नहीं करता है। आप इसे प्रत्येक स्क्रिप्ट के लिए GameObject को बंध किए बिना इसे स्थिर बना सकते हैं और इसे कहीं से भी कॉल कर सकते हैं, इसका उपयोग करना चाहते हैं।
    2019-05-08 12: 20: 14Z
  5. इसलिए मुझे सार्वजनिक शून्य लोडलेवेल (स्ट्रिंग नाम) को सार्वजनिक स्थिर शून्य लोडेल (स्ट्रिंग नाम) में बदलने की आवश्यकता है?
    2019-05-08 12: 25: 39Z
    2 उत्तर                              2                         

    समस्या

    आप SPAWNER पर टकराव की जाँच कर रहे हैं; जब कोई स्पॉनर को मारता है तो वह दुश्मनों को गिनता है। लेकिन Spawner के स्क्रीनशॉट में एक टक्कर बॉक्स नहीं है, इसलिए इसे कभी भी हिट नहीं किया जा सकता है। दृश्य परिवर्तन कोड को कभी नहीं बुलाया जा सकता है।

    तो कोड के आधार पर खेल इस तरह दिखता है:

    1. एक्स दुश्मन,
    2. Spawner X को बार मारो,
    3. (हटाए गए: Spawner को नष्ट करें)
    4. दृश्य बदलें।

    मैं यह अनुमान लगा रहा हूं कि यह वैचारिक रूप से गलत है और आप वास्तव में दागे गए दुश्मनों पर टकराव की जाँच करना चाहते हैं, जो तब नष्ट हुए दुश्मनों की मात्रा को गिनेंगे, और जब वे सभी मृत हो जाएंगे तो दृश्य बदल जाएगा।


    समाधान

    वैचारिक रूप से, आप जो चाहते हैं वह है:

    1. X दुश्मनों को स्पॉन करें
    2. हर दुश्मन के लिए चर की गिनती करें
    3. शत्रु की मृत्यु पर, इसे नीचे गिनें
    4. जब 0, दृश्य बदलें

    तो हम इसे कैसे कोडित करते हैं?

    ठीक है, हर दुश्मन को उस वस्तु का संदर्भ चाहिए जो गिनती रखती है। आप इसे कई तरीकों से कर सकते हैं, जब मैं व्यक्तिगत रूप से करता हूं तो मेरे पास आमतौर पर सिर्फ एक स्पॉर्नर होता है जो सभी के लिए जिम्मेदार होता है इसलिए मैं इसे एक सिंगलटन बनाता हूं, जो कि कहीं से भी संदर्भ हो सकता है:

    EnemySpawner

    public class EnemySpawner : MonoBehaviour 
    {
        public static Spawner Instance = null;
        int CurrentNumOfEnemies = 0;
        // ... etc
    
        void Start() 
        {
            if (Instance == null)
                 Instance = this;
    
            // Spawn enemies like you do already, CurrentNumOfEnemies++ for every spawned
        }
    
        public OnEnemyDeath() {
            CurrentNumOfEnemies--;
            if (CurrentNumOfEnemies < 1) 
            {
                // You killed everyone, change scene: 
                LevelManager.LoadLevel("Your Level");
            }
        }
    
    }
    

    शत्रु लिपि (मुझे नहीं पता कि आपका वर्तमान कोड कैसा दिखता है, लेकिन यहां मैं कैसे THINK आपका कोड दिखता है) के आधार पर एक न्यूनतम समाधान है:

    void OnDestroy() 
    {
        // This will run automatically when you run Destroy() on this gameObject
        EnemySpawner.Instance.OnEnemyDeath(); // Tell the EnemySpawner that someone died
    }
    

    यह केवल तभी काम करेगा जब आपके पास वास्तव में केवल एक स्पॉर्नर होगा। यदि आपके पास कई लोग हैं, तो आपको अपने स्पैनर के उदाहरण को प्रत्येक स्पॉन्ड दुश्मन को भेजना होगा। यदि आप चाहें तो मैं आपको यह भी दिखा सकता हूं कि ths कैसे करना है।


    बोनस सामग्री

    LevelManager को GameObject पर होने की आवश्यकता नहीं है, यह इसके बजाय स्थिर हो सकता है:

    1. किसी भी GameObject से LevelManager स्क्रिप्ट निकालें
    2. अपना LevelManager कोड इसमें बदलें:
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    public static class LevelManager 
    {
        public static void LoadLevel(string name)
        {
            Debug.Log("Level loading requested for" + name);
            SceneManager.LoadScene(name);
        }
    }
    

    अब आप इसे किसी भी स्क्रिप्ट या GameObject के संदर्भ को प्रारंभ करने की आवश्यकता के बिना, कहीं से भी उपयोग कर सकते हैं:

    LevelManager.LoadLevel("My Level");
    
        
    2
    2019-05-08 13: 08: 34Z
    1. धन्यवाद, आपके समय और मदद के लिए फ्रेड्रिक, मैं समझता हूं कि आप जो कह रहे हैं लेकिन फिर भी, कोडिंग वास्तव में मेरा मजबूत सूट नहीं है, क्या आप मुझे बता सकते हैं कि मेरे पास क्या है कोड में परिवर्तन या जोड़ने के लिए? धन्यवाद
      2019-05-08 12: 29: 25Z
    2. मैंने EnemySpawner script void OnCollisionEnter2D (Collision col) {if (col.gameObjectject .name == "दुश्मन 1") {नष्ट करें (कॉल) के लिए निम्न कोड जोड़ा। gameObject); CurrentNumOfEnemies ++; } मुझे नहीं पता कि मैं क्या करने के लिए मान गया था, लेकिन मैं अभी भी काम नहीं कर रहा हूं
      2019-05-08 12: 40: 11Z
    3. मैंने वास्तव में दूसरे दिन यह सटीक फीचर किया था, यहां स्रोत कोड
      है
      2019-05-08 12: 50: 40Z
    4. लेकिन मैं देखूंगा कि मैं आपकी क्या मदद कर सकता हूं। कृपया अपना शत्रु कोड जोड़ें (यदि आपके पास कोई है)
      2019-05-08 12: 51: 29Z
    5. आह, मैं अब आपका EnemyShooter कोड देखता हूं। आप इसे इसके स्थान पर जोड़ सकते हैं, 0600350991100101035062 कोड में, बस DestroyEnemy() जोड़ें और मेरे 0600350991100101035062 कोड को अनदेखा करें। मुझे बताएं कि क्या आप चाहते हैं कि मैं अपना उत्तर संपादित करूं और आपको अपना कोड कैसे संपादित करना चाहिए।
      2019-05-08 14: 03: 44Z

      EnemySpawner.Instance.OnEnemyDeath(); को कभी भी निष्पादित नहीं किया जाता है, क्योंकि आप ऊपर दिए गए टेस्ट में ऑब्जेक्ट को नष्ट कर देते हैं।

          
      2
      2019-05-08 12: 13: 10Z
      1. जरूरी नहीं कि सच हो; गंतव्य वस्तु को तुरंत नष्ट नहीं करता है ( यहां और अधिक पढ़ें - लेकिन वैचारिक रूप से यह एक त्रुटिपूर्ण तर्क संकेत कर सकता है।
        2019-05-08 12: 14: 33Z
      2. साभार फ्रेड्रिक; अभी के लिए, मैं जवाब देता हूं कि यह ओपी को मदद करेगा।
        2019-05-08 12: 15: 48Z
      3. यह सही उत्तर हो सकता है, हालांकि अगले फ्रेम से पहले दृश्य बदलने वाले तर्क को निष्पादित नहीं किया जा सकता है। नष्ट होने पर समय निर्धारित करके इसे आसानी से डीबग किया जा सकता है: OnDestroy
        2019-05-08 12: 17: 41Z
      4. मैंने नष्ट कर दिया (this.gameObject); लेकिन फिर भी, कुछ भी नहीं हो रहा है
        2019-05-08 12: 20: 45Z
      5. मैंने नाश (gameObject, 1) जोड़ा; नष्ट करने के बजाय (this.gameObject); लेकिन दृश्य अभी भी लोड नहीं हो रहा है।
        2019-05-08 12: 23: 45Z
        myLevelManager.LoadLevel("NextLevelMenu");
स्रोत रखा गया यहाँ