// @Brief : OnDrawGizmos void OnDrawGizmos() { if (m_pLive2dModel != null) { float fModelWidth = m_pLive2dModel.getCanvasWidth(); float fModelHeight = m_pLive2dModel.getCanvasHeight(); Matrix4x4 mOrthoProjection = Matrix4x4.Ortho(0, fModelWidth, fModelWidth, 0, -50.0f, 50.0f); Matrix4x4 mWorldPosition = transform.localToWorldMatrix; mWorldPosition[13] += (fModelHeight / fModelWidth) * mWorldPosition[5]; Gizmos.color = Color.red; float fWeight = (fModelWidth / fModelWidth) * transform.lossyScale.y; float fHeight = (fModelHeight / fModelWidth) * transform.lossyScale.y; Vector3[] pVertices = new Vector3[4]; pVertices[0] = new Vector3(mWorldPosition[12] + fWeight, mWorldPosition[13] + fHeight, mWorldPosition[14]); pVertices[1] = new Vector3(mWorldPosition[12] - fWeight, mWorldPosition[13] + fHeight, mWorldPosition[14]); pVertices[2] = new Vector3(mWorldPosition[12] - fWeight, mWorldPosition[13] - fHeight, mWorldPosition[14]); pVertices[3] = new Vector3(mWorldPosition[12] + fWeight, mWorldPosition[13] - fHeight, mWorldPosition[14]); Gizmos.DrawLine(pVertices[0], pVertices[1]); Gizmos.DrawLine(pVertices[1], pVertices[2]); Gizmos.DrawLine(pVertices[2], pVertices[3]); Gizmos.DrawLine(pVertices[3], pVertices[0]); } }
void OnPostRender() { Live2DModelUnity live2DModel = (Live2DModelUnity)_model.getLive2DModel(); var w = live2DModel.getCanvasWidth(); var h = live2DModel.getCanvasHeight(); L2DModelMatrix matrix = new L2DModelMatrix(w, h); matrix.setWidth(_w); matrix.setCenterPosition(0.5f, 0.5f); matrix.setX(_x); matrix.setY(_y); Matrix4x4 m1 = Matrix4x4.identity; float[] m2 = matrix.getArray(); for (int i = 0; i < 16; i++) { m1[i] = m2[i]; } live2DModel.setMatrix(m1); //_model.Update();_model.Draw 中有调用 UpdateMouth(); live2DModel.update(); _model.Draw(Live2dViewType); }
private void setModel(Live2DModelUnity LModel) { if (live2DModelUnity != null) { if (isDontRelease) { live2DModelUnity = null; } else { live2DModelUnity.releaseModel(); } } if (LModel != null) { live2DModelUnity = LModel; } else { live2DModelUnity = Live2DModelUnity.loadModel(mocFile.bytes); } for (int i = 0; i < textureFiles.Length; i++) { live2DModelUnity.setTexture(i, textureFiles[i]); } modelW = live2DModelUnity.getCanvasWidth(); modelH = live2DModelUnity.getCanvasHeight(); live2DCanvasPos = Matrix4x4.Ortho(0f, modelW, modelH, 0f, -50f, 50f); aspect = modelH / modelW; motion = Live2DMotion.loadMotion(motionFile.bytes); motion.setLoop(loop: true); motionMgr.startMotion(motion); }
public Live2DModelUnity CreateLive2DModelUnity(int MstID) { Texture2D[] array = new Texture2D[4]; int resourceMstId = Utils.GetResourceMstId(MstID); string path = "Live2D/" + resourceMstId + "/" + resourceMstId + ".moc"; TextAsset textAsset = Resources.Load(path) as TextAsset; Live2DModelUnity live2DModelUnity = Live2DModelUnity.loadModel(textAsset.bytes); for (int i = 0; i < 4; i++) { array[i] = Resources.Load <Texture2D>("Live2D/" + MstID + "/texture_0" + i); } for (int j = 0; j < textureFiles.Length; j++) { live2DModelUnity.setTexture(j, array[j]); } modelW = live2DModelUnity.getCanvasWidth(); modelH = live2DModelUnity.getCanvasHeight(); live2DCanvasPos = Matrix4x4.Ortho(0f, modelW, modelH, 0f, -50f, 50f); aspect = modelH / modelW; return(live2DModelUnity); }
// Start is called before the first frame update void Start() { Live2D.init();//Live2D的初始化 //Live2D.dispose();//Live2D的释放 //读取模型 //moc读取 //Application.dataPath 就是Assets文件夹下目录 //Live2DModelUnity.loadModel(Application.dataPath+ "/Resources/Epsilon/runtime/Epsilon.moc"); //json读取 和之前替换模型一样操作 moc复制出来一个后缀加.bytes //modleFile = Resources.Load<TextAsset>("Epsilon/runtime/Epsilon.moc"); live2DModel = Live2DModelUnity.loadModel(modleFile.bytes); //与贴图建立关联 //加载所有贴图 //tex = Resources.LoadAll<Texture2D>("Epsilon/runtime/Epsilon.1024"); for (int i = 0; i < tex.Length; i++) { live2DModel.setTexture(i, tex[i]); } //制定显示位置和尺寸 参数分别为左右下上 近视口距离(离相机近的距离)50 远视口距离(离相机远的距离)-50 (官方建议参数) //正交矩阵与相关Api设置显示图像 float modelWidth = live2DModel.getCanvasWidth(); float modelHeight = live2DModel.getCanvasHeight(); live2DCanvasPos = Matrix4x4.Ortho(0, modelWidth, modelWidth, 0, 50, -50); //播放动作 //实例化动作对象 //live2DMotionIdle = Live2DMotion.loadMotion(Application.dataPath+""); //TextAsset mtnFile = Resources.Load<TextAsset>(); //live2DMotionIdle = Live2DMotion.loadMotion(mtnFile.bytes); motions = new Live2DMotion[motionFiles.Length]; for (int i = 0; i < motions.Length; i++) { motions[i] = Live2DMotion.loadMotion(motionFiles[i].bytes); } //设置某一个动画的一些属性 //重复播放是否淡入 不带很僵硬 motions[0].setLoopFadeIn(false); //设置淡入淡出时间 参数毫秒 motions[0].setFadeOut(1000); motions[0].setFadeIn(1000); ////动画是否循环 //motions[0].setLoop(true); //motions[5].setLoop(true); ////第二个参数播放完是否删除 //motionQueueManager.startMotion(motions[0]); //motionQueueManagerA.startMotion(motions[5]); #region 左右两侧头发的摇摆 //头发摇摆左 //套用物理运算 长度影响摇摆周期(短慢长快) //空气阻力0-1也影响速度 默认0.5 //质量 physicsHairSideLeft.setup(0.2f, 0.5f, 0.14f); //设置输入参数 //设置哪一个部分变动时进行哪一种物理运算 PhysicsHair.Src srcXLeft = PhysicsHair.Src.SRC_TO_X;//横向摇摆 //第三个参数 头发影响度 变动时头发受到0.005影响速度 json表推荐 第四个权重 physicsHairSideLeft.addSrcParam(srcXLeft, "PARAM_ANGLE_X", 0.005f, 1); //设置输出表现 PhysicsHair.Target targetLeft = PhysicsHair.Target.TARGET_FROM_ANGLE;//根据角度表现`angleV会很快到极限值然后停留一段 physicsHairSideLeft.addTargetParam(targetLeft, "PARAM_HAIR_SIDE_L", 0.005f, 1); //头发摇摆右 //套用物理运算 长度影响摇摆周期(短慢长快) //空气阻力0-1也影响速度 默认0.5 //质量 physicsHairSideRight.setup(0.2f, 0.5f, 0.14f); //设置输入参数 //设置哪一个部分变动时进行哪一种物理运算 PhysicsHair.Src srcXRight = PhysicsHair.Src.SRC_TO_X;//横向摇摆 //第三个参数 头发影响度 变动时头发受到0.005影响速度 json表推荐 第四个权重 physicsHairSideRight.addSrcParam(srcXRight, "PARAM_ANGLE_X", 0.005f, 1); //设置输出表现 PhysicsHair.Target targetRight = PhysicsHair.Target.TARGET_FROM_ANGLE;//根据角度表现` physicsHairSideRight.addTargetParam(targetRight, "PARAM_HAIR_SIDE_R", 0.005f, 1); #endregion #region 前后头发摇摆 //左边 physicsHairBackLeft.setup(0.24f, 0.5f, 0.18f); PhysicsHair.Src srcXBackLeft = PhysicsHair.Src.SRC_TO_X; PhysicsHair.Src srcZBackLeft = PhysicsHair.Src.SRC_TO_G_ANGLE; physicsHairBackLeft.addSrcParam(srcXBackLeft, "PARAM_ANGLE_X", 0.005f, 1); physicsHairBackLeft.addSrcParam(srcZBackLeft, "PARAM_ANGLE_Z", 0.8f, 1); PhysicsHair.Target targetBackLeft = PhysicsHair.Target.TARGET_FROM_ANGLE; physicsHairBackLeft.addTargetParam(targetBackLeft, "PARAM_HAIR_BACK_L", 0.005f, 1); //右边 physicsHairBackRight.setup(0.24f, 0.5f, 0.18f); PhysicsHair.Src srcXBackRight = PhysicsHair.Src.SRC_TO_X; PhysicsHair.Src srcZBackRight = PhysicsHair.Src.SRC_TO_G_ANGLE; physicsHairBackRight.addSrcParam(srcXBackRight, "PARAM_ANGLE_X", 0.005f, 1); physicsHairBackRight.addSrcParam(srcZBackRight, "PARAM_ANGLE_Z", 0.8f, 1); PhysicsHair.Target targetBackRight = PhysicsHair.Target.TARGET_FROM_ANGLE; physicsHairBackRight.addTargetParam(targetBackRight, "PARAM_HAIR_BACK_R", 0.005f, 1); #endregion ////加载表情数据 expressions = new L2DExpressionMotion[expressionFiles.Length]; for (int i = 0; i < expressions.Length; i++) { expressions[i] = L2DExpressionMotion.loadJson(expressionFiles[i].bytes); } }