【问题标题】:Unity: Several gameObjects in an array(?)Unity:数组中的几个游戏对象(?)
【发布时间】:2017-01-30 04:14:58
【问题描述】:

我正在统一制作这款清版游戏,它具有以下机制:当玩家的对撞机撞到敌人的:

public GameObject obj;
...

void OnTriggerEnter(Collider collider){
obj=collider.gameObject;
}

那么,当玩家攻击时,如果它与obj的距离足够小,敌人就会受到伤害:

void hit(){
    if(kicked&&close){  //if he is kicking and is close enough
        obj.GetComponent<health>().DealDamage(damage); //this is inside a try/catch, just in case obj=null
(...)
}

问题是,如果有 2 个敌人碰到玩家,只有最后一个会被分配给变量 obj,所以他会独自承受打击,这是我不希望发生的。

有什么建议吗?我应该更换吗

GameObject obj;

有一个数组?怎么样?

然后,在 OnTriggerEnter 方法上,将对象添加到数组中? (怎么做?)

【问题讨论】:

  • 数组的大小是不可变的,你需要一个大小可以动态收缩和增长的数据结构。请改用List
  • 如果我使用一个比我需要的更大的数组怎么办?
  • 替代方法 - 使用Physics.OverlapSphere() 之类的方法在攻击时检查玩家攻击范围内的敌人,然后相应地伤害他们(如果有的话)。
  • @DavidSpira 这将取决于你是否可以明确地说出什么是“比你需要的更多”。我不建议只制作一个 10,000 长度的数组,因为那会非常浪费。

标签: c# unity3d gameobject


【解决方案1】:

一个简单的方法是让你的玩家拿着一个触发盒。当敌人进入触发框时,他们会被添加到一个集合中并在退出时移除:

public class PlayerAttack:MonoBehaviour
{
    private HashSet<Enemy> list = null;
    private void Awake(){ this.list = new HashSet<Enemy>(); }
    private void OnTriggerEnter(Collider col)
    {
         Enemy enemy = col.transform.GetComponent<Enemy>();
         if(enemy != null)
         {
             this.list.Add(enemy);  
         } 
    }
    private void OnTriggerExit(Collider col)
    {
         Enemy enemy = col.transform.GetComponent<Enemy>();
         if(enemy != null && this.list.Contains(enemy) == true)
         { 
             this.list.Remove(enemy);  
         } 
    }
    public void OnAttack()
    {
         foreach(Enemy enemy in this.list)
         { 
            enemy.GetComponent<Health>.DealDamage(damage); 
         }
    }
}

OnAttack 是你的攻击方法,它会遍历所有近距离的敌人。 HashSet 是一个很好的候选者,因为它不会添加两次相同的项目,因此不会有看到敌人被多次命中的风险。

【讨论】:

  • 我试过这个,我收到了这个错误消息 Assets/Scripts/movement.cs(16,13): error CS0246: The type or namespace name HashSet1' can not be found。您是否缺少 using 指令或程序集引用? @Everts 这是第 16 行 private HashSet list = null;
  • 顺便说一句,我使用的是 sublime 文本,但我现在意识到 monodevelop 无法识别 HashSet。也许我必须先导入一些东西?
  • 当这种事情发生时,您的第一个解决方案是右键单击错误然后解决。它很可能会建议添加一些 using 指令。在 Visual Studio 中,您可以将光标放在错误和 Ctrl + 上。 (不确定该快捷方式在 MonoDevelop 中是否有效)。在 HashSet 的情况下,您可能缺少 System.Collections.Generic
【解决方案2】:

我没能解决这个问题。伤害永远不会被分配。

private HashSet<Enemy> list = null;

private void Awake(){this.list = new HashSet<Enemy>();}

void OnTriggerEnter(Collider col){

     Enemy enemy = col.transform.GetComponent<Enemy>();
     print(enemy); // this occurs
     if(enemy != null && this.list.Contains(enemy) == true)
     { 
        print(enemy); // this never occurs
         this.list.Remove(enemy);  
     } 
    }
    }


void hit(){      
    print("hit"); // this occurs

    foreach(Enemy enemy in this.list)
     {   // this never occurs
        enemy.GetComponent<health>().DealDamage(damage); 
     }

@Everts

【讨论】:

    【解决方案3】:

    您拥有屏幕上所有对象的列表,如敌人、树木、盒子等。
    在无限循环中,您对所有对象执行一些操作:

    while(true)
    {
        // Here non combat characters do something.
        foreach(NonCombatCharacter character in NonCombatCharacters)
        {
            switch(character.Type)
            {
                case tinyBird: character.DoAction(Actions.Fly); break;
                case ...
                default:break;
            }
        }
        // Here your combat character aka enemies
        foreach(CombatCharacter character in CombatCharacters)
        {
            // Here you do your combat logic, cheks and etc.
        }
        // And then you player character change the world model, here you
        // process all player action such as changing position, losing hp.
        // And then world keep lifecycle again
    }
    

    编辑:所以每个对象都有全局数组。即使您不创建数组,您也可以统一获得它们。
    给你:
    https://docs.unity3d.com/ScriptReference/Object.FindObjectsOfType.html
    使用文档,大多数常见的答案都在那里。

    【讨论】:

    • 这并不能真正回答问题。
    • 如果您“明白了”,请实际回答。这解释了基础知识。我是编辑答案以便更好地理解。
    • 就像埃文所说,这并不能回答 OP 的问题。该数组不适用于跟踪整个世界中的所有实体。它是用于跟踪和处理最新对象碰撞的参考数组。这种方法不仅会过度杀伤力,而且也无法解决他的问题。 (还有while(true)?认真的吗?)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多