與二次元老婆邂逅的遊戲的建立過程(三)
阿新 • • 發佈:2020-12-11
技術標籤:遊戲
上期我們讓老婆進行了一些簡單的動作
但是因為沒有頭髮擺動顯得不自然
所以今天我們來給老婆加上頭髮的自然搖擺
廢話少說我們開始吧
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using live2d;
using live2d.framework;
public class live2dModel : MonoBehaviour
{
public TextAsset modelFile;
private Live2DModelUnity live2DModel;
private Matrix4x4 live2DCanvasPos;
public Texture2D[] textures;
private L2DMotionManager L2DMotionManager;
public TextAsset[] motionFiles;
private Live2DMotion[] motions;
private MotionQueueManager motionQueueManager;
public int motionIndex;
//自動眨眼
private EyeBlinkMotion eyeBlinkMotion;
//滑鼠拖拽引起動作變化
private L2DTargetPoint drag;
//套物理運算的設定
private PhysicsHair physicsHairSideLeft;
private PhysicsHair physicsHairSideRight;
private PhysicsHair physicsHairBackLeft;
private PhysicsHair physicsHairBackRight;
// Use this for initialization
void Start()
{
//初始化
Live2D.init();
//讀取模型
//TextAsset modelFile = Resources.Load<TextAsset>("Epsilon/runtime/Epsilon.moc");
live2DModel = Live2DModelUnity.loadModel(modelFile.bytes);
//與貼圖建立聯絡
//Live2DModelUnity.loadModel(modelFile.bytes);
for (int i = 0; i < textures.Length; i++)
{
live2DModel.setTexture(i, textures[i]);
}
//指定顯示位置與尺寸(實用正交矩陣與相關API顯示影象,再由遊戲物體的位置和攝像機的size調整到合適的位置)
float modelWidth = live2DModel.getCanvasWidth();
live2DCanvasPos = Matrix4x4.Ortho(0, modelWidth, modelWidth, 0, -50, 50);
//播放動作
//例項化動作物件
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);
//motionQueueManager = new MotionQueueManager();
//motionQueueManager.startMotion(motions[0]);
#region 左右前邊
//左發
physicsHairSideLeft = new PhysicsHair();
//套用物理運算(長度單位公尺影響搖擺的週期,頭髮的阻力,頭髮的重量)
physicsHairSideLeft.setup(0.2f, 0.5f, 0.14f);
//設定輸入引數
//設定哪一個部分變動時進行的那一種物理運算
PhysicsHair.Src srcX = PhysicsHair.Src.SRC_TO_X;//橫向搖擺
physicsHairSideLeft.addSrcParam(srcX, "PARAM_ANGLE_X", 0.005f, 1);
//設定輸出表現
PhysicsHair.Target target = PhysicsHair.Target.TARGET_FROM_ANGLE;
physicsHairSideLeft.addTargetParam(target, "PARAM_HAIR_SIDE_L", 0.005f, 1);
//右發
physicsHairSideRight = new PhysicsHair();
//套用物理運算(長度單位公尺影響搖擺的週期,頭髮的阻力,頭髮的重量)
physicsHairSideRight.setup(0.2f, 0.5f, 0.14f);
//設定輸入引數
//設定哪一個部分變動時進行的那一種物理運算
PhysicsHair.Src srcXRight = PhysicsHair.Src.SRC_TO_X;//橫向搖擺
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
//動作的優先順序使用
L2DMotionManager = new L2DMotionManager();
//眨眼
eyeBlinkMotion = new EyeBlinkMotion();
//滑鼠拖拽
drag = new L2DTargetPoint();
}
// Update is called once per frame
void Update()
{
//模型位置(矩陣形式的區域性座標轉換成世界座標)
live2DModel.setMatrix(transform.localToWorldMatrix * live2DCanvasPos);
//if (Input.GetKeyDown(KeyCode.M))
//{
// motionIndex++;
// if (motionIndex>=motions.Length)
// {
// motionIndex = 0;
// }
// motionQueueManager.startMotion(motions[motionIndex]);
//}
//motionQueueManager.updateParam(live2DModel);
//模型跟隨滑鼠轉向與看向
Vector3 pos = Input.mousePosition;
if (Input.GetMouseButton(0))
{
drag.Set(pos.x / Screen.width * 2 - 1, pos.y / Screen.height * 2 - 1);
}
else if (Input.GetMouseButtonUp(0))
{
drag.Set(0, 0);
}
//引數及時更新,考慮加速度等自然因素,計算座標,進行逐幀更新
drag.update();
//模型轉向
if (drag.getX() != 0)
{
live2DModel.setParamFloat("PARAM_ANGLE_X", 30 * drag.getX());
live2DModel.setParamFloat("PARAM_ANGLE_Y", 30 * drag.getY());
live2DModel.setParamFloat("PARAM_BODY_ANGLE_X", 10 * drag.getX());
live2DModel.setParamFloat("PARAM_EYE_BALL_X", drag.getX());
live2DModel.setParamFloat("PARAM_EYE_BALL_Y", drag.getY());
}
//眨眼
eyeBlinkMotion.setParam(live2DModel);
long time = UtSystem.getUserTimeMSec();//執行時間
//更新模型定點等
live2DModel.update();
}
private void OnRenderObject()
{
live2DModel.draw();
}
private void StartMotion(int motionIndex, int priority)
{
if (L2DMotionManager.getCurrentPriority() >= priority)
{
return;
}
L2DMotionManager.startMotion(motions[motionIndex]);
}
}
這樣我們是實現了前鬢的抖動
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using live2d;
using live2d.framework;
public class live2dModel : MonoBehaviour
{
public TextAsset modelFile;
private Live2DModelUnity live2DModel;
private Matrix4x4 live2DCanvasPos;
public Texture2D[] textures;
private L2DMotionManager L2DMotionManager;
public TextAsset[] motionFiles;
private Live2DMotion[] motions;
private MotionQueueManager motionQueueManager;
public int motionIndex;
//自動眨眼
private EyeBlinkMotion eyeBlinkMotion;
//滑鼠拖拽引起動作變化
private L2DTargetPoint drag;
//套物理運算的設定
private PhysicsHair physicsHairSideLeft;
private PhysicsHair physicsHairSideRight;
private PhysicsHair physicsHairBackLeft;
private PhysicsHair physicsHairBackRight;
// Use this for initialization
void Start()
{
//初始化
Live2D.init();
//讀取模型
//TextAsset modelFile = Resources.Load<TextAsset>("Epsilon/runtime/Epsilon.moc");
live2DModel = Live2DModelUnity.loadModel(modelFile.bytes);
//與貼圖建立聯絡
//Live2DModelUnity.loadModel(modelFile.bytes);
for (int i = 0; i < textures.Length; i++)
{
live2DModel.setTexture(i, textures[i]);
}
//指定顯示位置與尺寸(實用正交矩陣與相關API顯示影象,再由遊戲物體的位置和攝像機的size調整到合適的位置)
float modelWidth = live2DModel.getCanvasWidth();
live2DCanvasPos = Matrix4x4.Ortho(0, modelWidth, modelWidth, 0, -50, 50);
//播放動作
//例項化動作物件
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);
//motionQueueManager = new MotionQueueManager();
//motionQueueManager.startMotion(motions[0]);
#region 左右前邊
//左發
physicsHairSideLeft = new PhysicsHair();
//套用物理運算(長度單位公尺影響搖擺的週期,頭髮的阻力,頭髮的重量)
physicsHairSideLeft.setup(0.2f, 0.5f, 0.14f);
//設定輸入引數
//設定哪一個部分變動時進行的那一種物理運算
PhysicsHair.Src srcX = PhysicsHair.Src.SRC_TO_X;//橫向搖擺
physicsHairSideLeft.addSrcParam(srcX, "PARAM_ANGLE_X", 0.005f, 1);
//設定輸出表現
PhysicsHair.Target target = PhysicsHair.Target.TARGET_FROM_ANGLE;
physicsHairSideLeft.addTargetParam(target, "PARAM_HAIR_SIDE_L", 0.005f, 1);
//右發
physicsHairSideRight = new PhysicsHair();
//套用物理運算(長度單位公尺影響搖擺的週期,頭髮的阻力,頭髮的重量)
physicsHairSideRight.setup(0.2f, 0.5f, 0.14f);
//設定輸入引數
//設定哪一個部分變動時進行的那一種物理運算
PhysicsHair.Src srcXRight = PhysicsHair.Src.SRC_TO_X;//橫向搖擺
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 = new PhysicsHair();
physicsHairBackLeft.setup(0.24f, 0.5f, 0.18f);
PhysicsHair.Src srcO = PhysicsHair.Src.SRC_TO_X;
PhysicsHair.Src srcZ = PhysicsHair.Src.SRC_TO_G_ANGLE;
physicsHairBackLeft.addSrcParam(srcO, "PARAM_ANGLE_X", 0.005F, 1);
physicsHairBackLeft.addSrcParam(srcZ, "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 = new PhysicsHair();
physicsHairBackRight.setup(0.24f, 0.5f, 0.18f);
PhysicsHair.Src srcOBack = PhysicsHair.Src.SRC_TO_X;
PhysicsHair.Src srcZBack = PhysicsHair.Src.SRC_TO_G_ANGLE;
physicsHairBackRight.addSrcParam(srcOBack, "PARAM_ANGLE_X", 0.005F, 1);
physicsHairBackRight.addSrcParam(srcZBack, "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
//動作的優先順序使用
L2DMotionManager = new L2DMotionManager();
//眨眼
eyeBlinkMotion = new EyeBlinkMotion();
//滑鼠拖拽
drag = new L2DTargetPoint();
}
// Update is called once per frame
void Update()
{
//模型位置(矩陣形式的區域性座標轉換成世界座標)
live2DModel.setMatrix(transform.localToWorldMatrix * live2DCanvasPos);
//if (Input.GetKeyDown(KeyCode.M))
//{
// motionIndex++;
// if (motionIndex>=motions.Length)
// {
// motionIndex = 0;
// }
// motionQueueManager.startMotion(motions[motionIndex]);
//}
//motionQueueManager.updateParam(live2DModel);
//模型跟隨滑鼠轉向與看向
Vector3 pos = Input.mousePosition;
if (Input.GetMouseButton(0))
{
drag.Set(pos.x / Screen.width * 2 - 1, pos.y / Screen.height * 2 - 1);
}
else if (Input.GetMouseButtonUp(0))
{
drag.Set(0, 0);
}
//引數及時更新,考慮加速度等自然因素,計算座標,進行逐幀更新
drag.update();
//模型轉向
if (drag.getX() != 0)
{
live2DModel.setParamFloat("PARAM_ANGLE_X", 30 * drag.getX());
live2DModel.setParamFloat("PARAM_ANGLE_Y", 30 * drag.getY());
live2DModel.setParamFloat("PARAM_BODY_ANGLE_X", 10 * drag.getX());
live2DModel.setParamFloat("PARAM_EYE_BALL_X", drag.getX());
live2DModel.setParamFloat("PARAM_EYE_BALL_Y", drag.getY());
}
//眨眼
eyeBlinkMotion.setParam(live2DModel);
long time = UtSystem.getUserTimeMSec();//執行時間
//更新模型定點等
live2DModel.update();
}
private void OnRenderObject()
{
live2DModel.draw();
}
private void StartMotion(int motionIndex, int priority)
{
if (L2DMotionManager.getCurrentPriority() >= priority)
{
return;
}
L2DMotionManager.startMotion(motions[motionIndex]);
}
}
這樣我們就實現了頭髮的自然擺動
其中的幾個頭髮的引數也是我們live2D裡面的
嗯對
三連還是要求一下的
萬一電腦前的大帥比或者大漂亮點讚了呢