void GenerateObjects()
        {
            if (_prefab == null)
            {
                AltoLog.Warn("Please select generate target object.");
                return;
            }
            if (_parent == _prefab)
            {
                AltoLog.Warn("Parent object and Target object should be different.");
                return;
            }

            int numX = Math.Min(Math.Max((int)_generateNum.x, 1), MaxNum);
            int numY = Math.Min(Math.Max((int)_generateNum.y, 1), MaxNum);
            int numZ = Math.Min(Math.Max((int)_generateNum.z, 1), MaxNum);

            var genInfo = new List <GenerateInfo>();

            for (int z = 0; z < numZ; ++z)
            {
                for (int y = 0; y < numY; ++y)
                {
                    for (int x = 0; x < numX; ++x)
                    {
                        genInfo.Add(MakeGenerateInfo(x, y, z));
                    }
                }
            }

            AltoLog.Info($"Generate { genInfo.Count } objects ...");
            PreprocessGenerateInfo(genInfo);
            DoGenerate(genInfo);
        }
        /// <summary>
        /// from のフィールドの内容をリフレクションで to に反映
        /// </summary>
        public static bool CopyFields(Object from, Object to)
        {
            var fromFields = from.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance).ToList();
            var toFields   = to.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance).ToList();

            if (fromFields.Count == 0)
            {
                AltoLog.Error($"[ObjectUtil] FieldInfo of from-object is null.");
                return(false);
            }
            if (toFields.Count == 0)
            {
                AltoLog.Error($"[ObjectUtil] FieldInfo of to-object is null.");
                return(false);
            }

            foreach (var toField in toFields)
            {
                var fromField = fromFields.Find(field => {
                    return(field.Name == toField.Name &&
                           field.MemberType == toField.MemberType);
                });
                if (fromField == null)
                {
                    AltoLog.Error($"[ObjectUtil] Field not found : {toField.Name}");
                    return(false);
                }

                object fromValue = fromField.GetValue(from);
                toField.SetValue(to, fromValue);
            }
            return(true);
        }
        /// <summary>
        /// from のプロパティの内容をリフレクションで to に反映
        /// </summary>
        public static bool CopyProps(Object from, Object to)
        {
            var fromProps = from.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList();
            var toProps   = to.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList();

            if (fromProps.Count == 0)
            {
                AltoLog.Error($"[ObjectUtil] PropertyInfo of from-object is null.");
                return(false);
            }
            if (toProps.Count == 0)
            {
                AltoLog.Error($"[ObjectUtil] PropertyInfo of to-object is null.");
                return(false);
            }

            foreach (var toProp in toProps)
            {
                var fromProp = fromProps.Find(prop => {
                    return(prop.Name == toProp.Name &&
                           prop.PropertyType == toProp.PropertyType);
                });
                if (fromProp == null)
                {
                    AltoLog.Error($"[ObjectUtil] Property not found : {toProp.Name}");
                    return(false);
                }

                object fromValue = fromProp.GetValue(from, null);
                toProp.SetValue(to, fromValue, null);
            }
            return(true);
        }
예제 #4
0
        //----------------------------------------------------------------------
        // Load (Called by framework)
        //----------------------------------------------------------------------

        /// <summary>
        /// ロードが必要なリソース(参照カウントが 1 以上で未ロードのリソース)をロードする。
        /// ロードは未ロードのものが無くなるまで行われる。
        /// (ロード処理中に新たなリソースが Retain された場合、それもロードしきってから処理が返る)
        /// </summary>
        public async UniTask Load()
        {
            if (_isLoading)
            {
                AltoLog.FW("[ResourceStore] Loading is already running.");
                return;
            }
            _isLoading = true;

            var addresses = _registry.GetAddressesToLoad();

            await LoadMulti(addresses);

            _isLoading = false;

            if (_registry.ShouldLoadAny())
            {
                // ロード中に新たなリソースが Retain されていた場合はそれもロードする
                ++_loadRetryCount;
                if (_loadRetryCount > 99)
                {
                    return;
                }
                await Load();

                --_loadRetryCount;
            }
        }
예제 #5
0
        void OnLoadResource(string assetAddress, UnityEngine.Object resource)
        {
            switch (resource)
            {
            case GameObject gameObj:
                _gameObjs.OnLoad(assetAddress, gameObj);
                break;

            case ScriptableObject scriptableObj:
                _scriptableObjs.OnLoad(assetAddress, scriptableObj);
                break;

            case AudioClip audioClip:
                _audios.OnLoad(assetAddress, audioClip);
                break;

            case SpriteAtlas spriteAtlas:
                _sprites.OnLoad(assetAddress, spriteAtlas);
                break;

            default:
                AltoLog.FW_Warn($"[ResourceStore] Unsupported asset type : {assetAddress} - {resource.GetType()}");
                break;
            }
        }
예제 #6
0
        /// <summary>
        /// TryParse のラップ版。Enum.TryParse() は "123" といった数字文字列が渡されたときに
        /// エラーにならないので、ここでは定義済みの Enum であるかどうかのチェックを含めている
        /// </summary>
        public static bool TryParse <T>(string str, out T result) where T : struct
        {
            bool parsed = Enum.TryParse(str, out result) && Enum.IsDefined(typeof(T), result);

            if (!parsed)
            {
                AltoLog.Error($"[EnumUtil] Parse error : {str}");
            }
            return(parsed);
        }
예제 #7
0
        public T GetObj <T>(string assetAddress) where T : ScriptableObject
        {
            var obj = _scriptableObjs.Get(assetAddress);

            if (!(obj is T))
            {
                AltoLog.FW_Error($"[ResourceStore] ScriptableObject cast error : <{assetAddress}>");
                return(null);
            }
            return((T)obj);
        }
예제 #8
0
        /// <summary>
        /// アセット 1 つをメモリにロード。
        /// ※ 参照カウンタが 1 以上になっていなければロードされない
        /// </summary>
        async UniTask LoadSingle(string assetAddress)
        {
            if (!_registry.IsReferenced(assetAddress))
            {
                return;
            }

            var asyncOpHandle = Addressables.LoadAssetAsync <UnityEngine.Object>(assetAddress);
            var resource      = await asyncOpHandle.Task;

            if (asyncOpHandle.Status != AsyncOperationStatus.Succeeded)
            {
                AltoLog.FW_Error($"[ResourceStore] Load Error : <b>{assetAddress}</b>");
                return;
            }
            _registry.MarkLoaded(assetAddress, resource, asyncOpHandle);
            OnLoadResource(assetAddress, resource);
        }
예제 #9
0
        /// <summary>
        /// "1" や "2" といった数字文字列を Enum の値に変換する。
        /// 空文字列の場合は 0 として扱う
        /// </summary>
        public static T FromNumericString <T>(string str) where T : struct
        {
            if (str == String.Empty)
            {
                return(EnumUtil.FromInt <T>(0));
            }

            try
            {
                T value = (T)Enum.ToObject(typeof(T), int.Parse(str));
                return(value);
            }
            catch (Exception ex)
            {
                AltoLog.Error($"[EnumUtil] Parse error : {str}");
                throw ex;
            }
        }
        /// <summary>
        /// 選択したオブジェクトを、選択したもののうち Hierarchy の index の若い 2 つの座標
        /// を基準にして等間隔に並べる。(選択順が取得できなかったのでこんな仕様)
        /// </summary>
        void ArrangeByFirstTwo()
        {
            var objs = Selection.gameObjects.OrderBy(go => go.transform.GetSiblingIndex()).ToList();

            if (objs.Count <= 2)
            {
                AltoLog.Error("3 つ以上のオブジェクトを選択してください");
                return;
            }

            var     first  = objs[0];
            var     second = objs[1];
            Vector3 diff   = second.transform.position - first.transform.position;

            for (int i = 2; i < objs.Count; ++i)
            {
                Vector3 pos = first.transform.position + (i * diff);
                Undo.RecordObject(objs[i].transform, "ArrangeByFirstTwo");
                objs[i].transform.position = pos;
            }
        }
예제 #11
0
        static void ImportCsv(
            string csvPath, string dataName, string dataPath,
            Func <string, Type> dataTypeGetter
            )
        {
            AltoLog.Info($"Master data csv update detected : { csvPath }");

            string destDataPath = $"{ dataPath }{ dataName }.asset";
            var    data         = AssetDatabase.LoadMainAssetAtPath(destDataPath);

            if (data == null)
            {
                AltoLog.Error($"Master data ScriptableObject not exist : { destDataPath }");
                return;
            }

            var type = dataTypeGetter(dataName);

            if (type == null)
            {
                AltoLog.Error($"Type reflection failed : { dataName }");
                return;
            }
            MethodInfo method = type.GetMethod("Import");

            if (method == null)
            {
                AltoLog.Error($"Method reflection failed");
                return;
            }

            var csvLines = LoadCsvFile(csvPath);

            method.Invoke(data, new object[] { csvLines });

            EditorUtility.SetDirty(data);
            AssetDatabase.SaveAssets();
            AltoLog.Success($"Master data import succeeded : { dataName }");
        }
        //----------------------------------------------------------------------
        // public
        //----------------------------------------------------------------------

        public void Generate()
        {
            if (!Directory.Exists(outputDirPath))
            {
                Directory.CreateDirectory(outputDirPath);
            }

            string outPath = $"{ outputDirPath }/{ outputFileName }";

            AltoLog.FW($"Generate Code : { outPath }");
            using (var fileStream = File.Open(outPath, FileMode.Create, FileAccess.Write))
            {
                using (var streamWriter = new StreamWriter(fileStream))
                {
                    var stringBuilder = new StringBuilder();
                    WriteOuter(stringBuilder);
                    streamWriter.Write(stringBuilder.ToString());
                }
            }

            AssetDatabase.Refresh();
            AltoLog.Success("Generate Code Completed.");
        }
예제 #13
0
 void OnUnloadResource(ResourceRegistry.ResourceEntry entry)
 {
     if (entry.type == typeof(GameObject))
     {
         _gameObjs.OnUnload(entry.address);
     }
     else if (entry.type.IsSubclassOf(typeof(ScriptableObject)))
     {
         _scriptableObjs.OnUnload(entry.address);
     }
     else if (entry.type == typeof(AudioClip))
     {
         _audios.OnUnload(entry.address);
     }
     else if (entry.type == typeof(SpriteAtlas))
     {
         _sprites.OnUnload(entry.address);
     }
     else
     {
         AltoLog.FW_Warn($"[ResourceStore] Unsupported asset type : {entry.address} - {entry.type}");
     }
 }
예제 #14
0
        protected override void WriteInner(StringBuilder builder)
        {
            var addresseSet = new HashSet <string>();
            var assetGroups = EditorFileUtil.LoadAssetGroups(assetDirPath);

            foreach (var group in assetGroups)
            {
                // Ignore Built-in resources
                if (group.ReadOnly)
                {
                    continue;
                }

                foreach (var entry in group.entries)
                {
                    bool isNew = addresseSet.Add(entry.address);
                    if (!isNew)
                    {
                        AltoLog.FW_Warn($"Duplicated address found : { entry.address }");
                    }
                }
            }
            AppendSymbols(builder, addresseSet);
        }
 void OnSceneLoading()
 {
     AltoLog.FW("[ResourceHub] Unload scene-scoped resources no longer needed.");
     sceneScopeResourceStore.Unload();
 }
 public async UniTask GoToNextScene(string nextSceneName, float fadeOutTime = 0.3f, float fadeInTime = 0.3f)
 {
     AltoLog.FW("[SceneDirector] * No scene context is given.");
     await LoadSceneWithFade(null, nextSceneName, false, fadeOutTime, fadeInTime);
 }
 public async UniTask GoToNextSceneWithCustomTransition(ISceneContext nextSceneContext)
 {
     AltoLog.FW($"[SceneDirector] Load scene with scene context : <b>{nextSceneContext}</b>");
     await LoadSceneWithFade(nextSceneContext, nextSceneContext.SceneName(), true);
 }
 public async UniTask GoToNextSceneWithCustomTransition(string nextSceneName)
 {
     AltoLog.FW("[SceneDirector] * No scene context is given.");
     await LoadSceneWithFade(null, nextSceneName, true);
 }
        //----------------------------------------------------------------------
        // private
        //----------------------------------------------------------------------

        async UniTask LoadSceneWithFade(
            ISceneContext nextSceneContext,
            string nextSceneName,
            bool useCustomTransition,
            float fadeOutTime = 0.3f,
            float fadeInTime  = 0.3f
            )
        {
            if (isInTransition)
            {
                AltoLog.FW_Warn($"[SceneDirector] Now in transition - {nextSceneName} is dismissed.");
                return;
            }
            isInTransition = true;

            //----- 暗転と後片付け
            if (useCustomTransition && currentSceneContext != null)
            {
                await currentSceneContext.CustomFadeOut();
            }
            else
            {
                await _screenFader.FadeOut(fadeOutTime);
            }
            sceneLoading?.Invoke();

            DestroyAllObjectsInScene();
            if (currentSceneContext != null)
            {
                await currentSceneContext.Finalize();

                currentSceneContext.CancelTokenSource.Cancel();
            }
            SetIsSceneReady(false);
            currentSceneContext = nextSceneContext;

            // 次のシーンに必要なリソースをロード、不要なものはアンロード
            await LoadAndUnloadResources(nextSceneContext);

            //----- 次のシーンの読み込み
            AltoLog.FW("[SceneDirector] - Init <b>Before</b> Load Scene");
            if (nextSceneContext != null)
            {
                await nextSceneContext.InitBeforeLoadScene();
            }

            await SceneManager.LoadSceneAsync(nextSceneName);

            DisableLocalAudioListener();

            AltoLog.FW("[SceneDirector] - Init <b>After</b> Load Scene");
            if (currentSceneContext != null)
            {
                await currentSceneContext.InitAfterLoadScene();
            }
            SetIsSceneReady(true);

            sceneLoaded?.Invoke();

            // シーンの 1 フレーム目は重くなるので 1 フレーム待ってからフェードイン
            await UniTask.DelayFrame(1);

            if (useCustomTransition && currentSceneContext != null)
            {
                await currentSceneContext.CustomFadeIn();
            }
            else
            {
                await _screenFader.FadeIn(fadeInTime);
            }

            isInTransition = false;
            currentSceneContext?.OnStartupScene();
        }
 public async UniTask GoToNextScene(ISceneContext nextSceneContext, float fadeOutTime = 0.3f, float fadeInTime = 0.3f)
 {
     AltoLog.FW($"[SceneDirector] Load scene with scene context : <b>{nextSceneContext}</b>");
     await LoadSceneWithFade(nextSceneContext, nextSceneContext.SceneName(), false, fadeOutTime, fadeInTime);
 }