how to clone several game objects in a way that clone properties of one can be adjusted to match all others in scene view

后端 未结 8 900
执念已碎
执念已碎 2020-12-11 15:29

I asked How can I adjust shape/dimensions of one clone to affect all other clones in the scene view and the accepted answer was spot on. It could only clone one game object.

相关标签:
8条回答
  • 2020-12-11 15:34

    make all items that need scaling children of an empty called WorldObjects then scale the world object, it will scale all its children accordingly. you can then either manually or through script remove the parent to make objects independent. best way without prefabs...

    0 讨论(0)
  • 2020-12-11 15:41

    I don’t want to use prefabs

    The new prefab system in Unity is exactly what you need. It fits all of your requirements:

    • Clone several unique game objects

      The prefab system is made for cloning unique gameobjects. It even supports prefab nesting.

    • I don't want to achieve this at runtime

      Great, prefabs only update globally when you click the override button in the editor.

    • I need a way to turn off the this repeated property/component replication on each clone

      That's equivalent to unpacking the object (breaking the connection).

    If you have a good reason to avoid using prefabs, you can always write a custom script that tracks changes in the properties you want to share, and updates all other objects immediately. You can make that script run in edit mode by adding the [ExecuteInEditMode] attribute to the class it's in, just don't forget to disable it when running the project. Again, I highly recommend using prefabs instead.

    0 讨论(0)
  • 2020-12-11 15:46

    Is this only for editing the objects in the editor? If so, then it sounds like prefabs are the way to go; you can directly edit the prefab and all of its 'clones' in the scene will have all changes, including all monobehaviours, transforms, and whatnot replicated to that of the prefab.

    If you need this to work at runtime, then you will likely need some code to do this for you. You haven't quite provided enough clarification as to what exactly you want to do, so for the below example I'll assume that you have a gameobject with a mesh or sprite component, and want its size/scale modified alongside all of its "clones";

    using UnityEngine;
    using System.Collections.Generic;
    
    public class ShapeClone : MonoBehaviour
    {
        //This will hold references to the other "clone" gameobjects.
        public List<GameObject> otherClones = new List<GameObject>();
    
        //All the "clones" in the list otherClones will have their scale matched to this gameobject's scale
        public bool leader;
    
    
        private void Update()
        {
            if (leader) //Only change other clones' scales if marked as leader, to avoid every single clone
                        //overriding each other's scale every single frame, which could be rather chaotic
            {
                for (int i = 0; i < otherClones.Count; i++)
                {
                    //setting each of the other clones' scale to that of this object.
                    otherClones[i].transform.localScale = this.transform.localScale;
                }
            }
        }
    }
    

    The above is a brief example to give you an idea and is by no means extensive, but you should be able to apply it to what you're trying to do; for example, if you wanted to replicate the colour of sprites across gameobjects instead, you can modify otherClones to be a list of Sprite references instead, and instead of setting the scale in update, you can set the colour of each of the Sprite components to that of this object.

    If you're only needing this functionality in the editor and not during runtime, though - I highly recommend going with the first option using prefabs, as it will give you far more functionality at a fraction of the cost, performance wise.

    0 讨论(0)
  • 2020-12-11 15:51

    You should use a ScriptableObject as data container and attach that to the gameobject, all clones will use the same synchronized ScriptableObject.

    0 讨论(0)
  • 2020-12-11 15:54

    It sounds like you have an object that has several clones. You want changing the shape or dimensions of any of those objects to affect the other ones?

    For this to happen, each object needs to know about the other ones. You can do this decentralized (each object contains a reference to each other) or centralized (one object governs the rest).

    The centralized approach is more simple so I'll give a simple example.

    public class Shape
    {
        public int length;
    }
    
    public class ShapeCentral
    {
        public List<Shape> shapes = new List<Shape>();
    
        public void CloneShape()
        {
            //instantiate new shape
            shapes.Add(new Shape());
        }
    
        public void SetCloneLength(int l)
        {
            shapes.ForEach(x => x.length = l);
        }
    }
    

    As you can see, one object can control all the clones at once. The trick is to not create clones using other methods or you will run into trouble.

    If you want to tighten up your variable access (which I recommend, its a good exercise) you could use a publisher/subscriber pattern. In this, when a new clone is instantiated, it subscribes to the SetCloneLength method. When you want to change the length, the central class publishes that message and it is sent to all the subscribers.

    The difference here is that in my example, the central class needs to keep track of all the clones, in publisher/subscriber, you don't.

    0 讨论(0)
  • 2020-12-11 15:58

    You should use events. Unity3d tutorials has a good, simple explanation: https://unity3d.com/learn/tutorials/topics/scripting/events

    0 讨论(0)
提交回复
热议问题