IK动画与MatchTarget区别:
MatchTarget实现从一段时间区域内,一个点到另一个点匹配的过程;IK动画用于直接将手或脚与某点的匹配
控制策略:a、在木头下新建两个点(空的GameObject),将这两个点调到合适位置,让手与这两个点进行匹配,完成托举木头的效果;
b、在匹配过程中,手部的旋转角度和位置是根据GameObject来匹配的,我们可以通过调节GameObject的角度和位置完成动画的手部角度的调节。
运行时可暂停运行,调节位置,逐帧更新动画,Transform齿轮处可Copy Component,调节完成后取消运行动画,Paste Component Values
1、勾选动画层的IK Pass
2、Player C#补充:
OnAnimatorIK(int layerIndex)方法在Update()方法外,因为勾选了IK Pass,系统会自动调用
print(layerIndex);可在控制台输出当前调用的动画层是几
Player总代码:
using UnityEngine;
public class Player : MonoBehaviour {
private Animator anim;
private int speedRotateID = Animator.StringToHash("SpeedRotate");
private int speedZID = Animator.StringToHash("SpeedZ");
private int vaultID = Animator.StringToHash("Vault");
private Vector3 matchTarget;
private CharacterController characterController;
private int vaultCurveID = Animator.StringToHash("vaultCurve");
private int sliderID = Animator.StringToHash("Slider");
private int sliderCurveID = Animator.StringToHash("sliderCurve");
private int isHoldLogID = Animator.StringToHash("IsHoldLog");
public Transform LeftHand, RightHand;
public GameObject unityLog;
void Start () {
anim = GetComponent<Animator>();
characterController = GetComponent<CharacterController>();
}
void Update () {
anim.SetFloat(speedZID, Input.GetAxis("Vertical") * 4.5f);
anim.SetFloat(speedRotateID, Input.GetAxis("Horizontal")*126);
ProcessVault();
ProcessSlider();
}
private void ProcessVault()
{
if (anim.GetFloat(speedZID) > 3 && anim.GetCurrentAnimatorStateInfo(0).IsName("LocalMotion"))
{
RaycastHit hit;
if (Physics.Raycast(transform.position + Vector3.up * 0.3f, transform.forward, out hit, 4.5f))
{
if (hit.collider.tag == "Obstacle")
{
if (hit.distance > 3)
{
Vector3 point = hit.point;
point.y = hit.transform.position.y + hit.collider.bounds.size.y + 0.09f; //普通的cube在水平面时默认中心高度y=0.5,但此模型水平中心高度为0(和底边一致)!,所以是它最低点位置+Y轴的大小
matchTarget = point;
anim.SetBool(vaultID, true);
}
}
}
else anim.SetBool(vaultID, false);
}
characterController.enabled = anim.GetFloat(vaultCurveID) < 0.5f;
if (anim.GetCurrentAnimatorStateInfo(0).IsName("Vault"))
{
anim.MatchTarget(matchTarget, Quaternion.identity, AvatarTarget.LeftHand, new MatchTargetWeightMask(Vector3.one, 0), 0.32f, 0.4f);
}
}
private void ProcessSlider()
{
if (anim.GetFloat(speedZID) > 3 && anim.GetCurrentAnimatorStateInfo(0).IsName("LocalMotion"))
{
RaycastHit hit;
if (Physics.Raycast(transform.position + Vector3.up * 1.5f, transform.forward, out hit, 5f))
{
if (hit.collider.tag == "Obstacle")
{
if (hit.distance <2.8)
{
Vector3 point = hit.point;
point.y = 0 ;
matchTarget = point+transform.forward*2;
anim.SetBool(sliderID, true);
}
}
}
}
else anim.SetBool(sliderID, false);
if (anim.GetCurrentAnimatorStateInfo(0).IsName("Slider"))
{
anim.MatchTarget(matchTarget, Quaternion.identity, AvatarTarget.Root, new MatchTargetWeightMask(new Vector3(1,0,1), 0), 0.38f, 0.67f);
}
if (anim.GetCurrentAnimatorStateInfo(0).IsName("Slider" ))
{
characterController.enabled = anim.GetFloat(sliderCurveID) < 0.5f;
}
}
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Log")
{
Destroy(other.gameObject);
unityLog.SetActive(true);
anim.SetBool(isHoldLogID, true);
}
}
private void OnAnimatorIK(int layerIndex)
{
if (layerIndex == 1) //动画层从0开始排序
{
//print(layerIndex);
int Weight = anim.GetBool(isHoldLogID) ? 1 : 0; //三元运算符
anim.SetIKPosition(AvatarIKGoal.LeftHand, LeftHand.position);
anim.SetIKRotation(AvatarIKGoal.LeftHand, LeftHand.rotation);
anim.SetIKPositionWeight(AvatarIKGoal.LeftHand, Weight);
anim.SetIKRotationWeight(AvatarIKGoal.LeftHand, Weight);
anim.SetIKPosition(AvatarIKGoal.RightHand, RightHand.position);
anim.SetIKRotation(AvatarIKGoal.RightHand, RightHand.rotation);
anim.SetIKPositionWeight(AvatarIKGoal.RightHand, Weight);
anim.SetIKRotationWeight(AvatarIKGoal.RightHand, Weight);
}
}
}
动画展示:
动画系统其他各功能链接:TimeLine
大家还有什么问题,欢迎在下方留言!
如果你有 技术的问题 或 项目开发
都可以加下方联系方式
和我聊一聊你的故事
文章浏览阅读703次,点赞2次,收藏3次。链接:https://pan.baidu.com/s/12l62pcm1ix0UgwKLb576aQ提取码:dcde喜欢点个赞_hadoop大数据平台构建与应用 米洪 案例源码
Go程序开发进阶保姆级教程,结合源码对Go协程的底层原理进行图文详解(为什么要有协程、协程的本质、协程是如何执行的、G-M-P调度模型、如何实现协程的并发、协程的抢占式调度)
文章浏览阅读1.9k次。(转)AES 加密算法的原理详解原文链接如下:AES简介高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用相同的密钥,具体的加密流程如下图:下面简单介绍下各个部分的作用与意义:明文P没有经过加密的数据。密钥K用来加密明文的密码,在对称加密算法中,加密与解密的密钥是相同的。密..._aes cbc 原理图
在res/values文件下定义一个attrs.xml文件,代码如下:在布局中使用,示例代码如下:
文章浏览阅读10w+次,点赞173次,收藏149次。接着上一篇OCR所说的,上一篇给大家介绍了tesseract 在命令行的简单用法,当然了要继承到我们的程序中,还是需要代码实现的,下面给大家分享下java实现的例子。拿代码扫描上面的图片,然后输出结果。主要思想就是利用Java调用系统任务。下面是核心代码:package com.zhy.test;import java.io.BufferedReader;import_tesocr jave
文章浏览阅读519次,点赞2次,收藏2次。图片来源:互联网众所周知,中国是智利车厘子最主要的出口对象,占据了其95%的市场份额。智利驻华大使馆商务参赞娜塔曾表示:“2020-2021产季车厘子实现了丰收,预计今年有50万吨左右的车厘子进入中国市场。”自2020年12月中旬开始,智利海运车厘子陆续到达中国,运输成本较此前空运方式大幅下滑。这意味着,国内消费者将能以更低的价格买到车厘子。然而,近日国内已有多地进口车厘子核酸检测结果为阳性,在这种情况下,你还敢大呼“车厘子自由”吗?01 数据获取本文利用Python采集了淘宝网1585.._爬虫 淘宝车厘子
二、封装调用 request 和 cancelRequest 的 callApi 与 cancelApi。四、在合适的地方取消该请求,注意对应上请求ID requestId。api/index.ts中存放的callApi和cancelApi。页面中pages/map/index.tsx。一、在封装的request.ts中。三、调用请求并配置该请求为可取消。map.ts调用callApi。
文章浏览阅读2.2k次。Oracle监听器服务不启动的时候可采取以下措施予以解决:一、连接主机字符串,提示没有监听器SVRMGR> connect internal/oracle@orcl;ORA-12541: TNS:no listenerSVRMGR>二、运行监听器,提示地址的协议专用组件指定不正确在开始菜单运行中键入lsnrctlLSNRCTL for 32-bit Windows: Version 9..._error oracle tns listener
文章浏览阅读365次,点赞9次,收藏6次。最后,使用 `document.write()` 方法将计算出的最小值和最大值输出到网页上,并通过 `` 标签换行,以便清晰地显示两个不同的结果。- 接着,初始化了两个变量 `min` 和 `max`,它们分别用来存储数组中的最小值和最大值。初始值都设为数组的第一个元素 `arr[0]`。` 结构来分别比较当前遍历到的元素是否为数组中的最小值和最大值,并据此更新 `min` 和 `max` 变量。- 首先,使用 `new Array()` 创建了一个新的数组 `arr` 并初始化了其中的元素。_遍历一个数组并找出数组中的最大值 和最小值js使用for循环
文章浏览阅读158次。react的事件机制_1. react 事件机制
文章浏览阅读50次。【代码】【LeetCode】(力扣) c/c++刷题-136.只出现一次的数字。
文章浏览阅读644次。ACM的算法(觉得很好,有层次感)POJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094) 初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) _前向星 acm算法与实现