目录
1 正向动力学和反向动力学
1.1 正向动力学
1.2 反向动力学
1.3 实现目标
2 实现反向动力
2.1 先定义一个目标
2.2 动画层layer,需要加 IK pass
2.3 增加头部朝向代码
2.3.1 专门的IK方法 OnAnimatorIK(int layerIndex){}
2.3.2 增加朝向代码
2.4 增加头部朝向代码
2.5 需要设置权重
2.6 需要设置位置position 和 rotation
2.7 具体代码: 头部和手都实现了IK朝向
1 正向动力学和反向动力学
1.1 正向动力学
- 正常的模型身体的运动
- 模仿人体的真实的骨骼。
1.2 反向动力学
- 真实世界中,不存在的,相反的一个骨骼方式
- 用目标---牵引 手指---牵引手臂,这样反向的指引方式
- 游戏里IK相关的就是
1.3 实现目标
- 想实现,玩家角色的眼睛,头部,手,一直指向目标
2 实现反向动力
2.1 先定义一个目标
public class TestPlayer1 : MonoBehaviour
{
public Transform target1;
private Animator animator1;
2.2 动画层layer,需要加 IK pass
- 需要进行反向动力学的动画层,
- 动画层layer,需要加 IK pass
2.3 增加头部朝向代码
2.3.1 专门的IK方法 OnAnimatorIK(int layerIndex){}
- 需要专门的IK方法
- private void OnAnimatorIK(int layerIndex){}
2.3.2 增加朝向代码
- animator1.SetLookAtWeight(1);
- animator1.SetLookAtPosition(target1.position);
private void OnAnimatorIK(int layerIndex)
{
//设置头部IK Weight=0表示不生效
animator1.SetLookAtWeight(1);
animator1.SetLookAtPosition(target1.position);
}
2.4 增加头部朝向代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestPlayer1 : MonoBehaviour
{
public Transform target1;
private Animator animator1;
// Start is called before the first frame update
void Start()
{
animator1=GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
float horzontal=Input.GetAxis("Horizontal");
float vetical=Input.GetAxis("Vertical");
Vector3 dir1=new Vector3(horzontal,0,vetical);
Debug.DrawRay(transform.position,dir1,Color.red);
//如果按下了移动按键
if(dir1 != Vector3.zero)
{
//面向向量
transform.rotation=Quaternion.LookRotation(dir1);
//播放跑步动画
animator1.SetBool("IsRun",true);
//朝着面向的前方移动
transform.Translate(Vector3.forward*2*Time.deltaTime);
}else
{
//播放walk动画
animator1.SetBool("IsRun",false);
}
if(Input.GetKeyDown(KeyCode.Q))
{
//触发wave参数
GetComponent<Animator>().SetTrigger("wave");
}
//获得曲线的test1参数
//Debug.Log(animator1.GetFloat("test1"));
}
void rightfoot()
{
Debug.Log("右脚");
}
void leftfoot()
{
Debug.Log("左脚");
}
private void OnAnimatorIK(int layerIndex)
{
//设置头部IK Weight=0表示不生效
animator1.SetLookAtWeight(1);
animator1.SetLookAtPosition(target1.position);
}
}
2.5 需要设置权重
- 权重=1 表示生效
- animator1.SetIKPositionWeight(AvatarIKGoal.RightHand,1);
- animator1.SetIKRotationWeight(AvatarIKGoal.RightHand,1);
private void OnAnimatorIK(int layerIndex)
{
//设置头部IK Weight=0表示不生效
animator1.SetLookAtWeight(1);
animator1.SetLookAtPosition(target1.position);
//设置右手position的IK权重
animator1.SetIKPositionWeight(AvatarIKGoal.RightHand,1);
//设置右手旋转IK权重
animator1.SetIKRotationWeight(AvatarIKGoal.RightHand,1);
//设置右手IK
animator1.SetIKPosition(AvatarIKGoal.RightHand,target1.position);
animator1.SetIKRotation(AvatarIKGoal.RightHand,target1.rotation);
}
2.6 需要设置位置position 和 rotation
- //设置右手IK
- animator1.SetIKPosition(AvatarIKGoal.RightHand,target1.position);
- animator1.SetIKRotation(AvatarIKGoal.RightHand,target1.rotation);
2.7 具体代码: 头部和手都实现了IK朝向
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestPlayer1 : MonoBehaviour
{
public Transform target1;
private Animator animator1;
// Start is called before the first frame update
void Start()
{
animator1=GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
float horzontal=Input.GetAxis("Horizontal");
float vetical=Input.GetAxis("Vertical");
Vector3 dir1=new Vector3(horzontal,0,vetical);
Debug.DrawRay(transform.position,dir1,Color.red);
//如果按下了移动按键
if(dir1 != Vector3.zero)
{
//面向向量
transform.rotation=Quaternion.LookRotation(dir1);
//播放跑步动画
animator1.SetBool("IsRun",true);
//朝着面向的前方移动
transform.Translate(Vector3.forward*2*Time.deltaTime);
}else
{
//播放walk动画
animator1.SetBool("IsRun",false);
}
if(Input.GetKeyDown(KeyCode.Q))
{
//触发wave参数
GetComponent<Animator>().SetTrigger("wave");
}
//获得曲线的test1参数
//Debug.Log(animator1.GetFloat("test1"));
}
void rightfoot()
{
Debug.Log("右脚");
}
void leftfoot()
{
Debug.Log("左脚");
}
private void OnAnimatorIK(int layerIndex)
{
//设置头部IK Weight=0表示不生效
animator1.SetLookAtWeight(1);
animator1.SetLookAtPosition(target1.position);
//设置右手position的IK权重
animator1.SetIKPositionWeight(AvatarIKGoal.RightHand,1);
//设置右手旋转IK权重
animator1.SetIKRotationWeight(AvatarIKGoal.RightHand,1);
//设置右手IK
animator1.SetIKPosition(AvatarIKGoal.RightHand,target1.position);
animator1.SetIKRotation(AvatarIKGoal.RightHand,target1.rotation);
}
}