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