2017-12-19 4 views
0

Ich habe eine große Anzahl von vorgefertigten. Diese prefabs haben mehrere Instanzen des gleichen Skript, das die folgenden Felder enthält:Unity serialisierte Felder Migration

[SerializeField] 
private AudioClip[] _audioClip; 

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

Da ich die Lautstärke der einzelnen Audioclip separat steuern können möchte, würde ich gerne verwenden:

[SerializeField] 
private VolumedAudioClip[] _audioClips; 

Wo:

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

Problem ist, dass, wenn ich es jetzt ändern, die alle die prefabs werden die Verweise auf die a verlieren udio Clips bereits eingestellt.

Ich weiß von FormerlySerializedAs Attribut, es hilft nicht in meinem Fall (nur wenn Sie ein Feld umbenennen).

Meine aktuelle Richtung ist es, ein Editor-Skript zu schreiben, das aus den alten Feldern liest und die Daten in die neuen Felder legt.

glücklich sein würde keine bessere Vorschläge zu hören ...

+0

, dass ein smart (faul) Weg ist, es zu tun. Fügen Sie einfach ein serialisiertes Feld Ihrer benutzerdefinierten Klasse in das Skript ein und führen Sie for-loop aus, um Referenzen der Audioclips mithilfe der Editor-Methode zu kopieren. Sobald Sie fertig sind, löschen Sie einfach Ihre alten Felder. Das sollte gut funktionieren.Lassen Sie mich wissen, wenn Sie Code benötigen –

+0

Das ist genau das, was ich tue. Problem ist, dass das Skript, das dieses Feld enthält, nicht vom Typ MonoBehavior ist, also muss ich Reflektion verwenden, um alle Felder dieser Typen zu erhalten –

+0

welche Art von Skript ist das? –

Antwort

0

Wenn Sie die Flexibilität, eine List<VolumedAudioClip> anstelle des VolumedAudioClip[] zu verwenden Ich habe eine sehr einfache und schnelle Lösung für Sie:

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); 
     } 
    } 
} 

Das Attribut [ContextMenu] fügt die CopyIt() - Methode dem Kontextmenü des Inspektors hinzu. Hier ist, wie Sie es verwenden, als: (I verwendet int[] _audioClip zur Demonstration)

So am Anfang wir die ursprüngliche Anordnung von AudioClip[] _audioClip haben gefüllt und die Liste der List<VolumedAudioClip> _audioClips leer.

The ofiginal array is filled

Nun, wenn Sie in das Kontextmenü (Zahnradsymbol) gehen im Inspektoren unser ContextMenu Punkt „das Array kopieren“ erscheint. (Ist das nicht awesom!)

The context menu method

Nach einem einfachen Klick sehen Sie die Elemente AudioClip[] _audioClip auf die neue Liste kopiert werden List<VolumedAudioClip> _audioClips

The new List with copied content

HINWEIS
Ich schrieb Das ist sehr schnell und es ist sicher nicht perfekt. Wenn Sie also bereits Änderungen an den Volumes vornehmen und diese Funktion erneut verwenden, werden die Lautstärke-Optimierungen verloren gehen Die Liste wird wieder mit dem Standardwert gefüllt.

Also ich würde empfehlen, die Funktion zu verwenden und dann aus Ihrem Skript zu entfernen, so dass Sie nicht versehentlich vermasseln können.

Hoffe, es hilft Ihnen

Verwandte Themen