Skip to content

Instantly share code, notes, and snippets.

@lazlo-bonin
Created January 18, 2019 17:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lazlo-bonin/72f032303ad9d01a226cabdfa739f91e to your computer and use it in GitHub Desktop.
Save lazlo-bonin/72f032303ad9d01a226cabdfa739f91e to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Impossible.Ete
{
// Relays IK values to the animator callback
[RequireComponent(typeof(Animator))]
public class InverseKinematicsRelay : BaseComponent
{
public Animator animator { get; private set; }
public Vector3 lookAtPosition { get; set; }
public float lookAtWeight { get; set; }
private Dictionary<AvatarIKGoal, float> positionWeights = new Dictionary<AvatarIKGoal, float>();
private Dictionary<AvatarIKGoal, float> rotationWeights = new Dictionary<AvatarIKGoal, float>();
private Dictionary<AvatarIKGoal, Vector3> positions = new Dictionary<AvatarIKGoal, Vector3>();
private Dictionary<AvatarIKGoal, Quaternion> rotations = new Dictionary<AvatarIKGoal, Quaternion>();
private HashSet<AvatarIKGoal> goals = new HashSet<AvatarIKGoal>();
protected override void Awake()
{
base.Awake();
animator = GetComponent<Animator>();
goals = new HashSet<AvatarIKGoal>(Enum.GetValues(typeof(AvatarIKGoal)).Cast<AvatarIKGoal>());
}
public void SetWeights(AvatarIKGoal goal, float weight)
{
SetPositionWeight(goal, weight);
SetRotationWeight(goal, weight);
}
public void SetPositionWeight(AvatarIKGoal goal, float weight)
{
if (!positionWeights.ContainsKey(goal))
{
positionWeights.Add(goal, weight);
}
else
{
positionWeights[goal] = weight;
}
}
public float GetPositionWeight(AvatarIKGoal goal)
{
return positionWeights.ContainsKey(goal) ? positionWeights[goal] : default(float);
}
public void SetRotationWeight(AvatarIKGoal goal, float weight)
{
if (!rotationWeights.ContainsKey(goal))
{
rotationWeights.Add(goal, weight);
}
else
{
rotationWeights[goal] = weight;
}
}
public float GetRotationWeight(AvatarIKGoal goal)
{
return rotationWeights.ContainsKey(goal) ? rotationWeights[goal] : default(float);
}
public void SetPosition(AvatarIKGoal goal, Vector3 position)
{
if (!positions.ContainsKey(goal))
{
positions.Add(goal, position);
}
else
{
positions[goal] = position;
}
}
public Vector3 GetPosition(AvatarIKGoal goal)
{
return positions.ContainsKey(goal) ? positions[goal] : default(Vector3);
}
public void SetRotation(AvatarIKGoal goal, Quaternion rotation)
{
if (!rotations.ContainsKey(goal))
{
rotations.Add(goal, rotation);
}
else
{
rotations[goal] = rotation;
}
}
public Quaternion GetRotation(AvatarIKGoal goal)
{
return rotations.ContainsKey(goal) ? rotations[goal] : default(Quaternion);
}
protected virtual void OnAnimatorIK()
{
animator.SetLookAtPosition(lookAtPosition);
animator.SetLookAtWeight(lookAtWeight, 1, 1, 1, 0);
foreach (var positionWeight in positionWeights)
{
animator.SetIKPositionWeight(positionWeight.Key, positionWeight.Value);
}
foreach (var rotationWeight in rotationWeights)
{
animator.SetIKRotationWeight(rotationWeight.Key, rotationWeight.Value);
}
foreach (var position in positions)
{
animator.SetIKPosition(position.Key, position.Value);
}
foreach (var rotation in rotations)
{
animator.SetIKRotation(rotation.Key, rotation.Value);
}
foreach (var goal in goals)
{
if (!positionWeights.ContainsKey(goal))
{
positionWeights.Add(goal, animator.GetIKPositionWeight(goal));
}
if (!rotationWeights.ContainsKey(goal))
{
rotationWeights.Add(goal, animator.GetIKRotationWeight(goal));
}
if (!positions.ContainsKey(goal))
{
positions.Add(goal, animator.GetIKPosition(goal));
}
if (!rotations.ContainsKey(goal))
{
rotations.Add(goal, animator.GetIKRotation(goal));
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment