列表添加功能未正确执行

时间:2018-06-07 04:00:57

标签: c# unity3d arraylist unityscript

我的代码:

     <?php
session_start();
include ("./PHPExcel/IOFactory.php");
include_once('./PHPExcel/PHPExcel.php');

$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$FileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));

// Allow only Excel doc
if($FileType != "xlsx" && $FileType != "xls" ) {
    $_SESSION['status']= "Only excel(.xls or .xlsx) files are allowed.";
    $uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) 
    $_SESSION['status']="file was not uploaded.";

 else {
    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) 
        $_SESSION['status']="File uploaded";
    else 
      $_SESSION['status']="error uploading your file.";
} ?>

我用一些数据列表创建了一些对象(enemys)的列表,这些数据列表是我使用unity的可编写脚本的对象创建的。这个脚本添加和删除enemys和 这个脚本工作正常,但是当有2个敌人时,很多敌人(同一个游戏对象开始多次添加),当涉及到删除所有数据时,不会被删除,所以即使我杀死了一个敌人,他仍然在场景中。

我的物品数据:

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

public class BattleCore : MonoBehaviour {

public List<GameObject> Enemy = new List<GameObject> ();
public List<EnemyFollow1> EnemyScript =  new List<EnemyFollow1>();
public List<StatData> stat = new List<StatData> ();
public int length;
public bool canMelee = false;
public List<ParticleSystem> ps = new List<ParticleSystem> (); 
public float AttackCooldownT = 0;
public float AttackCooldownTI = 3;

void OnTriggerEnter(Collider other)
{
    Debug.Log("ENTERED!");
    if (other.CompareTag("Enemy"))
    {
        canMelee = true;
        Enemy.Add (other.gameObject);
        for (int i = 0; i < Enemy.Count; i++)
        {
            ps.Add(Enemy[i].GetComponent<ParticleSystem>());
            EnemyScript.Add(Enemy[i].GetComponent<EnemyFollow1>());
            stat.Add(EnemyScript[i].enemyData);
        }
    }
}

void OnTriggerExit(Collider other) {
    if (other.CompareTag("Enemy"))
    {
        canMelee = false;       
        for (int i = 0; i < length; i++)
        {
            if (Enemy[i] == other.gameObject) 
            {
                Enemy.RemoveAt(i);
                stat.RemoveAt(i);
                EnemyScript.RemoveAt(i);
                ps.RemoveAt (i);
            }
        }
    }
}

void Update()
{
    if (canMelee && Input.GetKeyDown(KeyCode.Q) && Time.time > AttackCooldownT && Enemy.Count > 0)
    {
        for (int i = 0; i < Enemy.Count; i++)
        {
            stat[i].HP -= 20;
            ps [i].Play ();
        }
        AttackCooldownT = Time.time + AttackCooldownTI;
    }
}
}

此外,当我试图用相同的统计数据杀死敌人时,两个敌人都死在一起,而我只攻击一个。因为健康是全球性的,都会死亡。我无法弄清楚如何解决它。

在我的敌人跟随我写道:

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

[CreateAssetMenu]
public class StatData : ScriptableObject {

    public string Name;
    public bool Boss;
    public int HP, MaxHP, Atk, MaxAtk, SpAtk, MaxSpAtk, Def, MaxDef, SpDef, MaxSpDef;
    public Sprite sprite;
}

在新游戏中让敌人活着。 请帮忙!

2 个答案:

答案 0 :(得分:1)

这是parallel collections anti-pattern

的示例
Enemy.RemoveAt(i);
stat.RemoveAt(i);
EnemyScript.RemoveAt(i);
ps.RemoveAt (i);

您应该避免这样做,因为它会在您的数组中创建未被任何内容强制执行的依赖项。例如,如果您尝试对其中一个数组进行排序,那么您将打破索引之间的关系。

你应该创建一个&#34;包装器&#34;将这些不同对象绑定在一起的对象,然后只有一个列表。

class EnemyCollator {
    public GameObject go;
    public EnemyFollow1 script;
    public StatData stats;
    public ParticleSystem particles;
}
...
public List<EnemyCollator> allEnemies;

如果您希望您的数据具有查找关系(即&#34;找到与此GameObject相关的数据&#34;),请使用字典:

public Dictionary<GameObject,EnemyCollator> dataLookup;

或使用Linq查询:

GameObject go = allEnemies.Find(x => x.go == someGameObject);

一旦您开始以这种方式组织代码,您可能会遇到的问题就会消失。

答案 1 :(得分:0)

很难理解&amp;阅读你的代码。

但是我确实注意到一些可能对你有帮助的事情。

当您创建一个scriptableobject并将其分配给多个其他脚本/游戏对象时,它们都将引用相同的scriptableobject。因此,改变健康状况将改变调用它的所有对象的健康参考。

有几种解决方法,但我认为最简单的方法是:

在实例化时,将StatData中的变量分配给您的Enemyscript(或者在其中唤醒)

public class EnemyFollow1 : MonoBehaviour
{
    public string Name;
    public bool Boss;
    public int HP, MaxHP, Atk, MaxAtk, SpAtk, MaxSpAtk, Def, MaxDef, SpDef, MaxSpDef;
    public Sprite sprite;

    [SerializeField]
    private StatData statData;

    void Awake()
    {
        Name = statData.Name;
        Boss = StatData.Boss;
        // Etc...
    }
}

现在你总是确定正确的敌人的健康状况被修改了。 你也可以使用你拥有的Gameobjects列表来调用这个脚本所以你不需要“EnemyFollow1列表。

Enemy[i].GetComponentInChildren<EnemyFollow1>().HP -= 20;

// You can remove these
public List<EnemyFollow1> EnemyScript =  new List<EnemyFollow1>();
public List<StatData> stat = new List<StatData> ();

我也不确定你是否理解这一点。但是从列表中删除GameObject并不会破坏它! 因此,如果你想在 中删除一个游戏对象 ,请使用

Destroy(Enemy[i]);