统一列表

smokereaper98

会员
已加入
2019年11月16日
留言内容
12
编程经验
1-3
我有一个空的对象,它是场景中的生成器,并且我希望它每隔x倍的时间生成一个随机的预制件。.我使用此代码,但无法弄清楚..我肯定有一种更简单的创建方法来自数组的随机调用。


C#:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class obstacleSpawner : MonoBehaviour
{
    //vars
    public Rigidbody rb;
    public float ForwardForce;
    public GameObject Obstacle2;
    public GameObject Obstacle1;
    private Vector3 test;
    //lists
    public List<string> obstacles = new List<string>();



    void Start()
    {
        obstacles.Add("Obstacle1");
        obstacles.Add("Obstacle2");
        InvokeRepeating("spawnObstacle", 3f, 3f);
    }

    void Update()
    {
        rb.velocity = new Vector3(rb.velocity.y, rb.velocity.y, ForwardForce);
    }
    


    void spawnObstacle()
    {
        System.Random r = new System.Random();
        int genRand = r.Next(1, 2);

        test = new Vector3(10.47f, 0.4096543f, transform.position.z);
        Instantiate(obstacles[r], test, transform.rotation);
    }
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
您的问题可能出在用户界面中。上面的脚本将要求您的生成对象通过组件管理器进行连接。

选择您的游戏生成对象,然后提供您保存的脚本,将脚本从文件夹中拖入组件管理器。这就是您要通过Unity UI连接脚本的方式。但是,我通常会创建一个层次结构的场景管理器对象,然后在"现场",将场景管理器移到顶部,并将该场景的所有脚本添加到该游戏对象。无论如何,请参见屏幕截图:

截图_47.jpg


你为什么有这个:
C#:
Instantiate(obstacles[r], test, transform.rotation);
您应该在start void内部进行初始化,因为它甚至可以在文档中告诉您 Unity-手册:创建和使用脚本
您创建的那个方法甚至没有被使用:void spawnObstacle()

主题所属 第三方产品
 

smokereaper98

会员
已加入
2019年11月16日
留言内容
12
编程经验
1-3
您的问题可能出在用户界面中。上面的脚本将要求您的生成对象通过组件管理器进行连接。

选择您的游戏生成对象,然后提供您保存的脚本,将脚本从文件夹中拖入组件管理器。这就是您要通过Unity UI连接脚本的方式。但是,我通常会创建一个层次结构的场景管理器对象,然后在"现场",将场景管理器移到顶部,并将该场景的所有脚本添加到该游戏对象。无论如何,请参见屏幕截图:

查看附件719

你为什么有这个:
C#:
Instantiate(obstacles[r], test, transform.rotation);
您应该在start void内部进行初始化,因为它甚至可以在文档中告诉您 Unity-手册:创建和使用脚本
您创建的那个方法甚至没有被使用:void spawnObstacle()

主题所属 第三方产品
第23行使用了spawnObstacle void
C#:
 InvokeRepeating("spawnObstacle", 3f, 3f);
我要做的事情是使用一个随机生成的数字从数组中调用一个随机项,例如:barriers [RandomNumber]。那可能吗?
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
再仔细看看我给你的话。您仍然没有看到问题吗?

对的,这是可能的。但是除非您向它返回了一些东西,否则您不应该留下启动/更新的空白。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
在您的代码中,您有一个列表<string>
C#:
public List<string> obstacles = new List<string>();
在你的方法中:
void spawnObstacle(),您尝试使用random获得这些对象之一,并将列表视为字符串数组之类。随机数也不是字符串或整数,它不是一个类:
C#:
Instantiate(obstacles[r]
如果您确实要搜索列表,可以使用 清单<T>.Find(Predicate<T>)方法(System.Collections.Generic) 和Linq来获取值。
因此,即使您使用了random.Next()分配的int名为genRand。那么这也将是错误的,因为障碍列表是字符串类型,而不是int类型。
尝试按照所需方式编辑此伪代码。我认为您缺少的是可以通过使用获得的一些动态 元组<T1,T2> Class (System)。我在Unity中经常使用元组,因为它们使您能够扩展功能。
C#:
public class obstacleSpawner : MonoBehaviour
{
    //vars
    public Rigidbody rb;
    public float ForwardForce;
    public GameObject Obstacle2;
    public GameObject Obstacle1;
    private Vector3 test;
    //lists
    public List<Tuple<int, string, GameObject>> MyObstacles = new List<Tuple<int,string, GameObject>>();
    void Start()
    {
        MyObstacles.Add(Tuple.Create(0, "Obstacle1", Obstacle1));
        MyObstacles.Add(Tuple.Create(0, "Obstacle2", Obstacle2));
        InvokeRepeating("spawnObstacle", 3f, 3f);
    }
    void Update()
    {
        rb.velocity = new Vector3(rb.velocity.y, rb.velocity.y, ForwardForce);
    }
    void spawnObstacle()
    {
        System.Random r = new System.Random();
        int getRand = r.Next(0, 10);
        test = new Vector3(10.47f, 0.4096543f, transform.position.z);

        foreach (Tuple<int, string, GameObject> t in MyObstacles)
        {
            //NOTE : Not all if statements are required, just choose the one you want to check with, otherwise it will instantiate 3 times.
            /* Does it match the ID? */
            if (t.Item1 == getRand)
            {
                Instantiate(t.Item3, test, transform.rotation);
            }
            /* Does it match the obstacle name? */
            if (t.Item2 == "Obstacle2")
            {
                Instantiate(t.Item3, test, transform.rotation);
            }
            /* Does it match the game object? */
            if (t.Item3 == Obstacle1)
            {
                Instantiate(t.Item3, test, transform.rotation);
            }
        }
    }
}
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
抱歉,我忽略了重复调用API。您还应该知道,如果重复调用的值是0,它将不会为您做任何事情。 ;)

并记住将您的脚本连接到UI中的游戏生成对象,否则它也将不起作用。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
等一下这个 :
C#:
        MyObstacles.Add(Tuple.Create(0, "Obstacle1", Obstacle1));
        MyObstacles.Add(Tuple.Create(0, "Obstacle2", Obstacle2));
应该 :
C#:
        MyObstacles.Add(Tuple.Create(0, "Obstacle1", Obstacle1));
        MyObstacles.Add(Tuple.Create(1, "Obstacle2", Obstacle2));
注意,我从未更改过ID。您应该确保ID以某种方式自动递增。因此,您添加的对象越多,您将需要增加中的整数。

很高兴您发现它适合您的需求。
 
最佳 底部