Skip to content

Instantly share code, notes, and snippets.

@Nobuyuki-Kobayashi
Created August 5, 2020 00:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Nobuyuki-Kobayashi/83ef8d3098547c81cc56af47bd669610 to your computer and use it in GitHub Desktop.
Save Nobuyuki-Kobayashi/83ef8d3098547c81cc56af47bd669610 to your computer and use it in GitHub Desktop.
IK Look At script for Mecanim/Humanoid. Attach to your character. Before using it, you must turn on IK Pass of the Animator attached to your character.
//
// Mecanim.IkLookAt
// Mecanim.HumanoidでIK Look Atする。キャラクターにアタッチします。
// 使用する前にキャラクターにアタッチされているAnimatorのIK PassをONにしておくこと.
// 2017/01/14 N.Kobayashi
//
using UnityEngine;
using System.Collections;
namespace UnityChan
{
[RequireComponent(typeof(Animator))]
public class IKLookAt : MonoBehaviour {
protected Animator avatar;
public bool ikActive = true;
[HideInInspector]
public GameObject cameraObject = null;
[HideInInspector]
public Transform lookAtObj = null;
public bool isGUI = true;
public float maxLookAtWeight = 1.0f;
public float bodyWeight = 0.3f;
public float headWeight = 0.8f;
public float eyesWeight = 1.0f;
public float clampWeight = 0.5f;
private float lookAtWeight = 0.0f;
public float minDistanceIkOn = 1.0f;
public float maxDistanceIkOn = 3.0f;
public float minDotIkOn = 0.5f;
public Transform headJoint = null;
public Transform forwardJoint = null;
public float adjustSeconds = 2.0f;
private float adjustDelta;
private float sumAdjustDelta;
private bool isLookAtEnable = false;
// Use this for initialization
void Start () {
avatar = GetComponent<Animator>();
//lookAtObjectが指定されていない時には、MainCameraオブジェクトを探し、そのtransformをアタッチする.
if (lookAtObj == null)
{
cameraObject = GameObject.FindGameObjectWithTag("MainCamera");
lookAtObj = cameraObject.transform;
//Debug.Log("Get MainCamera's Transform");
}
}
void OnGUI()
{
if (isGUI)
{
GUILayout.Label("Activate Look at IK");
ikActive = GUILayout.Toggle(ikActive, "Activate IK");
}
}
void OnAnimatorIK(int layerIndex)
{
if(avatar)
{
if(ikActive)
{
if (isLookAtEnable)
{
avatar.SetLookAtWeight(lookAtWeight, bodyWeight, headWeight, eyesWeight, clampWeight);
}
if (lookAtObj != null)
{
avatar.SetLookAtPosition(lookAtObj.position);
}
}
else
{
avatar.SetLookAtWeight(0.0f);
}
}
}
void Update ()
{
if(avatar)
{
if(ikActive)
{
adjustDelta = Time.deltaTime / adjustSeconds;
//カメラとの距離と角度から、Look AtをON/OFFします.
Vector3 offsetVec = lookAtObj.position - headJoint.position;
Vector3 forwardVec = forwardJoint.position - headJoint.position;
float dist = offsetVec.sqrMagnitude;
float dot = Vector3.Dot(offsetVec.normalized, forwardVec.normalized);
if (((dist >= minDistanceIkOn * minDistanceIkOn) && (dist <= maxDistanceIkOn * maxDistanceIkOn)) && (dot >= minDotIkOn)){
isLookAtEnable = true;
//adjustDeltaの積算値よりIK Look Atのブレンド比率を変化させる.
if (sumAdjustDelta < 1.0f)
{
lookAtWeight = Mathf.SmoothStep(0.0f, maxLookAtWeight, sumAdjustDelta);
sumAdjustDelta = sumAdjustDelta + adjustDelta;
//Debug.Log("lookAtWeight : " + lookAtWeight);
}
else {
lookAtWeight = maxLookAtWeight;
}
} else {
isLookAtEnable = false;
sumAdjustDelta = 0.0f;
lookAtWeight = 0.0f;
//Debug.Log("lookAtWeight : Reset");
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment