博客
关于我
学习总结-2020年12月16日
阅读量:434 次
发布时间:2019-03-06

本文共 4603 字,大约阅读时间需要 15 分钟。

昨天把动画系统大致过了一遍,今天主要学习案例巩固,案例学习未完成,还是把一些操作总结以下。

  一.lerp的使用

  使用插值运算能够使得变化平滑,但是lerp插值的运算结果是无限趋近,无法到达,可以在插值后进行判断,插值结果和目标结果足够接近的化直接设置为目标结果。 

siren.GetComponent
().volume = Mathf.Lerp(siren.GetComponent
().volume,0,Time.deltaTime * intensityChangeSpeed);

这是一段控制声音的代码,将音量设置为现有音量和0之间的插值,插值百分比为帧时间乘以每秒变化速度,可以将音量逐渐降为0,但是最后的结果无限趋近于0。可以作判断,如果当前音量和0的差小于0.01,则直接将音量设置为0,否则进行插值运算。

插值除了上面的线性插值外,还可以使用球形插值Slerp。线性插值和球形插值使用方法相同,达到的效果相似,但是底层的运算方法不同,球形插值会运算角度和向量长度。

  二.pingpong的使用 

  使用pingpong方法能够使值在0和目标值之间来回变化,就像乒乓球一样。

alarmLight.intensity = Mathf.PingPong(Time.time * intensityChangeSpeed, 0.5f);

这是一段控制灯光强度的代码,使灯光强度在0和0.5之间来回变化,第一个参数为自递增的值,使用游戏运行时间。

  三.单例模式

  管理游戏进程和UI界面显示的脚本可以命名为GameManager(见下图,这个类名称为官方的类ID参考中的9号名称,将脚本修改为此名称脚本图标也会变成齿轮,谨慎使用)或者GameController等(随你乐意),这个类中的参数和方法等往往会被其他脚本设置或者调用,因此最好采用单例模式。

 

 

public static GameManager _instance;    void Start()    {        _instance = this;    }

见上面代码,在类中提供公开的静态的这个类的实例属性(一般可以命名为_instance),然后在初始化时将这个实例属性赋值,最好将构造方法私有化,这样在外部不能实例化这个类,而这个类自己提供了唯一的实例,因为是静态的,也可以在外部通过类名调用这个唯一实例。

  四.标签类Tags

  在游戏中,大量的游戏对象往往通过标签进行查找,在查找游戏对象时为了防止写错标签名,可以提供标签类Tags。

public class Tags : MonoBehaviour{    public const string player = "Player";    public const string siren = "Siren";    public const string enemy = "Enemy";}

标签类中使用const关键字修饰标签名称,可以在外部直接通过类名.属性名调用这个字符串(const是指静态且不可修改的变量),但是不能在外部修改属性的值。这里也可以使用枚举enum类,但是enum类的值是整数,这种方式更合适。

  五.角色的动画和移动

  角色的移动可以使用改变位移的方式,但是动画中也可以改变位移量(动画可以理解为在一定帧范围内,如0-60帧,游戏物体的位置、旋转、颜色等属性进行改变的过程),因此一般将位移直接做到动画中,播放动画人物模型也会相应的移动旋转等。

  下面使用2D混合树控制角色的移动。

 

 横轴的值代表角色的转向,纵轴的值代表角色的向前位移。从上到下四排分别对应跑、走、下蹲慢走、停止四种向前的状态,纵轴值对应1、0.5、0.25、0四种。从左到右三列对应向左转、没有方向改变、向右转,横轴值对应为-1、0、1三种。如走路并向左转为(-1,0.5),原地右转为(1,0)。接下来通过代码设置横轴和纵轴的值。

///     /// 获取键盘输入,并存储为h值和v值,以便update函数中用于设置animator的参数,使用插值运算使运动平滑    ///     private void GetInputInfo()    {        //左shift键和向前键,下蹲慢走        if (Input.GetKey(KeyCode.LeftShift) && (Input.GetAxis("Vertical") > 0.1f))        {            h = Mathf.Lerp(h,0f,acceleratedSpeed * Time.deltaTime);v = Mathf.Lerp(v, 0.25f, acceleratedSpeed * Time.deltaTime);        }        //向前向左和空格键,向左跑        else if(Input.GetAxis("Vertical") > 0.1f && Input.GetAxis("Horizontal") < -0.1f && Input.GetKey(KeyCode.Space))        {            h = Mathf.Lerp(h, -1f, acceleratedSpeed * Time.deltaTime); v = Mathf.Lerp(v, 1f, acceleratedSpeed * Time.deltaTime);        }        //向前向右键和空格键,向右跑        else if (Input.GetAxis("Vertical") > 0.1f && Input.GetAxis("Horizontal") > 0.1f && Input.GetKey(KeyCode.Space))        {            h = Mathf.Lerp(h, 1f, acceleratedSpeed * Time.deltaTime); v = Mathf.Lerp(v, 1f, acceleratedSpeed * Time.deltaTime);        }        //向前键和空格键,向前跑        else if (Input.GetAxis("Vertical") > 0.1f && Input.GetKey(KeyCode.Space))        {            h = Mathf.Lerp(h, 0f, acceleratedSpeed * Time.deltaTime); v = Mathf.Lerp(v, 1f, acceleratedSpeed * Time.deltaTime);        }        //向前向左键,向前走        else if (Input.GetAxis("Vertical") > 0.1f && Input.GetAxis("Horizontal") < -0.1f)        {            h = Mathf.Lerp(h, -1f, acceleratedSpeed * Time.deltaTime); v = Mathf.Lerp(v, 0.5f, acceleratedSpeed * Time.deltaTime);        }        //向前向右键,向右走        else if (Input.GetAxis("Vertical") > 0.1f && Input.GetAxis("Horizontal") > 0.1f)        {            h = Mathf.Lerp(h, 1f, acceleratedSpeed * Time.deltaTime); v = Mathf.Lerp(v, 0.5f, acceleratedSpeed * Time.deltaTime);        }        //向左键,原地左转        else if (Input.GetAxis("Horizontal") < -0.1f)        {            h = Mathf.Lerp(h, -1f, acceleratedSpeed * Time.deltaTime); v = Mathf.Lerp(v, 0f, acceleratedSpeed * Time.deltaTime);        }        //=向右键,原地右转        else if (Input.GetAxis("Horizontal") > 0.1f)        {            h = Mathf.Lerp(h, 1f, acceleratedSpeed * Time.deltaTime); v = Mathf.Lerp(v, 0f, acceleratedSpeed * Time.deltaTime);        }        //向前键,向前走        else if (Input.GetAxis("Vertical") > 0.1f)        {            h = Mathf.Lerp(h, 0f, acceleratedSpeed * Time.deltaTime); v = Mathf.Lerp(v, 0.5f, acceleratedSpeed * Time.deltaTime);        }        //idle状态        else        {            h = Mathf.Lerp(h, 0f, acceleratedSpeed * Time.deltaTime); v = Mathf.Lerp(v, 0f, acceleratedSpeed * Time.deltaTime);        }    }

在update函数中调用这个函数,设置好h和v值后将animator组件中的horizontal参数和vertical参数的值同步为h和v值。这里使用了线性插值使运动状态的变化不会太突兀,也可以直接设置h和v值,这样动画播放切换的时候会有一些生硬。

void Update()    {        GetInputInfo();        anim.SetFloat("Vertical", v);        anim.SetFloat("Horizontal", h);    }

可以看到,这里并没有向后运动的动画,如果有可以继续添加,纵轴的值设置为负值即可,如有向右后方运动的动画设置坐标为(1,-1),再通过代码获取相应按键后设置h和v值即可。

ps:这种按键控制方式感觉对第一人称游戏的主角运动较为适用,而且一般主角运动默认都是跑步的,这里默认运动为走,不过也懒得修改了。

转载地址:http://vahyz.baihongyu.com/

你可能感兴趣的文章
zookeeper安装部署步骤
查看>>
Linux I/O 重定向
查看>>
Hadoop学习笔记—Yarn
查看>>
误差计算
查看>>
对象的绑定方法
查看>>
__format__
查看>>
元类(metaclass)
查看>>
大白话OSI七层协议
查看>>
Python深浅拷贝
查看>>
使用线程的场景
查看>>
十天快速入门Python(目录)
查看>>
008 Python基本语法元素小结
查看>>
026 模块3-random库的使用
查看>>
027 实例6-圆周率的计算
查看>>
决策树算法原理(下)
查看>>
小白专场-树的同构-python语言实现
查看>>
小白专场-FileTransfer-python语言实现
查看>>
191006
查看>>
08-03 细分构建机器学习应用程序的流程-流程简介
查看>>
B-概率论-条件概率
查看>>