using System.Collections.Generic; using UnityEngine; using SanAndreasUnity.Importing.Animation; using SanAndreasUnity.Behaviours; using SanAndreasUnity.Utilities; using System.Linq; namespace SanAndreasUnity.UI { public class AnimationsWindow : PauseMenuWindow { private Vector2 m_scrollViewPos = Vector2.zero; private Vector2 m_packagesScrollViewPos = Vector2.zero; private bool m_displayPackages = true; private bool m_displayWalkcycleAnims = false; private bool m_displayAnimStats = false; private float m_minScrollViewHeight = 200; private float m_maxScrollViewHeight = 600; private int m_selectedPackageIndex = -1; private string[] m_ifpFileNames = new string[] {}; private string[] m_currentlyDisplayedIfpFileNames = new string[] {}; private string m_ifpSearchText = ""; AnimationsWindow() { // set default parameters this.windowName = "Animations"; this.useScrollView = false; } void Start () { this.RegisterButtonInPauseMenu (); // adjust rect this.windowRect = Utilities.GUIUtils.GetCenteredRect( new Vector2( 500, Screen.height * 0.85f ) ); } protected override void OnLoaderFinished() { base.OnLoaderFinished(); // cache all IFPs m_ifpFileNames = Importing.Archive.ArchiveManager.GetFileNamesWithExtension(".ifp").Select(fileName => fileName.Substring(0, fileName.Length - 4)).ToArray(); m_currentlyDisplayedIfpFileNames = m_ifpFileNames; } protected override void OnWindowGUI () { bool playerExists = Ped.Instance != null; // float headerHeight = m_displayAnimStats ? 300 : 100; // m_headerScrollViewPos = GUILayout.BeginScrollView (m_headerScrollViewPos, GUILayout.Height(headerHeight)); if (NetUtils.IsServer) { if (playerExists) Ped.Instance.shouldPlayAnims = !GUILayout.Toggle( !Ped.Instance.shouldPlayAnims, "Override player anims" ); } m_displayPackages = GUILayout.Toggle(m_displayPackages, "Display packages"); m_displayWalkcycleAnims = GUILayout.Toggle( m_displayWalkcycleAnims, "Display walkcycle anims"); m_displayAnimStats = GUILayout.Toggle( m_displayAnimStats, "Display anim stats"); // display anim stats if (m_displayAnimStats && playerExists) { DisplayAnimStats (); } // GUILayout.EndScrollView (); GUILayout.Space (10); if (m_displayPackages) { // display loaded ifp packages and their anims this.DisplayPackages (playerExists); } else { // display anim groups and their anims this.DisplayAnimGroups (playerExists); } } private void DisplayAnimStats () { GUILayout.Space (5); var model = Ped.Instance.PlayerModel; int numActiveClips = model.AnimComponent.OfType().Where(a => a.enabled).Count(); GUILayout.Label("Currently played anims [" + numActiveClips + "] :"); // display all currently played clips foreach (AnimationState animState in model.AnimComponent) { if (!animState.enabled) continue; DisplayStatsForAnim (animState); } if (model.LastAnimState != null) { GUILayout.Space (3); GUILayout.Label ("Last played anim:"); DisplayStatsForAnim (model.LastAnimState); } if (model.LastSecondaryAnimState != null) { GUILayout.Space (3); GUILayout.Label ("Last secondary played anim:"); DisplayStatsForAnim (model.LastSecondaryAnimState); } GUILayout.Space (7); GUILayout.Label ("Root frame velocity: " + model.RootFrame.LocalVelocity); } private void DisplayStatsForAnim (AnimationState animState) { // GUILayout.BeginHorizontal (); var clip = animState.clip; GUILayout.Label (string.Format ("name: {0}, length: {1}, frame rate: {2}, wrap mode: {3}, speed: {4}, " + "normalized speed: {5}, time: {6}, normalized time: {7}, time perc: {8}", clip.name, animState.length, clip.frameRate, animState.wrapMode, animState.speed, animState.normalizedSpeed, animState.time, animState.normalizedTime, animState.GetTimePerc () )); // GUILayout.EndHorizontal (); } private void DisplayAnimGroups(bool playerExists) { m_scrollViewPos = GUILayout.BeginScrollView (m_scrollViewPos, GUILayout.MinHeight(m_minScrollViewHeight), GUILayout.MaxHeight(m_maxScrollViewHeight)); float elementHeight = 25; foreach (var pair in Importing.Animation.AnimationGroup.AllLoadedGroups) { GUILayout.Space (5); GUILayout.Label ("Name: " + pair.Key); foreach (var pair2 in pair.Value) { if (!m_displayWalkcycleAnims && pair2.Key == AnimGroup.WalkCycle) continue; GUILayout.Label ("Type: " + pair2.Key); var animGroup = pair2.Value; for (int i=0; i < animGroup.Animations.Length; i++) { string animName = animGroup.Animations[i]; if (playerExists) { // display button which will play the anim if (GUILayout.Button (animName, GUILayout.Height(elementHeight))) { this.PlayAnim(new AnimId(animGroup.Type, AnimIndexUtil.Get(i))); } } else { GUILayout.Label (animName, GUILayout.Height(elementHeight)); } } } } GUILayout.EndScrollView(); } void DisplayPackages(bool playerExists) { string[] packageNames = m_currentlyDisplayedIfpFileNames; float animHeight = 25; // search box GUILayout.BeginHorizontal(); GUILayout.Label ("Ifp name:"); GUILayout.Space(5); m_ifpSearchText = GUILayout.TextField(m_ifpSearchText, GUILayout.Width(120)); GUILayout.Space(5); if (GUILayout.Button("Search")) { this.SearchIfps(); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); m_packagesScrollViewPos = GUILayout.BeginScrollView(m_packagesScrollViewPos, GUILayout.MinHeight(50)); int newPackageIndex = GUILayout.Toolbar(m_selectedPackageIndex, packageNames, GUILayout.MinHeight(animHeight)); GUILayout.EndScrollView(); if (newPackageIndex != m_selectedPackageIndex) { // changed selected package m_selectedPackageIndex = newPackageIndex; // load the package if it was not loaded so far if (newPackageIndex >= 0) { bool packageLoaded = Importing.Conversion.Animation.Loaded.ContainsKey(packageNames[newPackageIndex]); if (!packageLoaded) Importing.Conversion.Animation.LoadPackageOnly(packageNames[newPackageIndex]); } } if (newPackageIndex < 0) return; string selectedIfpName = packageNames[m_selectedPackageIndex]; if (! Importing.Conversion.Animation.Loaded.ContainsKey(selectedIfpName)) return; var package = Importing.Conversion.Animation.Loaded[selectedIfpName].AnimPackage; var clips = package.Clips; GUILayout.Space (10); // display all clips from this IFP package m_scrollViewPos = GUILayout.BeginScrollView (m_scrollViewPos, GUILayout.MinHeight(m_minScrollViewHeight), GUILayout.MaxHeight(m_maxScrollViewHeight)); for (int i = 0; i < clips.Length; i++) { var clip = clips [i]; if (playerExists) { if (GUILayout.Button (clip.Name, GUILayout.Height(animHeight))) { // play this anim this.PlayAnim(new AnimId (package.FileName, clip.Name)); } } else { GUILayout.Label (clip.Name, GUILayout.Height(animHeight)); } } GUILayout.EndScrollView (); } void SearchIfps() { string text = m_ifpSearchText.Trim(); if (string.IsNullOrWhiteSpace(text)) { m_currentlyDisplayedIfpFileNames = m_ifpFileNames; return; } m_currentlyDisplayedIfpFileNames = m_ifpFileNames.Where(fileName => fileName.Contains(text)).ToArray(); m_selectedPackageIndex = -1; } void PlayAnim(AnimId animId) { Ped.Instance.PlayerModel.ResetModelState (); var state = Ped.Instance.PlayerModel.PlayAnim (animId); state.wrapMode = WrapMode.Loop; } } }