【Mib自看】黑魂复刻Unity脚本

这篇博客记录了作者在Unity中复刻黑魂移动脚本和动画控制的过程,包括基本按键播放动画、模型移动、动画变换、跳跃、摄像头控制、攻击动画及其相关问题的解决方法。
摘要由CSDN通过智能技术生成

[课程地址]B站傅老师Unity课程学习记录,仅代表个人理解。

【自看】黑魂复刻Unity脚本

1、移动脚本

设计思路


为了设备与游戏的兼容,不直接使用某按键直接控制,方便玩家随意更改

简单代码演示
	/// <summary>
    /// 设置方向输入的字符串
    /// keyup为前,down为后,right为右,left为左
    /// </summary>
    public string keyup = "w", keydown = "s", keyright = "d", keyleft = "a";


    /// <summary>
    /// 转换输入的方向字符串为信号量
    /// Dup为(-1,1)区间的前后方向信号量
    /// Dright为(-1,1)区间的左右方向信号量
    /// </summary>
    public float Dup,Dright;

    /// <summary>
    /// 把方向字符串转换成方向信号量
    /// </summary>
    private void input_signal()
    {
   
        Dup = (Input.GetKey(keyup) ? 1.0f : 0) - (Input.GetKey(keydown) ? 1.0f : 0);
        Dright = (Input.GetKey(keyright) ? 1.0f : 0) - (Input.GetKey(keyleft) ? 1.0f : 0);
    }

2、动画

在private变量上面添加[SerializeField]是可以使得该变量在Inspector窗口显示的

	[SerializeField]
    private Animator anim;

在这里插入图片描述

动画脚本:ActorController + 输入脚本:PlayerInput

该脚本负责连接方向输入与动画播放

基本按键播放动画脚本

1、获得anim的组件之后,使用SetFloat()函数赋值给动画状态机,因为手柄输出方向的特性(可不全力输出最大值),该值并不是使用单纯的直接赋值,直接赋值有个弊端,当后退时,Dup的值为-1,即使改变了模型方向,也不能使得动画播放,值为-1时动画不会播放,而通过勾股定理处理后的方向向量赋值,可保证该值为正,保证动画可播放,而且不用增加额外的后退动画,节省资源。
2、获得模型的对象(GameObject类型),通过更改该对象的transform.forward的值,去改变模型的方向转向问题,因为有个父对象,父对象的transform.forward值不变且与模型的forward一致,则可以通过父对象的forward值与方向输入结合,更改模型的方向;

具体代码:
	anim.SetFloat("forward", pi.Dmag);
    model.transform.forward = pi.Dvec;

	Dmag = Mathf.Sqrt(Dup * Dup + Dright * Dright);
    Dvec = Dright * transform.right + Dup * transform.forward;

该代码目前还有缺陷:1、停止输入后方向回正 2、大幅度转向无补帧(无过渡)

1问题修复:当有方向输入才转向,不会不输入时把forward向量继续赋值
	if (Dmag > 0.1f)
    {
   
        Dvec = Dright * transform.right + Dup * transform.forward;
    }
2问题修复:转向值直接赋予模型,当然会直接转向,要过渡效果,只需把转向的值平滑赋予即可
(1)该v3变量不能使用Mathf的SmoothDamp函数,SmoothDamp函数不能传入v3类型的变量,只能float类型变量
(2)Slerp函数计算量大,但是效果比较好,lerp函数计算量小
PS:第三个参数越小,变化越慢,假如是1.0f,则等于没有平滑效果
//model.transform.forward = pi.Dvec;改为
model.transform.forward = Vector3.Slerp(model.transform.forward,pi.Dvec,0.2f);

增加模型移动功能,使模型能实际移动

定义一个输入方向大小与方向结合的变量

movingVec = pi.Dmag * model.transform.forward;//方向向量的大小 * 面向的方向
方法1、在FixedUpdate()中赋值给刚体的position
rigid.position += movingVec * Time.fixedDeltaTime * 3.5f;
方法2、赋值给刚体的velocity
Rigidbody.velocity = movingVec;
该行代码咋一看没啥问题,(方向向量的大小 * 面向的方向)赋值给刚体的velocity
赋值的时候应该清楚这值的特性,不能随便乱赋值,比如该movingVec是一个vector3的变量,(x,y,z)
x为摇杆深度*方向
z为摇杆深度*方向
而y恒定为0,因为对象的forward与right的方向都与y关系不大,只关乎x,z

应该改为:

Rigidbody.velocity = new Vector3 (movingVec.x,Rigidbody.velocity.y,movingVec.z);
x与z平常赋值,而y则保持Rigidbody原本的值
运动动画的变换
行走→奔跑动画变换

从状态机中设置,赋予的值小于0.5时走路,大于0.8时就奔跑

赋值给状态机的代码,值的大小由Dmag负责
anim.SetFloat("forward", pi.Dmag);

由上面那句代码可见,状态机更改动画(站立→奔跑)只由Dmag负责
所以对Dmag变量编写相应的代码即可

Dmag变量的代码,可见Dmag是随着输入改变的,所以对输入进行调整以达到相应的目标
Dmag = Mathf.Sqrt(Dup * Dup + Dright * Dright);

我们的目标是控制行走与奔跑,则我们需要加入一个条件,比如shift+方向才奔跑,老设定了
然后不奔跑时的赋值上限为行走的0.5,所以

只需把输入方向的上限改为0.5f即可
targetDup = (Input.GetKey(keyup) ? 0.5f : 0) - (Input.GetKey(keydown) ? 0.5f : 0);
targetDright = (Input.GetKey(keyright) ? 0.5f : 0) - (Input.GetKey(keyleft) ? 0.5f : 0);

当需要奔跑时,检测是否按下shift按键,把Dmag * 2 就可实现奔跑与行走的切换

直接赋值会出现bug,虽然游戏不会出错,但是如此赋值是没有过渡的,行走动画直接变为奔跑会显得很唐突
Dmag = Mathf.Sqrt(Dup * Dup + Dright * Dright) * 2.0f;

个人觉得最简单的解决方法:

因为targetDup赋给状态机的上限是0.5f,当赋值过去时是用的平滑函数
所以只需用三元表达式判断+平滑函数的目标值*2
则可以达到平滑效果
Dup = Mathf.SmoothDamp(Dup, targetDup * (Input.GetKey(keyrun) ? 2.0f : 1.0f), ref velocityDup, 0.2f);
Dright = Mathf.SmoothDamp(Dright, targetDright * (Input.GetKey
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值