/// <summary> /// 無限スクロールの初期化 /// TODO 未完成 あとでいい感じに実装する /// </summary> /// <typeparam name="TExtensionInfiniteScroll"></typeparam> /// <typeparam name="TExtensionInfiniteScrollData"></typeparam> /// <param name="view"></param> /// <param name="scrollDataList"></param> public void InitInfiniteScroll <TExtensionInfiniteScroll, TExtensionInfiniteScrollData>(LoopListView2 view, List <TExtensionInfiniteScrollData> scrollDataList) where TExtensionInfiniteScroll : IExtensionInfiniteScrollItem where TExtensionInfiniteScrollData : ExtensionScrollItemData { OrtegaLogger.Log("無限スクロールの初期化"); ScrollItemDataList = new List <ExtensionScrollItemData>(scrollDataList); view.InitListView(ScrollItemDataList.Count, OnUpdateInfiniteScroll <TExtensionInfiniteScroll>); }
/// <summary> /// カスタマイズされたマテリアルを適用する /// </summary> /// <param name="drawable"></param> /// <returns></returns> private static Material CustomizeMaterial(CubismDrawable drawable) { Material material = null; var cubismRenderer = drawable.gameObject.GetComponent <CubismRenderer>(); var split = drawable.Id.Split('_'); if (split.Length >= 2) { var originalName = split[0] + split[1]; var joinName = string.Empty; switch (split[0]) { //レンダーテクスチャ(パーティクル) //particle_部位名(_(スキニングしている場合記号)) case "Particle": var particleMaterialFolderPath = GetMaterialFolder(); joinName = particleMaterialFolderPath + "/" + originalName; material = AssetDatabase.LoadAssetAtPath <Material>(joinName + ".mat"); CustomRenderTexture customRenderTexture = null; if (material == null) { material = new Material(Shader.Find("Live2DVerification/CubismModelRenderTexture")); AssetDatabase.CreateAsset(material, joinName + ".mat"); //TODO 空のテクスチャを作成 customRenderTexture = new CustomRenderTexture(cubismRenderer.MainTexture.width, cubismRenderer.MainTexture.height); customRenderTexture.initializationMode = CustomRenderTextureUpdateMode.Realtime; customRenderTexture.updateMode = CustomRenderTextureUpdateMode.Realtime; AssetDatabase.CreateAsset(customRenderTexture, joinName + "CustomRenderTexture.asset"); //TODO material.SetTexture("RenderTex", customRenderTexture); OrtegaLogger.Log("CustomMaterial setting complete." + $"setting target:{drawable.Id}" + $"create:{joinName}CustomRenderTexture.asset & {joinName}.mat"); } else { customRenderTexture = AssetDatabase.LoadAssetAtPath <CustomRenderTexture>(joinName + "CustomRenderTexture.asset"); } //live2d専用のマテリアル設定 material.SetInt("_SrcColor", 1); material.SetInt("_DstColor", 10); material.SetInt("_SrcAlpha", 1); material.SetInt("_DstAlpha", 10); //独自のテクスチャ設定 material.SetTexture("_RenderTex", customRenderTexture); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); break; //流れるテクスチャ //flowTexture_部位名(_(スキニングしている場合記号)) case "FlowTexture": var flowTextureMaterialFolderPath = GetMaterialFolder(); joinName = flowTextureMaterialFolderPath + "/" + originalName; material = AssetDatabase.LoadAssetAtPath <Material>(joinName + ".mat"); Texture2D subTexture = null; Texture2D flowTexture = null; if (material == null) { material = new Material(Shader.Find("Live2DVerification/CubismModelFlowTexture")); AssetDatabase.CreateAsset(material, joinName + ".mat"); //TODO 空のテクスチャを作成 subTexture = new Texture2D(cubismRenderer.MainTexture.width, cubismRenderer.MainTexture.height, TextureFormat.ARGB32, false, false); var subTextureBytes = subTexture.EncodeToPNG(); File.WriteAllBytes(joinName + "SubTexture.png", subTextureBytes); flowTexture = new Texture2D(cubismRenderer.MainTexture.width, cubismRenderer.MainTexture.height, TextureFormat.ARGB32, false, false); var flowTextureBytes = flowTexture.EncodeToPNG(); File.WriteAllBytes(joinName + "FlowTexture.png", flowTextureBytes); Debug.Log("CustomMaterial setting complete." + $"setting target:{drawable.Id}" + $"create:{joinName}SubTexture.png & {joinName}FlowTexture.png & {joinName}.mat"); } else { subTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(joinName + "SubTexture.png"); flowTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(joinName + "FlowTexture.png"); } //live2d専用のマテリアル設定 material.SetInt("_SrcColor", 1); material.SetInt("_DstColor", 10); material.SetInt("_SrcAlpha", 1); material.SetInt("_DstAlpha", 10); //独自のテクスチャ設定 material.SetTexture("_SubTex", subTexture); material.SetTexture("_FlowMap", flowTexture); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); break; //新しいマテリアルが追加されたらどんどん追加記述していく。 default: OrtegaLogger.Log($"DefaultMaterial setting complete.setting target:{drawable.Id}"); break; } } return(material); }
public static void CustomizeCubismModel(CubismModelCustomizerParam param) { //内部的なシーンにプレハブをロードする var model = PrefabUtility.LoadPrefabContents(param.AssetPath); //var model = AssetDatabase.LoadAssetAtPath<GameObject>(param.AssetPath); //live2dモデルであるか? if (!model.GetComponent <CubismModel>()) { return; } var cubismModel = model.GetComponent <CubismModel>(); var renderController = model.GetComponent <CubismRenderController>(); renderController.SortingLayer = "UI_Window"; renderController.SortingOrder = -1; //イベントコンポーネントを設定する GetComponent <CubismEventExpansion>(model); //当たり判定使う場合 if (param.IsHitJudge) { GetComponent <CubismRaycaster>(model); //「hitArea_アニメーション名_ボイス名_部位名」の形を成しているものに関してCubismRaycastableExpansionを追加する foreach (var modelDrawable in cubismModel.Drawables) { var isHitJudgeTarget = false; var split = modelDrawable.Id.Split('_'); if (split.Length >= 4) { isHitJudgeTarget = split[0] == "HitArea"; } if (isHitJudgeTarget) { var raycastableExpansion = GetComponent <CubismRaycastableExpansion>(modelDrawable.gameObject); //アニメーションタイプの設定 var characterAnimationType = (CharacterAnimationType)Enum.Parse(typeof(CharacterAnimationType), split[1]); raycastableExpansion._animationType = characterAnimationType; //ボイスタイプの設定 var characterVoiceType = (CharacterVoiceType)Enum.Parse(typeof(CharacterVoiceType), split[2]); raycastableExpansion._voiceType = characterVoiceType; } } } //自動瞬きを使う場合 if (param.IsAutoBlinkActive) { var eyeBlinkController = GetComponent <CubismEyeBlinkController>(model); eyeBlinkController.BlendMode = CubismParameterBlendMode.Override; var autoEyeBlinkInput = GetComponent <CubismAutoEyeBlinkInput>(model); //平均的な瞬きのタイミングを入れておく autoEyeBlinkInput.MaximumDeviation = 1.86f; autoEyeBlinkInput.Mean = 4.62f; autoEyeBlinkInput.Timescale = 3.66f; //パラメーターに関しては[左眼 開閉(ParamEyeLOpen)]、[右目 開閉(ParamEyeROpen)]を設定している場合 //インポート時に自動追加してくれる?? //「eyeBlink_パラメーター名」の形を成しているものに関してCubismEyeBlinkParameterを追加する foreach (var modelParameter in cubismModel.Parameters) { var isEyeBlinkAddTarget = false; var split = modelParameter.Id.Split('_'); if (split.Length > 0) { isEyeBlinkAddTarget = split[0] == "EyeBlink"; } if (isEyeBlinkAddTarget) { GetComponent <CubismEyeBlinkParameter>(modelParameter.gameObject); } } } //リップシンクを使う場合 if (param.IsLipSyncActive) { var mouthController = GetComponent <CubismMouthController>(model); mouthController.BlendMode = CubismParameterBlendMode.Override; var lipSyncAudio = GetComponent <AudioSource>(model); var audioMouthInput = GetComponent <CubismAudioMouthInput>(model); audioMouthInput.AudioInput = lipSyncAudio; //平均的に口が綺麗に開くと思われる値を入れておく。 audioMouthInput.Gain = 3.24f; audioMouthInput.Smoothing = 0.044f; //「lipSync_パラメーター名」の形を成しているものに関してCubismMouthParameterを追加する foreach (var modelParameter in cubismModel.Parameters) { var isLipSyncAddTarget = false; var split = modelParameter.Id.Split('_'); if (split.Length > 0) { isLipSyncAddTarget = split[0] == "LipSync"; } if (isLipSyncAddTarget) { GetComponent <CubismMouthParameter>(modelParameter.gameObject); } } } //視線追従を使う場合 if (param.IsEyeTrackingActive) { var lookController = GetComponent <CubismLookController>(model); var targetObjectTransform = model.transform.Find("Target"); GameObject targetObject = null; if (targetObjectTransform == null) { targetObject = new GameObject("Target"); targetObject.transform.SetParent(model.transform, false); } else { targetObject = targetObjectTransform.gameObject; } var lookTarget = GetComponent <CubismLookTargetExpansion>(targetObject); //BlendModeの設定 lookController.BlendMode = CubismParameterBlendMode.Override; //Targetの設定 lookController.Target = lookTarget; //「eyeTracking_パラメータ名+(XYZ)」の形を成しているものに関しCubismLookParameterを追加する foreach (var modelParameter in cubismModel.Parameters) { var isEyeTrackingAddTarget = false; var split = modelParameter.Id.Split('_'); if (split.Length > 0) { isEyeTrackingAddTarget = split[0] == "EyeTracking"; } if (isEyeTrackingAddTarget) { GetComponent <CubismLookParameter>(modelParameter.gameObject); } } } //Particleの物理演算を使用する場合 if (param.IsPhysicalOperationParticle) { foreach (var drawable in cubismModel.Drawables) { var split = drawable.Id.Split('_'); if (split.Length >= 2) { var originalName = split[0] + split[1]; switch (split[0]) { //「PhysicalOperationParticle_部位名」 case "PhysicalOperationParticle": if (model.transform.Find(originalName) == null) { var physicalOperationParticleObj = new GameObject(originalName); physicalOperationParticleObj.transform.SetParent(model.transform, false); var physicalOperationParticleFollow = GetComponent <CubismFollowObjectExpansion>(physicalOperationParticleObj); //追従元のMeshFilterを設定。 var drawableMeshFilter = drawable.gameObject.GetComponent <MeshFilter>(); physicalOperationParticleFollow.TargetMeshFilter = drawableMeshFilter; //Z軸で一番手前に置く(xとyはdrawableのmeshFilter参照) var posX = physicalOperationParticleObj.transform.position.x; var posY = physicalOperationParticleObj.transform.position.y; if (drawableMeshFilter.mesh.vertices.Length > 0) { posX = drawableMeshFilter.mesh.vertices[0].x; posY = drawableMeshFilter.mesh.vertices[0].y; } physicalOperationParticleObj.transform.position = new Vector3(posX, posY, -10); var physicalOperationParticle = GetComponent <ParticleSystem>(physicalOperationParticleObj); var particleRenderer = physicalOperationParticle.GetComponent <Renderer>(); particleRenderer.sortingOrder = -1; particleRenderer.sortingLayerName = "UI_Window"; } break; } } } } //TODO マテリアルのフォルダパスを作成する var assetPathSplit = param.AssetPath.Split('/'); if (assetPathSplit.Length > 0) { ModelPlacePath = param.AssetPath.Replace(assetPathSplit[assetPathSplit.Length - 1], ""); } //アニメーション設定を自動作成する場合 if (param.IsAutoAnimationSetting) { /* * var animatorControllerPath = $"{ModelPlacePath}/live2d_data/animation/{model.name}.controller"; * * var runTimeAnimatorController = AssetDatabase.LoadAssetAtPath<RuntimeAnimatorController>(animatorControllerPath); * if (runTimeAnimatorController == null) * { * runTimeAnimatorController = AnimatorController.CreateAnimatorControllerAtPath(animatorControllerPath); * } * * var animatorController = runTimeAnimatorController as AnimatorController; * * //コントローラーに対してパラメーターを割り当てる * foreach (CharacterAnimationType animationType in Enum.GetValues(typeof(CharacterAnimationType))) * { * animatorController.AddParameter(animationType.ToString(), AnimatorControllerParameterType.Trigger); * } * * //.animのものに関して全件検索 * var clipsPath = AssetDatabase.FindAssets("t:AnimationClip", new[] { $"{ModelPlacePath}/live2d_data/animation/" }); * foreach (var clipPath in clipsPath) * { * var clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(clipPath); * AssetDatabase.AddObjectToAsset(clip, animatorController); * var state = animatorController.AddMotion(clip); * } * * //コントローラーをモデルのAnimatorにアタッチする * var modelAnimator = GetComponent<Animator>(model); * * //runtimeanimatorcontrollerが必要?? * modelAnimator.runtimeAnimatorController = animatorController; * * AssetDatabase.SaveAssets(); * //コントローラーの上書き? * FileUtil.ReplaceFile(animatorControllerPath, animatorControllerPath); * AssetDatabase.Refresh(); * * OrtegaLogger.Log("CubismModel Animation Setting Complete"); */ OrtegaLogger.Log("自動アニメーションの設定は未実装です"); } //TODO マテリアルの割り当て //CubismImporter.OnPickMaterial = CustomizeMaterial; foreach (var drawable in cubismModel.Drawables) { var split = drawable.Id.Split('_'); if (split.Length > 0 && CustomizeMaterialSplit.Contains(split[0])) { var material = CustomizeMaterial(drawable); var cubismRenderer = drawable.gameObject.GetComponent <CubismRenderer>(); cubismRenderer.Material = material; } } SetLayerRecursively(model, 5); //独自テクスチャ追加により必要になったオブジェクトを作成する foreach (var drawable in cubismModel.Drawables) { var split = drawable.Id.Split('_'); if (split.Length >= 2) { var originalName = split[0] + split[1]; switch (split[0]) { //レンダーテクスチャ(パーティクル) //particle_部位名(_(スキニングしている場合記号)) case "Particle": var particleCameraObjTransform = model.transform.Find(originalName + "_Camera"); GameObject particleCameraObj = null; Camera particleCamera = null; if (particleCameraObjTransform == null) { //カメラの生成 particleCameraObj = new GameObject(originalName + "_Camera"); particleCameraObj.transform.SetParent(model.transform, false); particleCamera = GetComponent <Camera>(particleCameraObj); var renderTextureAssetPath = GetMaterialFolder() + "/" + originalName + "CustomRenderTexture.asset"; var targetTexture = AssetDatabase.LoadAssetAtPath <CustomRenderTexture>(renderTextureAssetPath); particleCamera.targetTexture = targetTexture; OrtegaLogger.Log($"Setting complete.create:{particleCameraObj.name}"); } else { particleCameraObj = particleCameraObjTransform.gameObject; particleCamera = GetComponent <Camera>(particleCameraObj); } particleCamera.backgroundColor = new Color(0, 0, 0, 0); particleCamera.orthographic = true; //描画するレイヤーの設定(エフェクト専用のレイヤーCharacterEffect) particleCamera.cullingMask = 1 << LayerMask.NameToLayer("CharacterEffect"); particleCamera.clearFlags = CameraClearFlags.SolidColor; particleCamera.orthographicSize = 1; //カメラのレイヤー設定(CharacterEffect) particleCameraObj.layer = 9; //パーティクルの生成(デフォのものも自動でやってしまうとよいかも)(カメラの子にする var particleObjTransform = particleCameraObj.transform.Find(originalName + "_Particle"); GameObject particleObj = null; if (particleObjTransform == null) { particleObj = new GameObject(originalName + "_Particle"); particleObj.transform.SetParent(particleCameraObj.transform, false); var particle = GetComponent <ParticleSystem>(particleObj); var particleRenderer = particle.GetComponent <Renderer>(); particleRenderer.sortingOrder = -1; particleRenderer.sortingLayerName = "UI_Window"; OrtegaLogger.Log($"Setting complete.create:{particleObj.name}"); } else { particleObj = particleObjTransform.gameObject; } particleObj.layer = 9; break; //流れるテクスチャ //flowTexture_部位名(_(スキニングしている場合記号)) case "FlowTexture": //プレハブ内では何も生成しない break; } } } //プレハブの変更を保存する PrefabUtility.SaveAsPrefabAsset(model, param.AssetPath); PrefabUtility.UnloadPrefabContents(model); OrtegaLogger.Log("Setting All Complete"); }