// Use this for initialization private IEnumerator Start() { if (string.IsNullOrWhiteSpace(songResourceName)) { LogError("Song resource name is empty."); yield break; } if (string.IsNullOrWhiteSpace(idolSerialName)) { LogError("Idol serial name is empty."); yield break; } if (string.IsNullOrWhiteSpace(costumeName)) { LogError("Costume name is empty."); yield break; } if (motionNumber < 1 || motionNumber > 5) { LogError($"Invalid motion number: {motionNumber}, should be 1 to 5."); yield break; } var danceAssetName = $"dan_{songResourceName}_{motionNumber:00}"; var modelAssetName = $"cb_{costumeName}_{idolSerialName}"; if (!DanceAssetNameRegex.IsMatch(danceAssetName)) { LogError($"\"{danceAssetName}\" is not a valid dance asset name."); yield break; } if (!ModelAssetNameRegex.IsMatch(modelAssetName)) { LogError($"\"{modelAssetName}\" is not a valid model asset name."); yield break; } var danceBundlePath = Path.Combine(Application.streamingAssetsPath, $"{danceAssetName}.imo.unity3d"); var modelBundlePath = Path.Combine(Application.streamingAssetsPath, $"{modelAssetName}.unity3d"); AssetBundle danceBundle, modelBundle; if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer) { var www = new WWW(danceBundlePath); yield return(www); danceBundle = www.assetBundle; www.Dispose(); www = new WWW(modelBundlePath); yield return(www); modelBundle = www.assetBundle; www.Dispose(); } else { if (!File.Exists(danceBundlePath)) { LogError($"Dance bundle is not found at '{danceBundlePath}'."); yield break; } if (!File.Exists(modelBundlePath)) { LogError($"Model bundle is not found at '{modelBundlePath}'."); yield break; } danceBundle = AssetBundle.LoadFromFile(danceBundlePath); modelBundle = AssetBundle.LoadFromFile(modelBundlePath); } if (danceBundle == null) { LogError("Dance bundle is null."); yield break; } if (modelBundle == null) { LogError("Model bundle is null."); yield break; } var danceAssetPath = $"assets/imas/resources/exclude/imo/dance/{songResourceName}/{danceAssetName}_dan.imo.asset"; var danceData = danceBundle.LoadAsset <CharacterImasMotionAsset>(danceAssetPath); var modelAssetPath = $"assets/imas/resources/chara/body/{modelAssetName}/{modelAssetName}.fbx"; var fbx = modelBundle.LoadAsset <GameObject>(modelAssetPath); var instance = Instantiate(fbx); var ren = instance.GetComponentInChildren <SkinnedMeshRenderer>(); _renderer = ren; //var comp = instance.GetComponentsInChildren<Component>(); instance.transform.position = Vector3.zero; instance.transform.rotation = Quaternion.identity; var animator = instance.GetComponent <Animator>(); Debug.Assert(animator != null); // OK, create the animation var clip = AnimationCreator.CreateFrom(danceData); var anim = instance.AddComponent <Animation>(); anim.AddClip(clip, clip.name); anim.clip = clip; _animation = anim; }
private async UniTask <AnimationGroup> LoadClipsAsync() { if (_asyncLoadInfo != null) { return(await ReturnExistingAsync()); } AsyncLoadInfo <AnimationGroup> info = null; lock (this) { if (_asyncLoadInfo == null) { info = new AsyncLoadInfo <AnimationGroup>(); _asyncLoadInfo = info; } } if (info == null) { return(await ReturnExistingAsync()); } var songResourceName = commonResourceProperties.danceResourceName; if (string.IsNullOrWhiteSpace(songResourceName)) { info.Fail(); throw new FormatException("Song resource name is empty."); } if (placement.motionNumber < MltdSimulationConstants.MinDanceMotion || placement.motionNumber > MltdSimulationConstants.MaxDanceMotion) { info.Fail(); throw new FormatException($"Invalid motion number: {placement.motionNumber}, should be {MltdSimulationConstants.MinDanceMotion} to {MltdSimulationConstants.MaxDanceMotion}."); } if (placement.formationNumber < MltdSimulationConstants.MinDanceFormation || placement.motionNumber > MltdSimulationConstants.MaxDanceFormation) { info.Fail(); throw new FormatException($"Invalid formation number: {placement.motionNumber}, should be {MltdSimulationConstants.MinDanceFormation} to {MltdSimulationConstants.MaxDanceFormation}."); } var danceAssetName = $"dan_{songResourceName}_{placement.motionNumber:00}"; if (!DanceAssetNameRegex.IsMatch(danceAssetName)) { info.Fail(); throw new FormatException($"\"{danceAssetName}\" is not a valid dance asset name."); } var mainDanceBundle = await bundleLoader.LoadFromRelativePathAsync($"{danceAssetName}.imo.unity3d"); AssetBundle appealBundle = null; bool? appealBundleFound = null; AnimationClip mainDance; { var assetPath = $"assets/imas/resources/exclude/imo/dance/{songResourceName}/{danceAssetName}_dan.imo.asset"; var motionData = mainDanceBundle.LoadAsset <CharacterImasMotionAsset>(assetPath); mainDance = await DanceAnimation.CreateAsync(motionData, danceAssetName); } async UniTask <AnimationClip> LoadAppealMotionAsync(string postfix) { var appealAssetName = $"dan_{songResourceName}_{placement.formationNumber:00}"; AnimationClip result; var assetPath = $"assets/imas/resources/exclude/imo/dance/{songResourceName}/{appealAssetName}_{postfix}.imo.asset"; if (mainDanceBundle.Contains(assetPath)) { var motionData = mainDanceBundle.LoadAsset <CharacterImasMotionAsset>(assetPath); result = await DanceAnimation.CreateAsync(motionData, $"{appealAssetName}_{postfix}"); } else { if (appealBundleFound.HasValue) { if (!appealBundleFound.Value) { return(null); } } else { bool found; (appealBundle, found) = await TryLoadExternalAppealBundleAsync(); appealBundleFound = found; } if (appealBundle != null && appealBundle.Contains(assetPath)) { var motionData = appealBundle.LoadAsset <CharacterImasMotionAsset>(assetPath); result = await DanceAnimation.CreateAsync(motionData, $"{appealAssetName}_{postfix}"); } else { result = null; } } return(result); } var specialAppeal = await LoadAppealMotionAsync("apg"); var anotherAppeal = await LoadAppealMotionAsync("apa"); var gorgeousAppeal = await LoadAppealMotionAsync("bpg"); var animationGroup = new AnimationGroup(mainDance, specialAppeal, anotherAppeal, gorgeousAppeal); info.Success(animationGroup); return(animationGroup); }