Unity中Skinned Mesh Renderer Blend Shapes小试
Posted u010019717
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity中Skinned Mesh Renderer Blend Shapes小试相关的知识,希望对你有一定的参考价值。
第一个应用:如何使用网格渲染器Blend Shapes Unity制作木棍剥皮
1、 Intro
2、Modeling (Blender)
打开Blender 软件
调整视角
然后快捷键: Shift+A
添加Mesh : Cylinder
顶点数改为:
Rotate Around X Axis : 快捷键 R+X+90
Scale :Y Axis : 快捷键 S+Y
进入Edit Mode : 快捷键 Tab
Add more Loops : 快捷键 Ctrl + R 然后改变鼠标的滚轮: 就会看到横向线的变化。
下图中横向线都是新增的 。
->
Right click to undo movements
Exit Edit Mode : 快捷键 Tab
增加Shape Keys
进入Edit Mode然后 ,Alt + 横线选中, 然后快捷键 S + 0 , 一个关键帧就完成了。
重复n次把所有横线都增加key
然后点击File 导出 FBX 文件 。
然后导入Unity工程中。
3、 Setup scene
创建空对象挂点, Wood Holder, Wood , 然后拖拽模型挂上
然后调整模型的旋转,也可以看到在Blender中添加的 Shape keys 在Unity中有数据, 可以在Inspector中改变key的值查看scene中模型的变化。
替换成更像木头的材质: wood
场景中需要放另外的物体: 刻刀 Knife , 有碰撞体跟刚体(限制运动方向等参数设置),与控制脚本Knife.cs
4、Wood Rotation (DoTween)
添加第一个脚本 Wood.cs 让木头先旋转
using UnityEngine ; using DG.Tweening ; public class Wood : MonoBehaviour { [SerializeField] private SkinnedMeshRenderer skinnedMeshRenderer ; [SerializeField] private Transform woodTransform ; [SerializeField] private Vector3 rotationVector ; [SerializeField] private float rotationDuration ; private void Start () { woodTransform .DOLocalRotate (rotationVector, rotationDuration, RotateMode.FastBeyond360) .SetLoops (-1, LoopType.Restart) .SetEase (Ease.Linear) ; } public void Hit (int keyIndex, float damage) { float colliderHeight = 2.39705f ; //Skinned mesh renderer key's value is clamped between 0 & 100 float newWeight = skinnedMeshRenderer.GetBlendShapeWeight (keyIndex) + damage * (100f / colliderHeight) ; skinnedMeshRenderer.SetBlendShapeWeight (keyIndex, newWeight) ; } }
运行时就会旋转了。
5、 Knife Movement
添加脚本 Knife.cs 移动刀片
using UnityEngine ; public class Knife : MonoBehaviour { [SerializeField] private float movementSpeed ; [SerializeField] private float hitDamage ; [SerializeField] private Wood wood ; [SerializeField] private ParticleSystem woodFx ; private ParticleSystem.EmissionModule woodFxEmission ; private Rigidbody knifeRb ; private Vector3 movementVector ; private bool isMoving = false ; private void Start () { knifeRb = GetComponent<Rigidbody> () ; woodFxEmission = woodFx.emission ; } private void Update () { isMoving = Input.GetMouseButton (0) ; if (isMoving) movementVector = new Vector3 (Input.GetAxis ("Mouse X"), Input.GetAxis ("Mouse Y"), 0f) * movementSpeed * Time.deltaTime ; } private void FixedUpdate () { if (isMoving) knifeRb.position += movementVector ; } private void OnCollisionExit (Collision collision) { woodFxEmission.enabled = false ; } private void OnCollisionStay (Collision collision) { Coll coll = collision.collider.GetComponent <Coll> () ; if (coll != null) { // hit Collider: woodFxEmission.enabled = true ; woodFx.transform.position = collision.contacts [ 0 ].point ; coll.HitCollider (hitDamage) ; wood.Hit (coll.index, hitDamage) ; } } }
6、Colliders
添加碰撞体:
先调整参数,这样可以确定每个key的位置
为每个碰撞体添加脚本 Coll.cs
using UnityEngine ; public class Coll : MonoBehaviour { public int index ; BoxCollider boxCollider ; private void Awake () { boxCollider = GetComponent<BoxCollider> () ; index = transform.GetSiblingIndex () ; } public void HitCollider (float damage) { // Resize the collider's height(Y) depends on "damage" if (boxCollider.size.y - damage > 0.0f) boxCollider.size = new Vector3 (boxCollider.size.x, boxCollider.size.y - damage, boxCollider.size.z) ; else Destroy (this) ; // Remove Coll Component from this gameobject } }
7、Wood Deformation (Skinned Mesh Renderer)
Wood.cs 中 更改指定key的权重来达到木头的削皮
public void Hit (int keyIndex, float damage) { float colliderHeight = 2.39705f ; // 编辑器时碰撞体的size的y值 //Skinned mesh renderer key's value is clamped between 0 & 100 float newWeight = skinnedMeshRenderer.GetBlendShapeWeight (keyIndex) + damage * (100f / colliderHeight) ; skinnedMeshRenderer.SetBlendShapeWeight (keyIndex, newWeight) ; }
Knife.cs 中 削刀跟key碰撞体 碰撞就改变指定的key的权重
private void OnCollisionExit (Collision collision) { woodFxEmission.enabled = false ; } private void OnCollisionStay (Collision collision) { Coll coll = collision.collider.GetComponent <Coll> () ; if (coll != null) { // hit Collider: woodFxEmission.enabled = true ; woodFx.transform.position = collision.contacts [ 0 ].point ; coll.HitCollider (hitDamage) ; wood.Hit (coll.index, hitDamage) ; } }
8、Wood Fx (Particle System)
这个就没什么可说的,特效一直都在,只是在碰撞的时候开启particle system,同时改变特效的位置。脱离碰撞就关闭。
第二个应用:树的出现动画
添加一个cube:
然后添加水平跟垂直的边缘循环。
然后增加 Shape Keys : Base , key 1 把Cube 调整成树的形状。
编辑完 可以通过改变 Value 条来看效果,也有Misc参数可以调整。
就是从cube key成这样:
然后退出编辑模式, 为Cube 添加简单的纹理
然后将文件从Blender中导出 .fbx文件, 导入到Unity中
托转到场景中可是改变值看看效果:
添加如下控制脚本 ,作为数目的出生动画 :
以上是关于Unity中Skinned Mesh Renderer Blend Shapes小试的主要内容,如果未能解决你的问题,请参考以下文章
Unity中Skinned Mesh Renderer Blend Shapes小试
Unity中Skinned Mesh Renderer Blend Shapes小试
如何创建自己的 Raycast 组件,它不需要碰撞器,但在 C# Unity3D 中支持 Skinned Mesh Renderer?
Unity3d VFX 采用skinned mesh sampling(蒙皮采样)发射粒子效果时fbx模型是否优化(Optimized)带来的问题记录