为什么在设置执行脚本的顺序时仍然首先执行一个脚本?

Dan*_*Lip 1 c# unity-game-engine unity5

我有两个脚本附加到同一个emptygameobject.第一个脚本是:

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

public class SpawnObjects : MonoBehaviour
{
    public int numberOfObjects;
    public GameObject objectToPlace;
    public Vector3 newObjectsSize = new Vector3(5, 5, 5);
    public float spawnSpeed = 0.1f;

    private int wallsLengthX;
    private int wallsLengthZ;
    private int wallsPosX;
    private int wallsPosZ;
    private int currentObjects;
    private List<GameObject> objects = new List<GameObject>();

    void Start()
    {
        var wi = GetComponent<Walls>();
        wallsLengthX = (int)wi.lengthX;
        wallsLengthZ = (int)wi.lengthZ;
        wallsPosX = (int)wi.wallsStartPosition.x;
        wallsPosZ = (int)wi.wallsStartPosition.z;

        StartCoroutine(Spawn());
    }

    IEnumerator Spawn()
    { 
        for (int i = 0; i < numberOfObjects; i++)
        {
            GameObject newObject = (GameObject)Instantiate(objectToPlace);
            newObject.transform.localScale = new Vector3(newObjectsSize.x, newObjectsSize.y, newObjectsSize.z);
            newObject.transform.localPosition = GenerateRandomPositions(newObject);
            newObject.name = "Spawned Object";
            newObject.tag = "Spawned Object";
            objects.Add(newObject);
            yield return new WaitForSeconds(spawnSpeed);
            currentObjects += 1;
        }
    }

    private Vector3 GenerateRandomPositions(GameObject newObject)
    {
        float paddingX = Mathf.Clamp(newObject.transform.localScale.x, 0, wallsLengthX) / 2f;
        float paddingZ = Mathf.Clamp(newObject.transform.localScale.z, 0, wallsLengthZ) / 2f;
        float originX = wallsPosX + paddingX - wallsLengthX / 2f;
        float originZ = wallsPosZ + paddingZ - wallsLengthZ / 2f;
        float posx = UnityEngine.Random.Range(originX, originX + wallsLengthX - paddingX);
        float posz = UnityEngine.Random.Range(originZ, originZ + wallsLengthZ - paddingZ);
        float posy = Terrain.activeTerrain.SampleHeight(new Vector3(posx, 0, posz));

        return new Vector3(posx, posy, posz);
    }
}
Run Code Online (Sandbox Code Playgroud)

第二个脚本:

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

public class WayPoints : MonoBehaviour
{
    public GameObject[] waypoints;
    public Transform target;
    public float moveSpeed = 10f;
    public float moveSpeed1 = 10f;
    public float slowDownSpeed = 3f;
    public float reverseSlowDownSpeed = 3f;
    public float rotationSpeed = 1f;

    private Transform myTransform;
    private int targetsIndex = 0;
    private Vector3 originalPosition;
    private GameObject[] robots;

    public Transform reverseTarget;
    private int reverseTargetsIndex = 0;
    private Vector3 reverseOriginalPosition;

    public bool random = false;

    void Awake()
    {
        myTransform = transform;
    }
    // Use this for initialization
    void Start()
    {
        waypoints = GameObject.FindGameObjectsWithTag("Spawned Object");
Run Code Online (Sandbox Code Playgroud)

第一个脚本产生新的10个立方体.但是第二个脚本waypoints变量只获得1个"Spawned Object",而不是10个.

当我使用断点时,我看到它正在执行第一个在循环中执行的脚本:

for (int i = 0; i < numberOfObjects; i++)
Run Code Online (Sandbox Code Playgroud)

但后来它跳到第二个脚本获得一个"Spawned Object",然后回到第一个脚本并完成其余的循环.

而我想要的是它将首先使整个循环产生10个立方体,以便用第二个脚本获取它们.

我甚至在编辑器中做过:编辑>项目设置>脚本执行顺序但是它仍然没有首先完成整个循环只有一次迭代.

Fog*_*zie 5

你有一个Spawn()coroutine 的收益率:

yield return new WaitForSeconds(spawnSpeed);
Run Code Online (Sandbox Code Playgroud)

Start()功能被称为以正确的顺序,但第一个脚本刚开始每次迭代后产生协同程序.在第一次收益之后,它将等待继续直到WaitForSeconds结束; 在平均时间,第二个脚本将运行它Start().

作为一种解决方案,您无法通过脚本执行顺序来解决此问题.您的第二个脚本必须等到第一个脚本运行其Spawn()协程完成.有很多方法可以做到这一点,但最简单的方法是暴露Coroutine返回的对象StartCoroutine()bool DoneSpawningSpawnObjects类中制作类似标志的东西.