Unity3D-VR《静夜诗》5-李白吟诗

  • 1.设计场景中的可视内容
    • 1.1添加李白人物对象
    • 1.2添加显示诗词的文本对象
  • 2. 李白行走路径动画
    • 2.1动画控制器libaiMain
    • 2.2 动画编辑器编辑动画剪辑libaiMain
  • 3. 李白抬头等动画
    • 3.1 动画控制器
    • 3.2 动画事件脚本函数SetTrigger
  • 4. 李白行走时同步吟诗
    • 4.1 设置动画事件
    • 4.2 动画事件脚本函数PlayPoem
  • 5. 初始状态设定
  • 6. 背景音效
  • 7. 总结

窗户打开动画播放结束后,应该是出现李白吟诗了,如何实现呢?

在工程视图中选中NDVRresources\ Res\ Animations\ WinOpen动画剪辑文件,在监视视图中可以看到该动画剪辑的时长是1S。根据项目实现要求,大约在窗户打开1S后李白开始吟诗。
这样我们可以在播放窗户打开动画后延时2S再播放李白吟诗的动画。
按照习惯,先来完成场景中的可视内容的设计。

1.设计场景中的可视内容

1.1添加李白人物对象

将素材资源目录中已经提供的李白角色的预设对象拖放到场景中,调整到合适的位置及朝向。设置参考如下:

1.2添加显示诗词的文本对象

场景中合适的位置新建诗词文本背景Image对象ImagePoemBg,设置属性如下:

组件Image中的图片Five在资源目录NDVRresources\UIRcs中已经提供给大家了。

在对象ImagePoemBg下新建文本子对象TextPoem属性设置如下:

2. 李白行走路径动画

2.1动画控制器libaiMain

在LiBai\Animations目录下有许多李白的动画剪辑,如抬头、低头、左转等,还有2个动画控制器文件,其中动画控制器文件libaiMain是播放李白的行走的位移动画的,控制器设定如下:

默认状态是libaiMain,对应播放libaiMain动画剪辑,我们将动画控制器libaiMain拖放到LiBai对象上,自动为LiBai对象添加了动画控制器组件,并设置动画控制器Controller属性值为libaiMain。

可以试着运行场景,看看libaiMain动画状态播放的libaiMain动画剪辑
提示

不要搞混了概念,资源中提供的动画控制器文件、设定的动画状态名、状态对应的动画剪辑命名都是libaiMain)。

运行时在控制台出现了以下错误提示:

‘LiBai’ AnimationEvent ‘SetTrigger’ has no receiver! Are you missing a component?

你可以忽略这些错误继续运行,可以看到李白在屋里行走的过程,每走到一个地方,就会出现类似的错误,最后出现以下错误:

‘LiBai’ AnimationEvent ‘ShowQuestionp’ has no receiver! Are you missing a component?

错误的提示意思是动画播放到某一帧时动画事件没有对应受理的函数。

2.2 动画编辑器编辑动画剪辑libaiMain

动画控制器默认播放的就是libaiMain动画剪辑,libaiMain动画剪辑是一个路径动画,播放的是李白吟诗时在室内行走的路径。在场景中选中LiBai对象,通过Window | Animation 打开动画剪辑编辑器编辑LiBai对象上的动画剪辑libaiMain。操作界面如下:

说明

  • 在时间标尺上拖动红线(动画帧)可以看到整个动画播放时李白行走的路径位移。
  • 标尺下方白色柱状亮条表示该帧设定有一个动画事件,前面6个动画事件调用的函数是’SetTrigger’,最后一个动画事件调用的函数是’ShowQuestionp’。
  • 李白在行走到某个位置时还应该有一些转身、抬头、低头等动作,通过设置动画事件调用函数来播放这些小动画是我们常用的实现方法。问题是目前我们还没有设计好这样的脚本函数,这就导致了运行时的这些错误。

为了修正这些错误,要为动画控制器所在的对象LiBai添加新的脚本animationCtl.cs,脚本中添加 Public void SetTrigger(),代码参考如下:

public class animationCtl : MonoBehaviour {public void SetTrigger(){}
}

函数SetTrigger的实现可以在后面继续完善的。

可以将libaiMain动画剪辑中的最后一个调用的函数’ShowQuestionp’的动画事件去掉,因为根据实现功能要求是不需要实现(其实是在李白吟诗结束后界面上显示一个问题让玩家作答吧,同学们有兴趣可以想想如何实现这样的功能?)

测试:
运行场景,错误没有了。

3. 李白抬头等动画

3.1 动画控制器

LiBai对象的动画控制器播放的是李白行走的路径,通过观看项目运行视频或运行程序,可以看到李白行走到某一位置时不但会吟诗还会做一个动作(比如抬头、低头、转身等)。

在场景中选中LiBai对象下的子对象libai_libai_rig,在监视视图中可以看到子对象下也有一个动画控制器组件,动画控制器Animator的Controller属性默认为空,将工程视图中NDVRresources\SceneRcs\JiaoHu\LiBai\Animations目录下的另一动画控制器文件LiBai设置为该属性值。该动画控制器就是控制李白行走到某个位置时要做的转身、抬头等小动作。打开动画控制器文件LiBai,显示其动画状态设置如下:

说明

可以看到控制器有5个状态(待机、左转90度、低头、走路、抬头),分别对应着李白角色的5个动画剪辑,默认状态时LiBai_DaiJi(待机),左边还设定了4个Trigger型的4个参数,分别是zuozhuan(左转)、zoulu(走路)、taitou(抬头)、ditou(低头),这4个参数控制着动画状态间的5个过渡,比如当前如果是LiBai_DaiJi状态,触发了zuozhuan参数后,控制器就会将动画过渡到LiBai_ZuoZhuan90du状态,播放该状态对应的动画剪辑。

3.2 动画事件脚本函数SetTrigger

通过反复观看视频或发布后的软件,可以推测李白行走的libaiMain动画剪辑中的前面6个动画事件调用的函数SetTrigger分别是依次触发zuozhuan、ditou、zoulu、taitou、zuozhuan、ditou这6个动画参数的。所以函数SetTrigger是带有字符串参数的,要调用libai_libai_rig对象上的动画控制器,根据传递的触发参数过渡到对应动画状态,从而播放该状态的动画剪辑,实现李白行走到某个位置时低头、抬头等一些列动作。

打开animationCtl.cs脚本,根据需要进行修改,修改后的参考代码如下:

public class animationCtl : MonoBehaviour {public Animator anim_child;public void SetTrigger(string name)  //{anim_child.SetTrigger(name);}
}

在场景中选中LiBai对象,将libai_libai_rig对象拖放到animationCtl脚本的参数anim_child中,赋值好了脚本的参数后,再设置好LiBai对象上libaiMain动画剪辑中的6个动画事件调用函数SetTrigger的参数,分别依次是zuozhuan、ditou、zoulu、taitou、zuozhuan、ditou。 可以试着运行了。

测试:
李白行走时配有转身、低头、抬头动作。
提示:

在动画编辑器中可以拖动动画事件的高亮柱条,调整动画事件触发的事件。
李白初始位置可以设置为动画第一帧时的位置值。

4. 李白行走时同步吟诗

4.1 设置动画事件

通过观看项目运行视频或发布后的运行程序,结合李白行走动画剪辑libaiMain在时间轴上的转身、抬头等动画事件的设定时间,可以初步拟定在libaiMain动画播放后,2秒、6秒、13秒、18秒处显示诗词第一、二、三、四句文本及播放对应的音频剪辑,23秒处诗词文本消失。

在libaiMain动画的时间轴的对应点设置动画事件,调用脚本函数PlayPoem(int i)。
接下来我们实现该播放对应位置诗词的脚本函数。

4.2 动画事件脚本函数PlayPoem

在animationCtl.cs脚本类中要新增一个函数PlayPoem,根据参数的序号,显示对应的诗词文本和播放诗词音频

为此要在脚本类中增加一些变量的声明:

  • 要引用显示诗词文本的对象ImagePoemBg,以便通过调用对象的SetActive函数来设置诗词对象是否活动的(即可见),吟诗结束后设置诗词对象不活动(不可见)。根据动画事件函数的触发调用来更改ImagePoemBg对象的文本子对象TextPoem的显示内容
  • 要引用播放诗词音频的播放器
  • 要保存诗词音频剪辑的数组
  • 保存诗词文本的字符串数组。

打开animationCtl.cs脚本,新增一些变量的定义代码,变量的初始化代码,以及动画事件要调用的函数PlayPoem(int i)实现,完整的脚本参考代码的如下:

public class animationCtl : MonoBehaviour {public Animator anim_child;    public GameObject go_Poem;//诗词文本,\r\n表示换行[TextArea]public string[] poems={"窗\r\n前\r\n明\r\n月\r\n光","疑\r\n是\r\n地\r\n上\r\n霜","举\r\n头\r\n望\r\n明\r\n月","低\r\n头\r\n思\r\n故\r\n乡" };public AudioClip[] aduioPoems;//诗词音频//私有变量private AudioSource audioPlayer;//音频播放器private Text textPoem;private void Start(){   //初始化一些变量audioPlayer = GetComponent<AudioSource>();textPoem = go_Poem.GetComponentInChildren<Text>();go_Poem.SetActive(false);//初始不可见的}//设置动画参数,过渡到相应动画状态public void SetTrigger(string name)  //{anim_child.SetTrigger(name);}//显示对应序号的诗词文本、播放对应的诗词音频public void PlayPoem(int i) {        go_Poem.SetActive(true);//设置诗词文字可见if (i <=3 && i>=0) {textPoem.text = poems[i]; //显示诗词文字audioPlayer.clip = aduioPoems[i];//赋值诗词声音audioPlayer.Play();  //播放诗词声音}if(i==4){go_Poem.SetActive(false );//设置诗词文字可见} }
}

体会[TextArea]在变量声明中的使用,其效果可以看一下脚本在监视视图中变量展示形式的不同。数组定义初始赋值以及换行符请参考C#的语法。

脚本完成后在监视视图脚本组件中设置脚本的参数如下:

最后还要为LiBai对象添加AudioSource组件,如果没有的话在Start函数调用GetComponent()时会报错的。

思考:

变量能声明私有的尽量不要声明公有,脚本中anim_child变量声明改为私有private后,如何给它初始化?

测试:

运行后播放libaiMain动画,在播放过程中通过设置的动画事件调用脚本函数,实现诗词文本音频及转身抬头等动画的同步播放,最后诗词文本对象自动消失。

说明

项目演示中李白吟诗动画是在窗户打开后2秒播放的,初始不播放李白吟诗动画,只要设置LiBai对象的动画控制器组件Animator的enable属性为false即可,要播放时则设置为true。

5. 初始状态设定

要设定游戏的初始状态值,建议在全局游戏控制脚本GameManager的Start函数中设置。需要在全局游戏控制脚本中定义一些变量,以便引用游戏中的对象。

完成后的脚本GameManager.cs,参考代码如下:

public class GameManager : MonoBehaviour {public Animator animator_Window;//窗口动画控制器public Collider collider_Window;//可交互的窗口对象碰撞器public Animator animator_Libai;//李白动画控制器// Use this for initializationvoid Start () {        animator_Window.enabled  = false; //设置窗口动画控制器不使能(不起作用)        collider_Window.enabled = false; //设置窗口对象不可交互        animator_Libai.enabled = false; //设置李白动画控制器不使能(不起作用)        }//凝视开始按钮触发交互后执行的方法public void StartPlay(){        animator_Window.enabled = true; //设置窗口动画控制器使能(起作用)        collider_Window.enabled = true;  //设置窗口对象可交互}//凝视窗户触发交互后执行的方法public void OpenWindow(){collider_Window.enabled = false;   //关闭窗户对象可交互功能                                                               animator_Window.SetTrigger("Open");  //播放窗户打开动画StartCoroutine ("delayPlay");       //调用协程 延时2秒播放李白吟诗动画}//延时2秒后,播放李白行走动画、诗词声音、文字IEnumerator delayPlay(){yield return new WaitForSeconds (2);   //延时n秒animator_Libai.enabled = true; //播放李白行走动画                      }
}

注意协同函数delayPlay()的设计及调用方法,协同函数返回类型是IEnumerator,通过StartCoroutine()函数调用,具体使用方法可以参考Unity Script API文档。

在GameManager脚本的监视视图中对Public变量进行赋值,把场景中的LiBai对象赋值给animator_Libai(因为LiBai对象有Animator组件)。

想一想

显示诗词文本的对象是在哪初始设定的?

6. 背景音效

演示的项目在运行时是有背景音效的,建议在场景中的GameManager对象添加AudioSource组件,并设置属性如下(设置循环播放):

7. 总结

  • 建议用一个全局的脚本来控制一些游戏的逻辑实现,如全局变量的定义,公开一些函数在其他脚本中被调用,设置初始状态的值等。

  • 对于多数呈现的视觉效果,如动画,可以用程序实现,也可以用动画编辑实现。

  • 有时间轴延续进行的呈现(如李白吟诗),尽量用动画编辑器实现,配合动画事件的设定可以实现比较复杂的动画效果

  • 对于不确定的需要交互延续的(窗户闪烁及窗户打开)只能用编程实现。

Unity3D-VR《静夜诗》5-李白吟诗相关推荐

  1. Unity3D-VR《静夜诗》1-项目准备

    Unity3D-VR<静夜诗>1-项目准备 1 要实现的功能分析 1.1墙上挂的宝剑 1.2桌子上的书 1.3开始按钮 1.4窗户 2项目准备 2.1下载素材包 2.2新建一个工程项目 2 ...

  2. Unity3D-VR《静夜诗》2-凝视宝剑和书籍时出现提示文本信息

    Unity3D-VR<静夜诗>2-凝视宝剑和书籍时出现提示文本信息 墙上宝剑对象的交互实现 1.添加预设宝剑对象 2.添加宝剑介绍文本对象 3.凝视转圈功能的实现 3.1认识GearVRS ...

  3. Unity3D-VR《静夜诗》4-窗户门动画的播放

    Unity3D-VR<静夜诗>4-窗户门动画的播放 1.播放窗户门对象的闪烁动画 1.1窗户门对象的动画控制器 1.2播放窗户闪烁动画的实现思路 1.3新建控制脚本GameManager ...

  4. Unity3D-VR《静夜诗》3-开始按钮与开始文本信息

    Unity3D-VR<静夜诗>3-开始按钮与开始文本信息 1.开始按钮及开始信息文本UI对象的设计 1.1容器对象PanelBeginUI 1.2开始信息文本TextBegin 1.3开始 ...

  5. 【虚拟现实】Unity3D+VR的实现

    [虚拟现实]Unity3D+VR的实现 针对CardBoard一类的眼镜用Unity3D开发VR内容. 1.创建VRCamera: 使用Dive插件,从DiveUnityDemo提取摄像机和有关的脚本 ...

  6. 清晨六问?静夜六思?

    清晨六问?静夜六思? --但凡有成就的人总会擅长给自己提问题 清晨六问? 1.我今天的目标是什么? 2.我的核心大目标是什么? 3.我今天重要的3件事是什么? 4.我今天准备学到哪些新东西? 5.我今 ...

  7. Unity3D+VR的实现

    针对CardBoard一类的眼镜用Unity3D开发VR内容. 1.创建VRCamera: 使用Dive插件,从DiveUnityDemo提取摄像机和有关的脚本并export出来. 2.对象选择: 视 ...

  8. 基于vlc的unity3d vr视频播放器开发,简述

    需求: 项目需要在vr设备(htc vive.pico.小π等vr设备)中显示在线视频和播放本地视频的功能. 茶话: 当前做的比较好有htc vive的ViveCinema,场景做比较漂亮.他使用的是 ...

  9. 名帖316 沈尹默 行书《澹静庐诗剩》及《景宁杂诗》

    <中国书法名帖目录> 沈尹默,原名君默,祖籍浙江湖州人,1883年生于陕西兴安府汉阴厅(今陕西安康市汉阴县城关镇民主街)早年留学日本,后任北京大学教授和校长.辅仁大学教授.1949年后历任 ...

最新文章

  1. ubuntu设置securecrt串口权限
  2. leetcode--最长回文子串--python
  3. 如何自己动手写一个搜索引擎?我是一份害羞的教程
  4. 十六个字 一辈子学不完
  5. 远程连接windows系统提示:其他用户要远程登录,需要通过远程桌面服务进行登录的权限......
  6. 学习遗忘曲线_级联相关,被遗忘的学习架构
  7. mysql PT工具
  8. c语言定时器实验程序,89C51单片机实验三 定时器实验
  9. oracle批量修改同义词,ORACLE数据库 批量创建同义词
  10. 用显卡测试软件蓝屏,简单几步解决w10更新显卡驱动后重启蓝屏的问题
  11. rabbitmq-channel断网后没有断开情况记录
  12. 如何选择适合你的兴趣爱好(十五),油画
  13. 教育机构客户管理系统功能方案详解!
  14. Solidworks如何生成爆炸图
  15. 《C语言程序设计》课程总结报告
  16. python画五角星和六角星程序_python画五角星和六角星程序
  17. 别整天 “学妹/前女友”了,花2小时整理了Numpy测试习题100道,做个测验吧!
  18. 财务人员的计算机水平怎么描述,财务人员简历怎么写?
  19. Linux内核如何输出中文字符
  20. 报废摩托车发生交通事故影响责任划分吗

热门文章

  1. 怎么从扫描的PDF文档/图片里提取文字
  2. Arqit公司将于2023年用卫星发送量子密钥;QC Ware发布量子线性代数API | 全球量子科技与工业快讯第二十六期
  3. excel怎么批量插行_excel怎么批量隔行插入一行空白行?
  4. FreeRTOS+STM32L+ESP8266+MQTT协议传输温湿度数据,控制继电器到阿里云物联网平台
  5. bootstrap treeview 无限子级菜单展示与JSON处理 完整
  6. 曾经懵懂少年,曾经年少轻狂
  7. 非线性优化中的KTT条件(知乎文章的理解)
  8. h5+css3简单实现网页端五子棋游戏1.0版
  9. 阿里云账号登录名修改方法(图文详解)
  10. apple登录服务端验证