人物模型是從live2d下載下來的,這么可愛的二次元不可能是我畫的。
live2d本身有對鼠標監測的封裝方法(見對象L2DTargetPoint),鼠標在live2d的拖拽管理坐標系內會反饋一個鼠標的影響度,可看成一個在-1到1之間的比例值;
這里的方法是:
1.先獲取鼠標當前在屏幕的位置
2.利用已有公式將當前鼠標物理位置x轉換成live2d內的世界坐標值y
3.通過y值去設置人物本身在unity中的動作幅度轉動從而實現跟隨鼠標發生相應肢體變化的效果
先貼碼源

using System.Collections; using System.Collections.Generic; using UnityEngine; using live2d; using live2d.framework; public class Live2dModel : MonoBehaviour { public TextAsset modelFile; public Texture2D[] textures; public TextAsset[] motionFiles; //加載模型動畫數組 private Live2DMotion[] motions; //動作數組 private L2DMotionManager l2DMotionManager; //優先級的設置標准 //1.動作未進行的狀態,優先級為0 //2.待機動作發生時,優先級為1 //3.其他動作進行時,優先級為2 //4.無視優先級,強制發生的動作 private Live2DModelUnity live2dModel; private Matrix4x4 live2DCanvasPos; private MotionQueueManager motionQueueManager; //動作的管理 private MotionQueueManager motionQueueManagerA; private EyeBlinkMotion eyeBlinkMotion; //鼠標拖拽引起的動作變化 private L2DTargetPoint drag; public int motionIndex; public float a; // Start is called before the first frame update void Start() { //初始化 Live2D.init(); for (int i = 0; i < textures.Length; i++) { live2dModel.setTexture(i, textures[i]); } //指定顯示位置和尺寸(使用正交矩陣與相關API顯示圖像,再由游戲物體) float modelWidth = live2dModel.getCanvasWidth(); live2DCanvasPos = Matrix4x4.Ortho(0, modelWidth, modelWidth, 0, -50, 50); //播放動作 //實例化動作對象 //1.直接獲取路徑賦值來獲取動畫播放 //live2DMotionIdle = Live2DMotion.loadMotion(Application.dataPath + ""); //2.用textasset來加載動畫播放資源 //TextAsset mtnFile = Resources.Load<TextAsset>(""); //live2DMotionIdle = Live2DMotion.loadMotion(mtnFile.bytes); motions = new Live2DMotion[motionFiles.Length]; for (int i = 0; i < motionFiles.Length; i++) { motions[i] = Live2DMotion.loadMotion(motionFiles[i].bytes); //遍歷完成所有動作的加載 } //設置某一個動畫的一些屬性 //setLoopFadeIn方法:重復播放的時候是否加上動作漸變淡入(即當前動作幀數較多 False是不淡入 //setFadeOut方法:如果不設置那么默認淡出時間是1000ms 動作播放時長 motions[0].setLoopFadeIn(false); motions[0].setFadeOut(1000); //動作的優先級使用 l2DMotionManager = new L2DMotionManager(); //眨眼 eyeBlinkMotion = new EyeBlinkMotion(); //鼠標拖拽 drag = new L2DTargetPoint(); } // Update is called once per frame void Update() { //具體是為了讓camera把人物顯示出來 live2dModel.setMatrix(transform.localToWorldMatrix * live2DCanvasPos); //模型跟隨鼠標轉向與看向 //得到的live2d鼠標監測點的比例值是-1到1(對應一個live2d的拖拽管理坐標系,或者說叫影響度) //然后我們通過這個值去設置我們的參數 比如選擇30°*當前得到的值 //就會按照這個值所帶來的影響度去影響我們的模型 //從而達到看向鼠標點位置的效果 Vector3 pos = Input.mousePosition; if (Input.GetMouseButton(0)) //0按下鼠標左鍵 1按下鼠標右鍵 { //把當前的屏幕鼠標坐標轉化成l2d內的鼠標監測坐標 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); //更新模型定點、參數、貼圖 live2dModel.update(); } //繪圖 private void OnRenderObject() { live2dModel.draw(); } private void StartMotion(int motionIndex, int priority) { //當前播放的動畫優先級比傳進來的高 返回 if (l2DMotionManager.getCurrentPriority() >= priority) { return; } l2DMotionManager.startMotion(motions[motionIndex]); } }
詳細見注釋。
沒研究出來怎么發GIF圖,動作效果待補充。