Skip to content

Instantly share code, notes, and snippets.

@hananoki
Last active March 9, 2020 23:35
Show Gist options
  • Save hananoki/0375c6327557e292791a63835a10c998 to your computer and use it in GitHub Desktop.
Save hananoki/0375c6327557e292791a63835a10c998 to your computer and use it in GitHub Desktop.
AudioClipをリスト表示してクリックでプレビューするやつ
/// Copyright (c) 2020 hananoki
/// This code is released under NYSL Version 0.9982
/// See http://www.kmonos.net/nysl/NYSL.TXT
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using System.Reflection;
using System.IO;
using UnityEditor.IMGUI.Controls;
public class AudioClipViewerWindow : EditorWindow {
public AudioClipViewerWindow m_window;
public AudioClipTreeView m_audioClipTreeView;
[MenuItem( "Window/AudioClipViewer" )]
public static void Open() {
var window = GetWindow<AudioClipViewerWindow>();
window.titleContent = new GUIContent( "AudioClipViewer" );
}
void OnGUI() {
if( m_audioClipTreeView == null) {
m_audioClipTreeView = new AudioClipTreeView();
m_audioClipTreeView.RegisterFiles();
m_audioClipTreeView.Reload();
}
m_audioClipTreeView.OnGUI( new Rect( 0, 0, position.width, position.height ) );
}
}
[Serializable]
public class AudioClipTreeViewItem : TreeViewItem {
public AudioClip audioClip;
}
public class AudioClipTreeView : TreeView {
public List<TreeViewItem> currentBindingItems;
AudioClip s_playAudioClip;
Texture2D AudioClipIcon;
public AudioClipTreeView( ) :
this(
new TreeViewState(),
new MultiColumnHeader(
new MultiColumnHeaderState(
new[] {
new MultiColumnHeaderState.Column() {
headerContent = new GUIContent( "Name" ),
},
new MultiColumnHeaderState.Column() {
headerContent = new GUIContent( "FilePath" ),
},
}
)
) ) {
}
public AudioClipTreeView( TreeViewState state, MultiColumnHeader multiColumnHeader )
: base( state, multiColumnHeader ) {
rowHeight = 18;
showAlternatingRowBackgrounds = true;
multiColumnHeader.ResizeToFit();
var lst = Resources.FindObjectsOfTypeAll<Texture2D>().Where( x => x.name.Contains( "AudioClip Icon" ) ).ToArray();
if( 1 <= lst.Length ) AudioClipIcon = lst[ 0 ];
//multiColumnHeader.height = 22;
}
public void RegisterFiles() {
var root = new TreeViewItem { depth = -1 };
var children = new List<TreeViewItem>();
int id = 0;
foreach( var p in AssetDatabase.FindAssets( "t:AudioClip" ) ) {
children.Add( new AudioClipTreeViewItem {
id = id,
audioClip = AssetDatabase.LoadAssetAtPath<AudioClip>( AssetDatabase.GUIDToAssetPath( p ) ),
} );
id++;
}
currentBindingItems = children;
root.children = currentBindingItems as List<TreeViewItem>;
}
protected override TreeViewItem BuildRoot() {
var root = new TreeViewItem { depth = -1 };
if( currentBindingItems == null || currentBindingItems.Count == 0 ) {
var children = new List<TreeViewItem>();
currentBindingItems = children;
}
root.children = currentBindingItems as List<TreeViewItem>;
return root;
}
protected override void SingleClickedItem( int id ) {
//base.ContextClickedItem( id );
var item = ( (AudioClipTreeViewItem) rootItem.children.Find( x => x.id == id ) );
if( s_playAudioClip != null ) {
StopClip( s_playAudioClip );
s_playAudioClip = null;
}
PlayClip( item.audioClip, 0, false );
s_playAudioClip = item.audioClip;
// 2019.1以前のバージョンはSelection.activeObjectすると内部的にStopClipが呼ばれている気がする
// 気になる場合は以下を消せばクリック選択で音が鳴るようになる
Selection.activeObject = s_playAudioClip;
}
protected override void RowGUI( TreeView.RowGUIArgs args ) {
var item = (AudioClipTreeViewItem) args.item;
for( var visibleColumnIndex = 0; visibleColumnIndex < args.GetNumVisibleColumns(); visibleColumnIndex++ ) {
var rect = args.GetCellRect( visibleColumnIndex );
var columnIndex = args.GetColumn( visibleColumnIndex );
var labelStyle = args.selected ? EditorStyles.whiteLabel : EditorStyles.label;
switch( columnIndex ) {
case 0:
EditorGUI.LabelField( rect, new GUIContent( item.audioClip.name, AudioClipIcon ), labelStyle );
break;
case 1:
EditorGUI.LabelField( rect, Path.GetDirectoryName( AssetDatabase.GetAssetPath( item.audioClip ) ), labelStyle );
break;
default:
break;
//throw new ArgumentOutOfRangeException( "columnIndex", columnIndex, null );
}
}
}
const BindingFlags AllMembers = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
delegate void Method_PlayClip( UnityEngine.AudioClip clip, int startSample = 0, bool loop = false );
static Method_PlayClip __PlayClip;
public static void PlayClip( UnityEngine.AudioClip clip, int startSample, bool loop ) {
if( __PlayClip == null ) {
var type = Assembly.Load( "UnityEditor.dll" ).GetType( "UnityEditor.AudioUtil" );
__PlayClip = (Method_PlayClip) Delegate.CreateDelegate( typeof( Method_PlayClip ), null, type.GetMethod( "PlayClip", AllMembers, null, new System.Type[] { typeof( AudioClip ), typeof( Int32 ), typeof( Boolean ) }, null ) );
}
__PlayClip( clip, startSample, loop );
}
delegate void Method_StopClip( UnityEngine.AudioClip clip );
static Method_StopClip __StopClip;
public static void StopClip( UnityEngine.AudioClip clip ) {
if( __StopClip == null ) {
var type = Assembly.Load( "UnityEditor.dll" ).GetType( "UnityEditor.AudioUtil" );
__StopClip = (Method_StopClip) Delegate.CreateDelegate( typeof( Method_StopClip ), null, type.GetMethod( "StopClip", AllMembers ) );
}
__StopClip( clip );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment