检查脚本附加的每个游戏对象的变量值

Posted

技术标签:

【中文标题】检查脚本附加的每个游戏对象的变量值【英文标题】:Check value of a variable from every gameobject that attached by a script 【发布时间】:2016-09-19 00:42:01 【问题描述】:

我有一个名为“student”的游戏对象,它附加了一个脚本,然后我手动复制它(ctrl+D),这样每个复制的学生对象都具有相同的脚本组件。这是脚本(因为太长,不完整)

public class StudentScript : MonoBehaviour 

private Animator animator;
float sec;
public int m;
public GameManage gm;

void Start () 
    animator = GetComponent<Animator> ();
    sec = 0f;
    m = 0;


void Update () 
    sec+=Time.deltaTime;
    if (m == 5 && animator.GetInteger ("Behav") == 0) 
        animator.SetTrigger ("Finish");
    


//this is called from another script
public void ResetStudentBehaviour()
    if (animator.GetInteger ("Behav") != 0) 
        animator.SetInteger ("Behav", 0);
        sec = 0f;
        if (m < 5) 
            m++;
        
    else
        Debug.Log ("student done <3");


我想要 => 如果每个学生的 m 值 m == 5,那么游戏结束。到目前为止我所做的是 GameManage 脚本中的 StudentScript(公共,所以我必须手动设置所有实例),然后检查每个学生的 m 值

public StudentScript stu1, stu2;
void Update () 
    if (stu1.m == 5 && stu2.m == 5) 
        StartCoroutine (ChangeScene());
    

IEnumerator ChangeScene()
    yield return new WaitForSeconds (10);
    SceneManager.LoadScene(5);

有没有一种简单的方法可以在不使用if (stu1.m == 5 &amp;&amp; stu2.m == 5) 的情况下检查所有学生对象的 m 值,因为在每个级别中,学生的数量都是不同的,所以我想为所有级别制作一个动态脚本

【问题讨论】:

【参考方案1】:

我会使用 List&lt;&gt; 并将所有 StudentScript 对象添加到其中。然后您可以使用System.LinqAll 方法检查列表中的所有元素。

using System.Linq

//Add all your StudentScript objects to this list
List<StudentScript> studentScripts = new List<StudentScript>();

if(studentScripts.All(x => x.m == 5))

    StartCoroutine (ChangeScene());

这样您可以使用StudentScripts.Add() 添加脚本,它可以是任意大小,并且仍然会检查所有元素。 x =&gt; x.m == 5 部分称为 lambda 表达式(以防你不知道)。它并不像看起来那么恐怖。

如果您不想使用 Linq 和 lambda,那么您可以遍历列表并更新变量。您可以将 if 语句替换为:

private bool isGameOver()

    bool gameOver = true;

    for(int i = 0; i < studentScripts.Count; i++)
    
        if (studentScripts[i].m != 5) 
        
            gameOver = false;
            break;
        
    

  return gameOver;


void Update()

    if (isGameOver()) 
    StartCoroutine (ChangeScene());
    

【讨论】:

我正在处理您答案的第二部分,但您已将其发布。我更喜欢这样,因为一些 linq 函数在 ios 中不起作用,而一些起作用的函数会大量分配内存。剩下的唯一事情是将问题的第二部分放入函数中。也许布尔函数称为isGameOver。这不是必需的,但它会使代码可重用。现在更新函数将有更少的代码。 聪明,我不知道iOS。再次感谢您的知识哈哈。为了完整起见,我会把它放在一个功能中!我认为All 可以记忆吗?我现在就对其进行分析并检查。 @Eeva 您还必须将using System.Collections.Generic; 放在脚本的顶部。 @Eeva 这个答案已经被编辑了很多。我修复了一个愚蠢的错误,程序员也是如此。立即尝试,它应该可以工作。 @gjttt1 我不知道AllorderBy 和其他一些人由于AOT 有问题。无论如何,我通过将函数更改为 bool 来稍微修复代码,然后如果游戏结束则返回。强烈建议您回答中的第二种方法。 GameEngines 中的内存分配一点都不好,尤其是当它们可以避免时。还优化了功能。【参考方案2】:

你可以找到场景中某种类型的所有物体,然后用Linq或类似的方法过滤它们。

StudentScript[] studentsInScene = Object.FindObjectsOfType<StudentScript>();

if (studentsInScene.All(student => student.m == 5))

    StartCoroutine(ChangeScene());

FindObjectsOfType 可能不如您自己管理的 List 快(尽管可能如此),但如果这不是您的瓶颈(很可能不是),那么这几行代码会简单得多理解,因此更可取。

【讨论】:

以上是关于检查脚本附加的每个游戏对象的变量值的主要内容,如果未能解决你的问题,请参考以下文章

如何在Visual Studio中检查函数末尾的变量值

检查内联函数内的变量值

“切换”和“如果”条件没有检查我在 PHP 上的变量值 [重复]

执行 bash 脚本时隐藏 Gitlab 管道日志中的变量值

如何使用一个 terraform 脚本和不同的变量值管理多个不同环境的部署

WebBrowser中获得脚本中的变量值