Race offsets and keyframe cloning
This commit is contained in:
parent
d3b676df06
commit
007e2dd513
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -53,6 +53,38 @@ namespace RimWorldAnimationStudio
|
|||
{ this.alienRaceDef = alienRaceDef; }
|
||||
}
|
||||
|
||||
public Vector3 GetAlienRaceOffset()
|
||||
{
|
||||
if (alienRaceDef == null)
|
||||
{ alienRaceDef = AlienRaceDefs.GetNamed("Human"); }
|
||||
|
||||
AlienRaceOffset raceOffset = raceOffsets.FirstOrDefault(x => x.defName == alienRaceDef.defName);
|
||||
|
||||
if (raceOffset == null)
|
||||
{
|
||||
raceOffset = new AlienRaceOffset(alienRaceDef.defName);
|
||||
raceOffsets.Add(raceOffset);
|
||||
}
|
||||
|
||||
return raceOffset.GetOffset();
|
||||
}
|
||||
|
||||
public void SetAlienRaceOffset(Vector2 offset)
|
||||
{
|
||||
if (alienRaceDef == null)
|
||||
{ return; }
|
||||
|
||||
AlienRaceOffset raceOffset = raceOffsets.FirstOrDefault(x => x.defName == alienRaceDef.defName);
|
||||
|
||||
if (raceOffset == null)
|
||||
{
|
||||
raceOffset = new AlienRaceOffset(alienRaceDef.defName);
|
||||
raceOffsets.Add(raceOffset);
|
||||
}
|
||||
|
||||
raceOffset.SetOffset(offset);
|
||||
}
|
||||
|
||||
public void ValidateData()
|
||||
{
|
||||
bodyDefTypes = bodyDefTypes.Intersect(Tags.bodyDefTypes.Concat(CustomTags.bodyDefTypes))?.ToList();
|
||||
|
|
|
@ -7,7 +7,33 @@ namespace RimWorldAnimationStudio
|
|||
[Serializable]
|
||||
public class AlienRaceOffset
|
||||
{
|
||||
public string defName;
|
||||
public Vector2 offset;
|
||||
public string defName = "Human";
|
||||
public string offset = "(0, 0)";
|
||||
|
||||
public AlienRaceOffset()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public AlienRaceOffset(string defName)
|
||||
{
|
||||
this.defName = defName;
|
||||
}
|
||||
|
||||
public void SetOffset(Vector2 raceOffset)
|
||||
{
|
||||
offset = "(" + raceOffset.x + ", " + raceOffset.y + ")";
|
||||
}
|
||||
|
||||
public Vector3 GetOffset()
|
||||
{
|
||||
string raceOffset = offset;
|
||||
raceOffset = raceOffset.Trim();
|
||||
raceOffset = raceOffset.Replace("(", "");
|
||||
raceOffset = raceOffset.Replace(")", "");
|
||||
var raceOffsets = raceOffset.Split(',');
|
||||
|
||||
return new Vector3(float.Parse(raceOffsets[0]), 0f, float.Parse(raceOffsets[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,8 +55,8 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
if (Workspace.actorManipulationMode == ActorManipulationMode.Pan)
|
||||
{
|
||||
keyframe.bodyOffsetX = mousePosition.x;
|
||||
keyframe.bodyOffsetZ = mousePosition.y;
|
||||
keyframe.bodyOffsetX = mousePosition.x - Workspace.animationDef.actors[actorID].GetAlienRaceOffset().x;
|
||||
keyframe.bodyOffsetZ = mousePosition.y - Workspace.animationDef.actors[actorID].GetAlienRaceOffset().z;
|
||||
}
|
||||
|
||||
else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)
|
||||
|
|
|
@ -45,12 +45,13 @@ namespace RimWorldAnimationStudio
|
|||
{
|
||||
if (Workspace.actorManipulationMode == ActorManipulationMode.Pan)
|
||||
{
|
||||
Vector3 headOffset = new Vector3(0f, 0.34f, 0f);
|
||||
headOffset = Quaternion.Euler(0, 0, keyframe.bodyAngle) * headOffset;
|
||||
// It's stupid but it works
|
||||
Vector3 localPosA = transform.localPosition;
|
||||
transform.position = mousePosition;
|
||||
Vector3 localPosB = transform.localPosition;
|
||||
transform.localPosition = localPosA;
|
||||
|
||||
float distance = Vector2.Dot(parent.transform.up, (Vector2)(mousePosition - parent.transform.position - headOffset));
|
||||
|
||||
keyframe.headBob = distance;
|
||||
keyframe.headBob += localPosB.y - localPosA.y;
|
||||
}
|
||||
|
||||
else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)
|
||||
|
|
|
@ -12,6 +12,8 @@ namespace RimWorldAnimationStudio
|
|||
public Dropdown bodyTypeDropdown;
|
||||
public InputField bodyOffsetXField;
|
||||
public InputField bodyOffsetZField;
|
||||
public InputField raceOffsetXField;
|
||||
public InputField raceOffsetZField;
|
||||
public Toggle initiatorToggle;
|
||||
|
||||
public void Initialize()
|
||||
|
@ -62,6 +64,10 @@ namespace RimWorldAnimationStudio
|
|||
default: actor.requiredGender = null; break;
|
||||
}
|
||||
|
||||
float.TryParse(raceOffsetXField.text, out x);
|
||||
float.TryParse(raceOffsetZField.text, out z);
|
||||
actor.SetAlienRaceOffset(new Vector2(x, z));
|
||||
|
||||
Workspace.Instance.RecordEvent("Actor body type offset data");
|
||||
}
|
||||
|
||||
|
@ -86,6 +92,12 @@ namespace RimWorldAnimationStudio
|
|||
if (bodyOffsetZField.isFocused == false)
|
||||
{ bodyOffsetZField.text = actor.bodyTypeOffset.GetOffset(bodyType).z.ToString(); }
|
||||
|
||||
if (raceOffsetXField.isFocused == false)
|
||||
{ raceOffsetXField.text = actor.GetAlienRaceOffset().x.ToString(); }
|
||||
|
||||
if (raceOffsetZField.isFocused == false)
|
||||
{ raceOffsetZField.text = actor.GetAlienRaceOffset().z.ToString(); }
|
||||
|
||||
initiatorToggle.isOn = actor.initiator;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,15 +15,13 @@ namespace RimWorldAnimationStudio
|
|||
public Dropdown raceSelectDropdown;
|
||||
public Transform raceSettingsWindow;
|
||||
public Toggle isHumanoidToggle;
|
||||
public InputField scaleField;
|
||||
|
||||
public override void Initialize(bool addedNewTag = false)
|
||||
{
|
||||
Reset();
|
||||
|
||||
string alienRaceDefName = raceSelectDropdown.value < raceSelectDropdown.options.Count ? raceSelectDropdown.options[raceSelectDropdown.value].text : "Human";
|
||||
if (alienRaceDefName == null || alienRaceDefName == "") alienRaceDefName = "Human";
|
||||
|
||||
AlienRaceDef alienRaceDef = AlienRaceDefs.GetNamed(alienRaceDefName);
|
||||
AlienRaceDef alienRaceDef = GetCurrentRaceDef();
|
||||
if (alienRaceDef == null) return;
|
||||
|
||||
isHumanoidToggle.isOn = alienRaceDef.isHumanoid;
|
||||
|
@ -80,6 +78,8 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
AddCloneObjectToParent(raceSettingsWindow, 3);
|
||||
}
|
||||
|
||||
scaleField.text = string.Format("{0:0.000}", alienRaceDef.scale.ToString());
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
|
@ -89,10 +89,7 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
public void SetIsHumanoid()
|
||||
{
|
||||
string alienRaceDefName = raceSelectDropdown.value < raceSelectDropdown.options.Count ? raceSelectDropdown.options[raceSelectDropdown.value].text : "Human";
|
||||
if (alienRaceDefName == null || alienRaceDefName == "") alienRaceDefName = "Human";
|
||||
|
||||
AlienRaceDef alienRaceDef = AlienRaceDefs.GetNamed(alienRaceDefName);
|
||||
AlienRaceDef alienRaceDef = GetCurrentRaceDef();
|
||||
if (alienRaceDef == null) return;
|
||||
|
||||
alienRaceDef.isHumanoid = isHumanoidToggle.isOn;
|
||||
|
@ -123,5 +120,22 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public AlienRaceDef GetCurrentRaceDef()
|
||||
{
|
||||
string alienRaceDefName = raceSelectDropdown.value < raceSelectDropdown.options.Count ? raceSelectDropdown.options[raceSelectDropdown.value].text : "Human";
|
||||
if (alienRaceDefName == null || alienRaceDefName == "") alienRaceDefName = "Human";
|
||||
|
||||
return AlienRaceDefs.GetNamed(alienRaceDefName);
|
||||
}
|
||||
|
||||
public void SetRaceScale()
|
||||
{
|
||||
AlienRaceDef alienRaceDef = GetCurrentRaceDef();
|
||||
if (alienRaceDef == null) return;
|
||||
|
||||
float scale = float.Parse(scaleField.text);
|
||||
alienRaceDef.scale = Mathf.Clamp(scale, 0.05f, 100f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ namespace RimWorldAnimationStudio
|
|||
string bodyType = alienRaceDef.isHumanoid ? actorBody.bodyType : "None";
|
||||
|
||||
Vector3 deltaPos = new Vector3(clip.BodyOffsetX.Evaluate(clipPercent), 0, clip.BodyOffsetZ.Evaluate(clipPercent));
|
||||
deltaPos += Workspace.animationDef.actors[actorID].bodyTypeOffset.GetOffset(bodyType);
|
||||
deltaPos += Workspace.animationDef.actors[actorID].bodyTypeOffset.GetOffset(bodyType) + Workspace.animationDef.actors[actorID].GetAlienRaceOffset();
|
||||
|
||||
float bodyAngle = clip.BodyAngle.Evaluate(clipPercent);
|
||||
float headAngle = clip.HeadAngle.Evaluate(clipPercent);
|
||||
|
@ -151,10 +151,11 @@ namespace RimWorldAnimationStudio
|
|||
int bodyFacing = (int)clip.BodyFacing.Evaluate(clipPercent);
|
||||
int headFacing = (int)clip.HeadFacing.Evaluate(clipPercent);
|
||||
|
||||
Vector3 headBob = new Vector3(0, 0, clip.HeadBob.Evaluate(clipPercent)) + PawnUtility.BaseHeadOffsetAt(bodyType, bodyFacing);
|
||||
float headBob = clip.HeadBob.Evaluate(clipPercent);
|
||||
Vector3 headOffset = new Vector3(0, 0, headBob) + PawnUtility.BaseHeadOffsetAt(bodyType, bodyFacing);
|
||||
|
||||
Vector3 bodyPos = new Vector3(deltaPos.x, deltaPos.z, 0);
|
||||
Vector3 headPos = new Vector3(headBob.x, headBob.z, 0);
|
||||
Vector3 headPos = new Vector3(headOffset.x, headOffset.z, 0);
|
||||
|
||||
Vector3 appendagePos = PawnUtility.AppendageOffsetAt(bodyType, bodyFacing);
|
||||
float appendageRotation = clip.GenitalAngle.Evaluate(clipPercent);
|
||||
|
@ -185,6 +186,8 @@ namespace RimWorldAnimationStudio
|
|||
actorBody.headRenderer.flipX = headFacing == 3;
|
||||
//actorBody.appendageRenderer.flipX = bodyFacing == 3;
|
||||
|
||||
actorBody.transform.localScale = new Vector3(alienRaceDef.scale, alienRaceDef.scale, alienRaceDef.scale);
|
||||
|
||||
// ActorKeyframeCard update
|
||||
if (ActorKeyframeCard.Instance.positionXField.isFocused == false) { ActorKeyframeCard.Instance.positionXField.text = bodyPos.x.ToString("0.000"); }
|
||||
if (ActorKeyframeCard.Instance.positionZField.isFocused == false) { ActorKeyframeCard.Instance.positionZField.text = bodyPos.y.ToString("0.000"); }
|
||||
|
@ -318,6 +321,38 @@ namespace RimWorldAnimationStudio
|
|||
Workspace.Instance.RecordEvent("Keyframe addition");
|
||||
}
|
||||
|
||||
public void ClonePawnKeyframe()
|
||||
{
|
||||
PawnAnimationClip clip = Workspace.Instance.GetCurrentPawnAnimationClip();
|
||||
List<PawnKeyframe> keyframes = clip?.keyframes;
|
||||
PawnKeyframe keyframe = Workspace.Instance.GetPawnKeyframe(Workspace.actorID, Workspace.keyframeID);
|
||||
|
||||
if (clip == null || keyframes == null)
|
||||
{ Debug.LogWarning("Cannot clone pawn keyframe - the AnimationDef is invalid"); return; }
|
||||
|
||||
if (keyframes.FirstOrDefault(x => x.atTick == stageTick) != null)
|
||||
{ Debug.LogWarning("Cannot clone pawn keyframe - a keyframe already exists at this tick"); return; }
|
||||
|
||||
if (keyframe == null)
|
||||
{ Debug.LogWarning("Cannot clone pawn keyframe - no keyframe has been selected for cloning"); return; }
|
||||
|
||||
PawnKeyframe cloneFrame = keyframe.Copy();
|
||||
cloneFrame.GenerateKeyframeID();
|
||||
cloneFrame.atTick = stageTick;
|
||||
|
||||
PawnKeyframe nextKeyframe = keyframes.FirstOrDefault(x => x.atTick > stageTick);
|
||||
|
||||
if (nextKeyframe != null)
|
||||
{ keyframes.Insert(keyframes.IndexOf(nextKeyframe), cloneFrame); }
|
||||
|
||||
else
|
||||
{ keyframes.Add(cloneFrame); }
|
||||
|
||||
clip.BuildSimpleCurves();
|
||||
|
||||
animationTimelines.GetComponentsInChildren<AnimationTimeline>()[Workspace.actorID].AddPawnKeyFrame(cloneFrame.keyframeID);
|
||||
}
|
||||
|
||||
public void RemovePawnKeyframe()
|
||||
{
|
||||
RemovePawnKeyframe(Workspace.actorID, Workspace.keyframeID);
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue