SanAndreasUnity/Assets/Scripts/UI/AnimationsWindow.cs
2020-05-31 19:09:52 +02:00

294 lines
7.6 KiB
C#

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<AnimationState>().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;
}
}
}