mirror of
https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
synced 2024-08-15 00:43:27 +00:00
v 1.0.0
This commit is contained in:
parent
0828ecd037
commit
2998865184
9821 changed files with 90 additions and 90 deletions
28
Source/Assets/Scripts/GUI/ActorManipulator.cs
Normal file
28
Source/Assets/Scripts/GUI/ActorManipulator.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class ActorManipulator : MonoBehaviour
|
||||
{
|
||||
public ActorManipulationMode actorManipulationMode;
|
||||
|
||||
private Image button;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
button = GetComponent<Image>();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (Workspace.actorManipulationMode == actorManipulationMode)
|
||||
{ button.color = Constants.ColorGoldYellow; }
|
||||
|
||||
else
|
||||
{ button.color = Constants.ColorWhite; }
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/ActorManipulator.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/ActorManipulator.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f627be313335bf748b33eea98541581d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Source/Assets/Scripts/GUI/Actors.meta
Normal file
8
Source/Assets/Scripts/GUI/Actors.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f3c96477ef8cc42468ea6a39764a2e81
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
126
Source/Assets/Scripts/GUI/Actors/ActorBody.cs
Normal file
126
Source/Assets/Scripts/GUI/Actors/ActorBody.cs
Normal file
|
@ -0,0 +1,126 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class ActorBody : MonoBehaviour, IPointerClickHandler, IDragHandler, IEndDragHandler
|
||||
{
|
||||
public int actorID;
|
||||
public SpriteRenderer bodyRenderer;
|
||||
public ActorBodyPart actorBodyPartPrefab;
|
||||
|
||||
private Vector3 dragDelta = new Vector3();
|
||||
|
||||
private void Start()
|
||||
{
|
||||
EventsManager.onActorBodyPartSelected.AddListener(delegate(ActorBodyPart bodyPart) { OnActorBodyPartSelected(bodyPart); });
|
||||
EventsManager.onActorBodySelected.AddListener(delegate(ActorBody actorBody) { OnActorBodySelected(actorBody); });
|
||||
EventsManager.onActorIDChanged.AddListener(delegate {
|
||||
if (Workspace.ActorID == actorID)
|
||||
{ EventsManager.OnActorBodySelected(this); }
|
||||
});
|
||||
|
||||
if (Workspace.ActorID == actorID)
|
||||
{ Activate(); }
|
||||
|
||||
foreach (ActorAddonDef actorAddonDef in ActorAddonDefs.allDefs)
|
||||
{
|
||||
ActorBodyPart actorBodyPart = Instantiate(actorBodyPartPrefab, transform);
|
||||
actorBodyPart.Initialize(this, actorAddonDef);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnActorBodySelected(ActorBody actorBody)
|
||||
{
|
||||
if (actorBody == this)
|
||||
{ bodyRenderer.color = Constants.ColorGreen; }
|
||||
|
||||
else
|
||||
{ bodyRenderer.color = Constants.ColorWhite; }
|
||||
}
|
||||
|
||||
public void OnActorBodyPartSelected(ActorBodyPart bodyPart)
|
||||
{
|
||||
if (bodyPart.parent == this)
|
||||
{ bodyRenderer.color = Constants.ColorLightGreen; }
|
||||
|
||||
else
|
||||
{ bodyRenderer.color = Constants.ColorWhite; }
|
||||
}
|
||||
|
||||
public void Initialize(int actorID)
|
||||
{
|
||||
this.actorID = actorID;
|
||||
|
||||
if (actorID == Workspace.ActorID)
|
||||
{ Activate(); }
|
||||
}
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
if (eventData.pointerCurrentRaycast.gameObject.GetComponent<ActorBodyPart>())
|
||||
{ return; }
|
||||
|
||||
Activate();
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
Activate();
|
||||
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
|
||||
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
|
||||
|
||||
if (dragDelta == Vector3.zero)
|
||||
{ dragDelta = mousePosition - transform.position; }
|
||||
|
||||
if (Workspace.actorManipulationMode == ActorManipulationMode.Pan)
|
||||
{
|
||||
keyframe.BodyOffsetX = mousePosition.x - dragDelta.x - Workspace.GetActor(actorID).GetFinalTransformOffset().x;
|
||||
keyframe.BodyOffsetZ = mousePosition.y - dragDelta.y - Workspace.GetActor(actorID).GetFinalTransformOffset().y;
|
||||
}
|
||||
|
||||
else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)
|
||||
{
|
||||
float angle = -Vector2.SignedAngle(Vector2.down, (Vector2)mousePosition - (Vector2)transform.position);
|
||||
keyframe.BodyAngle = angle;
|
||||
}
|
||||
|
||||
else if (Workspace.actorManipulationMode == ActorManipulationMode.Face)
|
||||
{
|
||||
float angle = Vector2.SignedAngle(Vector2.up, (Vector2)mousePosition - (Vector2)transform.position);
|
||||
int facing = -Mathf.RoundToInt(angle / 90f );
|
||||
facing = facing < 0 ? facing + 4 : facing;
|
||||
|
||||
keyframe.BodyFacing = facing;
|
||||
}
|
||||
|
||||
PawnAnimationClip clip = Workspace.GetPawnAnimationClip(actorID);
|
||||
clip.BuildSimpleCurves();
|
||||
|
||||
EventsManager.OnPawnKeyframeChanged(keyframe);
|
||||
}
|
||||
|
||||
public void OnEndDrag(PointerEventData eventData)
|
||||
{
|
||||
Workspace.RecordEvent("Actor position / orientation");
|
||||
dragDelta = Vector3.zero;
|
||||
}
|
||||
|
||||
public ActorBodyPart GetActorBodyPart(string bodyPart)
|
||||
{
|
||||
return GetComponentsInChildren<ActorBodyPart>(true)?.FirstOrDefault(x => x.bodyPart.ToLower() == bodyPart);
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
Workspace.ActorID = actorID;
|
||||
Workspace.selectedBodyPart = null;
|
||||
|
||||
EventsManager.OnActorBodySelected(this);
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/Actors/ActorBody.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/Actors/ActorBody.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 511a9ed9093e7fc458dec8d3c657f9a5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
165
Source/Assets/Scripts/GUI/Actors/ActorBodyPart.cs
Normal file
165
Source/Assets/Scripts/GUI/Actors/ActorBodyPart.cs
Normal file
|
@ -0,0 +1,165 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class ActorBodyPart : MonoBehaviour, IPointerClickHandler, IDragHandler, IEndDragHandler
|
||||
{
|
||||
public SpriteRenderer bodyPartRenderer;
|
||||
public ActorBody parent;
|
||||
public string bodyPart;
|
||||
|
||||
private Vector3 dragDelta = new Vector3();
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (parent == null) return;
|
||||
|
||||
EventsManager.onActorBodyPartSelected.AddListener(delegate (ActorBodyPart bodyPart) { OnActorBodyPartSelected(bodyPart); });
|
||||
EventsManager.onActorBodySelected.AddListener(delegate (ActorBody actorBody) { OnActorBodySelected(actorBody); });
|
||||
|
||||
if (Workspace.ActorID == parent.actorID)
|
||||
{ parent.Activate(); }
|
||||
}
|
||||
|
||||
public void Initialize(ActorBody parent, ActorAddonDef actorAddonDef)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.bodyPart = actorAddonDef.addonName;
|
||||
|
||||
bodyPartRenderer.sprite = actorAddonDef.graphicData.GetSprite();
|
||||
bodyPartRenderer.transform.localScale = (Vector3)actorAddonDef.graphicData.GetDrawSize();
|
||||
|
||||
Start();
|
||||
}
|
||||
|
||||
public void OnActorAddonChange(ActorAddon actorAddon)
|
||||
{
|
||||
if (actorAddon.AddonName == bodyPart)
|
||||
{ gameObject?.SetActive(actorAddon.Render); }
|
||||
}
|
||||
|
||||
public void OnActorBodySelected(ActorBody actorBody)
|
||||
{
|
||||
if (actorBody == parent)
|
||||
{ bodyPartRenderer.color = Constants.ColorLightGreen; }
|
||||
|
||||
else
|
||||
{ bodyPartRenderer.color = Constants.ColorWhite; }
|
||||
}
|
||||
|
||||
public void OnActorBodyPartSelected(ActorBodyPart bodyPart)
|
||||
{
|
||||
if (bodyPart == this)
|
||||
{ bodyPartRenderer.color = Constants.ColorGreen; }
|
||||
|
||||
else if (bodyPart.parent == parent)
|
||||
{ bodyPartRenderer.color = Constants.ColorLightGreen; }
|
||||
|
||||
else
|
||||
{ bodyPartRenderer.color = Constants.ColorWhite; }
|
||||
}
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
if (eventData.pointerCurrentRaycast.gameObject.GetComponent<ActorBodyPart>() == null)
|
||||
{ return; }
|
||||
|
||||
Activate();
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
Activate();
|
||||
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
|
||||
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
|
||||
mousePosition = new Vector3(mousePosition.x, mousePosition.y, 0f);
|
||||
|
||||
if (dragDelta == Vector3.zero)
|
||||
{ dragDelta = mousePosition - transform.position; }
|
||||
|
||||
if (bodyPart.ToLower() == "head")
|
||||
{
|
||||
if (Workspace.actorManipulationMode == ActorManipulationMode.Pan)
|
||||
{
|
||||
// It's stupid, but it works
|
||||
Vector3 localPosA = transform.localPosition;
|
||||
transform.position = mousePosition - dragDelta;
|
||||
Vector3 localPosB = transform.localPosition;
|
||||
transform.localPosition = localPosA;
|
||||
|
||||
keyframe.HeadBob += localPosB.y - localPosA.y;
|
||||
}
|
||||
|
||||
else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)
|
||||
{
|
||||
float angle = -Vector2.SignedAngle(Vector2.down, (Vector2)mousePosition - (Vector2)transform.position);
|
||||
keyframe.HeadAngle = angle;
|
||||
}
|
||||
|
||||
else if (Workspace.actorManipulationMode == ActorManipulationMode.Face)
|
||||
{
|
||||
float angle = Vector2.SignedAngle(Vector2.up, (Vector2)mousePosition - (Vector2)transform.position);
|
||||
int facing = -Mathf.RoundToInt(angle / 90f);
|
||||
facing = facing < 0 ? facing + 4 : facing;
|
||||
|
||||
keyframe.HeadFacing = facing;
|
||||
}
|
||||
}
|
||||
|
||||
else if (bodyPart.ToLower() == "appendage")
|
||||
{
|
||||
if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)
|
||||
{
|
||||
float angle = -Vector2.SignedAngle(Vector2.up, (Vector2)mousePosition - (Vector2)transform.position);
|
||||
keyframe.GenitalAngle = angle;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
AddonKeyframe addonKeyframe = keyframe.GetAddonKeyframe(bodyPart);
|
||||
ActorAddon addon = Workspace.GetCurrentPawnAnimationClip().GetActorAddon(bodyPart);
|
||||
|
||||
if (Workspace.actorManipulationMode == ActorManipulationMode.Pan)
|
||||
{
|
||||
ActorBody anchoringActorBody = AnimationController.Instance.actorBodies.GetComponentsInChildren<ActorBody>()?.FirstOrDefault(x => x.actorID == addon.AnchoringActor);
|
||||
Vector3 anchor = PawnUtility.GetBodyPartAnchor(anchoringActorBody, addon.anchorName);
|
||||
transform.position = mousePosition - dragDelta;
|
||||
|
||||
addonKeyframe.PosX = transform.position.x - anchor.x;
|
||||
addonKeyframe.PosZ = transform.position.y - anchor.y;
|
||||
}
|
||||
|
||||
else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)
|
||||
{
|
||||
float angle = -Vector2.SignedAngle(Vector2.down, (Vector2)mousePosition - (Vector2)transform.position);
|
||||
addonKeyframe.Rotation = angle;
|
||||
}
|
||||
}
|
||||
|
||||
PawnAnimationClip clip = Workspace.GetPawnAnimationClip(parent.actorID);
|
||||
clip.BuildSimpleCurves();
|
||||
|
||||
EventsManager.OnPawnKeyframeChanged(keyframe);
|
||||
}
|
||||
|
||||
public void OnEndDrag(PointerEventData eventData)
|
||||
{
|
||||
Workspace.RecordEvent("Actor position / orientation");
|
||||
dragDelta = Vector3.zero;
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
Workspace.ActorID = parent.actorID;
|
||||
Workspace.selectedBodyPart = this;
|
||||
|
||||
EventsManager.OnActorBodyPartSelected(this);
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/Actors/ActorBodyPart.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/Actors/ActorBodyPart.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b23e33f312d52c642b86f5f2138f4030
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
28
Source/Assets/Scripts/GUI/AddSoundDefButton.cs
Normal file
28
Source/Assets/Scripts/GUI/AddSoundDefButton.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class AddSoundDefButton : MonoBehaviour
|
||||
{
|
||||
private Text text;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
text = GetComponentInChildren<Text>();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentOrPreviousKeyframe(Workspace.ActorID);
|
||||
|
||||
if (keyframe != null)
|
||||
{ text.text = string.IsNullOrEmpty(keyframe.SoundEffect) ? "None" : keyframe.SoundEffect; }
|
||||
|
||||
else
|
||||
{ text.text = "None"; }
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/AddSoundDefButton.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/AddSoundDefButton.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b7e9565ba13ac2e469767bcfad7da5d3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
19
Source/Assets/Scripts/GUI/AddonAnchorDropdown.cs
Normal file
19
Source/Assets/Scripts/GUI/AddonAnchorDropdown.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class AddonAnchorDropdown : MonoBehaviour
|
||||
{
|
||||
private void Start()
|
||||
{
|
||||
Dropdown dropdown = GetComponent<Dropdown>();
|
||||
|
||||
dropdown.ClearOptions();
|
||||
dropdown.AddOptions(Constants.bodyPartAnchorNames.Values.ToList());
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/AddonAnchorDropdown.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/AddonAnchorDropdown.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6a0ca236433ad584998f9c7a96dc3af8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
39
Source/Assets/Scripts/GUI/AnimationLengthsCard.cs
Normal file
39
Source/Assets/Scripts/GUI/AnimationLengthsCard.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class AnimationLengthsCard : MonoBehaviour
|
||||
{
|
||||
public Text stageLengthNormalText;
|
||||
public Text stageLengthQuickText;
|
||||
public Text animationLengthNormalText;
|
||||
public Text animationLengthQuickText;
|
||||
public float spacing = 10f;
|
||||
|
||||
private RectTransform rect;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
rect = GetComponent<RectTransform>();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(transform.parent.GetComponent<RectTransform>());
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(transform.parent.GetComponent<RectTransform>());
|
||||
rect.localPosition = new Vector3(rect.localPosition.x, spacing + transform.parent.GetComponent<RectTransform>().sizeDelta.y, rect.localPosition.z);
|
||||
|
||||
stageLengthNormalText.text = Workspace.GetCurrentAnimationStage().PlayTimeTicks + " (" + string.Format("{0:0.00}", Workspace.GetCurrentAnimationStage().PlayTimeTicks / 60f) + " s)";
|
||||
animationLengthNormalText.text = Workspace.animationDef.animationTimeTicks + " (" + string.Format("{0:0.00}", Workspace.animationDef.animationTimeTicks / 60f) + " s)";
|
||||
|
||||
stageLengthQuickText.text = Workspace.GetCurrentAnimationStage().PlayTimeTicksQuick + " (" + string.Format("{0:0.00}", Workspace.GetCurrentAnimationStage().PlayTimeTicksQuick / 60f) + " s)";
|
||||
animationLengthQuickText.text = Workspace.animationDef.animationTimeTicksQuick + " (" + string.Format("{0:0.00}", Workspace.animationDef.animationTimeTicksQuick / 60f) + " s)";
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/AnimationLengthsCard.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/AnimationLengthsCard.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 060e49b40b1097e46b662059e4e29cdf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
119
Source/Assets/Scripts/GUI/AnimationTimeline.cs
Normal file
119
Source/Assets/Scripts/GUI/AnimationTimeline.cs
Normal file
|
@ -0,0 +1,119 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class AnimationTimeline : MonoBehaviour, IPointerClickHandler
|
||||
{
|
||||
public int actorID = -1;
|
||||
public KeyframeSlider keyframeSliderPrefab;
|
||||
|
||||
private Transform anchorTransform;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
EventsManager.onAnimationTimelinesChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onKeyframeCountChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onActorIDChanged.AddListener(delegate { UpdateTimelineSelection(); });
|
||||
EventsManager.onStageWindowSizeChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onAnimationStageChanged.AddListener(delegate { UpdateGUI(); });
|
||||
|
||||
UpdateTimelineSelection();
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void Initialize(int actorID)
|
||||
{
|
||||
anchorTransform = transform.parent;
|
||||
this.actorID = actorID;
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void ClearKeyframeSliders()
|
||||
{
|
||||
foreach (KeyframeSlider slider in GetComponentsInChildren<KeyframeSlider>())
|
||||
{ Destroy(slider.gameObject); }
|
||||
}
|
||||
|
||||
public void UpdateGUI()
|
||||
{
|
||||
if (actorID < 0) return;
|
||||
|
||||
PawnAnimationClip clip = Workspace.GetPawnAnimationClip(actorID);
|
||||
if (clip == null) return;
|
||||
|
||||
clip.BuildSimpleCurves();
|
||||
|
||||
ClearKeyframeSliders();
|
||||
|
||||
foreach (PawnKeyframe keyframe in clip.Keyframes)
|
||||
{ AddPawnKeyFrame(keyframe.keyframeID); }
|
||||
|
||||
InitiateUpdateOfGhostFrames();
|
||||
}
|
||||
|
||||
public void UpdateTimelineSelection()
|
||||
{
|
||||
GetComponent<Image>().color = (Workspace.ActorID == actorID ? Constants.ColorGoldYellow : Constants.ColorMidGrey);
|
||||
}
|
||||
|
||||
public void AddPawnKeyFrame(int keyframeID)
|
||||
{
|
||||
KeyframeSlider keyframeSlider = Instantiate(keyframeSliderPrefab, transform);
|
||||
keyframeSlider.Initialize(this, actorID, keyframeID);
|
||||
}
|
||||
|
||||
public void RemovePawnKeyFrame(int keyframeID)
|
||||
{
|
||||
KeyframeSlider keyframeSlider = GetComponentsInChildren<KeyframeSlider>().FirstOrDefault(x => x.keyframeID == keyframeID);
|
||||
Destroy(keyframeSlider?.gameObject);
|
||||
}
|
||||
|
||||
public void InitiateUpdateOfGhostFrames()
|
||||
{
|
||||
BroadcastMessage("UpdateGhostFrames");
|
||||
}
|
||||
|
||||
public void OnMoveTimeline(int delta)
|
||||
{
|
||||
int? siblingIndex = anchorTransform.parent.GetComponentsInChildren<AnimationTimeline>()?.ToList()?.IndexOf(this);
|
||||
int? siblingCount = anchorTransform.parent.GetComponentsInChildren<AnimationTimeline>()?.ToList()?.Count();
|
||||
|
||||
if (siblingIndex != null && siblingCount != null && MoveAnimationTimeline(siblingIndex.Value, delta))
|
||||
{ AnimationController.Instance.Initialize(); }
|
||||
}
|
||||
|
||||
public bool MoveAnimationTimeline(int startIndex, int delta)
|
||||
{
|
||||
if (startIndex + delta < 0 || startIndex + delta >= Workspace.GetCurrentAnimationStage().AnimationClips.Count)
|
||||
{ Debug.Log("Cannot move animation timeline - movement would exceed bounds"); return false; }
|
||||
|
||||
Actor actor = Workspace.animationDef.Actors[startIndex];
|
||||
Workspace.animationDef.Actors[startIndex] = Workspace.animationDef.Actors[startIndex + delta];
|
||||
Workspace.animationDef.Actors[startIndex + delta] = actor;
|
||||
|
||||
PawnAnimationClip clip = Workspace.GetPawnAnimationClip(startIndex);
|
||||
Workspace.GetCurrentAnimationStage().AnimationClips[startIndex] = Workspace.GetCurrentAnimationStage().AnimationClips[startIndex + delta];
|
||||
Workspace.GetCurrentAnimationStage().AnimationClips[startIndex + delta] = clip;
|
||||
|
||||
Workspace.ActorID = startIndex + delta;
|
||||
|
||||
Workspace.RecordEvent("Timeline move");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
Workspace.ActorID = actorID;
|
||||
Workspace.keyframeID.Clear();
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/AnimationTimeline.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/AnimationTimeline.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b3dd6b099b5c67744b84a5ec7283277b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
22
Source/Assets/Scripts/GUI/ButtonWithKeyCode.cs
Normal file
22
Source/Assets/Scripts/GUI/ButtonWithKeyCode.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class ButtonWithKeyCode : Button
|
||||
{
|
||||
public KeyCode keyCode;
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (Input.GetKeyDown(keyCode))
|
||||
{ onClick.Invoke(); }
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/ButtonWithKeyCode.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/ButtonWithKeyCode.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1bfc022fc38c6474db2a742159e458f4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Source/Assets/Scripts/GUI/Cards.meta
Normal file
8
Source/Assets/Scripts/GUI/Cards.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c026d569e32726d4eb8821db713d0aac
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
102
Source/Assets/Scripts/GUI/Cards/ActorAddonCard.cs
Normal file
102
Source/Assets/Scripts/GUI/Cards/ActorAddonCard.cs
Normal file
|
@ -0,0 +1,102 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class ActorAddonCard : MonoBehaviour
|
||||
{
|
||||
public string addonName;
|
||||
public Text label;
|
||||
public Toggle toggle;
|
||||
public Dropdown anchorDropdown;
|
||||
public InputField anchoringPawnField;
|
||||
public Dropdown layerDropdown;
|
||||
public ActorAddonKeyframeCard actorAddonKeyframeCard;
|
||||
|
||||
private ActorAddonDef actorAddonDef;
|
||||
|
||||
private PawnAnimationClip clip { get { return Workspace.GetCurrentPawnAnimationClip(); } }
|
||||
|
||||
private void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Initialize(ActorAddonDef actorAddonDef, ActorAddonKeyframeCard actorAddonKeyframeCard)
|
||||
{
|
||||
this.actorAddonDef = actorAddonDef;
|
||||
this.actorAddonKeyframeCard = actorAddonKeyframeCard;
|
||||
|
||||
addonName = actorAddonDef.addonName;
|
||||
label.text = actorAddonDef.label;
|
||||
|
||||
EventsManager.onAnimationChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onActorIDChanged.AddListener(delegate { UpdateGUI(); });
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void UpdateGUI()
|
||||
{
|
||||
if (Workspace.animationDef == null || string.IsNullOrEmpty(addonName)) return;
|
||||
|
||||
if (clip?.GetActorAddon(addonName) != null)
|
||||
{
|
||||
int i = Constants.bodyPartAnchorNames.Keys.ToList().IndexOf(clip.GetActorAddon(addonName).AnchorName);
|
||||
anchorDropdown.SetValueWithoutNotify(i);
|
||||
layerDropdown.SetValueWithoutNotify(layerDropdown.options.IndexOf(layerDropdown.options.First(x => x.text == clip.GetActorAddon(addonName).Layer)));
|
||||
anchoringPawnField.SetTextWithoutNotify(clip.GetActorAddon(addonName).AnchoringActor.ToString());
|
||||
toggle.SetIsOnWithoutNotify(clip.IsActorAddonVisible(addonName));
|
||||
|
||||
anchoringPawnField.interactable = anchorDropdown.value != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnToggleChanged()
|
||||
{
|
||||
if (clip?.GetActorAddon(addonName) != null)
|
||||
{ clip.GetActorAddon(addonName).render = toggle.isOn; }
|
||||
|
||||
EventsManager.OnPawnKeyframeChanged(null);
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void OnAnchorChanged()
|
||||
{
|
||||
if (clip?.GetActorAddon(addonName) != null)
|
||||
{ clip.GetActorAddon(addonName).AnchorName = Constants.bodyPartAnchorNames.Keys.ElementAt(anchorDropdown.value); }
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void OnLayerChanged()
|
||||
{
|
||||
if (clip?.GetActorAddon(addonName) != null)
|
||||
{ clip.GetActorAddon(addonName).Layer = layerDropdown.options[layerDropdown.value].text; }
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void OnAnchoringPawnChanged()
|
||||
{
|
||||
if (clip?.GetActorAddon(addonName) != null)
|
||||
{
|
||||
int i = int.Parse(anchoringPawnField.text);
|
||||
|
||||
if (i < 0) { i = clip.GetOwningActorID(); }
|
||||
i = Mathf.Clamp(i, 0, Workspace.animationDef.Actors.Count - 1);
|
||||
|
||||
clip.GetActorAddon(addonName).AnchoringActor = i;
|
||||
anchoringPawnField.SetTextWithoutNotify(i.ToString());
|
||||
}
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/Cards/ActorAddonCard.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/Cards/ActorAddonCard.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 919aed3c4b9671c4e8dc109c7d608683
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
71
Source/Assets/Scripts/GUI/Cards/ActorAddonKeyframeCard.cs
Normal file
71
Source/Assets/Scripts/GUI/Cards/ActorAddonKeyframeCard.cs
Normal file
|
@ -0,0 +1,71 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class ActorAddonKeyframeCard : MonoBehaviour
|
||||
{
|
||||
public string addonName;
|
||||
public Text label;
|
||||
public InputField xOffsetField;
|
||||
public InputField zOffsetField;
|
||||
public InputField rotationField;
|
||||
|
||||
private ActorAddonDef actorAddonDef;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Initialize(ActorAddonDef actorAddonDef)
|
||||
{
|
||||
this.actorAddonDef = actorAddonDef;
|
||||
this.addonName = actorAddonDef.addonName;
|
||||
|
||||
label.text = actorAddonDef.label + ":";
|
||||
|
||||
EventsManager.onAnimationChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onStageIDChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onActorIDChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onStageTickChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onPawnKeyframeChanged.AddListener(delegate { UpdateGUI(); });
|
||||
|
||||
xOffsetField.onEndEdit.AddListener(delegate { OnValueChanged(); });
|
||||
zOffsetField.onEndEdit.AddListener(delegate { OnValueChanged(); });
|
||||
rotationField.onEndEdit.AddListener(delegate { OnValueChanged(); });
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void OnValueChanged()
|
||||
{
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
|
||||
|
||||
keyframe.GetAddonKeyframe(addonName).PosX = float.Parse(xOffsetField.text);
|
||||
keyframe.GetAddonKeyframe(addonName).PosZ = float.Parse(zOffsetField.text);
|
||||
keyframe.GetAddonKeyframe(addonName).Rotation = float.Parse(rotationField.text);
|
||||
|
||||
Workspace.GetCurrentPawnAnimationClip().BuildSimpleCurves();
|
||||
Workspace.RecordEvent("Actor addon position / orientation");
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void UpdateGUI()
|
||||
{
|
||||
PawnAnimationClip clip = Workspace.GetCurrentPawnAnimationClip();
|
||||
|
||||
xOffsetField.SetTextWithoutNotify(string.Format("{0:0.000}", clip.GetActorAddon(addonName).PosX.Evaluate((float)Workspace.StageTick / Workspace.StageWindowSize)));
|
||||
zOffsetField.SetTextWithoutNotify(string.Format("{0:0.000}", clip.GetActorAddon(addonName).PosZ.Evaluate((float)Workspace.StageTick / Workspace.StageWindowSize)));
|
||||
rotationField.SetTextWithoutNotify(string.Format("{0:0.000}", clip.GetActorAddon(addonName).Rotation.Evaluate((float)Workspace.StageTick / Workspace.StageWindowSize)));
|
||||
|
||||
gameObject.SetActive(clip.GetActorAddon(addonName).render == true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8a63bb35c73985c46b65383f08d4afd9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
129
Source/Assets/Scripts/GUI/Cards/ActorCard.cs
Normal file
129
Source/Assets/Scripts/GUI/Cards/ActorCard.cs
Normal file
|
@ -0,0 +1,129 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class ActorCard : MonoBehaviour
|
||||
{
|
||||
public Toggle initiatorToggle;
|
||||
public Dropdown selectActorLayerDropdown;
|
||||
public Dropdown bodyTypeDropdown;
|
||||
public InputField bodyOffsetXField;
|
||||
public InputField bodyOffsetZField;
|
||||
public Dropdown raceDropdown;
|
||||
public InputField raceOffsetXField;
|
||||
public InputField raceOffsetZField;
|
||||
|
||||
private Actor actor { get { return Workspace.GetCurrentActor(); } }
|
||||
private PawnAnimationClip clip { get { return Workspace.GetCurrentPawnAnimationClip(); } }
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
UpdateRaceDropdown();
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
// General events
|
||||
EventsManager.onAnimationChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onActorIDChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onDefNamesChanged.AddListener(delegate { UpdateRaceDropdown(); });
|
||||
|
||||
// Local events
|
||||
initiatorToggle.onValueChanged.AddListener(delegate {
|
||||
actor.initiator = initiatorToggle.isOn;
|
||||
Workspace.RecordEvent("Change in actor sex initiator status ");
|
||||
});
|
||||
|
||||
selectActorLayerDropdown.onValueChanged.AddListener(delegate {
|
||||
clip.Layer = selectActorLayerDropdown.options[selectActorLayerDropdown.value].text;
|
||||
Workspace.RecordEvent("Change in actor render layer");
|
||||
});
|
||||
|
||||
bodyTypeDropdown.onValueChanged.AddListener(delegate { OnDropdownChanged(); });
|
||||
bodyOffsetXField.onEndEdit.AddListener(delegate { OnInputFieldChanged(); });
|
||||
bodyOffsetZField.onEndEdit.AddListener(delegate { OnInputFieldChanged(); });
|
||||
|
||||
raceDropdown.onValueChanged.AddListener(delegate { OnDropdownChanged(); });
|
||||
raceOffsetXField.onEndEdit.AddListener(delegate { OnInputFieldChanged(); });
|
||||
raceOffsetZField.onEndEdit.AddListener(delegate { OnInputFieldChanged(); });
|
||||
|
||||
// Initialize
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void OnInputFieldChanged()
|
||||
{
|
||||
string bodyType = bodyTypeDropdown.options[bodyTypeDropdown.value].text;
|
||||
bodyType = string.IsNullOrEmpty(bodyType) ? "Male" : bodyType;
|
||||
|
||||
float.TryParse(bodyOffsetXField.text, out float x);
|
||||
float.TryParse(bodyOffsetZField.text, out float z);
|
||||
actor.BodyTypeOffset.SetOffset(bodyType, new Vector2(x, z));
|
||||
|
||||
float.TryParse(raceOffsetXField.text, out x);
|
||||
float.TryParse(raceOffsetZField.text, out z);
|
||||
actor.SetPawnRaceOffset(new Vector2(x, z));
|
||||
|
||||
Workspace.RecordEvent("Actor offset");
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void OnDropdownChanged()
|
||||
{
|
||||
actor.bodyType = bodyTypeDropdown.options[bodyTypeDropdown.value].text;
|
||||
|
||||
if (raceDropdown.options[raceDropdown.value].text != actor.GetPawnRaceDef().defName)
|
||||
{ Workspace.selectedBodyPart = null; }
|
||||
|
||||
actor.SetPawnRaceDef(raceDropdown.options[raceDropdown.value].text);
|
||||
|
||||
Workspace.RecordEvent("Actor body type/race change");
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void UpdateRaceDropdown()
|
||||
{
|
||||
int index = raceDropdown.value;
|
||||
raceDropdown.ClearOptions();
|
||||
|
||||
IEnumerable<string> optionsList = DefaultTags.defNames.Concat(CustomTags.defNames);
|
||||
foreach (string defName in optionsList)
|
||||
{ raceDropdown.options.Add(new Dropdown.OptionData(defName)); }
|
||||
|
||||
raceDropdown.value = Mathf.Clamp(index, 0, raceDropdown.options.Count - 1);
|
||||
raceDropdown.captionText.text = raceDropdown.options[raceDropdown.value].text;
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void UpdateGUI()
|
||||
{
|
||||
initiatorToggle.isOn = actor.Initiator;
|
||||
|
||||
string layer = clip.Layer;
|
||||
selectActorLayerDropdown.SetValueWithoutNotify(selectActorLayerDropdown.options.FindIndex(x => x.text == layer));
|
||||
|
||||
string bodyType = actor.bodyType;
|
||||
bodyTypeDropdown.SetValueWithoutNotify(bodyTypeDropdown.options.FindIndex(x => x.text == bodyType));
|
||||
|
||||
bodyOffsetXField.SetTextWithoutNotify(string.Format("{0:0.000}", actor.BodyTypeOffset.GetOffset(bodyType).x));
|
||||
bodyOffsetZField.SetTextWithoutNotify(string.Format("{0:0.000}", actor.BodyTypeOffset.GetOffset(bodyType).z));
|
||||
|
||||
bodyTypeDropdown.interactable = actor.GetPawnRaceDef().isHumanoid;
|
||||
bodyOffsetXField.interactable = actor.GetPawnRaceDef().isHumanoid;
|
||||
bodyOffsetZField.interactable = actor.GetPawnRaceDef().isHumanoid;
|
||||
|
||||
string race = actor.GetPawnRaceDef().defName;
|
||||
raceDropdown.SetValueWithoutNotify(raceDropdown.options.FindIndex(x => x.text == race));
|
||||
|
||||
raceOffsetXField.SetTextWithoutNotify(string.Format("{0:0.000}", actor.GetPawnRaceOffset().x));
|
||||
raceOffsetZField.SetTextWithoutNotify(string.Format("{0:0.000}", actor.GetPawnRaceOffset().z));
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/Cards/ActorCard.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/Cards/ActorCard.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9731614c7527b624492dd33f9b006fcb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
87
Source/Assets/Scripts/GUI/Cards/ActorKeyframeCard.cs
Normal file
87
Source/Assets/Scripts/GUI/Cards/ActorKeyframeCard.cs
Normal file
|
@ -0,0 +1,87 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class ActorKeyframeCard : Singleton<ActorKeyframeCard>
|
||||
{
|
||||
public InputField positionXField;
|
||||
public InputField positionZField;
|
||||
public InputField rotationField;
|
||||
public InputField headBobField;
|
||||
public InputField headRotationField;
|
||||
public InputField appendageRotationField;
|
||||
|
||||
public ActorAddonCard actorAddonCardPrefab;
|
||||
public ActorAddonKeyframeCard actorAddonKeyframeCardPrefab;
|
||||
|
||||
public Transform actorAddonCards;
|
||||
public Transform actorKeyframeCards;
|
||||
|
||||
public SelectActorAddonsDialog selectActorAddonsDialog;
|
||||
|
||||
private Actor actor { get { return Workspace.GetCurrentActor(); } }
|
||||
|
||||
private void Start()
|
||||
{
|
||||
EventsManager.onAnimationChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onStageIDChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onActorIDChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onStageTickChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onKeyframeCountChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onPawnKeyframeChanged.AddListener(delegate { UpdateGUI(); });
|
||||
|
||||
positionXField.onEndEdit.AddListener(delegate { OnValueChanged(); });
|
||||
positionZField.onEndEdit.AddListener(delegate { OnValueChanged(); });
|
||||
rotationField.onEndEdit.AddListener(delegate { OnValueChanged(); });
|
||||
headBobField.onEndEdit.AddListener(delegate { OnValueChanged(); });
|
||||
headRotationField.onEndEdit.AddListener(delegate { OnValueChanged(); });
|
||||
appendageRotationField.onEndEdit.AddListener(delegate { OnValueChanged(); });
|
||||
|
||||
foreach (ActorAddonDef actorAddonDef in ActorAddonDefs.allDefs)
|
||||
{
|
||||
ActorAddonKeyframeCard actorAddonKeyframeCard = Instantiate(actorAddonKeyframeCardPrefab, actorKeyframeCards);
|
||||
actorAddonKeyframeCard.Initialize(actorAddonDef);
|
||||
|
||||
ActorAddonCard actorAddonCard = Instantiate(actorAddonCardPrefab, actorAddonCards);
|
||||
actorAddonCard.Initialize(actorAddonDef, actorAddonKeyframeCard);
|
||||
|
||||
selectActorAddonsDialog.AddActorAddonCard(actorAddonCard);
|
||||
}
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void OnValueChanged()
|
||||
{
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
|
||||
|
||||
keyframe.BodyOffsetX = float.Parse(positionXField.text);
|
||||
keyframe.BodyOffsetZ = float.Parse(positionZField.text);
|
||||
keyframe.BodyAngle = float.Parse(rotationField.text);
|
||||
keyframe.HeadBob = float.Parse(headBobField.text);
|
||||
keyframe.HeadAngle = float.Parse(headRotationField.text);
|
||||
keyframe.GenitalAngle = float.Parse(appendageRotationField.text);
|
||||
|
||||
Workspace.GetCurrentPawnAnimationClip().BuildSimpleCurves();
|
||||
Workspace.RecordEvent("Actor position / orientation");
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void UpdateGUI()
|
||||
{
|
||||
ActorPosition actorPosition = actor.GetCurrentPosition();
|
||||
|
||||
positionXField.SetTextWithoutNotify(string.Format("{0:0.000}", actorPosition.bodyOffsetX));
|
||||
positionZField.SetTextWithoutNotify(string.Format("{0:0.000}", actorPosition.bodyOffsetZ));
|
||||
rotationField.SetTextWithoutNotify(string.Format("{0:0.000}", actorPosition.bodyAngle));
|
||||
headBobField.SetTextWithoutNotify(string.Format("{0:0.000}", actorPosition.headBob));
|
||||
headRotationField.SetTextWithoutNotify(string.Format("{0:0.000}", actorPosition.headAngle));
|
||||
appendageRotationField.SetTextWithoutNotify(string.Format("{0:0.000}", actorPosition.genitalAngle));
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/Cards/ActorKeyframeCard.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/Cards/ActorKeyframeCard.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 58ad3d066d9103541806d07bc98823d6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
94
Source/Assets/Scripts/GUI/Cards/AnimationControlCard.cs
Normal file
94
Source/Assets/Scripts/GUI/Cards/AnimationControlCard.cs
Normal file
|
@ -0,0 +1,94 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class AnimationControlCard : MonoBehaviour
|
||||
{
|
||||
public InputField currentTimeField;
|
||||
public InputField stageWindowLengthField;
|
||||
public InputField playBackSpeedField;
|
||||
public Button playToggleButton;
|
||||
public Slider stageTimelineSlider;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
EventsManager.onAnimationChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onStageIDChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onStageTickChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onAnimationToggled.AddListener(delegate { playToggleButton.image.color = Workspace.IsAnimating ? Constants.ColorGoldYellow : Constants.ColorWhite; });
|
||||
|
||||
stageTimelineSlider.onValueChanged.AddListener(delegate { OnStageTimelineSliderChange(); });
|
||||
currentTimeField.onEndEdit.AddListener(delegate { OnCurrentTimeFieldChange(); });
|
||||
stageWindowLengthField.onEndEdit.AddListener(delegate { OnStageWindowLengthFieldChange(); });
|
||||
playBackSpeedField.onEndEdit.AddListener(delegate { OnPlayBackSpeedChange(); });
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void OnStageTimelineSliderChange()
|
||||
{
|
||||
Workspace.StageTick = (int)stageTimelineSlider.value;
|
||||
}
|
||||
|
||||
public void OnPlayBackSpeedChange()
|
||||
{
|
||||
Workspace.PlayBackSpeed = float.Parse(playBackSpeedField.text);
|
||||
}
|
||||
|
||||
public void OnCurrentTimeFieldChange()
|
||||
{
|
||||
Workspace.StageTick = Mathf.Clamp(int.Parse(currentTimeField.text), Constants.minTick, Workspace.StageWindowSize);
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void OnStageWindowLengthFieldChange()
|
||||
{
|
||||
int.TryParse(stageWindowLengthField.text, out int newStageWindowSize);
|
||||
newStageWindowSize = Mathf.Clamp(newStageWindowSize, Constants.minAnimationClipLength, Constants.maxAnimationClipLength);
|
||||
|
||||
Debug.Log("Resizing animation clip length to " + newStageWindowSize.ToString() + " ticks.");
|
||||
|
||||
if (Workspace.stretchKeyframes)
|
||||
{ Workspace.GetCurrentAnimationStage().StretchStageWindow(newStageWindowSize); }
|
||||
|
||||
else
|
||||
{
|
||||
Workspace.GetCurrentAnimationStage().ResizeStageWindow(newStageWindowSize);
|
||||
|
||||
foreach (PawnAnimationClip clip in Workspace.GetCurrentAnimationStage().AnimationClips)
|
||||
{
|
||||
List<PawnKeyframe> keyframes = clip.Keyframes.Where(x => x.atTick > newStageWindowSize)?.ToList();
|
||||
|
||||
if (keyframes.NullOrEmpty())
|
||||
{ continue; }
|
||||
|
||||
foreach (PawnKeyframe keyframe in keyframes)
|
||||
{
|
||||
if (clip.Keyframes.Count <= 2)
|
||||
{ break; }
|
||||
|
||||
clip.RemovePawnKeyframe(keyframe.keyframeID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Workspace.RecordEvent("Stage length");
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void UpdateGUI()
|
||||
{
|
||||
stageTimelineSlider.maxValue = Workspace.StageWindowSize;
|
||||
stageTimelineSlider.SetValueWithoutNotify(Workspace.StageTick);
|
||||
currentTimeField.SetTextWithoutNotify(Workspace.StageTick.ToString());
|
||||
stageWindowLengthField.SetTextWithoutNotify(Workspace.StageWindowSize.ToString());
|
||||
playBackSpeedField.SetTextWithoutNotify(Workspace.PlayBackSpeed.ToString());
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/Cards/AnimationControlCard.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/Cards/AnimationControlCard.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6b414452bfd6c9b4bb99542a51d77468
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
39
Source/Assets/Scripts/GUI/Cards/AnimationDefCard.cs
Normal file
39
Source/Assets/Scripts/GUI/Cards/AnimationDefCard.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class AnimationDefCard : MonoBehaviour
|
||||
{
|
||||
public InputField defNameField;
|
||||
public InputField labelField;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
EventsManager.onAnimationChanged.AddListener(delegate { UpdateInputFields(); });
|
||||
|
||||
defNameField.onEndEdit.AddListener(delegate {
|
||||
Workspace.animationDef.DefName = defNameField.text;
|
||||
Workspace.MakeHistoricRecord("AnimationDef update");
|
||||
});
|
||||
|
||||
labelField.onEndEdit.AddListener(delegate {
|
||||
Workspace.animationDef.Label = labelField.text;
|
||||
Workspace.MakeHistoricRecord("AnimationDef update");
|
||||
});
|
||||
|
||||
UpdateInputFields();
|
||||
}
|
||||
|
||||
public void UpdateInputFields()
|
||||
{
|
||||
defNameField.SetTextWithoutNotify(Workspace.animationDef.DefName);
|
||||
labelField.SetTextWithoutNotify(Workspace.animationDef.Label);
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/Cards/AnimationDefCard.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/Cards/AnimationDefCard.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e1d8f33927e6b4d44914a445362b802d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
67
Source/Assets/Scripts/GUI/Cards/StageCard.cs
Normal file
67
Source/Assets/Scripts/GUI/Cards/StageCard.cs
Normal file
|
@ -0,0 +1,67 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class StageCard : MonoBehaviour, IPointerClickHandler
|
||||
{
|
||||
public Text stageName;
|
||||
public InputField stageNameField;
|
||||
public Image banner;
|
||||
|
||||
private int stageID { get { return transform.GetSiblingIndex(); } }
|
||||
|
||||
public void Start()
|
||||
{
|
||||
EventsManager.onStageIDChanged.AddListener(delegate { Initialize(stageName.text); });
|
||||
stageNameField.onEndEdit.AddListener(delegate { OnNameChange(); });
|
||||
}
|
||||
|
||||
public void Initialize(string stageName)
|
||||
{
|
||||
this.stageName.text = stageName;
|
||||
|
||||
if (Workspace.StageID == transform.GetSiblingIndex())
|
||||
{
|
||||
banner.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
banner.gameObject.SetActive(false);
|
||||
stageNameField.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnNameChange()
|
||||
{
|
||||
stageName.text = stageNameField.text;
|
||||
stageNameField.gameObject.SetActive(false);
|
||||
|
||||
Workspace.GetCurrentAnimationStage().StageName = stageName.text;
|
||||
Workspace.RecordEvent("Stage renamed");
|
||||
}
|
||||
|
||||
public void OnMoveStage(int delta)
|
||||
{
|
||||
Workspace.animationDef.MoveAnimationStage(stageID, delta);
|
||||
}
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
if (eventData.clickCount >= 2)
|
||||
{
|
||||
stageNameField.text = stageName.text;
|
||||
stageNameField.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
if (Workspace.StageID != transform.GetSiblingIndex())
|
||||
{ Workspace.RecordEvent("Stage selected"); }
|
||||
|
||||
Workspace.StageID = transform.GetSiblingIndex();
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/Cards/StageCard.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/Cards/StageCard.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 20b2be62d5fdc4b4992cede005ec2aee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
53
Source/Assets/Scripts/GUI/Cards/StageLoopsCard.cs
Normal file
53
Source/Assets/Scripts/GUI/Cards/StageLoopsCard.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class StageLoopsCard : MonoBehaviour
|
||||
{
|
||||
public InputField stageLoopsNormalField;
|
||||
public InputField stageLoopsQuickField;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
EventsManager.onAnimationTimelinesChanged.AddListener(delegate { UpdateGUI(); });
|
||||
EventsManager.onStageWindowSizeChanged.AddListener(delegate { UpdateGUI(); });
|
||||
|
||||
stageLoopsNormalField.onEndEdit.AddListener(delegate { OnStageLoopsNormalFieldChange(); });
|
||||
stageLoopsQuickField.onEndEdit.AddListener(delegate { OnStageLoopsFastFieldChange(); });
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
public void OnStageLoopsNormalFieldChange()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Workspace.GetCurrentAnimationStage().StageLoopsNormal = int.Parse(stageLoopsNormalField.text);
|
||||
|
||||
EventsManager.OnAnimationStageChanged(Workspace.GetCurrentAnimationStage());
|
||||
Workspace.RecordEvent("Cycle count (normal)");
|
||||
}
|
||||
|
||||
public void OnStageLoopsFastFieldChange()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Workspace.GetCurrentAnimationStage().StageLoopsQuick = int.Parse(stageLoopsQuickField.text);
|
||||
|
||||
EventsManager.OnAnimationStageChanged(Workspace.GetCurrentAnimationStage());
|
||||
Workspace.RecordEvent("Cycle count (fast)");
|
||||
}
|
||||
|
||||
public void UpdateGUI()
|
||||
{
|
||||
stageLoopsNormalField.SetTextWithoutNotify(Workspace.GetCurrentAnimationStage().StageLoopsNormal.ToString());
|
||||
stageLoopsQuickField.SetTextWithoutNotify(Workspace.GetCurrentAnimationStage().StageLoopsQuick.ToString());
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/Cards/StageLoopsCard.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/Cards/StageLoopsCard.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 38691dc973d99734f8f0f2a240df73fe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
24
Source/Assets/Scripts/GUI/Chaser.cs
Normal file
24
Source/Assets/Scripts/GUI/Chaser.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class Chaser : MonoBehaviour
|
||||
{
|
||||
public GameObject target;
|
||||
public bool chaseAlongX = true;
|
||||
public bool chaseAlongY = false;
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (target == null)
|
||||
{ return; }
|
||||
|
||||
float x = chaseAlongX ? target.transform.position.x : transform.position.x;
|
||||
float y = chaseAlongY ? target.transform.position.y : transform.position.y;
|
||||
|
||||
transform.position = new Vector3(x, y, 0f);
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/Chaser.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/Chaser.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9584d659e560b88409843604ae04229b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Source/Assets/Scripts/GUI/DialogBoxes.meta
Normal file
8
Source/Assets/Scripts/GUI/DialogBoxes.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: eabe165e5b1a70744a8073c1b5b541a7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,68 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class ConsoleMessagesDialog : MonoBehaviour
|
||||
{
|
||||
public bool isExpanded = false;
|
||||
public GameObject consoleWindow;
|
||||
public Transform logContent;
|
||||
public Text stackTrace;
|
||||
public Text currentMessage;
|
||||
public Text logMessagePrefab;
|
||||
public int maxMessages = 500;
|
||||
|
||||
private int currentMessages = 0;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
Application.logMessageReceived += LogMessage;
|
||||
}
|
||||
|
||||
public void ToggleExpand()
|
||||
{
|
||||
isExpanded = !isExpanded;
|
||||
|
||||
consoleWindow.SetActive(isExpanded);
|
||||
}
|
||||
|
||||
public void LogMessage(string logString, string stackTrace, LogType type)
|
||||
{
|
||||
if (currentMessages > maxMessages) return;
|
||||
currentMessages++;
|
||||
|
||||
currentMessage.text = logString;
|
||||
|
||||
Text logMessage = Instantiate(logMessagePrefab, logContent);
|
||||
logMessage.text = logString;
|
||||
|
||||
logMessage.GetComponent<Button>().onClick.AddListener(delegate { OpenStackTrace(stackTrace); });
|
||||
|
||||
if (type == LogType.Warning)
|
||||
{
|
||||
currentMessage.color = Constants.ColorRichOrange;
|
||||
logMessage.color = Constants.ColorRichOrange;
|
||||
}
|
||||
|
||||
else if (type == LogType.Exception || type == LogType.Error)
|
||||
{
|
||||
currentMessage.color = Constants.ColorRed;
|
||||
logMessage.color = Constants.ColorRed;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
currentMessage.color = Constants.ColorDarkGrey;
|
||||
logMessage.color = Constants.ColorDarkGrey;
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenStackTrace(string stackTrace)
|
||||
{
|
||||
this.stackTrace.text = stackTrace;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c62f9942e9d933848913ee2b28f65791
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
78
Source/Assets/Scripts/GUI/DialogBoxes/DialogBox.cs
Normal file
78
Source/Assets/Scripts/GUI/DialogBoxes/DialogBox.cs
Normal file
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class DialogBox : MonoBehaviour
|
||||
{
|
||||
public List<GameObject> cloneObjects;
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public void Pop()
|
||||
{
|
||||
Initialize();
|
||||
gameObject.SetActive(gameObject.activeSelf == false);
|
||||
}
|
||||
|
||||
public void RemoveCloneObjectsFromParent(Transform parent)
|
||||
{
|
||||
for (int i = 0; i < parent.childCount; i++)
|
||||
{ Destroy(parent.transform.GetChild(i).gameObject); }
|
||||
}
|
||||
|
||||
public GameObject AddCloneObjectToParent(Transform parent, int i = 0)
|
||||
{
|
||||
GameObject cloneObject = null;
|
||||
|
||||
if (cloneObjects != null && cloneObjects.Count > i)
|
||||
{ cloneObject = Instantiate(cloneObjects[i], parent); }
|
||||
|
||||
return cloneObject;
|
||||
}
|
||||
|
||||
public void AddCustomTag(InputField field, ref List<string> tags, ref List<string> customTags)
|
||||
{
|
||||
if (field?.text == null || field.text == "")
|
||||
{ return; }
|
||||
|
||||
if (tags.Contains(field.text) || customTags.Contains(field.text))
|
||||
{ field.text = ""; return; }
|
||||
|
||||
customTags.Add(field.text);
|
||||
|
||||
ApplicationManager.Instance.SaveCustomArrays();
|
||||
Initialize(true);
|
||||
}
|
||||
|
||||
public void RemoveCustomTag(ref List<string> customTags, string tag)
|
||||
{
|
||||
customTags.Remove(tag);
|
||||
|
||||
ApplicationManager.Instance.SaveCustomArrays();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public void AddCustomRace(InputField field)
|
||||
{
|
||||
if (field?.text == null || field.text == "")
|
||||
{ return; }
|
||||
|
||||
PawnRaceDefs.AddDef(new PawnRaceDef(field.text));
|
||||
|
||||
ApplicationManager.Instance.SavePawnRaceDefs();
|
||||
Initialize(true);
|
||||
}
|
||||
|
||||
public virtual void Initialize(bool addedNewTag = false) { }
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/DialogBoxes/DialogBox.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/DialogBoxes/DialogBox.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5a554bad525e79e4fb3dea0d391daf48
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
150
Source/Assets/Scripts/GUI/DialogBoxes/RaceSettingsDialog.cs
Normal file
150
Source/Assets/Scripts/GUI/DialogBoxes/RaceSettingsDialog.cs
Normal file
|
@ -0,0 +1,150 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using SFB;
|
||||
using System.IO;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class RaceSettingsDialog : DialogBox
|
||||
{
|
||||
public Dropdown raceSelectDropdown;
|
||||
public Transform raceSettingsWindow;
|
||||
public Toggle isHumanoidToggle;
|
||||
public InputField scaleField;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
raceSelectDropdown.ClearOptions();
|
||||
raceSelectDropdown.AddOptions(DefaultTags.defNames.Concat(CustomTags.defNames).ToList());
|
||||
|
||||
base.OnEnable();
|
||||
}
|
||||
|
||||
public override void Initialize(bool addedNewTag = false)
|
||||
{
|
||||
Reset();
|
||||
|
||||
PawnRaceDef pawnRaceDef = GetCurrentRaceDef();
|
||||
if (pawnRaceDef == null) return;
|
||||
|
||||
isHumanoidToggle.SetIsOnWithoutNotify(pawnRaceDef.isHumanoid);
|
||||
|
||||
Text bodyGraphicsTitle = AddCloneObjectToParent(raceSettingsWindow, 2).GetComponent<Text>();
|
||||
bodyGraphicsTitle.text = "Body graphic filepaths";
|
||||
|
||||
List<string> allTags = pawnRaceDef.isHumanoid ? DefaultTags.bodyTypes : new List<string>() { "None" };
|
||||
|
||||
foreach (string bodyType in allTags)
|
||||
{
|
||||
string _bodyType = bodyType;
|
||||
|
||||
if (pawnRaceDef.isHumanoid)
|
||||
{
|
||||
Text bodyTypeTitle = AddCloneObjectToParent(raceSettingsWindow, 2).GetComponent<Text>();
|
||||
bodyTypeTitle.text = bodyType;
|
||||
}
|
||||
|
||||
for (int i = 2; i >= 0; i--)
|
||||
{
|
||||
CardinalDirection facing = (CardinalDirection)i;
|
||||
|
||||
GameObject filepath = AddCloneObjectToParent(raceSettingsWindow, 0);
|
||||
filepath.GetComponent<Text>().text = facing.ToString();
|
||||
filepath.transform.Find("FilepathButton").GetComponent<Button>().onClick.AddListener(delegate
|
||||
{
|
||||
SetBodyTypeGraphicPath(pawnRaceDef, facing, _bodyType);
|
||||
});
|
||||
filepath.transform.FindDeepChild("FilepathLabel").GetComponent<Text>().text = pawnRaceDef.GetBodyTypeGraphicPath(facing, _bodyType);
|
||||
}
|
||||
|
||||
AddCloneObjectToParent(raceSettingsWindow, 3);
|
||||
}
|
||||
|
||||
if (pawnRaceDef.isHumanoid)
|
||||
{
|
||||
Text headGraphics = AddCloneObjectToParent(raceSettingsWindow, 2).GetComponent<Text>();
|
||||
headGraphics.text = "Head graphic filepaths";
|
||||
|
||||
for (int i = 2; i >= 0; i--)
|
||||
{
|
||||
CardinalDirection facing = (CardinalDirection)i;
|
||||
|
||||
GameObject filepath = AddCloneObjectToParent(raceSettingsWindow, 0);
|
||||
filepath.GetComponent<Text>().text = facing.ToString();
|
||||
filepath.transform.Find("FilepathButton").GetComponent<Button>().onClick.AddListener(delegate
|
||||
{
|
||||
SetHeadGraphicPath(pawnRaceDef, facing);
|
||||
});
|
||||
filepath.transform.FindDeepChild("FilepathLabel").GetComponent<Text>().text = pawnRaceDef.GetHeadGraphicPath(facing);
|
||||
}
|
||||
|
||||
AddCloneObjectToParent(raceSettingsWindow, 3);
|
||||
}
|
||||
|
||||
scaleField.text = string.Format("{0:0.000}", pawnRaceDef.scale);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
RemoveCloneObjectsFromParent(raceSettingsWindow);
|
||||
}
|
||||
|
||||
public void SetIsHumanoid()
|
||||
{
|
||||
PawnRaceDef pawnRaceDef = GetCurrentRaceDef();
|
||||
if (pawnRaceDef == null) return;
|
||||
|
||||
pawnRaceDef.isHumanoid = isHumanoidToggle.isOn;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public void SetHeadGraphicPath(PawnRaceDef pawnRaceDef, CardinalDirection direction)
|
||||
{
|
||||
var paths = StandaloneFileBrowser.OpenFilePanel("Select texture File", "", "png", false);
|
||||
|
||||
if (paths == null || paths.Any() == false || File.Exists(paths[0]) == false)
|
||||
{ Debug.LogWarning("Selected file was null or invalid"); return; }
|
||||
|
||||
pawnRaceDef.SetHeadGraphicPath(paths[0], direction);
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public void SetBodyTypeGraphicPath(PawnRaceDef pawnRaceDef, CardinalDirection direction, string bodyType)
|
||||
{
|
||||
var paths = StandaloneFileBrowser.OpenFilePanel("Select texture File", "", "png", false);
|
||||
|
||||
if (paths == null || paths.Any() == false || File.Exists(paths[0]) == false)
|
||||
{ Debug.LogWarning("Selected file was null or invalid"); return; }
|
||||
|
||||
pawnRaceDef.SetBodyTypeGraphicPath(paths[0], direction, bodyType);
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public PawnRaceDef GetCurrentRaceDef()
|
||||
{
|
||||
string pawnRaceDefName = raceSelectDropdown.value < raceSelectDropdown.options.Count ? raceSelectDropdown.options[raceSelectDropdown.value].text : "Human";
|
||||
if (pawnRaceDefName == null || pawnRaceDefName == "") pawnRaceDefName = "Human";
|
||||
|
||||
return PawnRaceDefs.GetNamed(pawnRaceDefName);
|
||||
}
|
||||
|
||||
public void SetRaceScale()
|
||||
{
|
||||
PawnRaceDef pawnRaceDef = GetCurrentRaceDef();
|
||||
if (pawnRaceDef == null) return;
|
||||
|
||||
float scale = float.Parse(scaleField.text);
|
||||
pawnRaceDef.scale = Mathf.Clamp(scale, 0.01f, 100f);
|
||||
|
||||
scaleField.text = string.Format("{0:0.000}", pawnRaceDef.scale);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 983d00d4d240d6c4780e903708f27c06
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class SelectActorAddonsDialog : DialogBox
|
||||
{
|
||||
private List<ActorAddonCard> actorAddonCards = new List<ActorAddonCard>();
|
||||
|
||||
public void AddActorAddonCard(ActorAddonCard actorAddonCard)
|
||||
{
|
||||
actorAddonCards.Add(actorAddonCard);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 869b2cd91a545c142b38856695c4257a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class SelectActorLayerDialog : DialogBox
|
||||
{
|
||||
public void Initialize()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
Reset();
|
||||
|
||||
for (int i = 0; i < DefaultTags.actorLayers.Count; i++)
|
||||
{
|
||||
string actorLayer = DefaultTags.actorLayers[i];
|
||||
|
||||
Transform _optionToggle = AddCloneObjectToParent(contentWindow).transform;
|
||||
_optionToggle.Find("Text").GetComponent<Text>().text = actorLayer;
|
||||
|
||||
Toggle toggleComp = _optionToggle.GetComponent<Toggle>();
|
||||
toggleComp.isOn = Workspace.GetCurrentPawnAnimationClip().Layer == actorLayer;
|
||||
toggleComp.onValueChanged.AddListener(delegate {
|
||||
|
||||
PawnAnimationClip clip = Workspace.GetCurrentPawnAnimationClip();
|
||||
|
||||
if (clip != null)
|
||||
{ clip.Layer = actorLayer; }
|
||||
|
||||
Workspace.RecordEvent("Actor layer set");
|
||||
});
|
||||
|
||||
toggleComp.group = contentWindow.GetComponent<ToggleGroup>();
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
RemoveCloneObjectsFromParent(contentWindow);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ce4b68a13ad01b14f97697ab310a74d9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class SelectAnimationDialog : DialogBox
|
||||
{
|
||||
public void Initialize(AnimationDefs defs)
|
||||
{
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
Reset();
|
||||
|
||||
for (int i = 0; i < defs.animationDefs.Count; i++)
|
||||
{
|
||||
AnimationDef animationDef = defs.animationDefs[i];
|
||||
|
||||
Transform _optionButton = AddCloneObjectToParent(contentWindow).transform;
|
||||
_optionButton.Find("Text").GetComponent<Text>().text = animationDef.DefName;
|
||||
|
||||
Button buttonComp = _optionButton.GetComponent<Button>();
|
||||
buttonComp.onClick.AddListener(delegate { Pop(); ApplicationManager.Instance.LoadAnimation(animationDef); });
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
RemoveCloneObjectsFromParent(contentWindow);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6db038d692d34c441b171c72c78e0066
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class SelectBodyDefTypesDialog : DialogBox
|
||||
{
|
||||
public override void Initialize(bool addedNewTag = false)
|
||||
{
|
||||
IEnumerable<string> allTags = DefaultTags.bodyDefTypes.Concat(CustomTags.bodyDefTypes);
|
||||
string placeHolderText = "Enter new body def type...";
|
||||
|
||||
Actor actor = Workspace.animationDef.Actors[Workspace.ActorID];
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
Reset();
|
||||
|
||||
for (int i = 0; i < allTags.Count(); i++)
|
||||
{
|
||||
string tag = allTags.ElementAt(i);
|
||||
|
||||
Transform _optionToggle = AddCloneObjectToParent(contentWindow).transform;
|
||||
_optionToggle.Find("Text").GetComponent<Text>().text = tag;
|
||||
|
||||
Toggle toggleComp = _optionToggle.GetComponent<Toggle>();
|
||||
toggleComp.isOn = actor.BodyDefTypes.Contains(tag);
|
||||
toggleComp.onValueChanged.AddListener(delegate
|
||||
{
|
||||
if (toggleComp.isOn && actor.BodyDefTypes.Contains(tag) == false)
|
||||
{ actor.BodyDefTypes.Add(tag); }
|
||||
|
||||
else if (toggleComp.isOn == false && actor.BodyDefTypes.Contains(tag))
|
||||
{ actor.BodyDefTypes.Remove(tag); }
|
||||
|
||||
Workspace.RecordEvent("Actor bodyDef type");
|
||||
});
|
||||
|
||||
if (CustomTags.bodyDefTypes.Contains(tag))
|
||||
{
|
||||
Button deleteButton = _optionToggle.Find("DeleteButton").GetComponent<Button>();
|
||||
deleteButton.gameObject.SetActive(true);
|
||||
deleteButton.onClick.AddListener(delegate { RemoveCustomTag(ref CustomTags.bodyDefTypes, tag); });
|
||||
}
|
||||
|
||||
if (addedNewTag && i == allTags.Count() - 1)
|
||||
{ toggleComp.isOn = true; }
|
||||
}
|
||||
|
||||
Transform _optionField = AddCloneObjectToParent(contentWindow, 1).transform;
|
||||
_optionField.Find("Placeholder").GetComponent<Text>().text = placeHolderText;
|
||||
|
||||
InputField fieldComp = _optionField.GetComponent<InputField>();
|
||||
fieldComp.onEndEdit.AddListener(delegate { AddCustomTag(fieldComp, ref DefaultTags.bodyDefTypes, ref CustomTags.bodyDefTypes); });
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
RemoveCloneObjectsFromParent(contentWindow);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b66fb83b0bed5a0438f6fbe11f0c35e0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class SelectBodyPartsDialog : DialogBox
|
||||
{
|
||||
public override void Initialize(bool addedNewTag = false)
|
||||
{
|
||||
IEnumerable<string> allTags = DefaultTags.bodyParts.Concat(CustomTags.bodyParts);
|
||||
string placeHolderText = "Enter new body part name...";
|
||||
|
||||
Actor actor = Workspace.animationDef.Actors[Workspace.ActorID];
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
Reset();
|
||||
|
||||
Transform _appendageToggle = AddCloneObjectToParent(contentWindow).transform;
|
||||
_appendageToggle.Find("Text").GetComponent<Text>().text = "Any appendage";
|
||||
|
||||
Toggle appendageToggleComp = _appendageToggle.GetComponent<Toggle>();
|
||||
appendageToggleComp.isOn = actor.IsFucking;
|
||||
appendageToggleComp.onValueChanged.AddListener(delegate { actor.IsFucking = appendageToggleComp.isOn; Workspace.RecordEvent("Actor required body part");});
|
||||
|
||||
Transform _orificeToggle = AddCloneObjectToParent(contentWindow).transform;
|
||||
_orificeToggle.Find("Text").GetComponent<Text>().text = "Any orifice";
|
||||
|
||||
Toggle orificeToggleComp = _orificeToggle.GetComponent<Toggle>();
|
||||
orificeToggleComp.isOn = actor.IsFucked;
|
||||
orificeToggleComp.onValueChanged.AddListener(delegate { actor.IsFucked = orificeToggleComp.isOn; Workspace.RecordEvent("Actor required body part"); });
|
||||
|
||||
for (int i = 0; i < allTags.Count(); i++)
|
||||
{
|
||||
string tag = allTags.ElementAt(i);
|
||||
|
||||
Transform _optionToggle = AddCloneObjectToParent(contentWindow).transform;
|
||||
_optionToggle.Find("Text").GetComponent<Text>().text = tag;
|
||||
|
||||
Toggle toggleComp = _optionToggle.GetComponent<Toggle>();
|
||||
toggleComp.isOn = actor.RequiredGenitals.Contains(tag);
|
||||
toggleComp.onValueChanged.AddListener(delegate
|
||||
{
|
||||
if (toggleComp.isOn && actor.RequiredGenitals.Contains(tag) == false)
|
||||
{ actor.RequiredGenitals.Add(tag); }
|
||||
|
||||
else if (toggleComp.isOn == false && actor.RequiredGenitals.Contains(tag))
|
||||
{ actor.RequiredGenitals.Remove(tag); }
|
||||
|
||||
Workspace.RecordEvent("Actor required body part");
|
||||
});
|
||||
|
||||
if (CustomTags.bodyParts.Contains(tag))
|
||||
{
|
||||
Button deleteButton = _optionToggle.Find("DeleteButton").GetComponent<Button>();
|
||||
deleteButton.gameObject.SetActive(true);
|
||||
deleteButton.onClick.AddListener(delegate { RemoveCustomTag(ref CustomTags.bodyParts, tag); });
|
||||
}
|
||||
|
||||
if (addedNewTag && i == allTags.Count() - 1)
|
||||
{ toggleComp.isOn = true; }
|
||||
}
|
||||
|
||||
Transform _optionField = AddCloneObjectToParent(contentWindow, 1).transform;
|
||||
_optionField.Find("Placeholder").GetComponent<Text>().text = placeHolderText;
|
||||
|
||||
InputField fieldComp = _optionField.GetComponent<InputField>();
|
||||
fieldComp.onEndEdit.AddListener(delegate { AddCustomTag(fieldComp, ref DefaultTags.bodyParts, ref CustomTags.bodyParts); });
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
RemoveCloneObjectsFromParent(contentWindow);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 459a1b2a918e12f468445853ea5821e0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class SelectDefNamesDialog : DialogBox
|
||||
{
|
||||
public override void Initialize(bool addedNewTag = false)
|
||||
{
|
||||
IEnumerable<string> allTags = DefaultTags.defNames.Concat(CustomTags.defNames);
|
||||
string placeHolderText = "Enter new def name...";
|
||||
|
||||
Actor actor = Workspace.animationDef.Actors[Workspace.ActorID];
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
Reset();
|
||||
|
||||
for (int i = 0; i < allTags.Count(); i++)
|
||||
{
|
||||
string tag = allTags.ElementAt(i);
|
||||
|
||||
Transform _optionToggle = AddCloneObjectToParent(contentWindow).transform;
|
||||
_optionToggle.Find("Text").GetComponent<Text>().text = tag;
|
||||
|
||||
Toggle toggleComp = _optionToggle.GetComponent<Toggle>();
|
||||
toggleComp.isOn = actor.DefNames.Contains(tag);
|
||||
toggleComp.onValueChanged.AddListener(delegate
|
||||
{
|
||||
if (toggleComp.isOn && actor.DefNames.Contains(tag) == false)
|
||||
{ actor.DefNames.Add(tag); }
|
||||
|
||||
else if (toggleComp.isOn == false && actor.DefNames.Contains(tag))
|
||||
{ actor.DefNames.Remove(tag); }
|
||||
|
||||
Workspace.RecordEvent("Actor def name");
|
||||
});
|
||||
|
||||
if (CustomTags.defNames.Contains(tag))
|
||||
{
|
||||
Button deleteButton = _optionToggle.Find("DeleteButton").GetComponent<Button>();
|
||||
deleteButton.gameObject.SetActive(true);
|
||||
deleteButton.onClick.AddListener(delegate {
|
||||
RemoveCustomTag(ref CustomTags.defNames, tag);
|
||||
EventsManager.OnDefNamesChanged();
|
||||
});
|
||||
}
|
||||
|
||||
if (addedNewTag && i == allTags.Count() - 1)
|
||||
{ toggleComp.isOn = true; }
|
||||
}
|
||||
|
||||
Transform _optionField = AddCloneObjectToParent(contentWindow, 1).transform;
|
||||
_optionField.Find("Placeholder").GetComponent<Text>().text = placeHolderText;
|
||||
|
||||
InputField fieldComp = _optionField.GetComponent<InputField>();
|
||||
fieldComp.onEndEdit.AddListener(delegate
|
||||
{
|
||||
AddCustomTag(fieldComp, ref DefaultTags.defNames, ref CustomTags.defNames);
|
||||
AddCustomRace(fieldComp);
|
||||
EventsManager.OnDefNamesChanged();
|
||||
});
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
RemoveCloneObjectsFromParent(contentWindow);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9842b9e0fd45d4643af5bed7ba2de307
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class SelectInteractionDefsDialog : DialogBox
|
||||
{
|
||||
public override void Initialize(bool addedNewTag = false)
|
||||
{
|
||||
IEnumerable<string> allTags = DefaultTags.interactionDefTypes.Concat(CustomTags.interactionDefTypes);
|
||||
string placeHolderText = "Enter new interaction def type...";
|
||||
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
Reset();
|
||||
|
||||
for (int i = 0; i < allTags.Count(); i++)
|
||||
{
|
||||
string tag = allTags.ElementAt(i);
|
||||
|
||||
Transform _optionToggle = AddCloneObjectToParent(contentWindow).transform;
|
||||
_optionToggle.Find("Text").GetComponent<Text>().text = tag;
|
||||
|
||||
Toggle toggleComp = _optionToggle.GetComponent<Toggle>();
|
||||
toggleComp.isOn = Workspace.animationDef.InteractionDefTypes.Contains(tag);
|
||||
toggleComp.onValueChanged.AddListener(delegate
|
||||
{
|
||||
if (toggleComp.isOn && Workspace.animationDef.InteractionDefTypes.Contains(tag) == false)
|
||||
{ Workspace.animationDef.InteractionDefTypes.Add(tag); }
|
||||
|
||||
else if (toggleComp.isOn == false && Workspace.animationDef.InteractionDefTypes.Contains(tag))
|
||||
{ Workspace.animationDef.InteractionDefTypes.Remove(tag); }
|
||||
|
||||
Workspace.RecordEvent("Animation InteractionDef");
|
||||
});
|
||||
|
||||
if (CustomTags.interactionDefTypes.Contains(tag))
|
||||
{
|
||||
Button deleteButton = _optionToggle.Find("DeleteButton").GetComponent<Button>();
|
||||
deleteButton.gameObject.SetActive(true);
|
||||
deleteButton.onClick.AddListener(delegate { RemoveCustomTag(ref CustomTags.interactionDefTypes, tag); });
|
||||
}
|
||||
|
||||
if (addedNewTag && i == allTags.Count() - 1)
|
||||
{ toggleComp.isOn = true; }
|
||||
}
|
||||
|
||||
Transform _optionField = AddCloneObjectToParent(contentWindow, 1).transform;
|
||||
_optionField.Find("Placeholder").GetComponent<Text>().text = placeHolderText;
|
||||
|
||||
InputField fieldComp = _optionField.GetComponent<InputField>();
|
||||
fieldComp.onEndEdit.AddListener(delegate { AddCustomTag(fieldComp, ref DefaultTags.interactionDefTypes, ref CustomTags.interactionDefTypes); });
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
RemoveCloneObjectsFromParent(contentWindow);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cace588a3682dc649b94355d8eee4a77
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class SelectSexTypesDialog : DialogBox
|
||||
{
|
||||
public override void Initialize(bool addedNewTag = false)
|
||||
{
|
||||
IEnumerable<string> allTags = DefaultTags.sexTypes.Concat(CustomTags.sexTypes);
|
||||
string placeHolderText = "Enter new sex type...";
|
||||
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
Reset();
|
||||
|
||||
for (int i = 0; i < allTags.Count(); i++)
|
||||
{
|
||||
string tag = allTags.ElementAt(i);
|
||||
|
||||
Transform _optionToggle = AddCloneObjectToParent(contentWindow).transform;
|
||||
_optionToggle.Find("Text").GetComponent<Text>().text = tag;
|
||||
|
||||
Toggle toggleComp = _optionToggle.GetComponent<Toggle>();
|
||||
toggleComp.isOn = Workspace.animationDef.SexTypes.Contains(tag);
|
||||
toggleComp.onValueChanged.AddListener(delegate
|
||||
{
|
||||
if (toggleComp.isOn && Workspace.animationDef.SexTypes.Contains(tag) == false)
|
||||
{ Workspace.animationDef.SexTypes.Add(tag); }
|
||||
|
||||
else if (toggleComp.isOn == false && Workspace.animationDef.SexTypes.Contains(tag))
|
||||
{ Workspace.animationDef.SexTypes.Remove(tag); }
|
||||
|
||||
Workspace.RecordEvent("Animation sex type");
|
||||
});
|
||||
|
||||
if (CustomTags.sexTypes.Contains(tag))
|
||||
{
|
||||
Button deleteButton = _optionToggle.Find("DeleteButton").GetComponent<Button>();
|
||||
deleteButton.gameObject.SetActive(true);
|
||||
deleteButton.onClick.AddListener(delegate { RemoveCustomTag(ref CustomTags.sexTypes, tag); });
|
||||
}
|
||||
|
||||
if (addedNewTag && i == allTags.Count() - 1)
|
||||
{ toggleComp.isOn = true; }
|
||||
}
|
||||
|
||||
Transform _optionField = AddCloneObjectToParent(contentWindow, 1).transform;
|
||||
_optionField.Find("Placeholder").GetComponent<Text>().text = placeHolderText;
|
||||
|
||||
InputField fieldComp = _optionField.GetComponent<InputField>();
|
||||
fieldComp.onEndEdit.AddListener(delegate { AddCustomTag(fieldComp, ref DefaultTags.sexTypes, ref CustomTags.sexTypes); });
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
RemoveCloneObjectsFromParent(contentWindow);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1d4b7a5a5ddb7d744b726c3c13e2fc5e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class SelectSoundDefDialog : DialogBox
|
||||
{
|
||||
public override void Initialize(bool addedNewTag = false)
|
||||
{
|
||||
IEnumerable<string> allTags = DefaultTags.soundDefs.Concat(CustomTags.soundDefs);
|
||||
string placeHolderText = "Enter new sound def...";
|
||||
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
Reset();
|
||||
|
||||
for (int i = 0; i < allTags.Count(); i++)
|
||||
{
|
||||
string tag = allTags.ElementAt(i);
|
||||
|
||||
Transform _optionToggle = AddCloneObjectToParent(contentWindow).transform;
|
||||
_optionToggle.Find("Text").GetComponent<Text>().text = tag;
|
||||
|
||||
Toggle toggleComp = _optionToggle.GetComponent<Toggle>();
|
||||
toggleComp.isOn = Workspace.GetCurrentOrPreviousKeyframe(Workspace.ActorID)?.SoundEffect == tag;
|
||||
toggleComp.onValueChanged.AddListener(delegate
|
||||
{
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentOrPreviousKeyframe(Workspace.ActorID);
|
||||
|
||||
if (keyframe != null)
|
||||
{ keyframe.SoundEffect = tag; }
|
||||
|
||||
Workspace.RecordEvent("Keyframe sound effect");
|
||||
});
|
||||
|
||||
if (CustomTags.soundDefs.Contains(tag))
|
||||
{
|
||||
Button deleteButton = _optionToggle.Find("DeleteButton").GetComponent<Button>();
|
||||
deleteButton.gameObject.SetActive(true);
|
||||
deleteButton.onClick.AddListener(delegate { RemoveCustomTag(ref CustomTags.soundDefs, tag); });
|
||||
}
|
||||
|
||||
if (addedNewTag && i == allTags.Count() - 1)
|
||||
{ toggleComp.isOn = true; }
|
||||
|
||||
toggleComp.group = contentWindow.GetComponent<ToggleGroup>();
|
||||
}
|
||||
|
||||
Transform _optionField = AddCloneObjectToParent(contentWindow, 1).transform;
|
||||
_optionField.Find("Placeholder").GetComponent<Text>().text = placeHolderText;
|
||||
|
||||
InputField fieldComp = _optionField.GetComponent<InputField>();
|
||||
fieldComp.onEndEdit.AddListener(delegate { AddCustomTag(fieldComp, ref DefaultTags.soundDefs, ref CustomTags.soundDefs); });
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Transform contentWindow = transform.FindDeepChild("Content");
|
||||
RemoveCloneObjectsFromParent(contentWindow);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7cc6afc7ba6ae0f42b3a2df6e73c5b16
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
43
Source/Assets/Scripts/GUI/DropdownMenu.cs
Normal file
43
Source/Assets/Scripts/GUI/DropdownMenu.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class DropdownMenu : MonoBehaviour, IDeselectHandler
|
||||
{
|
||||
public Transform dropdownMenu;
|
||||
|
||||
public void OpenMenu()
|
||||
{
|
||||
dropdownMenu.gameObject.SetActive(true);
|
||||
EventSystem.current.SetSelectedGameObject(this.gameObject);
|
||||
}
|
||||
|
||||
public void CloseMenu()
|
||||
{
|
||||
if (EventSystem.current.currentSelectedGameObject != null)
|
||||
{
|
||||
Transform child = transform.FindDeepChild(EventSystem.current.currentSelectedGameObject.name);
|
||||
|
||||
if (child != null)
|
||||
{
|
||||
EventSystem.current.SetSelectedGameObject(this.gameObject);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dropdownMenu.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
public void OnDeselect(BaseEventData eventData)
|
||||
{
|
||||
Invoke("CloseMenu", 0.15f);
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/DropdownMenu.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/DropdownMenu.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7367efff96a6a9043ac1c6b3a25dcc39
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
22
Source/Assets/Scripts/GUI/InactiveDuringAnimationPreview.cs
Normal file
22
Source/Assets/Scripts/GUI/InactiveDuringAnimationPreview.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class InactiveDuringAnimationPreview : MonoBehaviour
|
||||
{
|
||||
private InputField inputfield;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
inputfield = GetComponent<InputField>();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
inputfield.interactable = Workspace.IsAnimating == false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 92068b39ed172084296a595f5a09e54b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
23
Source/Assets/Scripts/GUI/KeybindLabel.cs
Normal file
23
Source/Assets/Scripts/GUI/KeybindLabel.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class KeybindLabel : MonoBehaviour
|
||||
{
|
||||
public string command;
|
||||
|
||||
private Text keybindLabel;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
keybindLabel = GetComponent<Text>();
|
||||
keybindLabel.text = KeybindConfig.GetKeybindLabel(command);
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/KeybindLabel.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/KeybindLabel.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2aa5d5fba80ba8346882964ef3756de3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
261
Source/Assets/Scripts/GUI/KeyframeSlider.cs
Normal file
261
Source/Assets/Scripts/GUI/KeyframeSlider.cs
Normal file
|
@ -0,0 +1,261 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class KeyframeSlider : Slider, IPointerClickHandler, IBeginDragHandler, IEndDragHandler
|
||||
{
|
||||
public int keyframeID;
|
||||
public AnimationTimeline timeline;
|
||||
public Transform ghostSliders;
|
||||
public Slider ghostSliderPrefab;
|
||||
public Image handleImage;
|
||||
public GameObject soundIcon;
|
||||
public int maxGhosts = 4;
|
||||
|
||||
public KeyframeSlider linkedSlider;
|
||||
public PawnKeyframe pivotKeyframe;
|
||||
public int linkedOffset;
|
||||
|
||||
private PawnAnimationClip clip { get { return Workspace.GetPawnAnimationClip(actorID); } }
|
||||
private PawnKeyframe keyframe { get { return Workspace.GetPawnKeyframe(keyframeID); } }
|
||||
|
||||
private int actorID;
|
||||
private float dragTimeStart = -1f;
|
||||
private int dragTickStart = -1;
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
onValueChanged.AddListener(delegate (float value) { OnValueChanged(); });
|
||||
}
|
||||
|
||||
public void Initialize(AnimationTimeline timeline, int actorID, int keyframeID)
|
||||
{
|
||||
this.timeline = timeline;
|
||||
this.actorID = actorID;
|
||||
this.keyframeID = keyframeID;
|
||||
|
||||
maxValue = Workspace.StageWindowSize;
|
||||
value = keyframe.atTick.Value;
|
||||
}
|
||||
|
||||
public void OnValueChanged()
|
||||
{
|
||||
keyframe.atTick = (int)value;
|
||||
clip.BuildSimpleCurves();
|
||||
|
||||
timeline.InitiateUpdateOfGhostFrames();
|
||||
}
|
||||
|
||||
// Ghost sliders are non-interactable slider handle
|
||||
public void UpdateGhostFrames()
|
||||
{
|
||||
if (maxGhosts == 0)
|
||||
{ return; }
|
||||
|
||||
int requiredGhosts = GetGhostFramesRequired();
|
||||
int currentGhostCount = ghostSliders.childCount;
|
||||
|
||||
for (int i = 0; i < Mathf.Max(requiredGhosts, currentGhostCount); i++)
|
||||
{
|
||||
if (clip == null || keyframe == null) continue;
|
||||
|
||||
int targetTick = (int)(i * clip.duration + keyframe.atTick);
|
||||
|
||||
if (ghostSliders.childCount <= i)
|
||||
{ Instantiate(ghostSliderPrefab, ghostSliders); }
|
||||
|
||||
GameObject ghostSliderObject = ghostSliders.GetChild(i).gameObject;
|
||||
ghostSliderObject.SetActive(i < requiredGhosts);
|
||||
|
||||
Slider ghostSlider = ghostSliderObject.GetComponent<Slider>();
|
||||
ghostSlider.maxValue = Workspace.StageWindowSize;
|
||||
ghostSlider.value = targetTick;
|
||||
|
||||
if (targetTick > ghostSlider.maxValue)
|
||||
{ ghostSlider.gameObject.SetActive(false); }
|
||||
}
|
||||
}
|
||||
|
||||
public int GetGhostFramesRequired()
|
||||
{
|
||||
if (Workspace.animationDef.AnimationStages[Workspace.StageID].IsLooping == false)
|
||||
{ return 0; }
|
||||
|
||||
if (clip.duration <= 1)
|
||||
{ return 0; }
|
||||
|
||||
return Math.Min(Mathf.CeilToInt((float)Workspace.StageWindowSize / clip.duration), maxGhosts);
|
||||
}
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
Workspace.ActorID = actorID;
|
||||
|
||||
if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.LeftCommand))
|
||||
{ Workspace.keyframeID.Add(keyframeID); }
|
||||
|
||||
else if (Workspace.keyframeID.NullOrEmpty() || Workspace.keyframeID.Contains(keyframeID) == false)
|
||||
{ Workspace.keyframeID = new List<int> { keyframeID }; }
|
||||
|
||||
if (eventData.clickCount >= 2)
|
||||
{ Workspace.StageTick = keyframe.atTick.Value; }
|
||||
}
|
||||
|
||||
public void OnBeginDrag(PointerEventData eventData)
|
||||
{
|
||||
// Select key
|
||||
Workspace.ActorID = actorID;
|
||||
dragTimeStart = Time.unscaledTime;
|
||||
dragTickStart = keyframe.atTick.Value;
|
||||
|
||||
if (Workspace.keyframeID.NullOrEmpty() || Workspace.keyframeID.Contains(keyframeID) == false)
|
||||
{ Workspace.keyframeID = new List<int> { keyframeID }; }
|
||||
|
||||
// The first key can't be moved though
|
||||
if (keyframe.atTick == Constants.minTick)
|
||||
{ interactable = false; return; }
|
||||
|
||||
interactable = true;
|
||||
|
||||
List<PawnKeyframe> selectedKeyframes = Workspace.GetPawnKeyframesByID(Workspace.keyframeID).Except(new List<PawnKeyframe>() { keyframe })?.ToList();
|
||||
|
||||
// Link other selected keyframes to the movement of this one
|
||||
if (selectedKeyframes.NotNullOrEmpty())
|
||||
{
|
||||
pivotKeyframe = keyframe.atTick <= selectedKeyframes.Min(x => x.atTick) ?
|
||||
selectedKeyframes.FirstOrDefault(x => x.atTick >= selectedKeyframes.Max(y => y.atTick)) :
|
||||
selectedKeyframes.FirstOrDefault(x => x.atTick <= selectedKeyframes.Min(y => y.atTick));
|
||||
|
||||
foreach (PawnKeyframe selectedKeyframe in selectedKeyframes)
|
||||
{
|
||||
KeyframeSlider unlinkedSlider = selectedKeyframe.GetKeyframeSlider();
|
||||
|
||||
if (unlinkedSlider != null)
|
||||
{
|
||||
if (selectedKeyframe.atTick == Constants.minTick) continue;
|
||||
if (Workspace.stretchKeyframes && unlinkedSlider.keyframe.atTick == pivotKeyframe.atTick) continue;
|
||||
|
||||
unlinkedSlider.linkedSlider = this;
|
||||
unlinkedSlider.linkedOffset = unlinkedSlider.keyframe.atTick.Value - keyframe.atTick.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
Workspace.ActorID = actorID;
|
||||
|
||||
// Sticky drag
|
||||
if (Time.unscaledTime - dragTimeStart < 0.05f) return;
|
||||
|
||||
base.OnDrag(eventData);
|
||||
|
||||
// Snap to nearest keyframe (on another timeline)
|
||||
int targetTick = Workspace.FindClosestKeyFrameAtTick(keyframe.atTick.Value, Mathf.CeilToInt(Workspace.StageWindowSize * 0.01f), actorID);
|
||||
if (Input.GetKey(KeyCode.LeftShift) && Workspace.DoesPawnKeyframeExistAtTick(Workspace.StageID, actorID, targetTick) == false)
|
||||
{ value = (float)targetTick; }
|
||||
}
|
||||
|
||||
public void OnEndDrag(PointerEventData eventData)
|
||||
{
|
||||
List<PawnKeyframe> keyframesToCheck = Workspace.GetAllPawnKeyframesAtTick(actorID, keyframe.atTick.Value);
|
||||
if (keyframesToCheck.NotNullOrEmpty())
|
||||
{
|
||||
foreach (PawnKeyframe _keyframe in keyframesToCheck)
|
||||
{
|
||||
if (_keyframe != keyframe)
|
||||
{ Workspace.GetAnimationClipThatOwnsKeyframe(_keyframe.keyframeID).RemovePawnKeyframe(_keyframe.keyframeID); }
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Selectable selectable in Selectable.allSelectablesArray)
|
||||
{
|
||||
if (selectable is KeyframeSlider)
|
||||
{
|
||||
KeyframeSlider linkedSlider = selectable.GetComponent<KeyframeSlider>();
|
||||
PawnKeyframe linkedKeyframe = linkedSlider.keyframe;
|
||||
|
||||
if (linkedSlider.linkedSlider != null)
|
||||
{
|
||||
keyframesToCheck = Workspace.GetAllPawnKeyframesAtTick(actorID, linkedKeyframe.atTick.Value);
|
||||
|
||||
if (keyframesToCheck.NotNullOrEmpty() && keyframesToCheck.Count > 1)
|
||||
{
|
||||
foreach (PawnKeyframe _keyframe in keyframesToCheck)
|
||||
{
|
||||
if (_keyframe.keyframeID != linkedKeyframe.keyframeID)
|
||||
{ Workspace.GetAnimationClipThatOwnsKeyframe(_keyframe.keyframeID).RemovePawnKeyframe(_keyframe.keyframeID); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
linkedSlider.linkedSlider = null;
|
||||
linkedSlider.pivotKeyframe = null;
|
||||
}
|
||||
}
|
||||
|
||||
interactable = false;
|
||||
|
||||
Workspace.RecordEvent("Keyframe move");
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (keyframe == null) return;
|
||||
|
||||
// Update outdated values
|
||||
if (Workspace.keyframeID.NullOrEmpty() || Workspace.keyframeID.Contains(keyframeID) == false)
|
||||
{ linkedSlider = null; }
|
||||
|
||||
else if (Workspace.stretchKeyframes && linkedSlider != null)
|
||||
{ value = Mathf.CeilToInt(linkedSlider.keyframe.atTick.Value + linkedOffset * linkedSlider.ScaledOffsetFromPivot()); }
|
||||
|
||||
else if (Workspace.stretchKeyframes == false && linkedSlider != null)
|
||||
{ value = Mathf.Clamp(linkedSlider.keyframe.atTick.Value + linkedOffset, Constants.minTick, Workspace.StageWindowSize); }
|
||||
|
||||
else if (keyframe.atTick.Value != value)
|
||||
{ value = keyframe.atTick.Value; }
|
||||
|
||||
// Update key color
|
||||
if (keyframe.atTick.HasValue && Workspace.keyframeID.Contains(keyframeID) && Workspace.StageTick == keyframe.atTick.Value)
|
||||
{ handleImage.color = Constants.ColorPurple; }
|
||||
|
||||
else if (Workspace.keyframeID.Contains(keyframeID))
|
||||
{ handleImage.color = Constants.ColorCyan; }
|
||||
|
||||
else if (Workspace.StageTick == keyframe.atTick.Value)
|
||||
{ handleImage.color = Constants.ColorPink; }
|
||||
|
||||
else
|
||||
{ handleImage.color = Constants.ColorGrey; }
|
||||
|
||||
// Show sound symbol
|
||||
string soundDef = Workspace.GetPawnKeyframe(keyframeID)?.SoundEffect;
|
||||
soundIcon.SetActive(soundDef != null && soundDef != "" && soundDef != "None");
|
||||
}
|
||||
|
||||
public float ScaledOffsetFromPivot()
|
||||
{
|
||||
if (dragTickStart == pivotKeyframe.atTick.Value) return 0f;
|
||||
|
||||
return (float)(keyframe.atTick.Value - pivotKeyframe.atTick.Value) / (dragTickStart - pivotKeyframe.atTick.Value);
|
||||
}
|
||||
|
||||
public bool IsPivotKeyframe(PawnKeyframe otherKeyframe)
|
||||
{
|
||||
return pivotKeyframe == otherKeyframe;
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/KeyframeSlider.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/KeyframeSlider.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9c733f5218a2b4a449e3115b2bef26f2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
67
Source/Assets/Scripts/GUI/LinearScale.cs
Normal file
67
Source/Assets/Scripts/GUI/LinearScale.cs
Normal file
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class LinearScale : Singleton<LinearScale>
|
||||
{
|
||||
public Transform animationTimelines;
|
||||
public int targetDivisions = 30;
|
||||
public List<int> divisionBands = new List<int>() { 5, 10, 25, 50, 100, 250, 500, 1000 };
|
||||
public GameObject linearScaleTickPrefab;
|
||||
|
||||
private List<int> divisions = new List<int>();
|
||||
private float minDiff = -1f;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
EventsManager.onAnimationChanged.AddListener(delegate { UpdateLinearScale(); });
|
||||
EventsManager.onStageIDChanged.AddListener(delegate { UpdateLinearScale(); });
|
||||
EventsManager.onStageWindowSizeChanged.AddListener(delegate { UpdateLinearScale(); });
|
||||
|
||||
UpdateLinearScale();
|
||||
}
|
||||
|
||||
public void UpdateLinearScale()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(animationTimelines.GetComponent<RectTransform>());
|
||||
minDiff = -1f;
|
||||
|
||||
foreach (int division in divisionBands)
|
||||
{
|
||||
float numDivisions = (float)Workspace.StageWindowSize / division;
|
||||
|
||||
if (minDiff >= 0f && Mathf.Abs(targetDivisions - numDivisions) > minDiff) continue;
|
||||
minDiff = Mathf.Abs(targetDivisions - numDivisions);
|
||||
|
||||
int i = 0;
|
||||
divisions.Clear();
|
||||
|
||||
while (i + division <= Workspace.StageWindowSize)
|
||||
{
|
||||
i += division;
|
||||
divisions.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Transform child in transform)
|
||||
{ Destroy(child.gameObject); }
|
||||
|
||||
foreach (int division in divisions)
|
||||
{
|
||||
GameObject obj = Instantiate(linearScaleTickPrefab, transform);
|
||||
obj.GetComponentInChildren<Text>().text = division.ToString();
|
||||
|
||||
float xOffset = ((float)(division - Constants.minTick) / (Workspace.StageWindowSize - Constants.minTick)) * transform.parent.GetComponent<RectTransform>().rect.width;
|
||||
obj.GetComponent<RectTransform>().localPosition = new Vector3(xOffset, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/LinearScale.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/LinearScale.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4264bb913f7501844bf60529d6b59b8a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Source/Assets/Scripts/GUI/Props.meta
Normal file
8
Source/Assets/Scripts/GUI/Props.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9171c89c691f71d4eb37426db074efc8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
12
Source/Assets/Scripts/GUI/Props/SexProp.cs
Normal file
12
Source/Assets/Scripts/GUI/Props/SexProp.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
[Serializable]
|
||||
public class SexProp
|
||||
{
|
||||
public string label;
|
||||
public Sprite sprite;
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/Props/SexProp.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/Props/SexProp.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 94f6b7ad49adabe428c011abfcf4da53
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
28
Source/Assets/Scripts/GUI/Props/SexPropManager.cs
Normal file
28
Source/Assets/Scripts/GUI/Props/SexPropManager.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class SexPropManager : MonoBehaviour
|
||||
{
|
||||
public List<SexProp> sexProps = new List<SexProp>();
|
||||
public Dropdown sexPropDropdown;
|
||||
|
||||
private SpriteRenderer spriteRenderer;
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
spriteRenderer = GetComponent<SpriteRenderer>();
|
||||
|
||||
foreach (SexProp sexProp in sexProps)
|
||||
{ sexPropDropdown.options.Add(new Dropdown.OptionData(sexProp.label)); }
|
||||
}
|
||||
|
||||
public void OnOptionChanged()
|
||||
{
|
||||
spriteRenderer.sprite = sexProps[sexPropDropdown.value].sprite;
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/Props/SexPropManager.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/Props/SexPropManager.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 587f7397b0c3ecf4495edb8af5dbd777
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
26
Source/Assets/Scripts/GUI/QuiverToggle.cs
Normal file
26
Source/Assets/Scripts/GUI/QuiverToggle.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class QuiverToggle : MonoBehaviour
|
||||
{
|
||||
public void Update()
|
||||
{
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentOrPreviousKeyframe(Workspace.ActorID);
|
||||
GetComponent<Toggle>().isOn = keyframe != null && keyframe.Quiver;
|
||||
}
|
||||
|
||||
public void OnValueChanged()
|
||||
{
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentOrPreviousKeyframe(Workspace.ActorID);
|
||||
|
||||
if (keyframe != null)
|
||||
{ keyframe.Quiver = GetComponent<Toggle>().isOn; }
|
||||
|
||||
Workspace.RecordEvent("Actor quiver");
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/QuiverToggle.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/QuiverToggle.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1aaf656fd4e788245accc65162730545
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
35
Source/Assets/Scripts/GUI/RequiresAnimationDef.cs
Normal file
35
Source/Assets/Scripts/GUI/RequiresAnimationDef.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class RequiresAnimationDef : MonoBehaviour
|
||||
{
|
||||
private Button button;
|
||||
private List<Text> buttonText;
|
||||
private List<Color> buttonTextColor = new List<Color>();
|
||||
|
||||
private void Start()
|
||||
{
|
||||
button = GetComponent<Button>();
|
||||
buttonText = GetComponentsInChildren<Text>()?.ToList();
|
||||
|
||||
if (buttonText != null)
|
||||
{
|
||||
for (int i = 0; i < buttonText.Count; i++)
|
||||
{ buttonTextColor.Add(buttonText[i].color); }
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
button.interactable = Workspace.animationDef != null;
|
||||
|
||||
for (int i = 0; i < buttonText.Count; i++)
|
||||
{ buttonText[i].color = button.interactable ? buttonTextColor[i] : Constants.ColorMidGrey; }
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/RequiresAnimationDef.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/RequiresAnimationDef.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7903694afa5d7ba429917c147e222781
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
30
Source/Assets/Scripts/GUI/SelectActorLayerButton.cs
Normal file
30
Source/Assets/Scripts/GUI/SelectActorLayerButton.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class SelectActorLayerButton : MonoBehaviour
|
||||
{
|
||||
private Text text;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
text = GetComponentInChildren<Text>();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
PawnAnimationClip clip = Workspace.GetCurrentPawnAnimationClip();
|
||||
|
||||
if (clip != null)
|
||||
{ text.text = clip.Layer; }
|
||||
|
||||
else
|
||||
{ text.text = "Pawn"; }
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/SelectActorLayerButton.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/SelectActorLayerButton.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 329a2ecc35813f94fa879c7f434c8fb7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
26
Source/Assets/Scripts/GUI/SnapToKeyframe.cs
Normal file
26
Source/Assets/Scripts/GUI/SnapToKeyframe.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class SnapToKeyframe : MonoBehaviour, IDragHandler
|
||||
{
|
||||
private Slider slider;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
slider = GetComponent<Slider>();
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
int targetTick = Workspace.FindClosestKeyFrameAtTick((int)slider.value, Mathf.CeilToInt(Workspace.StageWindowSize * 0.01f));
|
||||
|
||||
if (Input.GetKey(KeyCode.LeftShift))
|
||||
{ slider.value = (float)targetTick; }
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/SnapToKeyframe.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/SnapToKeyframe.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 09b43781ddbab9c49b81b88c7a8b4076
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Source/Assets/Scripts/GUI/Tooltips.meta
Normal file
8
Source/Assets/Scripts/GUI/Tooltips.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3b338b9ecc1c2584d82563578794ad43
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
72
Source/Assets/Scripts/GUI/Tooltips/Tooltip.cs
Normal file
72
Source/Assets/Scripts/GUI/Tooltips/Tooltip.cs
Normal file
|
@ -0,0 +1,72 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class Tooltip : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
|
||||
{
|
||||
public string message = "Undefined";
|
||||
public string executedCommand;
|
||||
public float delay = 0f;
|
||||
public Vector2 offset = new Vector2(5f, -15f);
|
||||
public bool flipX = false;
|
||||
|
||||
public GameObject tooltip;
|
||||
public Text tooltipText;
|
||||
private bool isActive;
|
||||
private bool isDisplayed;
|
||||
private float activeTime = -1f;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
tooltip = Resources.FindObjectsOfTypeAll<TooltipMessage>()?.FirstOrDefault().gameObject;
|
||||
tooltipText = tooltip?.GetComponentInChildren<Text>();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (tooltip == null || isActive == false || (activeTime + delay) > Time.unscaledTime) return;
|
||||
|
||||
if (isDisplayed == false)
|
||||
{
|
||||
tooltip.GetComponent<RectTransform>().pivot = flipX ? new Vector2(1, 1) : new Vector2(0, 1);
|
||||
tooltipText.text = message;
|
||||
|
||||
if (executedCommand != null && executedCommand != "")
|
||||
{ tooltipText.text += " (" + KeybindConfig.GetKeybindLabel(executedCommand) + ")"; }
|
||||
|
||||
tooltip.transform.position = (Vector2)transform.position + offset;
|
||||
tooltip.gameObject.SetActive(true);
|
||||
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(tooltip.GetComponent<RectTransform>());
|
||||
|
||||
isDisplayed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDisable()
|
||||
{
|
||||
if (isActive)
|
||||
{ OnPointerExit(new PointerEventData(EventSystem.current)); }
|
||||
}
|
||||
|
||||
public void OnPointerEnter(PointerEventData pointerEventData)
|
||||
{
|
||||
isActive = true;
|
||||
activeTime = Time.unscaledTime;
|
||||
}
|
||||
|
||||
public void OnPointerExit(PointerEventData pointerEventData)
|
||||
{
|
||||
isActive = false;
|
||||
isDisplayed = false;
|
||||
tooltip.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/GUI/Tooltips/Tooltip.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/Tooltips/Tooltip.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c05e9ac2a2f311549b12f094d2785a20
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Source/Assets/Scripts/GUI/Tooltips/TooltipMessage.cs
Normal file
8
Source/Assets/Scripts/GUI/Tooltips/TooltipMessage.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class TooltipMessage : MonoBehaviour
|
||||
{
|
||||
|
||||
}
|
11
Source/Assets/Scripts/GUI/Tooltips/TooltipMessage.cs.meta
Normal file
11
Source/Assets/Scripts/GUI/Tooltips/TooltipMessage.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ec8ec1002bf0dda4aa55bfb75b152066
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue