第三人称射击游戏人物瞄准仰角的控制方案

news2024/12/23 10:31:57

这个功能有多种方案实现,总体可以分为两类:

1.改变腰的旋转;

2.改变手臂和头的旋转;

其中方案1:

只要转动腰一个骨骼,比较简单;

但是因为腰以上的部分都不动,第三人称比较僵硬;

又因为腰以上的部分保持稳定,所以适合在第一人称使用。

方案2:

转动3个骨骼,比较复杂;

调好了第三人称效果好一些;

因为枪相对头和第一人称相机的位置不固定,第一人称看到的枪的位置和远近也不固定,仰视时枪可能和头、第一人称相机穿模。

animator.SetBoneLocalRotation()实现(只转动腰,最简单的方案)

需要把相应层打开IK Pass,在OnAnimatorIK()里执行animator.SetBoneLocalRotation(),可以直接改变某个骨骼的旋转。这似乎是官方推荐的方法:

b3f7156805484dcda305b6d50d197669.png

Quaternion.AngleAxis()输入的轴是物体的局部坐标系的,所以要获得Spine坐标系下人物x轴的向量。Quaternion.AngleAxis()返回一个旋转变化,把它乘给spine.localRotation。这里angleX是仰角,是个会变大变小的值,怎么能做变化量?

 public Animator animator;
    HumanBodyBones boneToLookUpDown=HumanBodyBones.Spine;
    Transform spine;
    [Range(-90,90)]
    public float angleX=0;
    void Start(){
        animator = GetComponent<Animator>();
        spine=animator.GetBoneTransform(boneToLookUpDown);
    }
    void OnAnimatorIK(){
        Quaternion spineRot=Quaternion.AngleAxis(angleX,spine.InverseTransformDirection(transform.right));
        animator.SetBoneLocalRotation(boneToLookUpDown,spine.localRotation*spineRot);
    }

这里animator.SetBoneLocalRotation()之前我打印了一下spine.localEulerAngles,结果是:

3ba60c0f64d3477485b12b2f02641bea.png

animator.SetBoneLocalRotation()之前spine的旋转一直不变,会被动画系统掰回原来的旋转,所以animator.SetBoneLocalRotation(xxx,spine.localRotation*deltaRot);里面虽然有spine的当前旋转,但这个旋转一直是人物姿势被改变前的旋转,这句其实是设置spine的局部绝对旋转。

如果不运行,只在编辑模式看一下效果,可以把人物的旋转归零,选Global,Rotate Tool,直接旋转Spine骨骼。

6faf79048cce49b39d957eeaf2be8072.png

效果

894c7dbef3f34c30b50679e59dfcd530.png766678e95ca049b6a847a55a684d2f57.png

动画一维混合树实现(转动双臂和头,对动画要求高)

如果有人物仰视俯视的动画,可以用一维混合树实现。

我试了从持枪平视做持枪仰视,修改chest、upper chest、spine的Front-Back,结果上下半身都动了,我不会做只动上半身,但是可以只修改arm,做成持枪仰视俯视的动画,上半身保持直立;

18e47513cc684a66b5fbb3d30cebcdd3.png01f3a057b87a4878816730a727faa35e.png

以上原因导致这个方案只能改变双臂做仰视俯视的效果。所以持枪状态在body层是一个移动的二维混合树,arm层是控制仰角的一维混合树。

第一人称效果(枪相对头的位置变化了,所以看到枪的位置不一样):e478e3fd202e41199dd55596193f468b.png

f94fd8586dc64abf86a5b4e403ed301f.png

因为没有严格K动画,改变仰角的时候左手的位置是变化的。

Unity使用一维混合树改变人物仰角_单机游戏热门视频 (bilibili.com)

枪通过IK带动双手(转动双臂和头。调整很繁琐)

人物改变仰角的时候枪是绕右肩旋转的,所以在瞄准姿势在人物根节点下右肩的位置放一个节点作为转轴Axis。

把枪挂载到Axis下,在枪下面建左手右手的IKGoal节点。枪应该使Axis在枪托尾部的位置。IKGoal的位置和旋转需要运行后手调。

Axis前方很远的地方建一个target,作为头看向的目标。

配置双手IK:

public Transform rightHandIK,leftHandIK;
    void HandsIK(){
        animator.SetIKPosition(AvatarIKGoal.RightHand,rightHandIK.position);
        animator.SetIKPositionWeight(AvatarIKGoal.RightHand,1);

        animator.SetIKRotation(AvatarIKGoal.RightHand,rightHandIK.rotation);
        animator.SetIKRotationWeight(AvatarIKGoal.RightHand,1);

        animator.SetIKPosition(AvatarIKGoal.LeftHand,leftHandIK.position);
        animator.SetIKPositionWeight(AvatarIKGoal.LeftHand,1);

        animator.SetIKRotation(AvatarIKGoal.LeftHand,leftHandIK.rotation);
        animator.SetIKRotationWeight(AvatarIKGoal.LeftHand,1);
    }

配置头看向:

public Transform target;
    void HeadLookIK(){
        animator.SetLookAtPosition(target.position);
        animator.SetLookAtWeight(1);
    }

总结起来,节点的决定关系是:

Axis->枪->双手IK->双手

需要手调的变量有:

1.Axis的位置;

2.枪的位置;

3.双手IK的位置和旋转;

效果

看上去好像不错,其实仰视的时候枪和头、第一人称相机穿模了。所以这个适用于第三人称,第一人称适合方案1.

Aim Constraint组件实现(只转动腰,和方案1效果一样但是麻烦得多,已经废弃)

在人物的chest上挂载Aim Constraint组件,人物上挂载一个控制俯仰的轴targetAxis,targetAxis前方很远处挂一个空物体target,该组件把物体的Aim Vector方向朝向Sources物体。sources物体选target。Aim Vector不能选z轴正方向,因为持枪状态人的胸朝向右前方,就是chest的z轴正方向朝向右前方,应该指向准星的是枪口的方向。所以需要得到枪口方向在chest坐标系下的向量。

1.选中人物;

2.来到Animation窗口找到持枪动画,点预览;

3.在脚本里加带有[ContextMenu()]的方法,执行

chest.InverseTransformDirection(character.forward);

4.在脚本的...里执行

得到的就是枪口方向在chest坐标系下的向量,把这个Vector3抄下来,写给Aim Vector。

0951c9fe13bac30c4f7baf4a20fe554e.png

如果给人物趴着的动画制作这个效果,需要在趴着的状态执行上述代码,再得到一个Aim Vector。

为什么必须用AimConstraint?直接用代码旋转chest不行吗?

运行状态下,对于有Animator的物体,在Scene窗口移动旋转人物的骨骼,无效,因为人物正受Animator操控,播放指定的动画,Animator的优先级高于改变Transform。但是AimConstraint的优先级高于Animator。

控制优先级AimConstraint>Animator>Transform

AimConstraint开启关闭的代码放在哪里

因为瞄准约束影响上半身的效果,而状态机Body层和Arm层没有做同步,可能出现一些难以预料的状态组合,最稳的方法是放在Arm层的各状态脚本里。当然趴着瞄准的代码要放在Body层的状态脚本了。

持步枪的子状态机。瞄准约束打开放在Rifle Stand的OnStateEnter(),关闭根据想在哪些状态关闭放在相应的OnStateEnter()。因为

1.一个状态无法知道下一个状态是什么,放在OnStateExit()里会帮下一个状态决定了AimConstraint开启或关闭,造成一刀切的效果;

2.且OnStateExit()在下一个状态的OnStateEnter()之后,会覆盖OnStateEnter()的效果;

所以AimConstraint的开启关闭不宜放在OnStateExit()

7985c859edec4c499fc85af8b4e491e6.png

Constraint Settings

enabled勾选,Lock不勾选状态下,勾选isActive时,会把当前的旋转填入Rotation At Rest.

没有运行时,enabled,isActive,Lock全部勾选时,约束会实时生效。

如果不想用Constraint Settings的功能就关闭isActive,把两个Rotation设0,一直勾选Lock。

a3159276b26b6969fcd4fb258e67c8d3.png

LookAtConstraint是加给第一人称相机还是头部?

第一人称相机是头部的子物体,人物不拿枪,鼠标前后移动时,需要相机仰视俯视,这时不需要人物的整个上半身仰起或俯下,胸部的Aim Constraint关闭。问题是这个组件加给头还是第一人称相机?如果加给头,鼠标前后移动的时候人物会仰头低头,很生动,但是人物跑步的时候身体会晃,但是头一直稳定,很僵硬。如果加给相机,人物仰头低头的效果就没了,但是跑步的时候头随身体摇晃,很生动。

观察了绝地求生,跑步的时候第三人称看人物的头摇晃很厉害,第一人称看影子头也摇晃很厉害,但是第一人称相机很稳定,说明应该是第一人称相机加了约束;另外在第三人称仰视俯视的时候好像只有相机在仰视俯视,人物的头没有动。这个可以观察比赛开始之前,集合的玩家一定有在俯视仰视的,但是人物的头都在平视。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2183479.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

tk.mapper框架使用

说明&#xff1a;tk.mapper是一款DAO框架&#xff0c;也是基于Mybatis的&#xff0c;个人感觉&#xff0c;他是基于MyBatis和MyBatis-plus、MyBatis-Flex之间的过渡框架——能调用DAO的API&#xff0c;不手写SQL&#xff0c;但功能没有后面这两款框架多。本文介绍tk.mapper框架…

PyInstaller打包并设置图标

PyInstaller 是一个用于将 Python 代码打包成独立可执行文件的工具。如果你的 Python 代码中使用了一些资源文件&#xff08;如图片、音频、配置文件等&#xff09;&#xff0c;那么你需要将这些资源文件一起打包到可执行文件中&#xff0c;以便在运行时能够访问这些资源。 以…

STM32新建工程-基于库函数

一、创建一个新工程 我这里选择STM32F103C8的型号&#xff0c;然后点击OK。 keil5里面的小助手&#xff0c;暂时不用&#xff0c;叉掉 二、为工程添加文件和路径 在工程模板中还需要添加启动文件、系统头文件、系统时钟文件&#xff0c;创建一个文件夹start&#xff0c;将下面…

【韩顺平Java笔记】第5章:程序控制结构

文章目录 102. 回顾上一章节103. 顺序控制103.1 顺序控制 104. 单分支使用104.1 分支控制 if-else 介绍104.2 单分支 105. 单分支流程图106. 双分支使用107. 双分支流程图108. 双分支练习题109. 多分支使用109.1 多分支的流程图 110. 多分支练习1111. 多分支练习2112. 嵌套分支…

Fibonacci数列最小步数

1.题目&#xff1a; 2.解析&#xff1a; 让a,b,c回滚构造斐波那契数列 &#xff1a;ab, bc, cab; 输入的数 n小于c,在b,c之间&#xff0c;只要 n1 或者 n-1&#xff08;贪心思想&#xff1a;n只加一或者只减一&#xff09; 最后再求n-b,c-n的最小值&#xff0c;获得最小步数 …

《Linux从小白到高手》理论篇(八):Linux的进程管理详解

本篇将介绍Linux的进程管理相关知识&#xff0c;并将深入介绍Linux的进程间相互通信。 进程就是运行中的程序&#xff0c;一个运行着的程序&#xff0c;可能有多个进程。 比如Oracle DB&#xff0c;启动Oracle实例服务后&#xff0c;就会有多个进程。 Linux进程分类 在 Linux…

csp-j模拟一补题报告

前言 又要开始写补题报告了&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; &#xff08;“关于二进制中1的个数的研究”这篇文章可能会延期&#xff09; 第一题 题目 交替出场 (alter.cpp/c) 问题描述 给定一个字符串&#xff0c…

DC00024基于ssm实验室预约管理系统java web项目web教师预约jsp预约管理系统

1、项目功能演示 DC00024基于web实验室预约管理系统ssm教室预约实验室预约管理系统java web项目MySQL 2、项目功能描述 基于ssm实验室预约管理系统分为用户和系统管理员两个角色。 2.1 系统管理员 1、系统登录 2、用户管理&#xff1a;修改个人信息、修改个人密码、教师管理…

Forrester 报告揭示 2024 年十大云市场趋势:AI 与边缘计算融合带来机遇与挑战

云计算de小白 Forrester 在其“2024 年十大云计算趋势”报告中表示&#xff1a;“2024 年&#xff0c;基于云端的 AI 产品的市场采用和普及度将达到高潮。” Forrester 表示&#xff1a;“企业用户已经投资了微软 M365 Copilot 等人工智能服务作为提高生产力的工具&#xff0…

2024新淘宝镜像地址下载【vue-cli】

需要先安装NodeJS&#xff0c;然后再安装Vue-cli NodeJS下载 nodejs下载&#xff0c;直接搜官网 网址&#xff1a;https://nodejs.org/zh-cn LTS为长期稳定版本&#xff1a; 安装过程 只需要配置一下安装目录&#xff0c;其他都点下一步next 注意安装目录无中文无空格 验证…

vulnhub-Basic Pentesting 2靶机

vulnhub&#xff1a;https://www.vulnhub.com/entry/basic-pentesting-2,241/ 导入靶机(建议VirtualBox&#xff0c;VMWare扫不到)&#xff0c;放在kali同网段&#xff0c;扫描 靶机在192.168.81.3&#xff0c;扫描端口 很多端口&#xff0c;存在网站服务&#xff0c;访问 啥也…

加密与安全_HTOP 一次性密码生成算法

文章目录 HOTP 的基础原理HOTP 的工作流程HOTP 的应用场景HOTP 的安全性安全性增强措施Code生成HOTP可配置项校验HOTP可拓展功能计数器&#xff08;counter&#xff09;计数器在客户端和服务端的作用计数器的同步机制客户端和服务端中的计数器表现服务端如何处理计数器不同步计…

centos7安装docker-ce服务

docker服务安装 前言一、使用阿里云源进行安装二、使用清华源安装三、使用官网源安装 前言 centos7安装docker-ce 服务 一、使用阿里云源进行安装 centos7安装docker在国内使用阿里云的源安装比较快速。 # 获取yum源 sudo yum install -y yum-utils; sudo yum-config-manager …

(Linux驱动学习 - 4).Linux 下 DHT11 温湿度传感器驱动编写

DHT11的通信协议是单总线协议&#xff0c;可以用之前学习的pinctl和gpio子系统完成某IO引脚上数据的读与写。 一.在设备树下添加dht11的设备结点 1.流程图 2.设备树代码 &#xff08;1&#xff09;.在设备树的 iomuxc结点下添加 pinctl_dht11 &#xff08;2&#xff09;.在根…

解决Excel时出现“被保护单元格不支持此功能“的解决办法,详细喂饭级教程

今天有个朋友发过来一个excel文件&#xff0c;本来想修改表格的内容&#xff0c;但是提示&#xff0c;被保护单元格不支持此功能&#xff0c;对于这个问题&#xff0c;找到一个解决方法&#xff0c;现记录下来&#xff0c;分享给有需要的朋友。 表格文件名为aaa.xls,以WPS为例。…

十一、磁盘的结构

1.磁盘的结构 磁盘 磁盘由表面涂有磁性物质的圆形盘片组成 磁道 每个盘片被划分为一个个磁道 扇区 每个磁道又划分为一个个扇区&#xff0c;每个扇区就是“磁盘块”&#xff0c;由于其容量相等&#xff0c;内磁道扇区面积小&#xff0c;故密度大。 盘面 磁盘有多个盘片“…

【AIGC】ChatGPT提示词解析:如何打造个人IP、CSDN爆款技术文案与高效教案设计

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;打造个人IP爆款文案提示词使用方法 &#x1f4af;CSDN爆款技术文案提示词使用方法 &#x1f4af;高效教案设计提示词使用方法 &#x1f4af;小结 &#x1f4af;前言 在这…

时序必读论文14|VLDB24 TFB:全面且公平的时间序列预测方法框架

论文标题&#xff1a;TFB: Towards Comprehensive and Fair Benchmarking of Time Series Forecasting Methods 论文链接&#xff1a;https://arxiv.org/pdf/2403.20150.pdf 代码链接&#xff1a;https://github.com/decisionintelligence/TFB 前言 五一过后读的第一篇文章…

MySQL 大数据量导入与导出全攻略

《MySQL 大数据量导入与导出全攻略》 在实际的数据库应用中&#xff0c;我们经常会遇到需要处理大数据量的导入和导出的情况。无论是数据迁移、备份恢复&#xff0c;还是数据共享&#xff0c;高效地处理大数据量都是至关重要的。那么&#xff0c;MySQL 是如何应对大数据量的导…

深度学习 Transformer 的标签平滑(Label Smoothing)

01 引言 标签平滑&#xff08;Label Smoothing&#xff09;是一种正则化技术&#xff0c;用于深度学习中的分类任务&#xff0c;尤其是在Transformer模型中。它的目的是减少模型对于训练数据中硬标签&#xff08;hard labels&#xff0c;即标准的one-hot编码&#xff09;的过…