Effect(一)—— fyRibbonTrail
来源:互联网 发布:linux提权 编辑:程序博客网 时间:2024/06/08 12:30
目录为:Assets/Scripts/Effect/fyParticleSystem/目录下
fyRibbonTrail.cs
这个类是所有丝带特效的基类,
在这里面用代码生成丝带mesh,并控制颜色.
代码如下:
using UnityEngine;using System.Collections.Generic;[System.Serializable]public class ColorKey{ public Color color; public float time; //构造函数 public ColorKey() { time = 1.0f; color = new Color (1.0f, 1.0f, 1.0f, 1.0f); } //构造函数 public ColorKey (Color color, float time) { this.color = color; this.time = time; }}//继承Monopublic class fyRibbonTrail: MonoBehaviour{ //最大Ribbon段数 public int maxElement = 10; //Ribbon每段的宽度 public float segWidth = 2.0f; //Ribbon每段的长度 public float segLength = 1.0f; //对象Transform public Transform source = null; //对象 public GameObject renderObj = null; //UV重复长度 public float mUVLength = 1.0f; //Mesh protected Mesh mMesh = null; //MeshRederer protected MeshRenderer mMeshRender = null; //纹理旋转矩阵 protected Matrix4x4 mMatrix = Matrix4x4.identity; //偏移位置 public Vector2 mOffset = new Vector2 (0, 0); //旋转位置 public float mOffRot = 0; //平移 public Vector2 mTranslate = new Vector2 (0, 0); //缩放 public Vector2 mScale = new Vector2 (1, 1); //旋转 public float mRotate = 0.0f; //设置周期时间 public float mColorPeriodTime = 0.0f; public float mColorCurTime = 0; //颜色渐变 //这颜色估计要自己指定 public ColorKey[] colorKey = new ColorKey[5]; //保存对应的shader public Shader mShader = null; //保存对应的Texture2D public Texture2D mTexture = null; //朝向类型 public enum OrientType { World_Type, BillBoard_Type } //纹理寻址类型 public enum MaterialAddressType { Common_Type, //普通纹理寻址 Sequence_Type, //序列帧寻址 Repeat_Type, //重复寻址 } //Blend类型 public enum BlendType { Replace_Type, Alpha_Type, Additive_Type, Distort_Additive, } //朝向 public OrientType mOrientType = OrientType.World_Type; //纹理寻址类型 public MaterialAddressType mMaterialType = MaterialAddressType.Common_Type; //blend type public BlendType mBlendType = BlendType.Additive_Type; public Vector3 mNormal = new Vector3 (0, 1, 0); //Ribbon Segment列表 protected Vector3[] elemPosPool; protected Vector2[] elemUVPool; protected Color[] elemColorPool; //是否创建完成 protected bool bCreated = false; void Start() { //从这里看来这个脚本要挂到Object上去 renderObj = this.gameObject; source = renderObj.transform; //运行状态,已经有Mesh数据,不需要重新创建 ReCreate (); //初始变换矩阵 InitMatrix (); } //Matrix初始化 public void InitMatrix() { //初始偏移 //单位矩阵 Matrix4x4 xlate = Matrix4x4.identity; if (mOffset.x != 0 || mOffset.y != 0) { //x xlate.m03 = mOffset.x; //y xlate.m13 = mOffset.y; } //初始旋转 Matrix4x4 rotMatrix = Matrix4x4.identity; if (mOffRot != 0) { //把度数转为弧度 float theta = mOffRot * Mathf.Deg2Rad; float cosTheta = Mathf.Cos (theta); float sinTheta = Mathf.Sin (theta); //绕Z轴旋转--------------------------- //cos -sin 0 0 //sin cos 0 0 //0 0 1 0 //0 0 0 1 //填充旋转矩阵 rotMatrix.m00 = cosTheta; rotMatrix.m01 = -sinTheta; rotMatrix.m10 = sinTheta; rotMatrix.m11 = cosTheta; //----------------------------------- // Offset center of rotation to center of texture //x translate rotMatrix.m03 = 0.5f + ((-0.5f * cosTheta) - (-0.5f * sinTheta)); //y translate rotMatrix.m13 = 0.5f + ((-0.5f * sinTheta) + (-0.5f * cosTheta)); } //旋转和平移联结起来 mMatrix = xlate * rotMatrix; //设置旋转效果 if (mMeshRender != null) { //编辑模式 if (!Application.isPlaying) { //sharedMaterial:得到原始的material,任何改变都会影响到引用这个material的其他物体 if (mMeshRender.sharedMaterial != null) { //设置旋转效果 mMeshRender.sharedMaterial.SetMatrix ("_TransMatrix", mMatrix); } } //运行模式 else { //material:得到一个副本,这个material改变,并不影响其他引用改变之前的material的物体 if (mMeshRender.material != null) { //把transfom传到shader里面去 mMeshRender.material.SetMatrix ("_TransMatrix", mMatrix); } } } } //Update is called once per frame void Update() { //更新颜色 UpdateColor (Time.deltaTime); //更新Ribbon //由子类实现 UpdateRibbon (Time.deltaTime); //更新变换矩阵 UpdateMatrix (); } //创建Ribbon virtual public void ReCreate() { //检测源物体 if (maxElement < 1) { Debug.LogError ("the ribbon max element must be more than 0!"); return; } renderObj.name = "fyRibbon"; //获取MeshFilter,准获取Mesh MeshFilter mf = gameObject.GetComponent<MeshFilter> (); //没有就创建 if (mf == null) { mf = renderObj.AddComponent<MeshFilter> (); //在面板中不可编辑 mf.hideFlags = HideFlags.NotEditable; } //获取MeshRenderer MeshRenderer mr = gameObject.GetComponent<MeshRenderer> (); //没有就创建 if (mr == null) { mr = renderObj.AddComponent<MeshRenderer> (); //关闭投影 mr.castShadows = false; //关闭接收阴影 mr.receiveShadows = false; //设置不可编辑状态 mr.hideFlags = HideFlags.NotEditable; } mMeshRender = mr; //创建mesh if (mf.sharedMesh == null) { mf.sharedMesh = new Mesh (); } mMesh = mf.sharedMesh; //组件不可见 //mf.hideFlags = HideFlags.HideInInspector; //创建RibbonMesh CreateRibbonMesh (mf.sharedMesh); //编辑状态 if (!Application.isPlaying) { //第一次创建 if (mMeshRender.sharedMaterial == null) { Texture2D defaultTex = Resources.Load ("effect/test/flare") as Texture2D; //设置默认shader if (mShader == null) { //修改为默认材质以及贴图 Shader shader = Shader.Find ("fyShader/Additive"); mShader = shader; mMeshRender.sharedMaterial = new Material (shader); } //设置默认texture if (mTexture == null) { mTexture = defaultTex; mMeshRender.sharedMaterial.SetTexture ("_MainTex", defaultTex); } } if (mShader != null) { mMeshRender.sharedMaterial = new Material (mShader); if (mTexture != null) { mMeshRender.sharedMaterial.SetTexture ("_MainTex", mTexture); } } } //运行状态 else { if (mShader != null) { mMeshRender.material = new Material (mShader); if (mTexture != null) { mMeshRender.material.SetTexture ("_MainTex", mTexture); } } } bCreated = true; } //改变贴图 public void ChangeTexture(Texture2D tex) { //保存贴图 mTexture = tex; if (mMeshRender != null && mMeshRender.sharedMaterial != null) { mMeshRender.sharedMaterial.SetTexture ("_MainTex", tex); } } //其实就是创建mesh //创建RibbonMesh void CreateRibbonMesh(Mesh mesh) { //局部坐标系 法线方向 //指向y轴正半轴 Vector3 normal = new Vector3 (0, 1, 0); Vector3 sourcePos = new Vector3 (0, 0, 0); Debug.Log ("source pos " + sourcePos.ToString ()); //初始RibbonElement Pool elemPosPool = new Vector3[(maxElement + 1) * 2]; elemUVPool = new Vector2[(maxElement + 1) * 2]; elemColorPool = new Color[(maxElement + 1) * 2]; //初始方向 //指向z轴正半轴 Vector3 dir = new Vector3 (0, 0, 1); //这里Normalize没什么意义 dir.Normalize (); mesh.Clear (); //默认初始长度,编辑时候需要处理 float length = 0.0001f; //默认maxElement = 10 //segLength = 1 //length = 10 length = maxElement * segLength; //这里很奇怪 //deltaLength = 1 float deltaLength = length / maxElement; //默认结束位置 Vector3 endPos = sourcePos + dir * length; //数据点 //i表示element段数 for (int i = 0; i < elemPosPool.Length / 2.0f; i++) { //距离起始点的距离 i * deltaLengh float vLength = i * deltaLength; //当前段的起始pos Vector3 vPos = endPos - dir * vLength; //垂直法向 //dir(0, 0, 1) //normal(0, 1, 0) //vDir = (-1, 0, 0); Vector3 vDir = Vector3.Cross (dir, normal); //当前段的中心点坐标 Vector3 p1 = vPos + vDir * segWidth / 2.0f; //上一段的中心店坐标,不过上一段存不存在无所谓,只是算距离得出的 Vector3 p2 = vPos - vDir * segWidth / 2.0f; //保存顶点数据 //存储当前段的中心点 elemPosPool [i * 2] = p1; elemColorPool [i * 2] = new Color (1, 1, 1, 1); //存储上一段的中心点 elemPosPool [i * 2 + 1] = p2; elemColorPool [i * 2 + 1] = new Color (1, 1, 1, 1); //对UV没那么了解,这里看着有点迷 //Repeat_Type if (mMaterialType == MaterialAddressType.Repeat_Type) { //默认mUVLength = 1 //vLength几乎等于当前i float uv = vLength / mUVLength; elemUVPool [i * 2] = new Vector2 (-uv, 1.0f); elemUVPool [i * 2 + 1] = new Vector2 (-uv, 0.0f); } else { //根据UV类型 //跟上面相比,少了1 elemUVPool [i * 2] = new Vector2 (1.0f - vLength / length, 1.0f); elemUVPool [i * 2 + 1] = new Vector2 (1.0f - vLength / length, 0.0f); } } //这里定义三角形index int[] index = new int[maxElement * 2 * 3]; for (int i = 0; i < maxElement; i++) { int index0 = i * 2; int index1 = i * 2 + 1; //其实就是 i * 2 + 2 int index2 = (i + 1) * 2; int index3 = (i + 1) * 2 + 1; //三角形条带 // 0 ---- 1 // / // 2 ----- 3 index [i * 6 + 0] = index0; index [i * 6 + 1] = index1; index [i * 6 + 2] = index2; index [i * 6 + 3] = index3; index [i * 6 + 4] = index2; index [i * 6 + 5] = index1; } //顶点 mesh.vertices = elemPosPool; //UV mesh.uv = elemUVPool; //Color mesh.colors = elemColorPool; //三角形index mesh.triangles = index; //重新计算法线 mesh.RecalculateNormals (); //重新计算边界体积 mesh.RecalculateBounds (); //Mesh优化,运行时会变快,不过这函数只在自己代码生成mesh时用 mesh.Optimize (); } //更新变换矩阵 public virtual void UpdateMatrix() { if (mMeshRender != null) { bool updateMatrix = false; //先缩放再平移再旋转 //缩放 if (mScale.x != 1 || mScale.y != 1) { //Offset to center of texture //缩放 mMatrix.m00 /= mScale.x; mMatrix.m11 /= mScale.y; //Skip matrix concat since first matrix update //x translate mMatrix.m03 = (-0.5f * mMatrix.m00) + 0.5f; //y translate mMatrix.m13 = (-0.5f * mMatrix.m11) + 0.5f; updateMatrix = true; } //平移 if (mTranslate.x != 0 || mTranslate.y != 0) { Matrix4x4 xlate = Matrix4x4.identity; xlate.m03 = mTranslate.x; xlate.m13 = mTranslate.y; //联结 mMatrix = xlate * mMatrix; updateMatrix = true; } //旋转 if (mRotate != 0) { Matrix4x4 rotMatrix = Matrix4x4.identity; float theta = mRotate * Mathf.Deg2Rad; float cosTheta = Mathf.Cos (theta); float sinTheta = Mathf.Sin (theta); rotMatrix.m00 = cosTheta; rotMatrix.m01 = -sinTheta; rotMatrix.m10 = sinTheta; rotMatrix.m11 = cosTheta; //Offset center of rotation to center of texture rotMatrix.m03 = 0.5f + ((-0.5f * cosTheta) - (-0.5f * sinTheta)); rotMatrix.m13 = 0.5f + ((-0.5f * sinTheta) + (-0.5f * cosTheta)); mMatrix = rotMatrix * mMatrix; updateMatrix = true; } //设置旋转效果 //只要改变了,updateMatrix这个标志就会为true if (updateMatrix) { //编辑模式 if (!Application.isPlaying) { if (mMeshRender.sharedMaterial != null) { //设置效果 mMeshRender.sharedMaterial.SetMatrix ("_TransMatrix", mMatrix); } } //运行模式 else { if (mMeshRender.material != null) { mMeshRender.material.SetMatrix ("_TransMatrix", mMatrix); } } } } } //更新颜色 public virtual void UpdateColor(float deltaTime) { if (mColorPeriodTime == 0) { return; } //计算颜色值,颜色有效 Color gColor = new Color (); mColorCurTime += deltaTime; //计算当前颜色时间 if (mColorCurTime > mColorPeriodTime) { mColorCurTime = 0; } //计算颜色 gColor = GetGradientColor (); //Debug.Log("color" + gColor.ToString()); //遍历修改数据点 //改变颜色 for (int i = 0; i < elemPosPool.Length / 2.0f; i++) { elemColorPool [i * 2] = gColor; elemColorPool [i * 2 + 1] = gColor; } mMesh.colors = elemColorPool; } //根据当前时间计算颜色 public virtual Color GetGradientColor() { Color gcolor = new Color (); //计算比例值 float factor = mColorCurTime / mColorPeriodTime; //计算color值 //colorKey数组长度默认等于5 int colorLength = colorKey.Length; for (int i = 0; i < colorLength - 1; i++) { //当前 ColorKey key1 = colorKey [i % colorLength]; //下一个 ColorKey key2 = colorKey [(i + 1) % colorLength]; //计算距离 float dist = key2.time - key1.time; //其实这里就是在按线性插值来混合颜色 if (factor >= key1.time && factor <= key2.time) { float ff = (factor - key1.time) / dist; // key1 --------------------------key2 // factor gcolor = key1.color * (1 - ff) + key2.color * ff; break; } } return gcolor; } //更新Ribbon //由子类继承 public virtual void UpdateRibbon(float deltaTime) { } //重置 public virtual void Reset() { if (mMesh == null) { return; } //重置位置 Vector3 sourcePos = source.position; //初始RibbonElement Pool elemPosPool = new Vector3[(maxElement + 1) * 2]; elemUVPool = new Vector2[(maxElement + 1) * 2]; //初始方向 Vector3 dir = new Vector3 (0, 0, 1); //仍然的无意义 dir.Normalize (); //默认初始长度 float length = maxElement * segLength; float deltaLength = length / maxElement; //默认结束位置 Vector3 endPos = sourcePos + dir * length; float totalElemLength = maxElement * segLength; //真实最大长度 float realLength = totalElemLength > length ? length : totalElemLength; //遍历修改数据点 for (int i = 0; i < elemPosPool.Length / 2.0f; i++) { float vLength; if (i * segLength > length) { vLength = length; } else { vLength = i * segLength; } Vector3 vPos = endPos - dir * vLength; //垂直法向 Vector3 vDir = Vector3.Cross (dir, mNormal); Vector3 p1 = vPos + vDir * segWidth / 2.0f; Vector3 p2 = vPos - vDir * segWidth / 2.0f; //转为局部坐标 p1 -= sourcePos; p2 -= sourcePos; //重置顶点数据 elemPosPool [i * 2] = p1; elemUVPool [i * 2] = new Vector2 (1.0f - vLength / realLength, 1.0f); elemColorPool [i * 2] = new Color (1, 1, 1, 1); elemPosPool [i * 2 + 1] = p2; elemUVPool [i * 2 + 1] = new Vector2 (1.0f - vLength / realLength, 0.0f); elemColorPool [i * 2 + 1] = new Color (1, 1, 1, 1); } mMesh.vertices = elemPosPool; mMesh.uv = elemUVPool; mMesh.RecalculateNormals (); mMesh.RecalculateBounds (); mMesh.Optimize (); //刷新矩阵数据 mMatrix = Matrix4x4.identity; InitMatrix (); mColorCurTime = 0; Debug.Log ("reset"); }}
阅读全文
0 0
- Effect(一)—— fyRibbonTrail
- Effect(二)—— fyDragRibbon
- Effect(三)—— fyLinkRibbon
- Effect(四)—— AbsorbEffect
- Effect(五)—— IEffect
- Effect(六)—— BeAttackEffect
- Effect(七)—— BuffEffect
- Effect(八)—— NormalEffect
- Effect(九)—— OnlySoundEffect
- Effect(十)—— PassitiveEffect
- Effect(十一)—— SkillAreaEffect
- Effect(十二)—— ExplodeEffect
- Effect(十三)—— flyEffect
- Effect(十四)—— EffectManager
- Effect(十五)—— EffectScript
- Effect(十六)—— SetActiveScript
- Effect(十七)—— SM_MoveThis
- Effect(十八)—— SM_RotateThis
- form表单新增的三个属性,form属性,multiple属性,pattern属性。
- mysql 主从复制和主主复制配置
- jenkins+Gitlab+maven+tomcat实现自动集成、打包、部署
- 10.18 文件名排序 2433
- 一个感染性木马病毒分析(三)--文件的修复
- Effect(一)—— fyRibbonTrail
- Dll&Lib的生成以及调用
- 动态链接执行过程
- SVN的标准目录结构:trunk、branches、tags
- React Native如何与夜神模拟器连接
- AIDL回调报错: enforceInterface() expected 'com.unistron.ReadIDCardAIDL' but read 'com.xx.CallBackIdC
- 详细的json用法
- 初试 minikube 本地部署运行 kubernetes 实例
- springMVC之与jsp页面交互1