Skip to content

Commit 4f90ce7

Browse files
Merge pull request #93 from Live2D/birp/develop
Update to Cubism 5 SDK for Unity R4_2
2 parents ca8babb + 158d818 commit 4f90ce7

306 files changed

Lines changed: 634088 additions & 47323 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Assets/Live2D/Cubism/CHANGELOG.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,49 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66

77

8+
## [5-r.4.2] - 2026-05-14
9+
10+
### Added
11+
12+
* Add `CubismLookCenterTransform` and `CubismLookCenterArtMesh` to allow setting the look-at center using either a Transform or an ArtMesh.
13+
14+
### Changed
15+
16+
* Change property names related to multiply color and screen color.
17+
* Change to work with the `Input System` package.
18+
* Update each model's prefab to match environment updates.
19+
* Change to allow specifying `AnimatorController` in scenes under `Assets/Live2D/Cubism/Samples/AsyncBenchmark`.
20+
* Change to explicitly set texture sampler settings.
21+
* Change the `Assets/Live2D/Cubism/Samples/AsyncBenchmark/AutomaticAsyncBenchmark.unity` scene.
22+
* Add background to text UI.
23+
* Change target fps to 30fps on mobile environments.
24+
* Change `Enable Async` to be disabled by default.
25+
* Change the `Assets/Live2D/Cubism/Samples/OriginalWorkflow/Pose.unity` scene.
26+
* Change the `Assets/Live2D/Cubism/Samlpes/OriginalWorkflow/Motion.unity` scene.
27+
* Change the version of the development project to `6000.0.68f1`.
28+
29+
### Fixed
30+
31+
* Fix an issue where look-at tracking was misaligned when using `CubismLookController`.
32+
* Fix an issue where collision detection remained active even when the collision detection Drawable was hidden.
33+
* Fix an issue where pressing the reset button in the `CubismParametersInspector` would revert to the state before the reset when running the scene.
34+
* Fix an issue where `CubismPartColorsEditor` was using incorrect flags for determination.
35+
* Fix an issue where the re-import process for a model did not support increasing or decreasing parameters and other elements.
36+
* Fix CubismImporterBase.Save so that it no longer performs a reimport when saving.
37+
* Fix the importer to import motion3.json first, followed by model3.json, and then all other assets.
38+
* Fix PoseMotionImporter processing to accommodate the new import order.
39+
* Fix an issue where the texture settings were not as intended when imported.
40+
* Fix an issue where the Koharu model's .model3.json was missing references to .motion3.json.
41+
* Fix Koharu's corrupted .motion3.json files.
42+
* Fix an issue where specifying an override in `CubismParameterExtensionMethods.BlendToValue()` caused the applied value to be the current value of that parameter. by [@LoS-Light](https://github.com/Live2D/CubismUnityComponents/pull/89)
43+
* Fix an issue where arrays accessed in `OnDynamicDrawableData()` were processed with invalid indexes.
44+
* Fix an issue where the `Koharu` model used in scenes under `Assets/Live2D/Cubism/Samples/AsyncBenchmark` was outdated.
45+
* Fix an issue where reimporting a model prefab containing deleted components caused an error and prevented the prefab from being regenerated correctly.
46+
* Fix a duplicate blend calculation in `CubismParameterExtensionMethods.BlendToValue()`.
47+
* Fix an issue where the import process would run for models imported under the `StreamingAssets` folder. by [@redwyre](https://github.com/Live2D/CubismUnityComponents/pull/90)
48+
* Fix an issue where Raycast was functional even when `CubismRaycastable` was inactive.
49+
50+
851
## [5-r.4.1] - 2025-07-17
952

1053
### Changed
@@ -474,6 +517,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
474517
* Fix issue where Priority value was not reset after playing motion with CubismMotionController.
475518

476519

520+
[5-r.4.2]: https://github.com/Live2D/CubismUnityComponents/compare/5-r.4.1...5-r.4.2
477521
[5-r.4.1]: https://github.com/Live2D/CubismUnityComponents/compare/5-r.4...5-r.4.1
478522
[5-r.4]: https://github.com/Live2D/CubismUnityComponents/compare/5-r.3...5-r.4
479523
[5-r.3]: https://github.com/Live2D/CubismUnityComponents/compare/5-r.2...5-r.3

Assets/Live2D/Cubism/Core/CubismModel.cs

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,28 @@ public static void ResetMocReference(CubismModel model, CubismMoc moc)
8686
model.Moc = moc;
8787
}
8888

89+
/// <summary>
90+
/// Resets non-serialized fields of a <see cref="CubismModel"/>.
91+
/// </summary>
92+
/// <remarks>
93+
/// Call after <c>PrefabUtility.SaveAsPrefabAsset</c> to clear stale
94+
/// component references that may have been cached by <see cref="OnValidate"/>
95+
/// during the prefab replacement.
96+
/// </remarks>
97+
/// <param name="model">Target Cubism model.</param>
98+
public static void ResetNonSerializedFields(CubismModel model)
99+
{
100+
if (model.TaskableModel != null)
101+
{
102+
model.TaskableModel.ReleaseUnmanaged();
103+
model.TaskableModel = null;
104+
}
105+
106+
model._parameters = null;
107+
model._parts = null;
108+
model._drawables = null;
109+
model._canvasInformation = null;
110+
}
89111
/// <summary>
90112
/// <see cref="Moc"/> backing field.
91113
/// </summary>
@@ -275,7 +297,7 @@ private bool CanRevive
275297
/// <summary>
276298
/// Revives instance.
277299
/// </summary>
278-
private void Revive()
300+
internal void Revive()
279301
{
280302
// Return if already revive.
281303
if (IsRevived)
@@ -320,6 +342,28 @@ private void Reset(CubismMoc moc)
320342
}
321343
else
322344
{
345+
// Filter stale entries whose UnmanagedIndex exceeds the new Moc count.
346+
var unmanagedParamerterCount = TaskableModel.UnmanagedModel.Parameters.Count;
347+
if (Parameters.Length > unmanagedParamerterCount)
348+
{
349+
var filtered = new CubismParameter[unmanagedParamerterCount];
350+
var n = 0;
351+
352+
for (var i = 0; i < Parameters.Length; i++)
353+
{
354+
if (Parameters[i].UnmanagedIndex < unmanagedParamerterCount)
355+
{
356+
filtered[n++] = Parameters[i];
357+
}
358+
}
359+
360+
if (n < unmanagedParamerterCount)
361+
{
362+
Array.Resize(ref filtered, n);
363+
}
364+
365+
Parameters = filtered;
366+
}
323367
Parameters.Revive(TaskableModel.UnmanagedModel);
324368
}
325369

@@ -334,6 +378,28 @@ private void Reset(CubismMoc moc)
334378
}
335379
else
336380
{
381+
// Filter stale entries whose UnmanagedIndex exceeds the new Moc count.
382+
var unmanagedPartCount = TaskableModel.UnmanagedModel.Parts.Count;
383+
if (Parts.Length > unmanagedPartCount)
384+
{
385+
var filtered = new CubismPart[unmanagedPartCount];
386+
var n = 0;
387+
388+
for (var i = 0; i < Parts.Length; i++)
389+
{
390+
if (Parts[i].UnmanagedIndex < unmanagedPartCount)
391+
{
392+
filtered[n++] = Parts[i];
393+
}
394+
}
395+
396+
if (n < unmanagedPartCount)
397+
{
398+
Array.Resize(ref filtered, n);
399+
}
400+
401+
Parts = filtered;
402+
}
337403
Parts.Revive(TaskableModel.UnmanagedModel);
338404
}
339405

@@ -348,6 +414,28 @@ private void Reset(CubismMoc moc)
348414
}
349415
else
350416
{
417+
// Filter stale entries whose UnmanagedIndex exceeds the new Moc count.
418+
var unmanagedDrawableCount = TaskableModel.UnmanagedModel.Drawables.Count;
419+
if (Drawables.Length > unmanagedDrawableCount)
420+
{
421+
var filtered = new CubismDrawable[unmanagedDrawableCount];
422+
var n = 0;
423+
424+
for (var i = 0; i < Drawables.Length; i++)
425+
{
426+
if (Drawables[i].UnmanagedIndex < unmanagedDrawableCount)
427+
{
428+
filtered[n++] = Drawables[i];
429+
}
430+
}
431+
432+
if (n < unmanagedDrawableCount)
433+
{
434+
Array.Resize(ref filtered, n);
435+
}
436+
437+
Drawables = filtered;
438+
}
351439
Drawables.Revive(TaskableModel.UnmanagedModel);
352440
}
353441

Assets/Live2D/Cubism/Editor/CubismAssetProcessor.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ namespace Live2D.Cubism.Editor
2626
/// </summary>
2727
public class CubismAssetProcessor : AssetPostprocessor
2828
{
29+
private const string Motion3JsonExtension = ".motion3.json";
30+
private const string Model3JsonExtension = ".model3.json";
31+
2932
#region Unity Event Handling
3033

3134
#if !UNITY_2017_3_OR_NEWER
@@ -58,8 +61,26 @@ private static void OnPostprocessAllAssets(
5861

5962
var assetList = CubismCreatedAssetList.GetInstance();
6063

64+
// Import motion3.json first to create AnimationClip
65+
var orderedAssetPaths = importedAssetPaths
66+
.OrderBy(path =>
67+
{
68+
if (path.EndsWith(Motion3JsonExtension, StringComparison.OrdinalIgnoreCase))
69+
{
70+
return 0;
71+
}
72+
73+
if (path.EndsWith(Model3JsonExtension, StringComparison.OrdinalIgnoreCase))
74+
{
75+
return 1;
76+
}
77+
78+
return 2;
79+
})
80+
.ToArray();
81+
6182
// Handle any imported Cubism assets.
62-
foreach (var assetPath in importedAssetPaths)
83+
foreach (var assetPath in orderedAssetPaths)
6384
{
6485
var importer = CubismImporter.GetImporterAtPath(assetPath);
6586

@@ -69,6 +90,12 @@ private static void OnPostprocessAllAssets(
6990
continue;
7091
}
7192

93+
if (assetPath.StartsWith("Assets/StreamingAssets/"))
94+
{
95+
Debug.LogWarning("CubismAssetProcessor : Skipping import of " + assetPath);
96+
continue;
97+
}
98+
7299
try
73100
{
74101
importer.Import();

Assets/Live2D/Cubism/Editor/Importers/CubismImporter.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,16 +220,32 @@ private static void BuiltinTextureImportHandler(CubismModel3JsonImporter importe
220220
var textureImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture)) as TextureImporter;
221221

222222

223+
if (!textureImporter)
224+
{
225+
Debug.LogError("[Texture Importer] Could not get TextureImporter for texture used by Cubism model.");
226+
return;
227+
}
228+
229+
223230
// Return early if texture already seems to be set up.
224-
if (textureImporter.alphaIsTransparency)
231+
if (!textureImporter.mipmapEnabled
232+
&& textureImporter.alphaIsTransparency
233+
&& textureImporter.textureType == TextureImporterType.Default
234+
&& textureImporter.textureCompression == TextureImporterCompression.Uncompressed
235+
&& textureImporter.wrapMode == TextureWrapMode.Repeat
236+
&& textureImporter.filterMode == FilterMode.Bilinear)
225237
{
226238
return;
227239
}
228240

229241

230242
// Set up texture importing.
243+
textureImporter.mipmapEnabled = false;
231244
textureImporter.alphaIsTransparency = true;
232245
textureImporter.textureType = TextureImporterType.Default;
246+
textureImporter.textureCompression = TextureImporterCompression.Uncompressed;
247+
textureImporter.wrapMode = TextureWrapMode.Repeat;
248+
textureImporter.filterMode = FilterMode.Bilinear;
233249

234250

235251
EditorUtility.SetDirty(texture);

Assets/Live2D/Cubism/Editor/Importers/CubismImporterBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public void Save()
4242
assetImporter.userData = JsonUtility.ToJson(this);
4343

4444

45-
assetImporter.SaveAndReimport();
45+
AssetDatabase.WriteImportSettingsIfDirty(AssetPath);
4646
}
4747

4848
#region ICubismImporter

Assets/Live2D/Cubism/Editor/Importers/CubismModel3JsonImporter.cs

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using Live2D.Cubism.Framework.Json;
1313
using Live2D.Cubism.Framework.Motion;
1414
using Live2D.Cubism.Framework.MotionFade;
15+
using Live2D.Cubism.Framework.MouthMovement;
1516
using Live2D.Cubism.Framework.Pose;
1617
using Live2D.Cubism.Rendering.Masking;
1718
using System;
@@ -259,12 +260,31 @@ public override void Import()
259260
// Reset moc reference.
260261
CubismModel.ResetMocReference(model, MocAsset);
261262

263+
// Update moc asset before saving prefab to avoid IndexOutOfRangeException
264+
// when Inspector loads the prefab and calls Revive() with stale moc data.
265+
if (MocAsset != null)
266+
{
267+
EditorUtility.CopySerialized(moc, MocAsset);
268+
269+
// Revive by forcee to make instance using the new Moc.
270+
CubismMoc.ResetUnmanagedMoc(MocAsset);
271+
272+
EditorUtility.SetDirty(MocAsset);
273+
}
274+
262275
// Keep layer value.
263276
model.gameObject.layer = ModelPrefab.layer;
264277

265278
// Replace prefab.
266279
#if UNITY_2018_3_OR_NEWER
267280
ModelPrefab = PrefabUtility.SaveAsPrefabAsset(model.gameObject, $"{assetPath}.prefab");
281+
282+
// Clear stale non-serialized state cached during prefab replacement.
283+
var savedModel = ModelPrefab.FindCubismModel();
284+
if (savedModel != null)
285+
{
286+
CubismModel.ResetNonSerializedFields(savedModel);
287+
}
268288
#else
269289
ModelPrefab = PrefabUtility.ReplacePrefab(model.gameObject, ModelPrefab, ReplacePrefabOptions.ConnectToPrefab);
270290
#endif
@@ -277,20 +297,6 @@ public override void Import()
277297
// Clean up.
278298
Object.DestroyImmediate(model.gameObject, true);
279299

280-
281-
// Update moc asset.
282-
if (MocAsset != null)
283-
{
284-
EditorUtility.CopySerialized(moc, MocAsset);
285-
286-
287-
// Revive by force to make instance using the new Moc.
288-
CubismMoc.ResetUnmanagedMoc(MocAsset);
289-
290-
291-
EditorUtility.SetDirty(MocAsset);
292-
}
293-
294300
// Save state and assets.
295301
if (isImporterDirty)
296302
{
@@ -316,7 +322,7 @@ private static void CopyUserData(CubismModel source, CubismModel destination, bo
316322
foreach (var sourceComponent in source.GetComponents(typeof(Component)))
317323
{
318324
// Skip non-movable components.
319-
if (!sourceComponent.MoveOnCubismReimport(copyComponentsOnly))
325+
if (!sourceComponent || !sourceComponent.MoveOnCubismReimport(copyComponentsOnly))
320326
{
321327
continue;
322328
}
@@ -326,7 +332,8 @@ private static void CopyUserData(CubismModel source, CubismModel destination, bo
326332
|| sourceComponent.GetType() == typeof(CubismFadeController)
327333
|| sourceComponent.GetType() == typeof(CubismExpressionController)
328334
|| sourceComponent.GetType() == typeof(CubismPoseController)
329-
|| sourceComponent.GetType() == typeof(CubismParameterStore))
335+
|| sourceComponent.GetType() == typeof(CubismParameterStore)
336+
|| sourceComponent.GetType() == typeof(CubismDisplayInfoCombinedParameterInfo))
330337
{
331338
continue;
332339
}
@@ -368,11 +375,17 @@ private static void CopyUserData<T>(T[] source, T[] destination, bool copyCompon
368375
foreach (var sourceComponent in sourceT.GetComponents(typeof(Component)))
369376
{
370377
// Skip non-movable components.
371-
if (!sourceComponent.MoveOnCubismReimport(copyComponentsOnly))
378+
if (!sourceComponent || !sourceComponent.MoveOnCubismReimport(copyComponentsOnly))
372379
{
373380
continue;
374381
}
375382

383+
// Skip import-managed components that should not be inherited from the old prefab.
384+
if (sourceComponent.GetType() == typeof(CubismEyeBlinkParameter)
385+
|| sourceComponent.GetType() == typeof(CubismMouthParameter))
386+
{
387+
continue;
388+
}
376389

377390
// Copy component.
378391
var destinationComponent = destinationT.GetOrAddComponent(sourceComponent.GetType());
@@ -381,12 +394,14 @@ private static void CopyUserData<T>(T[] source, T[] destination, bool copyCompon
381394
var name = cdiParameterName.Name;
382395
EditorUtility.CopySerialized(sourceComponent, destinationComponent);
383396
cdiParameterName.Name = name;
397+
EditorUtility.SetDirty(cdiParameterName);
384398
}
385399
else if (destinationComponent is CubismDisplayInfoPartName cdiPartName && !string.IsNullOrEmpty(cdiPartName.Name))
386400
{
387401
var name = cdiPartName.Name;
388402
EditorUtility.CopySerialized(sourceComponent, destinationComponent);
389403
cdiPartName.Name = name;
404+
EditorUtility.SetDirty(cdiPartName);
390405
}
391406
else
392407
{

Assets/Live2D/Cubism/Editor/Inspectors/CubismParametersInspectorInspector.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ public override VisualElement CreateInspectorGUI()
9292
parameter.OverrideValue(parameter.DefaultValue);
9393
_elements[i].slider.value = parameter.DefaultValue;
9494
_elements[i].field.value = parameter.DefaultValue;
95+
EditorUtility.SetDirty(parameter);
9596
}
9697

9798
Undo.RecordObjects(target.Model.Parameters, "Change Parameter Values");

0 commit comments

Comments
 (0)