如何在Unity中制作VR全景动画

您所在的位置:网站首页 unity制作360全景 如何在Unity中制作VR全景动画

如何在Unity中制作VR全景动画

2023-12-30 09:15| 来源: 网络整理| 查看: 265

超简单的引言

本教程介绍的是如何一个人制作出像模像样的VR全景动画。笔者没有去详细的研究过动画的制作方式,或者说根本就不了解啊,所以本文章只是门外汉的一次自嗨,请勿认真,作为一种参考即可。

一 总览

我们都知道,任何项目的开始都需要有策划的参与,没有完整的项目书,在项目的制作过程中你是会很痛苦的,不管是针对团队或者是个人开发,计划书都是必须的存在。 笔者认为,一个简单的动画项目,至少需要有角色、场景和故事,才能够进行下去,所以这三者的获取对于个人开发者而言就十分重要的。 故事即剧本,对于想单人开发VR动画的人而言,脑海里肯定是已经有了一定的想法了,那么,把他写下来,你就成功的获取了三要素中的故事了。 场景即故事发生的地点,如果你的动画不是那么要求的话,一个Plane就可以作为场景了,稍微讲究一点就可以自己使用Terrain慢慢刷吧,那么场景也就有了。 角色是比较难搞到的一个要素,想要一个机子逾期的模型和动画可没那么的简单,外包是不可能外包的,一辈子都不可能外包,原因自然是没钱啊,那么怎么获取符合自己故事的人物模型呢,请看下文。

二 角色模型

提到角色,制作VR全景动画,需要的是3D的模型,那么如何快速地获取自己想要的模型呢,答案当然是自己制作,这里笔者推荐个人开发这使用体素模型,何为体素模型,就是身体由一个个的方块、像素快组成的模型,好处自然是制作简单,快速成型,制作这种模型,几乎不要花费额外的学习成本,上手就来,下面说一下笔者自己的人物模型制作过程。 首先,你需要去下载一个软件MagicalVoxel,打开软件是这个样子的。 MagicalVoxel 这款软件使用特别的交单,几乎就是秒上手,网上也有很多的使用教程,这里就不重复造轮子了,给你们看看笔者花了5分钟制作出来的一个模型,推荐使用T Pose,有没有感觉很震撼,哈哈,现在是丑了点,等下动起来会好看一点,制作完成后记得将模型导出成obj格式的。 man

三 角色动画

有了角色模型,就需要让模型动起来,给模型添加动画,这里笔者使用的是一个在线的网站mixamo,可以在线为人形的模型添加骨骼和动画,使用前需要先注册帐号。 截至到2017年5月5日,使用这个网站需要注意两点,这两点开始没注意到,浪费了笔者很多的时间:(1)注册帐号,选择的地区不能选择中国,否则你将没有权限下载绑定好骨骼的模型和动画。(2)浏览器,使用的浏览器需要支持WEBGL功能,笔者之前使用的是360安全浏览器,不支持这个功能,导致无法上传模型,后面切换到360极速浏览器,通过简单的设置后就可以了,如果你使用的是其他的浏览器,需要支持这个功能,下面的图片是360极速浏览器的简单设置。 开启webgl 一切都搞定后,点击上传,具体流程直接看图 上传 选中上传的文件 选中上传的文件 绑定骨骼 绑定骨骼 点击Next生成完之后就可以在自己的库中见到你的模型,而且是绑定骨骼的,模型已经动起来了。 下一步是选择动画,这个网站上有很多的动画供你选择,而且全是免费的应该 选中一个动画,点击添加到包里即可 进入到你的库中,就可以看到你的模型和选择的动画文件了 这里写图片描述 接下来就是选中模型和动画,点击QUEUE DOWNLOAD,如果你的帐号选得是中国,这边的按钮是不可用的,模型和动画是分开下载的,模型下载选中FBX格式,可以直接导入Unity使用。

四 开发制作第一步

嗯,素材什么的都有了,接下来就是在Unity中的开发了,笔者使用的是Unity3D 5.6版本,新建一个项目,将模型导入到项目中,再将模型拉入场景中,你会发现模型是没有贴图的,下载的时候也是没有的。 别着急,别忘了之前从MagicaVoxel导出的时候是有一张的贴图的,我们将这张贴图一起拖入项目中,再将贴图的类型改成Sprite类型,为模型的材质球附上这张贴图即可。(下面的效果是我之前制作的模型) 这里写图片描述 这里写图片描述 接下来新建一个动画控制器,为模型指定上,再将需要的动画拉入控制器,点击运行,就会发现模型已经动起来了。 这里写图片描述 以上是很简单的方式,实际上,在动画的流程中,角色的动作和语音是很复杂的一个过程,需要使用脚本去精准的控制整个流程的进行。

五 开发制作第二步

第二步也是最重要的一步,即渲染VR全景视频,即下面这样的效果。 这里写图片描述 如果是自己写算法去渲染估计可以独立成一本书,我们自然要偷懒咯,这里推荐一款商店里的插件,如果是商业开发最好去支持一下作者,最新已经更新到了2.2.1。 这里写图片描述 下面介绍一下这个插件的简单使用,这款插件有几种渲染模式,笔者这边只介绍如何渲染出正常VR全景视频的方法,在使用前需要注意一点,这个插件必须放在Assets的第一层目录,这涉及到一些插件自带工具的路径问题。 这个插件的核心就是一个预制体,VRPanoramaCamera 这里写图片描述 想要渲染出正常的VR全景视频,需要注意VRCapture这个脚本的一些属性 (1)Capture Type:渲染的类型,我们需要选择最后一个EquidistantMono (2)视频的分辨率设置 这里写图片描述 (3)Fps设置 这里写图片描述 (4)设置渲染的时长,这边和你设置的fps有关,如果是25fps那,这边就是25帧标识渲染1S 这里写图片描述 (5)这个是选择渲染视频还是音频,需要分开渲染,当然你也可以为你的视频进行后期配音也是可以的。 这里写图片描述 设置好这个脚本的参数,点击运行就可以开始渲染你的VR视频了,最后会渲染出一大堆的图片,一帧一张,存放在项目的跟目录位置,最下面的就是你的VR视频了。 这里写图片描述

总结语

这个教程其实就是多个工具插件的使用合集,虽说能够快速制作出一个VR全景视频,当真正想制作出优秀的作品,还是需要做很多的工作,如模型的细节、动画的类型、脚本控制流程的运行以及配音什么的,都是很重要的。这个教程只是抛砖引玉,希望有更多有兴趣的人可以加入到VR开发的行业中,为虚拟现实提供更多内容,同时也促进这个行业的良性发展。 咳咳!以上都是废话,好了,教程到此为止。还有什么疑问的地方可以留言,我有看到就会回复,谢谢。 最后放上一个我花了一天时间(建模,录音,选材,脚本什么地)做的一个demo视频的地址,因为选择的是最低画质(我电脑差点炸了,渣电脑渲染不起啊),而且最后合并视频和音频的时候没处理好,导致不同步,就将就看着吧。 http://pan.baidu.com/s/1eR8up3c 还有我控制流程的一个脚本,写的有点渣,纯粹为了实现而实现的,当做参考吧,制作动画的话感觉应该以时间线为事件的基准,嗯,我是这么认为的。

using System.Collections; using System.Collections.Generic; using UnityEngine; public class DanceManController : MonoBehaviour { public AudioSource BgmSource; public Transform DanceManAim; public float MoveSpeed = 0.5f; public float RotateSpeed = 0.5f; public float WaitTime = 5.0f; //Voice public AudioClip Voice01; public AudioClip Voice02; public AudioClip Voice03; public AudioClip Voice04; public AudioClip Bgm01; public AudioClip Bgm02; public AudioClip Bgm03; private Animator _animator; private GameObject _player; private Transform _danceManTransform; private AudioSource _audioSource; private bool _isWalk = false; private bool _isRotate = false; private float _bmgVolume = 0.15f; void Awake() { _animator = GetComponent(); _audioSource = GetComponent(); _player = GameObject.FindGameObjectWithTag("Player") as GameObject; _danceManTransform = transform; } void Start () { StartCoroutine("MoveMan"); PlayAudio(Voice01); PlayBGM(Bgm01, _bmgVolume); } void Update () { if (_isWalk) { if (Vector3.Distance(_danceManTransform.localPosition, DanceManAim.localPosition) > 0.05f) { _animator.SetBool("Walk", true); _danceManTransform.localPosition += (DanceManAim.localPosition - _danceManTransform.localPosition).normalized * MoveSpeed * Time.deltaTime; } else { OnManIdle(); } } if (_isRotate) { if (_danceManTransform.localEulerAngles.y < 180.0f) { _danceManTransform.Rotate(new Vector3(0, RotateSpeed, 0)); } else { _isRotate = false; PlayAudio(Voice02); StartCoroutine("Dance01"); } } } IEnumerator MoveMan() { yield return new WaitForSecondsRealtime(WaitTime); _isWalk = true; yield return 0; } IEnumerator Dance01() { yield return new WaitForSecondsRealtime(16.0f); PlayBGM(Bgm02, _bmgVolume); _animator.SetBool("Dance01", true); yield return 0; } IEnumerator Dance02() { yield return new WaitForSecondsRealtime(15.0f); PlayBGM(Bgm03, _bmgVolume); _animator.SetBool("Dance02", true); yield return 0; } IEnumerator EndVoice() { Debug.Log("结束语"); yield return new WaitForSecondsRealtime(33.0f); BgmSource.volume = _bmgVolume; _audioSource.Stop(); yield return 0; } public void OnManIdle() { _isWalk = false; _animator.SetBool("Walk", false); _isRotate = true; } public void PlayAudio(AudioClip clip) { _audioSource.volume = 1.0f; _audioSource.clip = clip; _audioSource.Play(); } public void PlayBGM(AudioClip clip,float volume) { BgmSource.volume = volume; BgmSource.clip = clip; BgmSource.Play(); } private int _dance01Size = 0;//Dance01的播放次数,三遍停止 private bool _endVoice = false;//是否播放结束音 public void OnDanceOver(int index) { if (index == 1) { if (_dance01Size == 2) { BgmSource.Stop(); _animator.SetBool("Dance01", false); PlayAudio(Voice03); StartCoroutine("Dance02"); } else { _dance01Size++; } } if (index == 2 && !_endVoice) { //_endVoice = true; //_bgmSource.volume = 0.05f; //PlayAudio(Voice04); //StartCoroutine("EndVoice"); } } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3