【问题标题】:Unity serialized fields migrationunity 序列化字段迁移
【发布时间】:2017-12-19 08:43:16
【问题描述】:

我有大量的预制件。这些预制件具有相同脚本的多个实例,其中包含以下字段:

[SerializeField]
private AudioClip[] _audioClip;

[SerializeField, Range(0, 1)]
private float _volume = 1;

由于我希望能够单独控制每个音频剪辑的音量,我想使用:

[SerializeField]
private VolumedAudioClip[] _audioClips;

地点:

[Serializable]
public class VolumedAudioClip
{
    [SerializeField]
    public AudioClip _audioClip;
    [SerializeField, Range(0, 1)]
    public float _volume = 1;
}

问题是,如果我现在更改它,所有预制件都将丢失对已设置的音频剪辑的引用。

我知道FormerlySerializedAs 属性,在我的情况下它没有帮助(仅当您重命名字段时)。

我目前的方向是编写一个编辑器脚本,该脚本将从旧字段中读取并将数据放入新字段中。

很高兴听到任何更好的建议...

【问题讨论】:

  • 这是一种聪明(懒惰)的方法。只需在脚本中添加自定义类的序列化字段并运行 for-loop 以使用编辑器方法复制音频剪辑的引用。完成后,只需删除旧字段。这应该可以正常工作。如果您需要代码,请告诉我
  • 这正是我正在做的。问题是持有这些字段的脚本不是 MonoBehavior 类型,所以我必须使用反射来获取这些类型的所有字段
  • 它是什么类型的脚本?
  • 哦,在我的回答之后阅读评论,这不是 MonoBehavior .. 以及 Umair M 已经问过它是什么,以及你是如何将其他值添加到数组中的?只有从 MonoBehavior 派生的类才能添加为预制件/游戏对象上的组件

标签: unity3d serialization


【解决方案1】:

如果您可以灵活地使用List<VolumedAudioClip> 而不是VolumedAudioClip[],我有一个非常简单快速的解决方案供您使用:

using System.Collections.Generic;
using System;
using UnityEngine;

public class test : MonoBehaviour
{

    [SerializeField]
    private AudioClip[] _audioClip;

    [SerializeField, Range(0, 1)]
    private float _volume = 1;

    [Serializable]
    public class VolumedAudioClip
    {
        [SerializeField]
        public AudioClip_audioClip;
        [SerializeField, Range(0, 1)]
        public float _volume = 1;

        public VolumedAudioClip(AudioClip clip)
        {
            _audioClip = clip;
        }
    }

    [SerializeField]
    private List<VolumedAudioClip> _audioClips;

    //THIS ADDS A CONTEXT MENU BUTTON TO THE INSPECTOR!
    [ContextMenu("Copy the array")]
    private void CopyIt()
    {
        //To make sure we don't add things multiple times
        _audioClips.Clear();

        //Than just insert the items from the original array
        foreach (AudioClip clip in _audioClip)
        {
            VolumedAudioClip newClip = new VolumedAudioClip(clip);
            _audioClips.Add(newClip);
        }
    }
}

[ContextMenu] 属性将 CopyIt() 方法添加到 Inspector 的上下文菜单中。以下是你的使用方法:(我使用int[] _audioClip 进行演示)

所以一开始我们填充了AudioClip[] _audioClip 的原始数组,而List&lt;VolumedAudioClip&gt; _audioClips 的列表为空。

现在,如果您转到 Inspector 中的上下文菜单(齿轮图标),则会显示我们的 ContextMenu 项“复制数组”。 (这是不是很棒!)

简单点击后,您会看到AudioClip[] _audioClip 的元素被复制到新列表List&lt;VolumedAudioClip&gt; _audioClips

注意
我写得很快,它肯定不是完美的,所以如果你已经对音量进行了调整,然后再次使用这个功能,音量调整将会丢失,因为列表再次填充了默认值。

所以我会推荐使用这个函数,而不是将它从你的脚本中删除,这样你就不会意外地搞砸了。

希望对您有所帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    • 2019-07-28
    • 2011-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多