Created
November 29, 2022 17:27
-
-
Save hecomi/fd3caf8aa0339455c441d95188d71f8b to your computer and use it in GitHub Desktop.
PicturesGenerator Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
namespace WeddingMovie | |
{ | |
public class ColorChanger : MonoBehaviour | |
{ | |
public Color color = Color.white; | |
[ContextMenu("ChangeColor")] | |
public void ChangeColor() | |
{ | |
Debug.LogFormat("ChangeColor({0})", color.ToString()); | |
ChangeColorRecursively(gameObject); | |
} | |
void ChangeColorRecursively(GameObject gameObject) | |
{ | |
var t = gameObject.transform; | |
var renderer = t.GetComponent<Renderer>(); | |
if (renderer) | |
{ | |
// 非実行時のエディタ上での material プロパティアクセスによるインスタンス生成は | |
// 警告が出るが、エディタ上で作業する分には問題ないので無視 | |
renderer.material.color = color; | |
} | |
for (int i = 0; i < t.childCount; ++i) | |
{ | |
var child = t.GetChild(i); | |
ChangeColorRecursively(child.gameObject); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
namespace WeddingMovie | |
{ | |
public class PictureChanger : MonoBehaviour | |
{ | |
public Texture2D texture; | |
public new Renderer renderer; | |
public void ChangeTexture() | |
{ | |
if (!renderer || !texture) return; | |
var material = renderer.material; | |
material.SetTexture("_BaseMap", texture); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEngine.Playables; | |
using UnityEngine.Timeline; | |
using System.Collections.Generic; | |
using System.Linq; | |
#if UNITY_EDITOR | |
using UnityEditor; | |
using UnityEditorInternal; | |
#endif | |
namespace WeddingMovie | |
{ | |
public enum PictureTimelineType | |
{ | |
BulletLeft, | |
BulletRight, | |
BomLeft, | |
BomRight, | |
} | |
public enum PictureRootAnimationType | |
{ | |
Up, | |
} | |
[System.Serializable] | |
public struct PictureData | |
{ | |
public PictureTimelineType type; | |
public Texture2D picture; | |
[Multiline] | |
public string text; | |
[HideInInspector] public Color inkColor; | |
public bool skip; | |
public static PictureTimelineType defaultType = PictureTimelineType.BulletRight; | |
public static string defaultText = "hogehoge"; | |
public static Color defaultInkColor = Color.white; | |
} | |
[System.Serializable] | |
public struct PictureTimelinePrefabData | |
{ | |
public PictureTimelineType type; | |
public GameObject prefab; | |
} | |
public class PicturesGenerator : MonoBehaviour | |
{ | |
public PictureData[] pictures; | |
public PictureTimelinePrefabData[] prefabs; | |
public Color inkColor; | |
} | |
#if UNITY_EDITOR | |
[CustomEditor(typeof(PicturesGenerator))] | |
public class PicturesGeneratorEditor : Editor | |
{ | |
ReorderableList reorderableList; | |
bool isPrefabsFoldedOut = true; | |
bool isPicturesFoldedOut = true; | |
void OnEnable() | |
{ | |
var prop = serializedObject.FindProperty("pictures"); | |
reorderableList = new ReorderableList(serializedObject, prop); | |
reorderableList.drawHeaderCallback += rect => | |
{ | |
EditorGUI.LabelField(rect, "Pictures"); | |
}; | |
reorderableList.drawElementCallback += (rect, index, isActive, isFocused) => | |
{ | |
var elem = prop.GetArrayElementAtIndex(index); | |
rect.x += 12; | |
EditorGUI.PropertyField(rect, elem, true); | |
}; | |
reorderableList.elementHeightCallback += index => | |
{ | |
var elem = prop.GetArrayElementAtIndex(index); | |
float height = EditorGUIUtility.standardVerticalSpacing * 2; | |
height += EditorGUI.GetPropertyHeight(elem, true); | |
return height; | |
}; | |
reorderableList.onAddCallback += list => | |
{ | |
prop.arraySize++; | |
var index = prop.arraySize - 1; | |
var elem = prop.GetArrayElementAtIndex(index); | |
elem.FindPropertyRelative("type").enumValueIndex = (int)PictureData.defaultType; | |
elem.FindPropertyRelative("text").stringValue = PictureData.defaultText; | |
elem.FindPropertyRelative("inkColor").colorValue = PictureData.defaultInkColor; | |
elem.FindPropertyRelative("skip").boolValue = false; | |
}; | |
} | |
public static bool Foldout(string title, bool display) | |
{ | |
var style = new GUIStyle("ShurikenModuleTitle"); | |
style.font = new GUIStyle(EditorStyles.label).font; | |
style.border = new RectOffset(15, 7, 4, 4); | |
style.fixedHeight = 22; | |
style.contentOffset = new Vector2(20f, -2f); | |
var rect = GUILayoutUtility.GetRect(16f, 22f, style); | |
GUI.Box(rect, title, style); | |
var e = Event.current; | |
var toggleRect = new Rect(rect.x + 4f, rect.y + 2f, 13f, 13f); | |
if (e.type == EventType.Repaint) { | |
EditorStyles.foldout.Draw(toggleRect, false, false, display, false); | |
} | |
if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition)) { | |
display = !display; | |
e.Use(); | |
} | |
return display; | |
} | |
public override void OnInspectorGUI() | |
{ | |
var style = new GUIStyle("ShurikenModuleTitle"); | |
style.font = new GUIStyle(EditorStyles.label).font; | |
style.border = new RectOffset(15, 7, 4, 4); | |
style.fixedHeight = 22; | |
style.contentOffset = new Vector2(20f, -2f); | |
serializedObject.Update(); | |
EditorGUI.BeginChangeCheck(); | |
isPrefabsFoldedOut = Foldout("Template", isPrefabsFoldedOut); | |
if (isPrefabsFoldedOut) | |
{ | |
EditorGUI.indentLevel++; | |
DrawInkColor(); | |
EditorGUILayout.Separator(); | |
DrawPrefabs(); | |
EditorGUILayout.Separator(); | |
EditorGUILayout.Separator(); | |
EditorGUI.indentLevel--; | |
} | |
isPicturesFoldedOut = Foldout("Pictures", isPicturesFoldedOut); | |
if (isPicturesFoldedOut) | |
{ | |
EditorGUI.indentLevel++; | |
DrawPictures(); | |
EditorGUI.indentLevel--; | |
} | |
DrawButton(); | |
if (EditorGUI.EndChangeCheck()) | |
{ | |
serializedObject.ApplyModifiedProperties(); | |
} | |
} | |
void DrawPrefabs() | |
{ | |
var prefabsProp = serializedObject.FindProperty("prefabs"); | |
EditorGUILayout.PropertyField(prefabsProp, true); | |
} | |
void DrawInkColor() | |
{ | |
var inkColorProp = serializedObject.FindProperty("inkColor"); | |
EditorGUILayout.PropertyField(inkColorProp, true); | |
} | |
void DrawPictures() | |
{ | |
if (reorderableList != null) | |
{ | |
reorderableList.DoLayoutList(); | |
} | |
} | |
void DrawButton() | |
{ | |
var txt = new GUIContent(" Rebuild Timeline "); | |
var style = GUI.skin.button; | |
style.fixedHeight = 32f; | |
var rt = GUILayoutUtility.GetRect(txt, style, GUILayout.ExpandWidth(false)); | |
rt.center = new Vector2(EditorGUIUtility.currentViewWidth / 2, rt.center.y); | |
if (GUI.Button(rt, txt, style)) | |
{ | |
SetupTimeline(); | |
} | |
} | |
void SetupTimeline() | |
{ | |
var generator = target as PicturesGenerator; | |
var gameObject = generator.gameObject; | |
var transform = gameObject.transform; | |
while (transform.childCount > 0) | |
{ | |
var child = transform.GetChild(0); | |
if (child) DestroyImmediate(child.gameObject); | |
} | |
var director = gameObject.GetComponent<PlayableDirector>(); | |
var asset = director.playableAsset; | |
var clips = new List<TimelineClip>(); | |
foreach (var output in asset.outputs) | |
{ | |
if (!output.streamName.Contains("Picture")) continue; | |
var track = output.sourceObject as ControlTrack; | |
foreach (var clip in track.GetClips()) | |
{ | |
clips.Add(clip); | |
} | |
} | |
clips = clips.OrderBy(x => x.start).ToList(); | |
var pictures = generator.pictures.Where(x => !x.skip).ToList(); | |
int nc = clips.Count; | |
int np = pictures.Count; | |
for (int i = 0; i < nc; ++i) | |
{ | |
var clip = clips[i]; | |
var playableAsset = clip.asset as ControlPlayableAsset; | |
if (playableAsset == null) continue; | |
if (i >= np) | |
{ | |
director.SetReferenceValue(playableAsset.sourceGameObject.exposedName, null); | |
continue; | |
} | |
var data = pictures[i]; | |
data.inkColor = generator.inkColor; | |
var prefab = generator.prefabs.FirstOrDefault(x => x.type == data.type).prefab; | |
if (prefab == null) continue; | |
var go = Instantiate(prefab, transform); | |
go.SetActive(false); | |
var setup = go.GetComponent<PictureTimelineSetup>(); | |
if (setup) | |
{ | |
setup.Setup(data); | |
} | |
director.SetReferenceValue(playableAsset.sourceGameObject.exposedName, go); | |
} | |
} | |
} | |
#endif | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
namespace WeddingMovie | |
{ | |
public class PictureTimelineSetup : MonoBehaviour | |
{ | |
[SerializeField] | |
TextMesh textMesh = null; | |
public void Setup(PictureData data) | |
{ | |
var colorChanger = GetComponent<ColorChanger>(); | |
if (colorChanger) | |
{ | |
colorChanger.color = data.inkColor; | |
colorChanger.ChangeColor(); | |
} | |
var pictureChanger = GetComponent<PictureChanger>(); | |
if (pictureChanger) | |
{ | |
pictureChanger.texture = data.picture; | |
pictureChanger.ChangeTexture(); | |
} | |
if (textMesh) | |
{ | |
textMesh.text = data.text; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment