【问题标题】:Unity3d. Get same component for duplicated GameObject统一3d。为重复的游戏对象获取相同的组件
【发布时间】:2017-07-21 20:02:38
【问题描述】:

我有一个游戏对象 (myObject) 和一个附加在该游戏对象 (myComponent) 某处的组件。

我复制了游戏对象:

var duplicate = Instantiate(myObject);

然后我想引用相同的组件,但在我的duplicate gameObject 上。

有没有办法在重复的对象上获取相同的组件?
我尝试按索引获取组件,但不适用于游戏对象的层次结构。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    您可以制作组件的副本,但由于组件只能有 1 个父级(游戏对象),这意味着 1 个组件实例不能与 2 个游戏对象共享。

    否则,如果您可以在两个游戏对象上拥有 2 个单独的组件实例,您可以从 gameObject(带有组件)创建预制件并实例化预制件。

    考虑到您可能有多个相同类型的组件,但具有不同的设置(属性),并且您想找到具有相同设置的组件,您必须使用 GetComponents 并遍历结果以查找新的(重复) 组件具有完全相同的设置。

    考虑(为简单起见)您寻找名为 Id 的属性:

    MyComponent myObjectsComponent = ... // here logic to find it, etc
    GameObject duplicate = Instantiate(myObject);
    List<MyComponent> myComponents = duplicate.GetComponents<MyComponent>();
    
    // This can be replaced with bellow LINQ
    MyComponent foundComponent = null;
    foreach(MyComponent c in myComponents) {
      if (c.Id=myObjectsComponent.Id) {
        foundComponent = c;
        break;
      }
    }
    

    您也可以使用 LINQ 来简化循环:

    MyComponent foundComponent = (from c in myComponents where c.Id=myObjectsComponent.Id select c).FirstDefault<MyComponent>();
    

    【讨论】:

    • 1 个组件 == 1 个游戏对象 - 没问题。但是假设我很难计算找到我需要的组件。然后复制根游戏对象。如何在重复的游戏对象上找到相同的(重复的)组件?
    • 据我了解:1.您使用复杂的规则查找组件实例,2.当您找到组件实例时 - 您复制它的游戏对象 3.您想访问相同的组件(类型)在新创建的游戏对象上?
    • 是的,但肯定不是同一类型,因为我可以拥有许多相同类型的组件。也许索引或其他的东西
    【解决方案2】:

    谢谢大家。

    我需要这样的东西:

    public static T GetSameComponentForDuplicate<T>(T c, GameObject original, GameObject duplicate)
        where T : Component
    {
        // remember hierarchy
        Stack<int> path = new Stack<int>();
    
        var g = c.gameObject;
        while (!object.ReferenceEquals(g, original))
        {
            path.Push(g.transform.GetSiblingIndex());
            g = g.transform.parent.gameObject;
        }
    
        // repeat hierarchy on duplicated object
        GameObject sameGO = duplicate;
        while (path.Count != 0)
        {
            sameGO = sameGO.transform.GetChild(path.Pop()).gameObject;
        }
    
        // get component index
        var cc = c.gameObject.GetComponents<T>();
        int componentIndex = -1;
        for (int i = 0; i < cc.Length; i++)
        {
            if (object.ReferenceEquals(c, cc[i]))
            {
                componentIndex = i;
                break;
            }
        }
    
        // return component with the same index on same gameObject
        return sameGO.GetComponents<T>()[componentIndex];
    }
    

    【讨论】:

      【解决方案3】:

      试试这个:

      var duplicate = Instantiate(myObject) as GameObject;
      var componentDup = duplicate.GetComponent<__YOUR_COMPONENT__>();
      

      https://docs.unity3d.com/ScriptReference/GameObject.GetComponent.html

      【讨论】:

      • 这段代码可以返回相同类型的不同组件。但我需要相同的组件
      • 哦,对不起,我认为 Instantiate 方法会在新的游戏对象中创建另一个类和实例,所以......它总是不同的。
      【解决方案4】:

      好的,我也将尝试了解您想要什么...我的解释是您希望在您的 duplicateObject 上引用特定的 myComponent。很好,你可以这样做:

      public class MyObject : MonoBehaviour {
      
          // Create a reference variable for the duplicate to have
          public Component theComponent { get; set; }
      
          void Start()
          {
              // Save the component you want the duplicate to have
              theComponent = GetComponent<Anything>(); 
      
              // Create the duplicate
              var duplicate = Instantiate(gameObject);
      
              // Set the component reference to the saved component
              duplicate.GetComponent<MyObject>().theComponent = theComponent;
          }
      
      }
      

      这样,您应该在对象的所有实例中都引用相同的组件。您也可以只创建一个包含对特定组件的静态引用的脚本,每个脚本都可以在不实例化任何内容的情况下访问该引用。

      using UnityEngine;
      public class DataHolder {
          public static Component theComponent;
      }
      

      【讨论】:

        猜你喜欢
        • 2016-06-29
        • 1970-01-01
        • 2012-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-26
        • 1970-01-01
        • 2022-08-23
        相关资源
        最近更新 更多