当前位置: 首页 > 工具软件 > log2timeline > 使用案例 >

timeline 相关代码

史洛城
2023-12-01
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.Timeline;
using System.IO;
using UnityEngine.Playables;

public class ExtractTimelineText
{
    
    [MenuItem("Tools/提取剧情文字")]
    static void Extract(){
        Editor_LuaConfig.Instance().Init();

        string fullPath = "Assets/Resources/Story";  //路径
        string txtPath = Application.dataPath + "/dialog.txt";

        int storyCount = 0;
  
        //获取指定路径下面的所有资源文件  
        if (Directory.Exists(fullPath)){  
            DirectoryInfo direction = new DirectoryInfo(fullPath);  
            FileInfo[] files = direction.GetFiles("*",SearchOption.TopDirectoryOnly);  
  
            // Debug.Log(files.Length);  

            StreamWriter writer; 
            FileInfo file = new FileInfo(txtPath); 
            writer = file.CreateText(); 
            

            for(int i=0;i<files.Length;i++){  
                if (files[i].Name.EndsWith(".meta")){  
                    continue;  
                }  
                if(!files[i].Name.EndsWith(".prefab"))
                    continue;  
                // Debug.Log( "Name:" + files[i].Name );  //打印出来这个文件架下的所有文件

                string prefabPath = fullPath + "/" + files[i].Name;
                GameObject tempObj = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
                if(tempObj == null){
                    Debug.LogWarning("not found prefab, name: " + prefabPath);
                }else{
                    PlayableDirector playableDirector = tempObj.GetComponent<PlayableDirector>();
                    if(playableDirector == null)
                        continue;
                    
                    writer.WriteLine("------story name " + files[i].Name + "------"); 
                    storyCount++;

                    PlayableAsset asset = playableDirector.playableAsset;
                    if(asset == null){
                        Debug.LogWarning("asset is null, story path: " + prefabPath);
                        writer.WriteLine("Error: asset is null, story path: " + prefabPath); 
                    }else{
                        // Debug.Log("asset name: " + asset.name);
                        foreach (PlayableBinding pb in asset.outputs)
                        {
                            var track = pb.sourceObject as TrackAsset;
                            if (track != null && track is DialogueTrack)
                            {
                                foreach (TimelineClip clip in track.GetClips())
                                {
                                    // Debug.Log("name:" + clip.displayName + "时间:" + clip.duration);
                                    DialogueClip dialogueClip = clip.asset as DialogueClip;
                                    // Debug.Log(dialogueClip.playerNameIndex + "---" + Editor_LuaConfig.Instance().GetDialogConfigText(dialogueClip.playerNameIndex.ToString()));
                                    string txt1 = Editor_LuaConfig.Instance().GetDialogConfigText(dialogueClip.playerNameIndex.ToString());
                                    if(string.IsNullOrEmpty(txt1)){
                                        Debug.LogWarning("not found index " + dialogueClip.playerNameIndex + ", story name: " + files[i].Name);
                                    }
                                    string txt2 = Editor_LuaConfig.Instance().GetDialogConfigText(dialogueClip.contentIndex.ToString());
                                    if(string.IsNullOrEmpty(txt1)){
                                        Debug.LogWarning("not found index " + dialogueClip.contentIndex + ", story name: " + files[i].Name);
                                    }
                                    writer.WriteLine(txt1 + ":" + txt2); 
                                }
                                break;
                            }
                        }
                    }
                }
            }  
            writer.Flush(); 
            writer.Dispose(); 
            writer.Close(); 
            Debug.Log("story text write finish!!! total count = " + storyCount);
        } 
        

        Editor_LuaMgr.Instance().DisposeLuaenv();
        Editor_LuaConfig.Instance().Release(); 
    }
}
public PlayableDirector InitStory(string name, Action<PlayableDirector> pdCallback, bool usePosition=false, Vector3 position=default(Vector3), Vector3 rotation=default(Vector3)){
		string fullPath = "Story/" + name;
		if(String.IsNullOrEmpty(name))
		{
			Debug.Log("没填要播放的story timeline名字");
			return null;
		}
        
		if (playableDirector != null)
		{
			playableDirector.Stop();
		}
		Debug.Log("Timeline: start load story timeline: " + fullPath);

		GameObject timeline = ObjectMgr.Instance().CreateObj(fullPath, null) as GameObject;
		if(timeline == null){
			Debug.LogWarning("timeline error name: " + name);
			pdCallback(null);
			return null;
		}
		
		UIMgr.Instance().DoSetUIShow(false);
		timeline.SetAllChildLayer("Timeline");
		if(usePosition){
			timeline.transform.position = position;
			timeline.transform.rotation = Quaternion.Euler(rotation);
		}
		
		List<Camera> cameras = new List<Camera>();
		timeline.GetComponentsInChildren<Camera>(true, cameras);
		for (int i = 0; i < cameras.Count; i++)
		{
			cameras[i].cullingMask = (1<<0) + (1<<1) + (1<<4) + (1<<14) + (1<<16);
			cameras[i].depth = 5;
			var al = cameras[i].GetComponent<AudioListener>();
			if(al != null){
				GameObject.Destroy(al);
			}
		}

		playableDirector = timeline.GetComponentInChildren<PlayableDirector>();
		playableDirector.stopped += pdCallback;
		playableDirector.stopped += OnPlayableDirectorStoryStopped;

		// timeline.transform.position = position;
		// timeline.transform.rotation = Quaternion.Euler(rotation);

		mBindings = new Dictionary<string, PlayableBinding>();
		PlayableAsset asset = playableDirector.playableAsset;
		if(asset == null){
			Debug.LogWarning("asset is null, timeline name: " + name);
			pdCallback(null);
			return null;
		}

		Dictionary<UnityEngine.Object, ActiveActorPartInfo> partInfos = new Dictionary<UnityEngine.Object, ActiveActorPartInfo>();


		// 角色运行时会被替换,角色的身体某一部分可能会设置隐藏/显示,这里记录需要设置的角色,以便替换角色后关联上隐藏部分
		foreach(var output in asset.outputs){
			UnityEngine.Object obj = playableDirector.GetGenericBinding(output.sourceObject);
			if(obj != null && obj is GameObject && (obj as GameObject).GetComponent<SkinnedMeshRenderer>() != null){
				Transform parent = (obj as GameObject).transform.parent;
				if(parent != null && parent.GetComponent<Animator>() != null){
					ActiveActorPartInfo info = new ActiveActorPartInfo();
					info.partName = (obj as GameObject).name;
					info.output = output;
					info.objPart = obj as GameObject;
					info.objParent = parent.gameObject;
					if(!partInfos.ContainsKey(output.sourceObject))
						partInfos.Add(output.sourceObject, info);
				}
			}
		}

		StoryActor[] storyActors = timeline.GetComponentsInChildren<StoryActor>();
		for (int i = storyActors.Length-1; i >=0; i--)
		{
			if(storyActors[i].actor != null){
				Vector3 scale = storyActors[i].transform.localScale;
				GameObject objIns = GameObject.Instantiate(storyActors[i].actor.gameObject);
				objIns.transform.SetParent(storyActors[i].transform.parent);
				objIns.transform.localPosition = Vector3.zero;
				objIns.transform.localRotation = Quaternion.identity;
				objIns.transform.localScale = scale;
				// objIns.transform.name = storyActors[i].transform.name;	//保留clone方便查看
				if(objIns.GetComponent<Animator>() != null)
					objIns.GetComponent<Animator>().runtimeAnimatorController = storyActors[i].GetComponent<Animator>().runtimeAnimatorController;

				foreach(var output in asset.outputs){
					UnityEngine.Object obj = playableDirector.GetGenericBinding(output.sourceObject);
					GameObject objBind = null;
					if(obj != null && obj is Animator){
						objBind = (obj as Animator).gameObject;
					}
					if(obj != null && obj is Transform){
						objBind = (obj as Transform).gameObject;
					}
					if(obj != null && obj is GameObject){
						objBind = obj as GameObject;

						// 替换 角色的身体某一部分
						if(partInfos.ContainsKey(output.sourceObject) && partInfos[output.sourceObject].objParent == storyActors[i].gameObject){
							playableDirector.SetGenericBinding(output.sourceObject, objIns.transform.Find(objBind.name).gameObject);
						}
					}
					if(objBind != null && storyActors[i].gameObject == objBind){
						
						playableDirector.SetGenericBinding(output.sourceObject, objIns);
					}
				}

				GameObject.Destroy(storyActors[i].gameObject);
			}
		}


		foreach(var output in asset.outputs){
			if(mBindings.ContainsKey(output.streamName)){
				Debug.Log("the same key: " + output.streamName);
			}else{
				mBindings.Add(output.streamName, output);
			}

		}
		Debug.Log("Timeline: load story timeline finish: " + fullPath);
		return playableDirector;
	}

 

 类似资料: