首页 > 解决方案 > 如何使用滑块从其生成器对象中的生成对象更改属性

问题描述

我有一个附有脚本 ( Defender) 的对象。这个脚本有一个defRadius属性。此外,我使用以下代码在一个圆圈中生成我的对象:

CircleSpawn

public class CircleSpawn : MonoBehaviour
{
    public float radius, radiusLast, spin, spinLast;
    public int numOfItems;
    public GameObject clonedObject;
    public List<GameObject> spawnedObjects;
}

CircleSpawnEditor

[CustomEditor(typeof(CircleSpawn))]
public class CircleSpawnEditor : Editor
{
public override void OnInspectorGUI ()
{
    var tar = (CircleSpawn)target;    
    EditorGUILayout.LabelField("Radius"); // Set as required
    tar.radius = EditorGUILayout.Slider(tar.radius, 0f, 100f);          
    EditorGUILayout.LabelField("Angle"); // Set as required
    tar.spin = EditorGUILayout.Slider(tar.spin, 0f, 360f);              
    EditorGUILayout.LabelField("Number of Items"); // Set as required
    tar.numOfItems = EditorGUILayout.IntSlider(tar.numOfItems, 0, 36);  
    EditorGUILayout.LabelField("Object");
    tar.clonedObject = (GameObject)EditorGUILayout.ObjectField(tar.clonedObject, 
    typeof(GameObject), true);

    float angle, angleBetween = 360.0f / tar.numOfItems;

    if (tar.spawnedObjects == null)
        tar.spawnedObjects = new List<GameObject>();

    // Solution #1    
    if (tar.spawnedObjects.Count != tar.numOfItems)
    {
        foreach (var ob in tar.spawnedObjects)
            DestroyImmediate(ob);

        tar.spawnedObjects.Clear();
        angle = 0f;

        for (int i = 0; i < tar.numOfItems; i++)
        {
            var rot = Quaternion.Euler(0f, 0f, tar.spin + angle);
            var localPos = rot * Vector3.right * tar.radius;    
            tar.spawnedObjects.Add(Instantiate(tar.clonedObject,
            tar.transform.position + localPos, rot));
            angle += angleBetween;
        }
    }

    // Solutions #2 & 3    
    if (!Mathf.Approximately(tar.spin, tar.spinLast) ||
        !Mathf.Approximately(tar.radius, tar.radiusLast))
    {
        tar.spinLast = tar.spin;
        tar.radiusLast = tar.radius;    
        angle = 0f;

        for (int i = 0; i < tar.numOfItems; i++)
        {
            var rot = Quaternion.Euler(0f, 0f, tar.spin + angle);
            var localPos = rot * Vector3.right * tar.radius;    
            tar.spawnedObjects[i].transform.position = 
            tar.transform.position + localPos;
            tar.spawnedObjects[i].transform.rotation = rot;
            angle += angleBetween;
        }
    }
}
}

如何生成替换为radius(附加到要克隆的对象的脚本的属性)的对象?CircleSpawndefRadiusDefender

标签: c#unity3d

解决方案


要从原始预制中读取和写入值,我们首先保存对新脚本的引用并在原始代码中Defender替换:tar.radius

public class Defender : MonoBehaviour
{
    public float Radius;
}

[CustomEditor(typeof(CircleSpawn))]
public class CircleSpawnEditor : Editor
{
    private Defender _defender;

    public override void OnInspectorGUI ()
    {
        var tar = (CircleSpawn)target;
        tar.clonedObject = (GameObject)EditorGUILayout.ObjectField(tar.clonedObject,
            typeof(GameObject), true);
        if (!tar.clonedObject) return;

        if (!_defender)
        {
            _defender = tar.clonedObject.GetComponent<Defender>();
            if (!_defender) return;
        }

        EditorGUILayout.LabelField("Radius"); // Set as required
        _defender.Radius = EditorGUILayout.Slider(_defender.Radius, 0f, 100f);
        EditorGUILayout.LabelField("Angle"); // Set as required
        tar.spin = EditorGUILayout.Slider(tar.spin, 0f, 360f);
        EditorGUILayout.LabelField("Number of Items"); // Set as required
        tar.numOfItems = EditorGUILayout.IntSlider(tar.numOfItems, 0, 36);
        EditorGUILayout.LabelField("Object");

        float angle, angleBetween = 360.0f / tar.numOfItems;

        if (tar.spawnedObjects == null)
            tar.spawnedObjects = new List<GameObject>();

        // Solution #1
        if (tar.spawnedObjects.Count != tar.numOfItems)
        {
            foreach (var ob in tar.spawnedObjects)
                DestroyImmediate(ob);

            tar.spawnedObjects.Clear();
            angle = 0f;

            for (int i = 0; i < tar.numOfItems; i++)
            {
                var rot = Quaternion.Euler(0f, 0f, tar.spin + angle);
                var localPos = rot * Vector3.right * _defender.Radius;
                tar.spawnedObjects.Add(Instantiate(tar.clonedObject,
                tar.transform.position + localPos, rot));
                angle += angleBetween;
            }
        }

        // Solutions #2 & 3
        if (!Mathf.Approximately(tar.spin, tar.spinLast) ||
            !Mathf.Approximately(_defender.Radius, tar.radiusLast))
        {
            tar.spinLast = tar.spin;
            tar.radiusLast = _defender.Radius;
            angle = 0f;

            for (int i = 0; i < tar.numOfItems; i++)
            {
                var rot = Quaternion.Euler(0f, 0f, tar.spin + angle);
                var localPos = rot * Vector3.right * _defender.Radius;
                tar.spawnedObjects[i].transform.position =
                tar.transform.position + localPos;
                tar.spawnedObjects[i].transform.rotation = rot;
                angle += angleBetween;
            }
        }
    }
}

推荐阅读