代码之家  ›  专栏  ›  技术社区  ›  Daniel Lip

在编辑模式下收到许多警告:在Awake、CheckConsistency或OnValidate期间无法调用SendMessage(多维数据集(克隆):OnDidAddComponent)

  •  0
  • Daniel Lip  · 技术社区  · 2 年前

    我希望脚本在编辑模式和运行时模式下都能工作, 但我收到了许多带有相同信息的警告:

    SendMessage cannot be called during Awake, CheckConsistency, or OnValidate (Cube(Clone): OnDidAddComponent)
    UnityEngine.GameObject:AddComponent<CurvedLinePoint> ()
    GenerateLines:CreateCubeAtPosition (UnityEngine.Vector3) (at Assets/Scripts/GenerateLines.cs:91)
    GenerateLines:GeneratePositions () (at Assets/Scripts/GenerateLines.cs:66)
    GenerateLines:GenerateIfNeeded () (at Assets/Scripts/GenerateLines.cs:36)
    GenerateLines:OnValidate () (at Assets/Scripts/GenerateLines.cs:23)
    

    我在Unity的论坛上看到了很多关于它的帖子,但没有看到任何解决方案。也许我需要创建一个编辑器脚本,使其也能在 edit mode ? 我的意思是编辑器脚本可能是正确的方式,而不是使用 [ExecuteInEditMode] 属性

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    [ExecuteInEditMode]
    public class GenerateLines : MonoBehaviour
    {
        public List<Vector3> positions = new List<Vector3>();
        public int amountOfPositions = 30;
        public int minRandRange, maxRandRange;
        public bool randomPositions = false;
        public bool generateNewPositions = false;
        public GameObject cubePrefab; // Assign a prefab with the CubeScript already attached if needed
    
        // Start is called before the first frame update
        void Awake()
        {
            GenerateIfNeeded();
        }
    
        private void OnValidate()
        {
            GenerateIfNeeded();
        }
    
        private void GenerateIfNeeded()
        {
            // If we're in play mode, do not execute any further (optional)
            if (Application.isPlaying)
            {
                return;
            }
    
            if (generateNewPositions || (positions.Count == 0 && amountOfPositions > 0))
            {
                GeneratePositions();
                generateNewPositions = false; // Reset flag to prevent constant regeneration
            }
        }
    
        private void GeneratePositions()
        {
            // First, destroy all existing children to prevent duplicates
            foreach (Transform child in transform)
            {
                // This line is for edit mode. In play mode, you would use Destroy.
                DestroyImmediate(child.gameObject);
            }
            positions.Clear();
    
            for (int i = 0; i < amountOfPositions; i++)
            {
                Vector3 position;
                if (randomPositions)
                {
                    var randPosX = UnityEngine.Random.Range(minRandRange, maxRandRange);
                    var randPosY = UnityEngine.Random.Range(minRandRange, maxRandRange);
                    var randPosZ = UnityEngine.Random.Range(minRandRange, maxRandRange);
                    position = new Vector3(randPosX, randPosY, randPosZ);
                }
                else
                {
                    position = new Vector3(i, i, i);
                }
                positions.Add(position);
                CreateCubeAtPosition(position);
            }
        }
    
        private void CreateCubeAtPosition(Vector3 position)
        {
            // Create the cube GameObject
            GameObject cube;
            if (cubePrefab != null)
            {
                // Instantiate cube from prefab
                cube = Instantiate(cubePrefab, position, Quaternion.identity, this.transform); // Set the parent to this object's transform
            }
            else
            {
                // Create a new primitive cube
                cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
                cube.transform.position = position;
                cube.transform.localScale = Vector3.one; // Set the scale to 1,1,1
    
                // Set the parent of the cube to this object's transform
                cube.transform.SetParent(this.transform, false);
            }
    
            // Add the CurvedLinePoint component to the cube
            cube.AddComponent<CurvedLinePoint>();
        }
    }
    
    2 回复  |  直到 2 年前
        1
  •  1
  •   Ali Bendaoud    2 年前

    你的变量我还没有在唤醒时初始化,这是有可能的。

        2
  •  0
  •   IDBB    2 年前

    遗憾的是,你无法使用 AddComponent 方法中的方法 Awake , CheckConsistency OnValidate 在里面 edit mode 。我会考虑分配 boolean true 在里面 OnValidate 并在中调用所需的方法 LateUpdate ,还将布尔值赋值回 false .

    bool generateIfNeeded = false;
    
    private void OnValidate()
    {
        generateIfNeeded = true;
    }
    
    private void LateUpdate()
    {
        if (generateIfNeeded)
        {
            generateIfNeeded = false;
    
            GenerateIfNeeded();
        }
    }