unity学习46:反向动力学IK

server/2025/2/22 5:07:33/

目录

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 updatevoid Start(){animator1=GetComponent<Animator>();}// Update is called once per framevoid 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 updatevoid Start(){animator1=GetComponent<Animator>();}// Update is called once per framevoid 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);//设置右手IKanimator1.SetIKPosition(AvatarIKGoal.RightHand,target1.position);animator1.SetIKRotation(AvatarIKGoal.RightHand,target1.rotation);}}


http://www.ppmy.cn/server/169759.html

相关文章

ChatGPT超级AI对话模型 黑客十问十答

完了完了&#xff0c;ChatGPT超级AI对话模型回答有关黑客的经典问题&#xff0c;简直行云流水&#xff0c;对答如流&#xff0c;并且逻辑十分清晰&#xff0c;看了一遍答案&#xff0c;已经忘记了这些是AI给出的回答&#xff0c;有了AI加持&#xff0c;黑客百问百答&#xff0c…

python实践-实现实时语音转文字本地部署版(二)

一、技术栈 python 3.10.6 vosk 需下载对应模型&#xff08;vosk-model-cn-0.22&#xff09;模型下载慢的同学看最后的资源链接。 pyaudio keyboard 二、实现功能 本地化实现麦克风语音录入&#xff0c;实时生成文字&#xff0c;并保存至本地文档。 三、实现代码 fro…

自制简单的图片查看器(python)

图片格式&#xff1a;支持常见的图片格式&#xff08;JPG、PNG、BMP、GIF&#xff09;。 import os import tkinter as tk from tkinter import filedialog, messagebox from PIL import Image, ImageTkclass ImageViewer:def __init__(self, root):self.root rootself.root.…

vue2和vue3的按需引入的详细对比通俗易懂

以下是 Vue2 与 Vue3 按需引入的对比详解&#xff0c;用最简单的语言和场景说明差异&#xff1a; 一、按需引入的本质 目标&#xff1a;只打包项目中实际用到的代码&#xff08;组件、API&#xff09;&#xff0c;减少最终文件体积。类比&#xff1a;去餐厅点餐&#xff0c;只…

< OS 有关 > Ubuntu 24 SSH 服务器更换端口 in jp/us VPSs

原因&#xff1a; 两台 VPS 的 ssh 端口一直被密码重试&#xff0c; us 这台已经封了 632, jp 这台两周前清过一次 sqlite3 数据&#xff0c;现在赞到 1008 Fail2Ban 是使用 sqlite3 来记录&#xff0c;数据量大后&#xff0c;硬盘的 I/O 会飙升&#xff0c;我有写过一个 app…

10个Kettle(Pentaho Data Integration)基础概念面试题及答案

10个Kettle&#xff08;Pentaho Data Integration&#xff09;基础概念面试题及答案 1. 什么是Kettle&#xff1f; 答案&#xff1a; Kettle&#xff08;现称Pentaho Data Integration&#xff0c;PDI&#xff09;是一款开源的ETL&#xff08;Extract, Transform, Load&#…

springsecurity自定义认证

// jwt 方式 package com.kongjs.note.system.convert;import com.kongjs.note.admin.model.dto.TokenInfoDTO; import com.kongjs.note.admin.service.TokenService; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import lombok.ext…

js 打开新标签页和关闭标签页

window.open(url, _blank)&#xff0c;blank属性可以在新标签打开 window.open 直接调用可能会有拦截提示&#xff0c;在用户交互事件时调用不会出现拦截 由window.open 打开的新的标签页或弹窗可以由window.close关闭 window.open会返回一个 WindowProxy 对象。只要符合同源…