This commit is contained in:
Nim XD
2024-08-27 21:01:33 +05:30
parent 99eaf514fd
commit 121a1b7c73
31803 changed files with 623461 additions and 623399 deletions

View File

@@ -1,116 +1,116 @@
using System.Collections.Generic;
using Assets.HeroEditor4D.Common.Scripts.CharacterScripts;
using Assets.HeroEditor4D.Common.Scripts.Enums;
using UnityEngine;
using UnityEngine.UI;
namespace Assets.HeroEditor4D.Common.Scripts.EditorScripts
{
public class CaptureOptions : MonoBehaviour
{
public Toggle Left;
public Toggle Right;
public Toggle Front;
public Toggle Back;
public Toggle Idle;
public Toggle Ready;
public Toggle Walk;
public Toggle Run;
public Toggle Slash;
public Toggle Jab;
public Toggle Shot;
public Toggle Cast;
public Toggle Block;
public Toggle Jump;
public Toggle Climb;
public Toggle Death;
public Toggle Shadow;
public InputField FrameSize;
public InputField FrameCount;
public void Open()
{
gameObject.SetActive(true);
}
public void Close()
{
gameObject.SetActive(false);
}
public void Capture()
{
var direction = Vector2.right;
if (Right.isOn) direction = Vector2.right;
if (Left.isOn) direction = Vector2.left;
if (Front.isOn) direction = Vector2.down;
if (Back.isOn) direction = Vector2.up;
var options = new List<CaptureOption>();
if (Idle.isOn) options.Add(new CaptureOption("Idle"));
if (Ready.isOn) options.Add(new CaptureOption("Ready"));
if (Walk.isOn) options.Add(new CaptureOption("Walk"));
if (Run.isOn) options.Add(new CaptureOption("Run"));
if (Slash.isOn) options.Add(new CaptureOption("Idle", FindObjectOfType<Character4D>().WeaponType == WeaponType.Melee2H ? "Slash2H" : "Slash1H"));
if (Jab.isOn) options.Add(new CaptureOption("Idle", "Jab"));
if (Shot.isOn)
{
var character = FindObjectOfType<Character>();
switch (character.WeaponType)
{
case WeaponType.Bow:
options.Add(new CaptureOption("Idle", "ShotBow"));
break;
case WeaponType.Firearm1H:
options.Add(new CaptureOption("Ready", "Fire1H"));
break;
case WeaponType.Firearm2H:
options.Add(new CaptureOption("Ready", "Fire2H"));
break;
case WeaponType.Paired:
options.Add(new CaptureOption("Idle", "SecondaryShot"));
break;
}
}
if (Cast.isOn) options.Add(new CaptureOption("Idle", "Cast"));
if (Block.isOn) options.Add(new CaptureOption("ShieldBlock"));
if (Jump.isOn) options.Add(new CaptureOption("Jump", "Idle"));
if (Climb.isOn) options.Add(new CaptureOption("Climb"));
if (Death.isOn) options.Add(new CaptureOption(null, null, "Death"));
FindObjectOfType<SpriteSheetCapture>().Capture(direction, options, int.Parse(FrameSize.text), int.Parse(FrameCount.text), Shadow.isOn);
Close();
}
public void OnFrameSizeChanged(string value)
{
if (FrameSize.text == "") return;
var valueInt = int.Parse(value);
if (valueInt < 128) valueInt = 128;
if (valueInt > 512) valueInt = 512;
FrameSize.SetTextWithoutNotify(valueInt.ToString());
}
public void OnFrameCountChanged(string value)
{
if (FrameCount.text == "") return;
var valueInt = int.Parse(value);
if (valueInt < 4) valueInt = 4;
if (valueInt > 16) valueInt = 16;
FrameCount.SetTextWithoutNotify(valueInt.ToString());
}
}
using System.Collections.Generic;
using Assets.HeroEditor4D.Common.Scripts.CharacterScripts;
using Assets.HeroEditor4D.Common.Scripts.Enums;
using UnityEngine;
using UnityEngine.UI;
namespace Assets.HeroEditor4D.Common.Scripts.EditorScripts
{
public class CaptureOptions : MonoBehaviour
{
public Toggle Left;
public Toggle Right;
public Toggle Front;
public Toggle Back;
public Toggle Idle;
public Toggle Ready;
public Toggle Walk;
public Toggle Run;
public Toggle Slash;
public Toggle Jab;
public Toggle Shot;
public Toggle Cast;
public Toggle Block;
public Toggle Jump;
public Toggle Climb;
public Toggle Death;
public Toggle Shadow;
public InputField FrameSize;
public InputField FrameCount;
public void Open()
{
gameObject.SetActive(true);
}
public void Close()
{
gameObject.SetActive(false);
}
public void Capture()
{
var direction = Vector2.right;
if (Right.isOn) direction = Vector2.right;
if (Left.isOn) direction = Vector2.left;
if (Front.isOn) direction = Vector2.down;
if (Back.isOn) direction = Vector2.up;
var options = new List<CaptureOption>();
if (Idle.isOn) options.Add(new CaptureOption("Idle"));
if (Ready.isOn) options.Add(new CaptureOption("Ready"));
if (Walk.isOn) options.Add(new CaptureOption("Walk"));
if (Run.isOn) options.Add(new CaptureOption("Run"));
if (Slash.isOn) options.Add(new CaptureOption("Idle", FindObjectOfType<Character4D>().WeaponType == WeaponType.Melee2H ? "Slash2H" : "Slash1H"));
if (Jab.isOn) options.Add(new CaptureOption("Idle", "Jab"));
if (Shot.isOn)
{
var character = FindObjectOfType<Character>();
switch (character.WeaponType)
{
case WeaponType.Bow:
options.Add(new CaptureOption("Idle", "ShotBow"));
break;
case WeaponType.Firearm1H:
options.Add(new CaptureOption("Ready", "Fire1H"));
break;
case WeaponType.Firearm2H:
options.Add(new CaptureOption("Ready", "Fire2H"));
break;
case WeaponType.Paired:
options.Add(new CaptureOption("Idle", "SecondaryShot"));
break;
}
}
if (Cast.isOn) options.Add(new CaptureOption("Idle", "Cast"));
if (Block.isOn) options.Add(new CaptureOption("ShieldBlock"));
if (Jump.isOn) options.Add(new CaptureOption("Jump", "Idle"));
if (Climb.isOn) options.Add(new CaptureOption("Climb"));
if (Death.isOn) options.Add(new CaptureOption(null, null, "Death"));
FindObjectOfType<SpriteSheetCapture>().Capture(direction, options, int.Parse(FrameSize.text), int.Parse(FrameCount.text), Shadow.isOn);
Close();
}
public void OnFrameSizeChanged(string value)
{
if (FrameSize.text == "") return;
var valueInt = int.Parse(value);
if (valueInt < 128) valueInt = 128;
if (valueInt > 512) valueInt = 512;
FrameSize.SetTextWithoutNotify(valueInt.ToString());
}
public void OnFrameCountChanged(string value)
{
if (FrameCount.text == "") return;
var valueInt = int.Parse(value);
if (valueInt < 4) valueInt = 4;
if (valueInt > 16) valueInt = 16;
FrameCount.SetTextWithoutNotify(valueInt.ToString());
}
}
}

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: 3e3173316187965498c4b406e61f0b54
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 3e3173316187965498c4b406e61f0b54
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,13 +1,13 @@
fileFormatVersion: 2
guid: e3ee0b5972fd424e87d8494571d6ffda
timeCreated: 1490683879
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: e3ee0b5972fd424e87d8494571d6ffda
timeCreated: 1490683879
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,21 +1,21 @@
using System;
using UnityEngine;
using UnityEngine.UI;
namespace Assets.HeroEditor4D.Common.Scripts.EditorScripts
{
public class ColorSetup : MonoBehaviour
{
public Slider Hue;
public Slider Saturation;
public Slider Brightness;
public Color Color;
public Action<float, float, float> OnColorChanged;
public void OnSliderChanged()
{
OnColorChanged?.Invoke(Hue.value, Saturation.value, Brightness.value);
}
}
using System;
using UnityEngine;
using UnityEngine.UI;
namespace Assets.HeroEditor4D.Common.Scripts.EditorScripts
{
public class ColorSetup : MonoBehaviour
{
public Slider Hue;
public Slider Saturation;
public Slider Brightness;
public Color Color;
public Action<float, float, float> OnColorChanged;
public void OnSliderChanged()
{
OnColorChanged?.Invoke(Hue.value, Saturation.value, Brightness.value);
}
}
}

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: aca024db56e4d73439efde21df1fbb9b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: aca024db56e4d73439efde21df1fbb9b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,44 +1,44 @@
using UnityEngine;
namespace Assets.HeroEditor4D.Common.Scripts.EditorScripts
{
public class HuePaint : MonoBehaviour
{
[Range(0.0f, 1.0f)]
public float Hue;
private MaterialPropertyBlock _materialPropertyBlock;
private SpriteRenderer _spriteRenderer;
private readonly int _shaderColor = Shader.PropertyToID("_Color");
private readonly int _shaderHue = Shader.PropertyToID("_Hue");
public void OnValidate()
{
if (Hue > 0)
{
ShiftHue();
}
}
public void Start()
{
if (Hue > 0)
{
ShiftHue();
}
}
public void ShiftHue()
{
_materialPropertyBlock ??= new MaterialPropertyBlock();
_spriteRenderer ??= GetComponent<SpriteRenderer>();
var spriteColor = _spriteRenderer.color;
_materialPropertyBlock.SetColor(_shaderColor, spriteColor);
_materialPropertyBlock.SetFloat(_shaderHue, Hue);
_spriteRenderer.SetPropertyBlock(_materialPropertyBlock);
}
}
using UnityEngine;
namespace Assets.HeroEditor4D.Common.Scripts.EditorScripts
{
public class HuePaint : MonoBehaviour
{
[Range(0.0f, 1.0f)]
public float Hue;
private MaterialPropertyBlock _materialPropertyBlock;
private SpriteRenderer _spriteRenderer;
private readonly int _shaderColor = Shader.PropertyToID("_Color");
private readonly int _shaderHue = Shader.PropertyToID("_Hue");
public void OnValidate()
{
if (Hue > 0)
{
ShiftHue();
}
}
public void Start()
{
if (Hue > 0)
{
ShiftHue();
}
}
public void ShiftHue()
{
_materialPropertyBlock ??= new MaterialPropertyBlock();
_spriteRenderer ??= GetComponent<SpriteRenderer>();
var spriteColor = _spriteRenderer.color;
_materialPropertyBlock.SetColor(_shaderColor, spriteColor);
_materialPropertyBlock.SetFloat(_shaderHue, Hue);
_spriteRenderer.SetPropertyBlock(_materialPropertyBlock);
}
}
}

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: 0de1853e6ed9442498281f9fca689282
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 0de1853e6ed9442498281f9fca689282
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,12 +1,12 @@
using UnityEngine;
namespace Assets.HeroEditor4D.Common.Scripts.EditorScripts
{
public class NavigateButton : MonoBehaviour
{
public void Navigate(string url)
{
Application.OpenURL(url);
}
}
using UnityEngine;
namespace Assets.HeroEditor4D.Common.Scripts.EditorScripts
{
public class NavigateButton : MonoBehaviour
{
public void Navigate(string url)
{
Application.OpenURL(url);
}
}
}

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: 6783527b793a79a4b93d95f9cca96dff
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 6783527b793a79a4b93d95f9cca96dff
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,16 +1,16 @@
using UnityEngine;
using UnityEngine.UI;
namespace Assets.HeroEditor4D.Common.Scripts.EditorScripts
{
/// <summary>
/// Used to set Slider zero value.
/// </summary>
public class SliderReset : MonoBehaviour
{
public void Reset()
{
GetComponentInParent<Slider>().value = 0;
}
}
using UnityEngine;
using UnityEngine.UI;
namespace Assets.HeroEditor4D.Common.Scripts.EditorScripts
{
/// <summary>
/// Used to set Slider zero value.
/// </summary>
public class SliderReset : MonoBehaviour
{
public void Reset()
{
GetComponentInParent<Slider>().value = 0;
}
}
}

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: 7eac1736b7a245f48a83b2a87db3d653
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 7eac1736b7a245f48a83b2a87db3d653
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,231 +1,231 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Assets.HeroEditor4D.Common.Scripts.CharacterScripts;
using Assets.HeroEditor4D.Common.Scripts.Common;
using UnityEngine;
using UnityEngine.UI;
namespace Assets.HeroEditor4D.Common.Scripts.EditorScripts
{
/// <summary>
/// Used for creating sprite sheets for frame-by-frame animation.
/// </summary>
public class SpriteSequenceCapture : MonoBehaviour
{
public Character4D Character4D;
public GameObject Canvas;
public GameObject Camera;
public string UpperBodyAnimationFolder;
public string LowerBodyAnimationFolder;
public string ComplexAnimationFolder;
public List<string> UpperBodyClipNames;
public List<string> LowerBodyClipNames;
public List<string> ComplexClipNames;
public Dropdown DirectionDropdown;
public Dropdown PrimaryAnimationDropdown;
public Dropdown SecondaryAnimationDropdown;
public Slider CameraSizeSlider;
public Dropdown FrameSizeDropdown;
public Dropdown FrameRatioDropdown;
public Dropdown ScreenshotIntervalDropdown;
public Dropdown ShadowDropdown;
public GameObject Shadow;
public ScreenshotTransparent ScreenshotTransparent;
#if UNITY_EDITOR
/// <summary>
/// Called only in Editor.
/// </summary>
public void OnValidate()
{
UpperBodyClipNames = Directory.GetFiles(UpperBodyAnimationFolder, "*.anim", SearchOption.AllDirectories).Select(Path.GetFileNameWithoutExtension).ToList();
LowerBodyClipNames = Directory.GetFiles(LowerBodyAnimationFolder, "*.anim", SearchOption.AllDirectories).Select(Path.GetFileNameWithoutExtension).ToList();
ComplexClipNames = Directory.GetFiles(ComplexAnimationFolder, "*.anim", SearchOption.AllDirectories).Select(Path.GetFileNameWithoutExtension).ToList();
UpperBodyClipNames.AddRange(ComplexClipNames);
for (var i = 0; i < UpperBodyClipNames.Count; i++)
{
if (UpperBodyClipNames[i].EndsWith("U")) UpperBodyClipNames[i] = UpperBodyClipNames[i].Substring(0, UpperBodyClipNames[i].Length - 1);
}
for (var i = 0; i < LowerBodyClipNames.Count; i++)
{
if (LowerBodyClipNames[i].EndsWith("L")) LowerBodyClipNames[i] = LowerBodyClipNames[i].Substring(0, LowerBodyClipNames[i].Length - 1);
}
PrimaryAnimationDropdown.options = new List<Dropdown.OptionData>();
SecondaryAnimationDropdown.options = new List<Dropdown.OptionData>();
foreach (var clipName in UpperBodyClipNames)
{
PrimaryAnimationDropdown.options.Add(new Dropdown.OptionData(clipName));
}
foreach (var clipName in LowerBodyClipNames)
{
SecondaryAnimationDropdown.options.Add(new Dropdown.OptionData(clipName));
}
PrimaryAnimationDropdown.value = UpperBodyClipNames.IndexOf("Slash1H");
SecondaryAnimationDropdown.value = LowerBodyClipNames.IndexOf("Idle");
}
/// <summary>
/// Called on start.
/// </summary>
public void Start()
{
if (Character4D) Character4D.SetDirection(Vector2.left);
foreach (var dropdown in new[] { PrimaryAnimationDropdown, SecondaryAnimationDropdown, FrameSizeDropdown, FrameRatioDropdown, ScreenshotIntervalDropdown, ShadowDropdown })
{
dropdown.RefreshShownValue();
}
if (UpperBodyClipNames.Count == 0) OnValidate();
}
/// <summary>
/// Called when direction dropdown changed.
/// </summary>
/// <param name="value"></param>
public void OnDirectionChanged(int value)
{
switch (value)
{
case 0: Character4D.SetDirection(Vector2.left); break;
case 1: Character4D.SetDirection(Vector2.right); break;
case 2: Character4D.SetDirection(Vector2.down); break;
case 3: Character4D.SetDirection(Vector2.up); break;
}
}
/// <summary>
/// Load character from prefab.
/// </summary>
public void Load()
{
var path = UnityEditor.EditorUtility.OpenFilePanel("Open character prefab", "", "prefab");
if (path.Length > 0)
{
path = "Assets" + path.Replace(Application.dataPath, null);
Load(path);
}
}
/// <summary>
/// Load character from prefab by given path.
/// </summary>
public void Load(string path)
{
var character = UnityEditor.AssetDatabase.LoadAssetAtPath<Character4D>(path);
if (character == null) throw new Exception("Error loading character, please make sure you are loading correct prefab!");
if (Character4D != null) Destroy(Character4D.gameObject);
Character4D = Instantiate(character, transform);
Character4D.transform.localPosition = Vector3.zero;
Shadow = Character4D.transform.Find("Shadow").gameObject;
OnDirectionChanged(DirectionDropdown.value);
var mat = new Material(Shader.Find("Sprites/Default"));
foreach (var spriteRenderer in Character4D.GetComponentsInChildren<SpriteRenderer>())
{
if (spriteRenderer.name != "Eyes")
{
spriteRenderer.material = mat;
}
}
Debug.LogWarning("All materials were replaced by [Sprites/Default] to avoid outline artefacts.");
}
/// <summary>
/// Create sprite sheet.
/// </summary>
public void Capture()
{
var frameSize = new[] { 256, 512, 1024 }[FrameSizeDropdown.value];
var frameRatio = FrameRatioDropdown.value + 4;
var interval = new[] { 0.1f, 0.25f, 0.5f, 1f }[ScreenshotIntervalDropdown.value];
Camera.GetComponent<Camera>().orthographicSize = CameraSizeSlider.value;
Shadow.SetActive(ShadowDropdown.value == 0);
var upperClips = new List<string> { UpperBodyClipNames[PrimaryAnimationDropdown.value] };
var lowerClips = new List<string> { LowerBodyClipNames[SecondaryAnimationDropdown.value] };
StartCoroutine(CaptureFrames(upperClips, lowerClips, frameSize, frameRatio, interval));
}
private void ShowFrame(string upperClip, string lowerClip, float normalizedTime)
{
if (ComplexClipNames.Contains(upperClip))
{
Character4D.Animator.Play(upperClip, 2, normalizedTime);
}
else
{
Character4D.Animator.Play(upperClip, 1, normalizedTime);
Character4D.Animator.Play(lowerClip, 0, normalizedTime);
}
Character4D.Animator.speed = 0;
if (Character4D.Animator.IsInTransition(1))
{
Debug.Log("IsInTransition");
}
}
private IEnumerator CaptureFrames(List<string> upperClips, List<string> lowerClips, int frameSize, int frameRatio, float interval)
{
Canvas.SetActive(false);
var death = upperClips.Any(i => i.Contains("Death"));
foreach (var upperClip in upperClips)
{
foreach (var lowerClip in lowerClips)
{
for (var i = 0; i < frameRatio; i++)
{
ShowFrame(upperClip, lowerClip, (float) i / (frameRatio - 1));
yield return new WaitForSeconds(interval);
string direction;
switch (DirectionDropdown.value)
{
case 0: direction = "Left"; break;
case 1: direction = "Right"; break;
case 2: direction = "Front"; break;
case 3: direction = "Back"; break;
default: throw new NotImplementedException();
}
var path = death ? $"{Application.dataPath.Replace("/Assets", null)}/SpriteSheets/{direction}/{upperClip}/{i}.png" : $"{Application.dataPath.Replace("/Assets", null)}/SpriteSheets/{direction}/{upperClip}-{lowerClip}/{i}.png";
ScreenshotTransparent.Width = ScreenshotTransparent.Height = frameSize;
ScreenshotTransparent.Capture(path);
}
}
if (death) break;
}
Canvas.SetActive(true);
}
#endif
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Assets.HeroEditor4D.Common.Scripts.CharacterScripts;
using Assets.HeroEditor4D.Common.Scripts.Common;
using UnityEngine;
using UnityEngine.UI;
namespace Assets.HeroEditor4D.Common.Scripts.EditorScripts
{
/// <summary>
/// Used for creating sprite sheets for frame-by-frame animation.
/// </summary>
public class SpriteSequenceCapture : MonoBehaviour
{
public Character4D Character4D;
public GameObject Canvas;
public GameObject Camera;
public string UpperBodyAnimationFolder;
public string LowerBodyAnimationFolder;
public string ComplexAnimationFolder;
public List<string> UpperBodyClipNames;
public List<string> LowerBodyClipNames;
public List<string> ComplexClipNames;
public Dropdown DirectionDropdown;
public Dropdown PrimaryAnimationDropdown;
public Dropdown SecondaryAnimationDropdown;
public Slider CameraSizeSlider;
public Dropdown FrameSizeDropdown;
public Dropdown FrameRatioDropdown;
public Dropdown ScreenshotIntervalDropdown;
public Dropdown ShadowDropdown;
public GameObject Shadow;
public ScreenshotTransparent ScreenshotTransparent;
#if UNITY_EDITOR
/// <summary>
/// Called only in Editor.
/// </summary>
public void OnValidate()
{
UpperBodyClipNames = Directory.GetFiles(UpperBodyAnimationFolder, "*.anim", SearchOption.AllDirectories).Select(Path.GetFileNameWithoutExtension).ToList();
LowerBodyClipNames = Directory.GetFiles(LowerBodyAnimationFolder, "*.anim", SearchOption.AllDirectories).Select(Path.GetFileNameWithoutExtension).ToList();
ComplexClipNames = Directory.GetFiles(ComplexAnimationFolder, "*.anim", SearchOption.AllDirectories).Select(Path.GetFileNameWithoutExtension).ToList();
UpperBodyClipNames.AddRange(ComplexClipNames);
for (var i = 0; i < UpperBodyClipNames.Count; i++)
{
if (UpperBodyClipNames[i].EndsWith("U")) UpperBodyClipNames[i] = UpperBodyClipNames[i].Substring(0, UpperBodyClipNames[i].Length - 1);
}
for (var i = 0; i < LowerBodyClipNames.Count; i++)
{
if (LowerBodyClipNames[i].EndsWith("L")) LowerBodyClipNames[i] = LowerBodyClipNames[i].Substring(0, LowerBodyClipNames[i].Length - 1);
}
PrimaryAnimationDropdown.options = new List<Dropdown.OptionData>();
SecondaryAnimationDropdown.options = new List<Dropdown.OptionData>();
foreach (var clipName in UpperBodyClipNames)
{
PrimaryAnimationDropdown.options.Add(new Dropdown.OptionData(clipName));
}
foreach (var clipName in LowerBodyClipNames)
{
SecondaryAnimationDropdown.options.Add(new Dropdown.OptionData(clipName));
}
PrimaryAnimationDropdown.value = UpperBodyClipNames.IndexOf("Slash1H");
SecondaryAnimationDropdown.value = LowerBodyClipNames.IndexOf("Idle");
}
/// <summary>
/// Called on start.
/// </summary>
public void Start()
{
if (Character4D) Character4D.SetDirection(Vector2.left);
foreach (var dropdown in new[] { PrimaryAnimationDropdown, SecondaryAnimationDropdown, FrameSizeDropdown, FrameRatioDropdown, ScreenshotIntervalDropdown, ShadowDropdown })
{
dropdown.RefreshShownValue();
}
if (UpperBodyClipNames.Count == 0) OnValidate();
}
/// <summary>
/// Called when direction dropdown changed.
/// </summary>
/// <param name="value"></param>
public void OnDirectionChanged(int value)
{
switch (value)
{
case 0: Character4D.SetDirection(Vector2.left); break;
case 1: Character4D.SetDirection(Vector2.right); break;
case 2: Character4D.SetDirection(Vector2.down); break;
case 3: Character4D.SetDirection(Vector2.up); break;
}
}
/// <summary>
/// Load character from prefab.
/// </summary>
public void Load()
{
var path = UnityEditor.EditorUtility.OpenFilePanel("Open character prefab", "", "prefab");
if (path.Length > 0)
{
path = "Assets" + path.Replace(Application.dataPath, null);
Load(path);
}
}
/// <summary>
/// Load character from prefab by given path.
/// </summary>
public void Load(string path)
{
var character = UnityEditor.AssetDatabase.LoadAssetAtPath<Character4D>(path);
if (character == null) throw new Exception("Error loading character, please make sure you are loading correct prefab!");
if (Character4D != null) Destroy(Character4D.gameObject);
Character4D = Instantiate(character, transform);
Character4D.transform.localPosition = Vector3.zero;
Shadow = Character4D.transform.Find("Shadow").gameObject;
OnDirectionChanged(DirectionDropdown.value);
var mat = new Material(Shader.Find("Sprites/Default"));
foreach (var spriteRenderer in Character4D.GetComponentsInChildren<SpriteRenderer>())
{
if (spriteRenderer.name != "Eyes")
{
spriteRenderer.material = mat;
}
}
Debug.LogWarning("All materials were replaced by [Sprites/Default] to avoid outline artefacts.");
}
/// <summary>
/// Create sprite sheet.
/// </summary>
public void Capture()
{
var frameSize = new[] { 256, 512, 1024 }[FrameSizeDropdown.value];
var frameRatio = FrameRatioDropdown.value + 4;
var interval = new[] { 0.1f, 0.25f, 0.5f, 1f }[ScreenshotIntervalDropdown.value];
Camera.GetComponent<Camera>().orthographicSize = CameraSizeSlider.value;
Shadow.SetActive(ShadowDropdown.value == 0);
var upperClips = new List<string> { UpperBodyClipNames[PrimaryAnimationDropdown.value] };
var lowerClips = new List<string> { LowerBodyClipNames[SecondaryAnimationDropdown.value] };
StartCoroutine(CaptureFrames(upperClips, lowerClips, frameSize, frameRatio, interval));
}
private void ShowFrame(string upperClip, string lowerClip, float normalizedTime)
{
if (ComplexClipNames.Contains(upperClip))
{
Character4D.Animator.Play(upperClip, 2, normalizedTime);
}
else
{
Character4D.Animator.Play(upperClip, 1, normalizedTime);
Character4D.Animator.Play(lowerClip, 0, normalizedTime);
}
Character4D.Animator.speed = 0;
if (Character4D.Animator.IsInTransition(1))
{
Debug.Log("IsInTransition");
}
}
private IEnumerator CaptureFrames(List<string> upperClips, List<string> lowerClips, int frameSize, int frameRatio, float interval)
{
Canvas.SetActive(false);
var death = upperClips.Any(i => i.Contains("Death"));
foreach (var upperClip in upperClips)
{
foreach (var lowerClip in lowerClips)
{
for (var i = 0; i < frameRatio; i++)
{
ShowFrame(upperClip, lowerClip, (float) i / (frameRatio - 1));
yield return new WaitForSeconds(interval);
string direction;
switch (DirectionDropdown.value)
{
case 0: direction = "Left"; break;
case 1: direction = "Right"; break;
case 2: direction = "Front"; break;
case 3: direction = "Back"; break;
default: throw new NotImplementedException();
}
var path = death ? $"{Application.dataPath.Replace("/Assets", null)}/SpriteSheets/{direction}/{upperClip}/{i}.png" : $"{Application.dataPath.Replace("/Assets", null)}/SpriteSheets/{direction}/{upperClip}-{lowerClip}/{i}.png";
ScreenshotTransparent.Width = ScreenshotTransparent.Height = frameSize;
ScreenshotTransparent.Capture(path);
}
}
if (death) break;
}
Canvas.SetActive(true);
}
#endif
}
}

View File

@@ -1,13 +1,13 @@
fileFormatVersion: 2
guid: 9f79a721ae5a8b84ea74c09390a4816d
timeCreated: 1521921264
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 9f79a721ae5a8b84ea74c09390a4816d
timeCreated: 1521921264
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,185 +1,185 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Assets.HeroEditor4D.Common.Scripts.CharacterScripts;
using Assets.HeroEditor4D.Common.Scripts.Common;
using Assets.HeroEditor4D.Common.Scripts.Enums;
using UnityEngine;
namespace Assets.HeroEditor4D.Common.Scripts.EditorScripts
{
[RequireComponent(typeof(Camera))]
public class SpriteSheetCapture : MonoBehaviour
{
private Character4D _character;
public void Capture(Vector2 direction, List<CaptureOption> options, int frameSize, int frameCount, bool shadow)
{
StartCoroutine(CaptureFrames(direction, options, frameSize, frameCount, shadow));
}
private IEnumerator CaptureFrames(Vector2 direction, List<CaptureOption> options, int frameSize, int frameCount, bool shadow)
{
_character = FindObjectOfType<Character4D>();
_character.SetDirection(direction);
_character.Shadows.ForEach(i => i.SetActive(false));
_character.Shadows[0].SetActive(shadow);
var stateHandler = _character.Animator.GetBehaviours<StateHandler>().SingleOrDefault(i => i.Name == "Death");
if (stateHandler)
{
stateHandler.StateExit.RemoveAllListeners();
}
var clips = new List<List<Texture2D>>();
foreach (var option in options)
{
_character.SetExpression("Default");
_character.AnimationManager.SetState(CharacterState.Idle);
_character.Animator.speed = 99;
yield return null;
_character.Animator.speed = 0;
var frames = new List<Texture2D>();
for (var j = 0; j < frameCount; j++)
{
var normalizedTime = (float) j / (frameCount - 1);
yield return ShowFrame(option.StateL, option.StateU, option.StateC, normalizedTime);
var clip = _character.Animator.GetCurrentAnimatorClipInfo(option.StateU == null ? 2 : 1)[0].clip;
var expressionEvent = clip.events.Where(i => i.functionName == "SetExpression" && Mathf.Abs(i.time / clip.length - normalizedTime) <= 1f / (frameCount - 1))
.OrderBy(i => Mathf.Abs(i.time / clip.length - normalizedTime)).FirstOrDefault();
if (expressionEvent != null)
{
_character.SetExpression(expressionEvent.stringParameter);
}
var frame = CaptureFrame(frameSize, frameSize);
frames.Add(frame);
yield return null;
}
clips.Add(frames);
}
_character.AnimationManager.SetState(CharacterState.Idle);
_character.Animator.speed = 1;
if (stateHandler)
{
stateHandler.StateExit.AddListener(() => _character.SetExpression("Default"));
}
var texture = CreateSheet(clips, frameSize, frameSize);
yield return StandaloneFilePicker.SaveFile("Save as sprite sheet", "", "Character", ".png", texture.EncodeToPNG(), (success, path) => { Debug.Log(success ? $"Saved as {path}" : "Error saving."); });
}
private IEnumerator ShowFrame(string stateL, string stateU, string stateC, float normalizedTime)
{
switch (stateU)
{
case "Idle" when _character.WeaponType == WeaponType.Firearm1H:
stateU = "IdleFirearm1H";
break;
case "Idle" when _character.WeaponType == WeaponType.Firearm2H:
stateU = "IdleFirearm2H";
break;
case "Ready" when _character.WeaponType == WeaponType.Firearm1H:
stateU = "ReadyFirearm1H";
break;
case "Ready" when _character.WeaponType == WeaponType.Firearm2H:
stateU = "ReadyFirearm2H";
break;
case "Ready":
stateU = "Ready1H";
break;
}
if (stateC != null)
{
_character.Animator.Play(stateC, 2, normalizedTime);
}
else
{
_character.Animator.Play(stateL, 0, normalizedTime);
_character.Animator.Play(stateU, 1, normalizedTime);
}
yield return null;
while (_character.Animator.GetCurrentAnimatorClipInfo(stateC == null ? 0 : 2).Length == 0)
{
yield return null;
}
if (_character.Animator.IsInTransition(1))
{
Debug.Log("IsInTransition");
}
}
private Texture2D CaptureFrame(int width, int height)
{
var cam = GetComponent<Camera>();
var renderTexture = new RenderTexture(width, height, 24);
var texture2D = new Texture2D(width, height, TextureFormat.ARGB32, false);
cam.targetTexture = renderTexture;
cam.Render();
RenderTexture.active = renderTexture;
texture2D.ReadPixels(new Rect(0, 0, width, height), 0, 0);
cam.targetTexture = null;
RenderTexture.active = null;
Destroy(renderTexture);
return texture2D;
}
private static Texture2D CreateSheet(List<List<Texture2D>> clips, int width, int height)
{
var texture = new Texture2D(clips[0].Count * width, clips.Count * height);
for (var i = 0; i < clips.Count; i++)
{
for (var j = 0; j < clips[i].Count; j++)
{
texture.SetPixels(j * width, (clips.Count - 1 - i) * height, width, height, clips[i][j].GetPixels());
}
}
texture.Apply();
return texture;
}
}
public class CaptureOption
{
public string StateL;
public string StateU;
public string StateC;
public CaptureOption(string stateL)
{
StateL = stateL;
StateU = stateL;
}
public CaptureOption(string stateL, string stateU, string stateC = null)
{
StateL = stateL;
StateU = stateU;
StateC = stateC;
}
}
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Assets.HeroEditor4D.Common.Scripts.CharacterScripts;
using Assets.HeroEditor4D.Common.Scripts.Common;
using Assets.HeroEditor4D.Common.Scripts.Enums;
using UnityEngine;
namespace Assets.HeroEditor4D.Common.Scripts.EditorScripts
{
[RequireComponent(typeof(Camera))]
public class SpriteSheetCapture : MonoBehaviour
{
private Character4D _character;
public void Capture(Vector2 direction, List<CaptureOption> options, int frameSize, int frameCount, bool shadow)
{
StartCoroutine(CaptureFrames(direction, options, frameSize, frameCount, shadow));
}
private IEnumerator CaptureFrames(Vector2 direction, List<CaptureOption> options, int frameSize, int frameCount, bool shadow)
{
_character = FindObjectOfType<Character4D>();
_character.SetDirection(direction);
_character.Shadows.ForEach(i => i.SetActive(false));
_character.Shadows[0].SetActive(shadow);
var stateHandler = _character.Animator.GetBehaviours<StateHandler>().SingleOrDefault(i => i.Name == "Death");
if (stateHandler)
{
stateHandler.StateExit.RemoveAllListeners();
}
var clips = new List<List<Texture2D>>();
foreach (var option in options)
{
_character.SetExpression("Default");
_character.AnimationManager.SetState(CharacterState.Idle);
_character.Animator.speed = 99;
yield return null;
_character.Animator.speed = 0;
var frames = new List<Texture2D>();
for (var j = 0; j < frameCount; j++)
{
var normalizedTime = (float) j / (frameCount - 1);
yield return ShowFrame(option.StateL, option.StateU, option.StateC, normalizedTime);
var clip = _character.Animator.GetCurrentAnimatorClipInfo(option.StateU == null ? 2 : 1)[0].clip;
var expressionEvent = clip.events.Where(i => i.functionName == "SetExpression" && Mathf.Abs(i.time / clip.length - normalizedTime) <= 1f / (frameCount - 1))
.OrderBy(i => Mathf.Abs(i.time / clip.length - normalizedTime)).FirstOrDefault();
if (expressionEvent != null)
{
_character.SetExpression(expressionEvent.stringParameter);
}
var frame = CaptureFrame(frameSize, frameSize);
frames.Add(frame);
yield return null;
}
clips.Add(frames);
}
_character.AnimationManager.SetState(CharacterState.Idle);
_character.Animator.speed = 1;
if (stateHandler)
{
stateHandler.StateExit.AddListener(() => _character.SetExpression("Default"));
}
var texture = CreateSheet(clips, frameSize, frameSize);
yield return StandaloneFilePicker.SaveFile("Save as sprite sheet", "", "Character", ".png", texture.EncodeToPNG(), (success, path) => { Debug.Log(success ? $"Saved as {path}" : "Error saving."); });
}
private IEnumerator ShowFrame(string stateL, string stateU, string stateC, float normalizedTime)
{
switch (stateU)
{
case "Idle" when _character.WeaponType == WeaponType.Firearm1H:
stateU = "IdleFirearm1H";
break;
case "Idle" when _character.WeaponType == WeaponType.Firearm2H:
stateU = "IdleFirearm2H";
break;
case "Ready" when _character.WeaponType == WeaponType.Firearm1H:
stateU = "ReadyFirearm1H";
break;
case "Ready" when _character.WeaponType == WeaponType.Firearm2H:
stateU = "ReadyFirearm2H";
break;
case "Ready":
stateU = "Ready1H";
break;
}
if (stateC != null)
{
_character.Animator.Play(stateC, 2, normalizedTime);
}
else
{
_character.Animator.Play(stateL, 0, normalizedTime);
_character.Animator.Play(stateU, 1, normalizedTime);
}
yield return null;
while (_character.Animator.GetCurrentAnimatorClipInfo(stateC == null ? 0 : 2).Length == 0)
{
yield return null;
}
if (_character.Animator.IsInTransition(1))
{
Debug.Log("IsInTransition");
}
}
private Texture2D CaptureFrame(int width, int height)
{
var cam = GetComponent<Camera>();
var renderTexture = new RenderTexture(width, height, 24);
var texture2D = new Texture2D(width, height, TextureFormat.ARGB32, false);
cam.targetTexture = renderTexture;
cam.Render();
RenderTexture.active = renderTexture;
texture2D.ReadPixels(new Rect(0, 0, width, height), 0, 0);
cam.targetTexture = null;
RenderTexture.active = null;
Destroy(renderTexture);
return texture2D;
}
private static Texture2D CreateSheet(List<List<Texture2D>> clips, int width, int height)
{
var texture = new Texture2D(clips[0].Count * width, clips.Count * height);
for (var i = 0; i < clips.Count; i++)
{
for (var j = 0; j < clips[i].Count; j++)
{
texture.SetPixels(j * width, (clips.Count - 1 - i) * height, width, height, clips[i][j].GetPixels());
}
}
texture.Apply();
return texture;
}
}
public class CaptureOption
{
public string StateL;
public string StateU;
public string StateC;
public CaptureOption(string stateL)
{
StateL = stateL;
StateU = stateL;
}
public CaptureOption(string stateL, string stateU, string stateC = null)
{
StateL = stateL;
StateU = stateU;
StateC = stateC;
}
}
}

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: 84a9c4adeaeac744cb3df1b6ba6f2fe0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 84a9c4adeaeac744cb3df1b6ba6f2fe0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,87 +1,87 @@
using System;
using System.Collections;
namespace Assets.HeroEditor4D.Common.Scripts.Common
{
public static class StandaloneFilePicker
{
#if UNITY_EDITOR
public static IEnumerator OpenFile(string title, string directory, string extension, Action<bool, string, byte[]> callback)
{
var path = UnityEditor.EditorUtility.OpenFilePanel(title, directory, extension.Replace(".", null));
if (!string.IsNullOrEmpty(path))
{
var bytes = System.IO.File.ReadAllBytes(path);
callback(true, path, bytes);
}
else
{
callback(false, null, null);
}
yield break;
}
public static IEnumerator SaveFile(string title, string directory, string defaultName, string extension, byte[] bytes, Action<bool, string> callback)
{
var path = UnityEditor.EditorUtility.SaveFilePanel(title, directory, defaultName, extension.Replace(".", null));
if (!string.IsNullOrEmpty(path))
{
System.IO.File.WriteAllBytes(path, bytes);
callback(true, path);
}
else
{
callback(false, null);
}
yield break;
}
#elif UNITY_STANDALONE_WIN || UNITY_WSA
public static IEnumerator OpenFile(string title, string directory, string extension, Action<bool, string, byte[]> callback)
{
throw new NotImplementedException("Import [Simple File Browser For Windows]: http://u3d.as/2QLg");
//yield return SimpleFileBrowserForWindows.WindowsFileBrowser.OpenFile(title, directory, "File", new[] { extension }, callback);
}
public static IEnumerator SaveFile(string title, string directory, string defaultName, string extension, byte[] bytes, Action<bool, string> callback)
{
throw new NotImplementedException("Import [Simple File Browser For Windows]: http://u3d.as/2QLg");
//yield return SimpleFileBrowserForWindows.WindowsFileBrowser.SaveFile(title, directory, defaultName, "Prefab", extension, bytes, callback);
}
#elif UNITY_WEBGL
public static IEnumerator OpenFile(string title, string directory, string extension, Action<bool, string, byte[]> callback)
{
throw new NotImplementedException("Import [Simple File Browser for WebGL]: http://u3d.as/2W52");
//SimpleFileBrowserForWebGL.WebFileBrowser.Upload((fileName, mime, bytes) => callback(true, null, bytes), extension);
}
public static IEnumerator SaveFile(string title, string directory, string defaultName, string extension, byte[] bytes, Action<bool, string> callback)
{
throw new NotImplementedException("Import [Simple File Browser for WebGL]: http://u3d.as/2W52");
//SimpleFileBrowserForWebGL.WebFileBrowser.Download(defaultName, bytes);
}
#else
public static IEnumerator OpenFile(string title, string directory, string extension, Action<bool, string, byte[]> callback)
{
throw new NotSupportedException();
}
public static IEnumerator SaveFile(string title, string directory, string defaultName, string extension, byte[] bytes, Action<bool, string> callback)
{
throw new NotSupportedException();
}
#endif
}
using System;
using System.Collections;
namespace Assets.HeroEditor4D.Common.Scripts.Common
{
public static class StandaloneFilePicker
{
#if UNITY_EDITOR
public static IEnumerator OpenFile(string title, string directory, string extension, Action<bool, string, byte[]> callback)
{
var path = UnityEditor.EditorUtility.OpenFilePanel(title, directory, extension.Replace(".", null));
if (!string.IsNullOrEmpty(path))
{
var bytes = System.IO.File.ReadAllBytes(path);
callback(true, path, bytes);
}
else
{
callback(false, null, null);
}
yield break;
}
public static IEnumerator SaveFile(string title, string directory, string defaultName, string extension, byte[] bytes, Action<bool, string> callback)
{
var path = UnityEditor.EditorUtility.SaveFilePanel(title, directory, defaultName, extension.Replace(".", null));
if (!string.IsNullOrEmpty(path))
{
System.IO.File.WriteAllBytes(path, bytes);
callback(true, path);
}
else
{
callback(false, null);
}
yield break;
}
#elif UNITY_STANDALONE_WIN || UNITY_WSA
public static IEnumerator OpenFile(string title, string directory, string extension, Action<bool, string, byte[]> callback)
{
throw new NotImplementedException("Import [Simple File Browser For Windows]: http://u3d.as/2QLg");
//yield return SimpleFileBrowserForWindows.WindowsFileBrowser.OpenFile(title, directory, "File", new[] { extension }, callback);
}
public static IEnumerator SaveFile(string title, string directory, string defaultName, string extension, byte[] bytes, Action<bool, string> callback)
{
throw new NotImplementedException("Import [Simple File Browser For Windows]: http://u3d.as/2QLg");
//yield return SimpleFileBrowserForWindows.WindowsFileBrowser.SaveFile(title, directory, defaultName, "Prefab", extension, bytes, callback);
}
#elif UNITY_WEBGL
public static IEnumerator OpenFile(string title, string directory, string extension, Action<bool, string, byte[]> callback)
{
throw new NotImplementedException("Import [Simple File Browser for WebGL]: http://u3d.as/2W52");
//SimpleFileBrowserForWebGL.WebFileBrowser.Upload((fileName, mime, bytes) => callback(true, null, bytes), extension);
}
public static IEnumerator SaveFile(string title, string directory, string defaultName, string extension, byte[] bytes, Action<bool, string> callback)
{
throw new NotImplementedException("Import [Simple File Browser for WebGL]: http://u3d.as/2W52");
//SimpleFileBrowserForWebGL.WebFileBrowser.Download(defaultName, bytes);
}
#else
public static IEnumerator OpenFile(string title, string directory, string extension, Action<bool, string, byte[]> callback)
{
throw new NotSupportedException();
}
public static IEnumerator SaveFile(string title, string directory, string defaultName, string extension, byte[] bytes, Action<bool, string> callback)
{
throw new NotSupportedException();
}
#endif
}
}

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: fc6c0c3038887d44ab774d3f884974ef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: fc6c0c3038887d44ab774d3f884974ef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: