Unity Live2D的接入和使用

下载地址

Live2D下载地址

Live2D的使用

Live2D导入Unity后文件结构如下,并且官方也提供了多个演示场景以供大家学习使用。

Unity Live2D的接入和使用_第1张图片
基本功能和使用
导入前的Live2D文件结构如下:在这里插入图片描述
分别为表情的Json配置文件,动作的Json配置文件,贴图以及物理Json配置文件等。
将此导入Unity后Live2D会自动处理配置文件,并在Runtime文件夹下生成Liv2D的预制体,expressionList表情列表和fadeMotionList动作列表,列表的引用关系Live2D已自动处理。
Unity Live2D的接入和使用_第2张图片
Unity Live2D的接入和使用_第3张图片
Live2D预制体所挂脚本
Unity Live2D的接入和使用_第4张图片
可选功能脚本
LookController与LookTarget配合使用,控制Live2D的鼠标追踪效果。
Mouth,EyeBlink控制Live2D自动眨眼功能和嘴巴张闭。
Expression表情管理。
Fade 动作淡入淡出管理。
同时自动眨眼还有鼠标追踪等功能,需要在相应可动部位添加相应功能脚本。
如自动眨眼:
Unity Live2D的接入和使用_第5张图片
嘴巴:
Unity Live2D的接入和使用_第6张图片
鼠标追踪:
Unity Live2D的接入和使用_第7张图片
这些都是Live2D提供的基本功能,只需要挂载相应脚本便可实现功能。

动作和表情的播放

示例脚本:

using Live2D.Cubism.Core;
using Live2D.Cubism.Framework;
using Live2D.Cubism.Framework.Expression;
using Live2D.Cubism.Framework.Motion;
using Live2D.Cubism.Framework.Raycasting;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace Live2D.Cubism.Samples.OriginalWorkflow.Demo
{
    [RequireComponent(typeof(CubismMotionController))]
    [RequireComponent(typeof(CubismRaycaster))]
    public class CubismSampleController : MonoBehaviour
    {
        /// 
        /// MotionController to be operated.
        /// 
        private CubismMotionController _motionController;

        /// 
        /// ExpressionController to be operated.
        /// 
        private CubismExpressionController _expressionController;

        /// 
        /// Operation animation clip from the inspector.
        /// 
        [SerializeField]
        private AnimationClip _bodyAnimation;

        /// 
        /// Array of motion set in tapbody.
        /// 
        [SerializeField]
        private AnimationClip[] _tapBodyMotions;

        /// 
        /// Motion set in roop motion.
        /// 
        private AnimationClip _roopMotion;

        /// 
        /// List of Drawables info.
        /// 
        private List<HitDrawableInfomation> _hasHitDrawables;

        /// 
        /// Component that performs ray judgment on Drawables of model.
        /// 
        private CubismRaycaster _raycaster;

        /// 
        /// Raycast Hit Results.
        /// 
        private CubismRaycastHit[] _raycastResults;

        /// 
        /// Enumeration type for hit area discrimination.
        /// 
        private enum HitArea
        {
            Head,
            Body
        }

        /// 
        /// Structure that stores Drawable information for which hit area is specified.
        /// 
        private struct HitDrawableInfomation
        {
            /// 
            /// Drawable with component set.
            /// 
            public CubismDrawable drawable;

            /// 
            /// HitArea.
            /// 
            public HitArea hitArea;
        }


        /// 
        /// Load model.
        /// 
        private void Start()
        {
            var model = this.FindCubismModel();

            // Get components.
            _motionController = model.GetComponent<CubismMotionController>();
            _expressionController = model.GetComponent<CubismExpressionController>();
            _raycaster = model.GetComponent<CubismRaycaster>();


            // Set behavior at the end of animation.
            _motionController.AnimationEndHandler = AnimationEnded;


            // Get up to 4 results of collision detection.
            _raycastResults = new CubismRaycastHit[4];


            // Cache the drawable in which the component is set.
            {
                _hasHitDrawables = new List<HitDrawableInfomation>();

                var hitAreas = Enum.GetValues(typeof(HitArea));
                var drawables = model.Drawables;


                for (var i = 0; i < hitAreas.Length; i++)
                {
                    for (var j = 0; j < drawables.Length; j++)
                    {
                        var cubismHitDrawable = drawables[j].GetComponent<CubismHitDrawable>();

                        if (cubismHitDrawable)
                        {
                            if (cubismHitDrawable.Name == hitAreas.GetValue(i).ToString())
                            {
                                var hitDrawable = new HitDrawableInfomation();
                                hitDrawable.drawable = drawables[j];
                                hitDrawable.hitArea = (HitArea)i;

                                _hasHitDrawables.Add(hitDrawable);
                                break;
                            }
                        }
                    }
                }
            }
        }


        /// 
        /// Update.
        /// 
        private void Update()
        {
            // Play if animation is specified.
            SpecifiedAnimationCheck();


            if(!Input.GetMouseButtonDown(0))
            {
                return;
            }


            // Cast ray from pointer position.
            var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            var hitCount = _raycaster.Raycast(ray, _raycastResults);


            // Motion playback according to the hit location.
            for (var i = 0; i < hitCount; i++)
            {
                var hitDrawable = _raycastResults[i].Drawable;

                for (var j = 0; j < _hasHitDrawables.Count; j++)
                {
                    if (hitDrawable == _hasHitDrawables[j].drawable)
                    {
                        var hitArea = _hasHitDrawables[j].hitArea;


                        // Tap body.
                        if (hitArea == HitArea.Body)
                        {
                            // Decide motion to play at random.
                            var motionIndex = UnityEngine.Random.Range(0, _tapBodyMotions.Length - 1);

                            Debug.Log("Tap body : Play : " + _tapBodyMotions[motionIndex].name);

                            _motionController.PlayAnimation(_tapBodyMotions[motionIndex], isLoop: false, priority:CubismMotionPriority.PriorityNormal);
                        }
                        // Tap head.
                        else if (hitArea == HitArea.Head)
                        {
                            // Decide expression motion to play at random.
                            var expressionNum = _expressionController.ExpressionsList.CubismExpressionObjects.Length;
                            var expressionIndex = UnityEngine.Random.Range(0, expressionNum - 1);

                            _expressionController.CurrentExpressionIndex = expressionIndex;

                            Debug.Log("Tap head : Play : " + _expressionController.ExpressionsList.CubismExpressionObjects[expressionIndex].name);
                        }

                        break;
                    }
                }
            }
        }


        /// 
        /// Check the specified animation and play it.
        /// 
        private void SpecifiedAnimationCheck()
        {
            if(_bodyAnimation != _roopMotion)
            {
                _roopMotion = _bodyAnimation;

                Debug.Log("Body animation : Play : " + _roopMotion.name);

                _motionController.PlayAnimation(_roopMotion, priority:CubismMotionPriority.PriorityIdle);
            }
        }


        /// 
        /// Called at the end of the animation.
        /// 
        /// 
        private void AnimationEnded(float instanceId)
        {
            // Play roop motion.
            _motionController.PlayAnimation(_roopMotion, priority:CubismMotionPriority.PriorityIdle);

            Debug.Log("Body animation : Play : " + _roopMotion.name);
        }
    }
}

注意,可交互部位要挂载相应功能脚本,点击才会生效。如要点击身体部位,可在预制体的Drawables下将相关区域挂载CubismHitDrawableCubismRaycastable脚本。如:
Unity Live2D的接入和使用_第8张图片
如此,射线检测到点击的相应区域,便可播放相应的动作或者表情了。

你可能感兴趣的:(Unity常用SDK接入)