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); }
//---------------------------------------------------------------------- // 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; } }
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; } }
/// <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); }
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); }
/// <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); }
/// <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; } }
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."); }
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}"); } }
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); }