Esempio n. 1
0
        private async UniTask <AnimationGroup> LoadClipsAsync(CameraControlMode cameraControlMode)
        {
            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.cameraResourceName;

            if (string.IsNullOrWhiteSpace(songResourceName))
            {
                info.Fail();
                throw new FormatException("Song resource name is empty.");
            }

            var camAssetName = $"cam_{songResourceName}";

            var camBundle = await bundleLoader.LoadFromRelativePathAsync($"{camAssetName}.imo.unity3d");

            AnimationClip mainCamera;

            {
                var camAssetPath = $"assets/imas/resources/exclude/imo/camera/{songResourceName}/{camAssetName}_cam.imo.asset";
                var mainCamData  = camBundle.LoadAsset <CharacterImasMotionAsset>(camAssetPath);

                switch (cameraControlMode)
                {
                case CameraControlMode.Direct:
                    mainCamera = CameraAnimation.CreateClipForCamera(mainCamData, camAssetName);
                    break;

                case CameraControlMode.Indirect:
                    mainCamera = CameraAnimation.CreateIndirectClip(mainCamData, camAssetName);
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(cameraControlMode), cameraControlMode, null);
                }
            }

            AnimationClip LoadAppealMotion(string postfix)
            {
                // For portrait variations: ".../{camAssetName}_tate_{postfix}.imo.asset"
                var assetPath = $"assets/imas/resources/exclude/imo/camera/{songResourceName}/{camAssetName}_{postfix}.imo.asset";

                if (!camBundle.Contains(assetPath))
                {
                    return(null);
                }

                var           motionData = camBundle.LoadAsset <CharacterImasMotionAsset>(assetPath);
                AnimationClip result;

                switch (cameraControlMode)
                {
                case CameraControlMode.Direct:
                    result = CameraAnimation.CreateClipForCamera(motionData, $"{camAssetName}_{postfix}");
                    break;

                case CameraControlMode.Indirect:
                    result = CameraAnimation.CreateIndirectClip(motionData, $"{camAssetName}_{postfix}");
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(cameraControlMode), cameraControlMode, null);
                }

                return(result);
            }

            var specialAppeal  = LoadAppealMotion("apg");
            var anotherAppeal  = LoadAppealMotion("apa");
            var gorgeousAppeal = LoadAppealMotion("bpg");

            var group = new AnimationGroup(mainCamera, specialAppeal, anotherAppeal, gorgeousAppeal);

            info.Success(group);

            return(group);
        }
Esempio n. 2
0
        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);
        }