ãUnityãReflectionã使ã£ãæ å ±åéã軽éåããã¢ã¤ãã¢
ã©ã¤ãã©ãªãéçºãã¦ããä¸ã§ãæ¸ãå¿å°ãæ
ä¿ããããã«Reflectionã使ç¨ãããå ´é¢ãåºã¦ãã¾ãã
ä¾ãã°ç¹å®ã®ãã¼ãæ¼ãããæã«æå®ããé¢æ°ãå®è¡ããããããªã·ã§ã¼ãã«ãããã¼ã®ä»çµã¿ãå®è£
ããå ´åãAttributeã§ã·ã§ã¼ãã«ããã¢ã¯ã·ã§ã³ãæå®åºæ¥ãããã«ãªã£ã¦ããã¨ä¾¿å©ã§ãã
[Shortcut("ãã¡ã¤ã«ä¿å", KeyCode.LeftControl, KeyCode.S)] static void OnSave() { // ä¿åå¦ç }
ãã®ãããªä½ãã«ãããã¨ããå ´åãã©ã¤ãã©ãªã®åæåå¦çã§ä»¥ä¸ã®ãããªã³ã¼ããæ¸ãã¦ã·ã§ã¼ãã«ããã¢ã¯ã·ã§ã³ãåéãããã¨ã«ãªãã¾ãã
void CollectShortcutActions() { // ã¢ããªå ã®å ¨ã¦ã®ã¢ã»ã³ããªãåå¾ foreach(var assembly in System.AppDomain.CurrentDomain.GetAssemblies()) { // ãã¹ã¦ã®åãåå¾ foreach(var type in assembly.GetTypes()) { // åã®ä¸ããprivate static, public staticé¢æ°ãåå¾ foreach(var method in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) { // [Shortcut]ãæå®ããã¦ããããå¤å® var attr = method.GetCustomAttributes<ShortcutAttribute>(); if (attr == null) continue; // ã·ã§ã¼ãã«ããã¢ã¯ã·ã§ã³ã®ç»é²å¦ç } } } }
è¦ãããã«éããã§ããã
Reflectionã使ã£ãå¦çã¯ãã¡ãããªã¼ãã¼ãããã®é«ããã®ã§ãããã¢ããªå
ã®å
¨ã¦ã®Assemblyã«å¯¾ãã¦å¦çãè¡ã£ã¦ãããããUnityã¨ã³ã¸ã³ã®æã¤ã¯ã©ã¹ç¾¤ããã®Attributeã使ã£ã¦ããªãAssemblyã«å¯¾ãã¦ãæ¤ç´¢å¦çãè¡ãããããªãã®å¦çæéãããã£ã¦ãã¾ã£ã¦ãã¾ãã
ä»åã¯ãã®å¦çããªãã¹ã軽ãããããã®ã¢ã¤ãã¢ãå
±æãã¾ãã
Attributeã®Assemblyãåãã
ã¾ãåãã«ãåéãããAttributeã¯ã©ã¹ãå¥Assemblyã¸åãåãã¾ãã
Unityã«ã¯Assembly Definition Assetã¨ããä»çµã¿ããããæå®ãããã©ã«ã以ä¸ã®ã³ã¼ããå¥ã®Assemblyã¸åãåãããã¨ãã§ãã¾ãã
Assembly Definition Assetã«ã¤ãã¦ã¯ãå
¬å¼ããã¥ã¢ã«ããã¡ãã®ãã¼ã¸ãåç
§ãã¦ãã ããã
対象ã®AssemblyããAttributeã®Assemblyã«ä¾åãã¦ãããã©ããããã§ãã¯ãã
å½ç¶ã§ãããAttributeã使ç¨ãã¦ããã¯ã©ã¹ãå«ã¾ããAssemblyã¯ãAttributeãå®ç¾©ãããAssemblyãåç
§ãã¦ãã¾ãã
ä¾ãã°ShortcutAttributeãåéãããã¨èããã¨ãã¯ãShortcutAttributeãå®ç¾©ããAssemblyãåç
§ãã¦ãããã®ã ããæ¤ç´¢ããã°ãããã¨ã«ãªãã¾ãã
C#ã§ã¯ãAssemblyãã©ã®Assemblyãåç
§ãã¦ããããåå¾ããAPIãç¨æããã¦ãã¾ãã
ããã使ã£ã¦ãã·ã§ã¼ãã«ããã¢ã¯ã·ã§ã³ã®åéå¦çã以ä¸ã®ããã«æ¸ãæãã¾ãã
void CollectShortcutActions() { foreach(var method in GetAllMethodWithAttribute<ShortcutAttribute>()) { // ã·ã§ã¼ãã«ããã¢ã¯ã·ã§ã³ã®ç»é²å¦ç } } IEnumerator<MethodInfo> GetAllMethodWithAttribute<T>() where T : System.Attribute { var targetAssemblyName = typeof(T).Assembly.GetName().FullName; foreach (var assembly in System.AppDomain.CurrentDomain.GetAssemblies()) { var referencedAssemblies = assembly.GetReferencedAssemblies(); var isTarget = assembly.GetName().FullName == targetAssemblyName; if (!isTarget) { for (int i = 0; i < referencedAssemblies.Length; i++) { var assemblyInfo = referencedAssemblies[i]; if (assemblyInfo.FullName == targetAssemblyName) { isTarget = true; break; } } } if (!isTarget) continue; foreach (var type in assembly.GetTypes()) { foreach (var method in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) { var attr = method.GetCustomAttributes<T>(); if (attr == null) continue; yield return method; } } } }
ããã§ãUnityã¨ã³ã¸ã³ã®ã¯ã©ã¹ç¾¤ãé¢ä¿ã®ãªãAssemblyã¸ã®æ¤ç´¢ãç¡ããªã£ããã¨ã«ãããå®è¡é度ãå¤§å¹ ã«æ¹åãã¾ãã
ãUnityãuGUI Imageã§Alpha Maskã使ããããã«å®è£ ããæ¹æ³
ã¯ããã«
ãã®è¨äºã¯ãå
æ¥å
¬éãã以ä¸ã®ãªãã¸ããªã®æè¡è§£èª¬ã§ãã
使ã£ã¦ã¿ããã¨ããæ¹ã¯ããã²ä½¿ã£ã¦ã¿ã¦ãã ããã
github.com
æ¦è¦
Unity uGUIã§Mask表ç¾ãè¡ãå ´åãæ¨æºã§å®è£
ããã¦ããMaskã³ã³ãã¼ãã³ãã使ç¨ããã¨ãå¢çã«ã²ã©ãã¸ã£ã®ã¼ãã§ããã¨ãããã¾ãã
Unityæ¨æºã®Maskã³ã³ãã¼ãã³ãã¯ã¹ãã³ã·ã«ã§ã¯ãªãããè¡ããããæãã®ã©ã¤ã³ã«ã¨ã¤ãªã¢ã¹ãåºã¦ãã¾ããã¨ãåå ã§ãã
Maskç»åã«ã¢ã«ãã¡å¤ãä»è¾¼ãã§ããã¹ãã³ã·ã«ã«æ¸ãè¾¼ã¾ããéã«æã or æããªãã®2å¤æ
å ±ã«ãªã£ã¦ãã¾ãããã§ãã
é«è§£å度ã®ç°å¢ã§ããã°ãã¾ãåé¡ã«ãªããªãã®ã§ãããä½è§£å度ç°å¢ã§ãã£ãããã¢ãã¤ã«ã®ããã«ããã©ã¼ãã³ã¹ä¸ã®åé¡ã§è§£å度ãä¸ããå ´åã«åé¡ã表é¢åãã¾ãã
ãã¹ã¯ã®ã¢ã«ãã¡å¤ã«ãã£ã¦ããã¹ã¯å¯¾è±¡ã®ã¢ã«ãã¡å¤ãæä½ãããã¨ãã§ããã°ããã¹ã¯ç»åã®å¢çã«ã¢ã«ãã¡ãã§ã¼ããããããã¨ã§ãã®ã¸ã£ã®ã¼ãç®ç«ããªãããã«ãããã¨ãã§ãããã§ãã
å®è£ ä¸ã®ãã¼ãã«
å®ç¾ããããã¨ã¯ãuGUI-Maskã¨åãã¤ã³ã¿ã¼ãã§ã¼ã¹ã§Alpha Maskãå®ç¾ããããã§ãã
ãããããããçµæ§é¢åèãã
ãã¹ã¯ã¨ãã¹ã¯å¯¾è±¡ã1対1ã®é¢ä¿ã§ã座æ¨ã絶対ã«åããªãã®ã§ããã°ã·ã§ã¼ãã¼ã§æ¥½ã«å®è£
ã§ãã¾ããã1対å¤ã®é¢ä¿ã«å ãã¦ãã¹ã¯ããã¹ã¯å¯¾è±¡ãèªç±ã«åãã¨ãªãã¨é端ã«é£ãããªãã¾ããä¾ãã°ä¸å³ã®ãããªå ´åã§ãã
ãã®å ´åãæ±ããåä½ã¯ã赤丸ã¨ãã¹ã¯ã®ç½ãé¨åã被ã£ã¦ãããã¯ã»ã«ã ããç»é¢ã«è¡¨ç¤ºããã(é»è²ã丸ã¯è¡¨ç¤ºãããªã)ãã¨ãªãã¾ãã
èãæ¹
ãã¹ã¯å¯¾è±¡ã®é ç¹ãæç»ããéã«ããã®é ç¹ä½ç½®ã®ãã¹ã¯UVãæ±ãããã¨ãã§ããã°ãUI/Defaultãæ¹é ãã以ä¸ã®ãããªã·ã§ã¼ãã¼ã§Alpha Maskãå®ç¾ã§ãããã§ãã
ã¤ã¾ããä½ããã®æ¹æ³ã§ãã¹ã¯å¯¾è±¡ã®é ç¹åº§æ¨ãããã¹ã¯ã®UV座æ¨ã«å¤æãã¦ããå¿
è¦ãããã¾ãã
å®è£ æ¹æ³
ç»é¢å ã®ãã¹ã¯ã®ã¿ãæ ãVPè¡åãä½ã*1
uGUI-Imageã®ããªã´ã³ã¯å¿
ãåè§å½¢ãªã®ã§ããã®åè§å½¢ãã¹ã¯ãªã¼ã³ã¨è¦ç«ã¦ãVPè¡åãä½æã§ããã°ãé ç¹åº§æ¨ããç¹å®ããªã´ã³ã®UVãæ±ãããã¨ãã§ãã¾ãã
ãã¹ã¯ã®Imageã³ã³ãã¼ãã³ãã§ã¿ã¤ãªã³ã°ãã¹ã©ã¤ã¹ã¯ä½¿ããªããªãã¾ããã諦ãããã¨ã«ãã¾ãã
Unityã§ã¯ãMatrix4x4.Orthoé¢æ°ã使ã£ã¦ãOrthograohicãªããã¸ã§ã¯ã·ã§ã³è¡åãçæãããã¨ãã§ãã¾ãã
docs.unity3d.com
ãã®é¢æ°ã®å¼æ°ã«æ¸¡ãleftãªã©ã¯ã以ä¸ã®åº§æ¨ç³»ã§ã®å¤ã§ãã*2
ãã®åº§æ¨ç³»ã§ããã¹ã¯ã®uGUI-Imageã®ç©å½¢ãå®ç¾©ãã¾ãã
å
·ä½çã«ã¯uGUI-Imageã®4è§ã®ã¯ã¼ã«ã座æ¨ãåå¾ãã¦ã¹ã¯ãªã¼ã³åº§æ¨ã«å¤æããå¾ãæ£è¦åãã¦camera.orthographicSizeã®åº§æ¨ç³»ã«å¤æãã¾ãã
ããã¾ã§ã§ããã°å¾ã¯ç°¡åã§ãVPè¡åãçæãã¦ãããªã¢ã«ã«SetMatrixãã¦ããã°CPUå´ã®å¦çã¯å®äºã§ãã
TRSè¡åãããã¦ããã®ã¯ã-1ã1ã®ç¯å²ã§åå¾ããå¤ã0ã1ã®ç¯å²ã«å¤æããããã§ãã
対å¿ããé ç¹ã·ã§ã¼ãã¼ã§ãå
ã»ã©ä½æããVPè¡åããUV座æ¨ãè¨ç®ããå¦çã¯ä»¥ä¸ã§ãã
çµæ
ããã§ãuGUI-Imageã§Alpha Maskã使ããããã«ãªãã¾ããã
Unityæ¨æºã®MaskããããAlpha Maskã®æ¹ãå¢çç·ã綺éºã§ãã
ãUnityãInspectorã§ç®¡çã§ããæ±ç¨ã¢ã»ããã¤ã³ãã¼ã¿ã¼ãå ¬éãã¾ãã
ä»äºã§æå±ãã¦ããããã¸ã§ã¯ããä½³å¢ã«å
¥ãã¾ãã¦ããã¯ã¹ãã£ã®æé©åãªã©ãã¢ã¼ãã£ã¹ãããã¨å
±åã§é²ãã¦ããã¾ãã
ãã®ä¸ã§ããã®éå§ç¸®ãã¯ã¹ãã£ãå§ç¸®ã«å¤ãããã®ã«å¤ãããªãï¼ãããã¯ã¹ãã£ã®maxSizeã512ã«ãããã®ã«ã§ããªãï¼ãã¨ãããããªå«ã³å£°ãããèãããããã§ããAssetPostProcessorã®ããã§ãããã¯ãã
éçºåæãä¸æã§ããã°ã²ã¼ã ãä½ãã ããªã®ã§æ¾ãè¾¼ãã°ãããªãã«åãã¤ã³ãã¼ã¿ã¼ã§ãåé¡ãªãã®ã§ãããä½³å¢ã«å
¥ãã¨ããã©ã¼ãã³ã¹å¯¾çã®ããã«ç´°ããè¨å®ããããªãã¾ãã
ãã£ã¨æ¬²ãããã°ãã¢ã¼ãã£ã¹ãããå´ã«ã¤ã³ãã¼ã¿ã¼ã®è¨å®ç®¡çã¾ã§ãé¡ããããã»ã»ã»ã¨ããããã§ãGUIã§è¨å®ã§ããæ±ç¨ã®ã¢ã»ããã¤ã³ãã¼ã¿ã¼ãä½ã£ã¦å
¬éãã¾ããã
ä½ã£ãçµç·¯
ããããAssetPostProcessorã£ã¦ã¢ã¼ãã£ã¹ãããã«åªãããªãããï¼ã¨å¸¸ã
æã£ã¦ããã¾ãããããã°ã©ã ãèªã¾ãªãã¨ä½ãã¦ãããããããªãããã©ã®ãã©ã«ãã«å¹ãã¦ããã®ããããããªãã
Artããã®ãã¡ã¤ã«ã®è¨å®ãå¤ãããªãã¦ã»ã»ã»ã
Engãããããã®ãã©ã«ã以ä¸ã¯ã¤ã³ãã¼ã¿ã¼ãè¨å®ãã¦ãããã»ã»ã»ã
Artããããªãã§ãããã§ã¯ãã®ãã©ã«ãã ãé¤å¤ãã¦ãã ããã
ã¨ãéå¹çãã®ä¸ãªãã¨æãã¾ãã
Unity-Asset-Importer-Extension
ãã®ã¢ã»ããã¯ããã©ã«ãã®ã¤ã³ã¹ãã¯ã¿ã¼ããã¢ã»ããã®ã¤ã³ãã¼ãè¨å®ãè¡ãã¾ãã
親ãã©ã«ãã®è¨å®ãåãã©ã«ããå¼ãç¶ãããã親ãã©ã«ãå´ã§å¤§ã¾ããªè¨å®ï¼ä¾ï¼UI-Textureãã©ã«ã以ä¸ã®ãã¯ã¹ãã£ã¯ãã¹ã¦Spriteã«ããçï¼ãè¡ããåãã©ã«ãå´ã§ç´°ããè¨å®ï¼ä¾ï¼å§ç¸®ããããmipmapä½ããçï¼ãè¡ããã¨ãã§ãã¾ãã
ãã¡ããã親ãã©ã«ãã®è¨å®ãåãã©ã«ãã§ç¡å¹åãããã¨ãå¯è½ã§ããç¡å¹åããå ´åã¯ãç¡å¹åããåãã©ã«ã以ä¸ã®ãã©ã«ãã«ã¯é©ç¨ãããªããªãã¾ãã
ããã©ã«ãã§ãUnity2017.1f1ã§å®ç¾©ããã¦ããAssetImporterã«è¨å®ãæµãè¾¼ãä»çµã¿ãæä¾ãã¦ãã¾ãã
DefaultTextureImporterãªã©ãããã§ãã
ãããã®ããã©ã«ãã¤ã³ãã¼ã¿ã¼ã¯èªåçæãã¦ãããçæãããã¼ã«ãå梱ãã¦ããã®ã§ãUnityã®ãã¼ã¸ã§ã³ãåããªã人ã¯READMEã«æ¸ããæé ã§åºåãç´ãã¦ããããã°ã¨æãã¾ãã
ãã¡ããæ©è½
ãã®ã¢ã»ããã®ãã¡ããã¯ãç¬èªã®ã¤ã³ãã¼ã¿ã¼ãGUIã§è¨å®ã§ããããã«ãªããã¨ã§ãã
public class CustomTextureImporter : IAssetImporterExtension { private bool isHogeFiag; public System.Type GetTargetImporterType() { return typeof(TextureImporter); } public void Apply (AssetImporter originalImporter, string assetPath, Property[] properties) { bool hogeFlag = properties.Where(o => o.name == "isHogeFlag").Select(o=>bool.Parse(o.value)).First(); // hogeFlagã使ã£ãå¦ç } }
ã®ãããªã¯ã©ã¹ãå®ç¾©ããã°ããã©ã«ãã®ã¤ã³ã¹ãã¯ã¿ã¼ããã¤ã³ãã¼ã¿ã¼ã®é©ç¨ã»isHogeFlagã®è¨å®ãè¡ããããã«ãªãã¾ãã
ç¾ç¶ã ã¨AssetPostProcessorã®OnPreprocessãã«ãã対å¿ãã¦ããªãã®ã§ãããOnPostprocessãã«ã対å¿ããã°ã¢ã»ããã³ãã¼ãAssetBundleNameã®èªåè¨å®ãªããããã®ã¢ã»ããã§å®è£
ã§ããããã«ãªãã¾ãã
-
-
- è¿½è¨ ---
-
ç°¡åã«å¯¾å¿ã§ãããã ã£ããã§OnPostprocess対å¿ãã¾ããã
OnPostprocessAllAssetsã®ã¿ã¤ãã³ã°ã§ãIAssetImporterExtension.OnPostprocessã¨OnRemoveprocessãã¢ã»ãããã¨ã«å¼ã³åºãã¾ãã
ãµã³ãã«ã¨ãã¦ãCustomImporter/以ä¸ã«CopyAssetImporterãå®è£
ãã¦ãã¾ãã
ããã§ããã¯ã¹ãã£ãç¹å®ãã©ã«ãã«å
¥ããã°ãµã¤ãºã®éããã¯ã¹ãã£ãèªåçæã¨ãã§ããããã«ãªãã¾ããã
æå¾ã«
ä½ã£ãã°ãããªã®ã§ã¾ã 使ãã«ããã¨ãããªã©ããã¨ã¯æãã¾ããã使ã£ã¦ã¿ã¦ãã£ã¼ãããã¯ããissueããããã ããã¨å¤§å¤å±ã¿ã«ãªãã¾ãã
ã¹ãã·ã£ã«ãµã³ã¯ã¹
é ã«ã.ããã¤ãããã¡ã¤ã«ã¯Unityãã¤ã³ãã¼ãããªãããã¤ã³ãã¼ãé ã«æ©ã¾ãªãã¦æ¸ãã¨ããXMLã§ã·ãªã¢ã©ã¤ãºããã¨Unityãã¼ã¸ã§ã³èããªãã¦è¯ããããã¼ã¿ããªãã£é«ãããã¨ãããã¼ã¹é¨åã®è¨è¨ã¯ç§ã®å¸«å ã®æ¸ããã³ã¼ãããå¼ç¶ãã¾ããã大å¤åå¼·ã«ãªãã¾ããã
ãUnityãiPhoneX対å¿ã®ç½ ããªããCanvasã®Anchorããããåé¡ã®è§£æ±ºç
æ¦è¦
é
ãã°ããªãããä»éçºä¸ã®æ°ä½ã²ã¼ã ã§iPhoneX対å¿ãè¡ããã¨ã«ãªãã¾ããã
ããããæ¤ç´¢ããã¨ããããªæ
å ±ã溢ãã¦ãã¾ãããã¾ãã¯å
¬å¼æ
å ±ãã»ã»ã»ã¨ãããã¨ã§Unityå
¬å¼ã®ãµã³ãã«ãå
ã«å¯¾å¿ãé²ããçµæãè¦äºã«å°é·ãè¸ãã ã®ã§å
±æãã¦ããã¾ãã
Unityå ¬å¼æ å ±
iPhoneXã®ç»é¢åé¡ã¯æ¥ççã«ãããªãè¿·æãªãã®ã§ããã
Unityããã¡æ©ããã®åé¡ã«åãåããããããªãªã¼ã¹ãçµã¦æ£å¼ã«SafeAreaã«å¯¾å¿ãã¦ãã¾ãã
helpdesk.unity3d.co.jp
Unity - Scripting API: Screen.safeArea
ä¸ã¤ç®ã®ãªã³ã¯ããUnityã®ãµã³ãã«ãã¿ããã¨ãã§ãã¾ãã
ãã®ãµã³ãã«ã®å
容ã¯ãè¦ç´ããã¨ä»¥ä¸ã®éãã§ãã
void ApplySafeArea()
{
var area = Screen.safeArea;
var anchorMin = area.position;
var anchorMax = area.position + area.size;
anchorMin.x /= Screen.width;
anchorMin.y /= Screen.height;
anchorMax.x /= Screen.width;
anchorMax.y /= Screen.height;
panel.anchorMin = anchorMin;
panel.anchorMax = anchorMax;
}
ãµã³ãã«ã®ç½
ä¸è¨ã®ãµã³ãã«ã§ãããç¹å®ã®ç¶æ³ä¸ã§ä¸å
·åãå¼ãèµ·ããã¾ãã
ç§ãééããä¸å
·åã¯ã以ä¸ã®ãããªãã®ã§ãã
- Canvasã®Anchorãå³ä¸ã«ããã
- ä¸é¨ã®UIãææ» ãç¹°ãè¿ãããã«ãªã
åå
ä¸è¨ã«æ¸ããä¸å
·åã¯ãScreen.SetResolutionã§ç»é¢è§£å度ãå¤æ´ãã¦ããå ´åã«çºçãã¾ãã
åå ã¯ãanchorMin/anchorMaxã®åè¦ç´ ãScreen.width/heightã§æ£è¦åãã¦ããé¨åã§ãã
Screen.width/heightã¯ãSetResolution以éã¯æå®ãã解å度ãè¿ãããã«ãªãã¾ãã
ããããScreen.safeAreaã§è¿ãããå¤ã¯ãã£ã¹ãã¬ã¤ã®è§£å度ã®ãããæ£è¦åã®è¨ç®ãçããCanvasã®Anchorãå³ä¸ã«ããã¦ãã¾ãããã§ãã
対å¿
ããã¤ã¹ã®ãã£ã¹ãã¬ã¤è§£å度ãDisplayã¯ã©ã¹ããåå¾ãããã®å¤ã§æ£è¦åãããã¨ã§åé¡ã解決ãããã¨ãã§ãã¾ãã
void ApplySafeArea() { var area = Screen.safeArea; var display = Display.displays[0]; var screenSize = new Vector2Int(display.systemWidth, display.systemHeght); var anchorMin = area.position; var anchorMax = area.position + area.size; anchorMin.x /= screenSize.x; anchorMin.y /= screenSize.y; anchorMax.x /= screenSize.x; anchorMax.y /= screenSize.y; panel.anchorMin = anchorMin; panel.anchorMax = anchorMax; }
ãUnityãã«ã¡ã©ï¼ã¤ã§UI解å度ãç¶æãã3D解å度ã ããä¸ããæ¹æ³
æããã¢ãã¤ã«ç«¯æ«ã®è§£å度ã¯çæ°ã®æ²æ±°ã¨ããè¨ããããã®å°ããªé¢ç©ã«ãã«HDã¨ãã®ãã£ã¹ãã¬ã¤ãç©ãã§ãã¾ãã
æ®ã£ãåçã綺éºã«è¦ããªãè¯ãã®ããããã¾ãããã1ãã¬ã¼ã 16msã¨ã33msã§æç»ããªãã¨ãããªãã²ã¼ã ã§ã¯ããªãè¾ããã®ãããã¾ãã
æ£ç´ãAndroidã®è§£å度åæ¦ããªããã°ããã£ã¨ã·ã§ã¼ãã¼ãªãããªã²ã¼ã ãä¸ã®ä¸ã«æº¢ãã¦ããã¨æãããã§ãã
ã¨ã¯ããä¸ã®æµãã§ãã®ã§ãæã
ã¨ã³ã¸ãã¢ã¯å·¥å¤«ãåããã¦ãããªãããªè¦ãç®ãåºããããæ¥ã
éé²ããããã§ããã¾ãã
ä¸è¨ãè¸ã¾ãã¦è¨ããããã¨ã¯ã
ã²ã¼ã ã®è§£å度è½ã¨ãã¦ãè¯ãããï¼
ã¨ãããã¨ã§ãã
ããããUI解å度ã720pã¾ã§è½ã¨ãã¦ãã¾ãã¨é端ã«ã¦ã¼ã¶ã¼ã«ãã¬ã¦ãã¾ãã¾ãã
UIã¯çµæ§è§£å度ã®å£åãç®ç«ã¤ãã§ãããã
ãããã3D空éå´ã®è§£å度ãè½ã¨ãã¦ãã»ã¨ãã©ç®ç«ããããã£ã«ã¬ã¼ãã稼ãã¦ç¾å³ããã®ã§ãã
ç§ã®å°æ¬ããã¨ã³ã¸ãã¢ã®ï¼äººãUnityã®å®åãããUnity 2017 Tokyoã§åããã¨ããã£ããã£ã¦ãã¾ãã
ãUnite 2017 Tokyoãã¹ãã¼ããã©ã³ã§ã©ãã¾ã§ã§ããï¼3Dã²ã¼ã ãããããåãããã¯ããã¯è¬åº§
3Då´ã®è§£å度ã ããä¸ãã
ãã¦ããã£ã¨æ¬é¡ã§ãã
ãããããã¨ã¯ããUI解å度ã¯é«ããã3D解å度ã¯ä½ããã¬ã³ããªã³ã°ã§ãã
ç°¡åã«è¨ãã¨3Dæç»ãèªåã§ç¨æããRenderTextureã«æç»ãã¦ã3Dæç»ãçµãã£ããBack Bufferã«Blitããã°è¯ããã¨ã«ãªãã¾ãã
Googleå
çã«èãã¦ã¿ãã¨ã以ä¸ã®ãããªè¨äºãããããã¾ããã
wordpress.notargs.com
ãã®è¨äºã®ä¸ã§ã¯ãBack Bufferã«Blitããç¨ã®ã«ã¡ã©ãç¨æãã¦ããã®ã«ã¡ã©ã«CommandBufferãAddãããã¨ã§RenderTextureãBackBufferã«æ¸ãè¾¼ãã§ãã¾ãã
ããã¯ãåä¸ã«ã¡ã©ã§ã®CommandBufferã§ã¯AfterImageEffects, AfterEveryThingã§ã®SetRenderTargetã§Back Bufferãæå®åºæ¥ãªãããã ã¨èªèãã¦ãã¾ãããäºå®ç§ããã®è¨äºãåèã«ãããã試ããã®ã§ã§ããæå®åºæ¥ãã以åã®è¨äºã§ã¯ãã®æ¹å¼ã§å®è£
ãã¦ãã¾ãã
appleorbit.hatenablog.com
ãããããããã§ãï¼
æ¬å½ã«å¶ç¶ã§ã¯ããã®ã§ããã以ä¸ã®è¨äºãã¿ã¤ãã¾ããã
Unity 5: AfterImageEffects and AfterEverything Traps – Updated My Journal.
å ¨CameraEventå ±éã§ãSetRenderTarget( -1 )ã¨æå®ããã¨Back Bufferãã»ãããããï¼RenderTargetIdentifer( int nameID )ã§ãããªã£ã¦ããï¼ï¼
æ¬å½ã«ãã®ããã°ã®èè
æ§ã«ã¯æè¬ã®å¿µããããã¾ããã
ã¨ããããã§ãæ¸ãã¦ã¿ã¾ããã
以ä¸ã®ã³ã¼ãã§ã3D解å度ã ãã1ã¤ã®ã«ã¡ã©ã§ä¸ãããã¨ãã§ãã¾ãã
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; /// <summary> /// 解å度ãå¤æ´ããã³ã³ãã¼ãã³ã /// </summary> [RequireComponent(typeof(Camera))] public class ResolutionConverter : MonoBehaviour { /// <summary> /// 解å度 /// </summary> public enum Resolution { None, HD, FULLHD } /// <summary> /// 解å度è¨å® /// </summary> [SerializeField] private Resolution m_Resolution = Resolution.None; /// <summary> /// ã¿ã¼ã²ããã«ã¡ã© /// </summary> private Camera m_Camera; /// <summary> /// ãã¬ã¼ã ãããã¡ /// </summary> private RenderTexture m_FrameBuffer; /// <summary> /// ã³ãã³ããããã¡ /// </summary> private CommandBuffer m_CommandBuffer; /// <summary> /// åæå /// </summary> private void Awake() { m_Camera = GetComponent<Camera> (); Apply (m_Resolution); } /// <summary> /// é©ç¨ãã /// </summary> public void Apply(Resolution resolution) { m_Resolution = resolution; if (resolution == Resolution.None) { return; } var size = GetResolutionSize (resolution); size = FitScreenAspect (Screen.width, Screen.height, size.x, size.y); UpdateFrameBuffer (size.x, size.y, 24); UpdateCameraTarget (); AddCommand (); } /// <summary> /// ãã¬ã¼ã ãããã¡ã®æ´æ° /// </summary> private void UpdateFrameBuffer(int width, int height, int depth, RenderTextureFormat format = RenderTextureFormat.Default) { if (m_FrameBuffer != null) { m_FrameBuffer.Release (); Destroy (m_FrameBuffer); } m_FrameBuffer = new RenderTexture (width, height, depth, format); m_FrameBuffer.useMipMap = false; m_FrameBuffer.Create (); } /// <summary> /// ã«ã¡ã©ã®æç»å ãæ´æ° /// </summary> private void UpdateCameraTarget() { if (m_FrameBuffer != null) { m_Camera.SetTargetBuffers (m_FrameBuffer.colorBuffer, m_FrameBuffer.depthBuffer); } else { m_Camera.SetTargetBuffers (Display.main.colorBuffer, Display.main.depthBuffer); } } /// <summary> /// 解å度ã®å®ãµã¤ãºãåå¾ /// </summary> private Vector2Int GetResolutionSize(Resolution resolution) { bool isPortrait = Screen.height > Screen.width; switch(resolution){ case Resolution.HD: if (isPortrait) { return new Vector2Int (720, 1280); } return new Vector2Int (1280, 720); case Resolution.FULLHD: if (isPortrait) { return new Vector2Int (1080, 1920); } return new Vector2Int (1920, 1080); } return new Vector2Int (Screen.width, Screen.height); } /// <summary> /// 解å度ã®è¨ç® /// </summary> private static Vector2Int FitScreenAspect(int width, int height, int maxWidth, int maxHeight) { // 解å度以ä¸ãªãä½ãããªã if (width <= maxWidth && height <= maxHeight) { return new Vector2Int (width, height); } if (width > height) { float aspect = height / (float)width; int w = Mathf.Min (width, maxWidth); int h = Mathf.RoundToInt (w * aspect); return new Vector2Int (w, h); } { float aspect = width / (float)height; int h = Mathf.Min (height, maxHeight); int w = Mathf.RoundToInt (height * aspect); return new Vector2Int (w, h); } } /// <summary> /// ã³ãã³ãã追å ãã /// </summary> private void AddCommand() { RemoveCommand (); // ã«ã©ã¼ãããã¡ãããã¯ãããã¡(ç»é¢)ã«æãããã³ãã³ã { m_CommandBuffer = new CommandBuffer (); m_CommandBuffer.name = "blit to Back buffer"; m_CommandBuffer.SetRenderTarget (-1); m_CommandBuffer.Blit (m_FrameBuffer, BuiltinRenderTextureType.CurrentActive); m_Camera.AddCommandBuffer (CameraEvent.AfterEverything, m_CommandBuffer); } } /// <summary> /// ã³ãã³ããç ´æ£ãã /// </summary> private void RemoveCommand() { if (m_CommandBuffer == null) { return; } if (m_Camera == null) { return; } m_Camera.RemoveCommandBuffer (CameraEvent.AfterEverything, m_CommandBuffer); m_CommandBuffer = null; } }
å人çã«æè¿æããã³ã·ã§ã³ã®ä¸ãã£ãå 容ã§ããã
ãUnityãç¡é§ãªããã¼ã³ã¼ã«ãªãã§æ·±åº¦ãããã¡ãåå¾ããæ¹æ³
Unityã§Depth Bufferã使ç¨ããæ¹æ³ã¨ãã¦å
¬å¼ã«ç´¹ä»ããã¦ããã®ã¯ãCamera.depthTextureModeã使ç¨ããæ¹æ³ã§ãã
ããããCamera.depthTextureModeã使ç¨ããã¨ãUpdateDepthTextureãªãã¬ã³ããªã³ã°ãã¹ãå¢ãã¦ãã¾ãã¾ãã
ããã¯å
¬å¼ãã¼ã¸ã«ãè¨è¼ããã¦ããéããUnityã®ä»æ§ã®ããã§ãã
https://docs.unity3d.com/jp/540/Manual/SL-CameraDepthTexture.html
ããã¹ãã¯ã¹ãã£ã¯ãã·ã£ãã¦ãã£ã¹ã¿ã¼ã®ã¬ã³ããªã³ã°ã«ä½¿ç¨ããã®ã¨åãã·ã§ã¼ãã¼å ãã¹ã使ç¨ãã¦ã¬ã³ããªã³ã°ããã¾ãï¼âShadowCasterâ pass type)ã
Unityå
é¨ã§ãShader Replaceã使ã£ã¦Depth Bufferãæ¸ãããã ãã«ããã¼ã³ã¼ã«ãçºè¡ãã¦ããããã«ãã®æåã¨ãªã£ã¦ãã¾ãã
çç±ã¯ä¸æã§ãããããããOpenGL2.0ä¸ä»£ã®ã¢ãã¤ã«ç«¯æ«ã¯Native Depth Textureããµãã¼ããã¦ããªã端æ«ããã£ãã®ã§ããããã«å¯¾å¿ãããããªã®ããªã¨ã
ãã¤ã¨ã³ãç³»ãªãMRTã§èªåã§æ·±åº¦ãããã¡æ¸ãã ãçãªã
Unityã®ä»æ§ã¯ã©ããããDepth Bufferã®ããã«ããã¼ã³ã¼ã«ãçºè¡ããã¨ãªãã¨æç»è² è·ã«ç¡è¦ã§ããªãã¤ã³ãã¯ããåºã¦ãã¾ãã
ããã§ããã¹ãå¢ãããã«Depth Bufferãåå¾ããæ¹æ³ã模索ãã¾ããã
Depth Bufferãåå¾ãã
çµè«ããè¨ãã¨ãCamera.SetTargetBuffersã使ç¨ãã¾ãã
private Camera m_Camera; private RenderTexture m_ColorBuffer; private RenderTexture m_DepthBuffer; private void Start() { m_Camera = GetComponent<Camera> (); // |ç§ã¯æ·±åº¦ãããã¡ãåå¾ããããã«ããã¼ã³ã¼ã«ãçºè¡ãã¾ãã><| //m_Camera.depthTextureMode = DepthTextureMode.Depth; // ã«ã©ã¼ãããã¡ãçæ m_ColorBuffer = new RenderTexture (Screen.width, Screen.height, 0); m_ColorBuffer.Create (); // 深度ãããã¡ãçæ m_DepthBuffer = new RenderTexture (Screen.width, Screen.height, 24, RenderTextureFormat.Depth); m_DepthBuffer.Create (); m_Camera.SetTargetBuffers (m_ColorBuffer.colorBuffer, m_DepthBuffer.depthBuffer); }
ãã®ã¾ã¾ã ã¨Shaderãã使ç¨ã§ããªãã®ã§ãCommandBufferã使ã£ã¦ä»»æã®ã¿ã¤ãã³ã°ã§ã»ãããã¾ãã
å ãã¦ãã«ã¡ã©ã®æç»å
ãã«ã©ã¼ãããã¡ã«ãªã£ã¦ãã¾ã£ã¦ããã®ã§ãBack buffer(ç»é¢)ã«æ¸ãæ»ãã¾ãã
private void AddCommand() { // 深度ãããã¡ãã»ããããã³ãã³ã { CommandBuffer command = new CommandBuffer (); command.name = "Set depth texture"; command.SetGlobalTexture ("_DepthTexture", m_DepthBuffer); m_Camera.AddCommandBuffer (CameraEvent.BeforeImageEffects, command); } // ã«ã©ã¼ãããã¡ãããã¯ãããã¡(ç»é¢)ã«æãããã³ãã³ã { CommandBuffer command = new CommandBuffer (); command.name = "blit to Back buffer"; // (注) // ã«ã¡ã©ã®æ¸ãè¾¼ã¿å ãRenderTextureãªã®ã«ãCameraEvent.AfterEverythingã®ã¿ã¤ãã³ã°ã§ // CameraTargetãback bufferã示ãã®ã¯æ£ããã®ã ãããã»ã»ã» // 確èªãã¼ã¸ã§ã³ï¼Unity5.6.1f1 command.SetRenderTarget (BuiltinRenderTextureType.CameraTarget); command.Blit (m_ColorBuffer, BuiltinRenderTextureType.CurrentActive); m_Camera.AddCommandBuffer (CameraEvent.AfterEverything, command); } }
ããã§ã_DepthTextureã«Shaderããã¢ã¯ã»ã¹ãããã¨ãå¯è½ã«ãªãã¾ããã
ãããªæãã®Shaderã§ãç»é¢ã«æ·±åº¦ãããã¡ã表示ã§ãã¾ãã
Shader "Test/BlitDepth" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Cull Off ZWrite Off ZTest Always Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float2 uv_depth : TEXCOORD1; float4 vertex : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; o.uv_depth = v.uv; return o; } sampler2D _MainTex; sampler2D _DepthTexture; fixed4 frag (v2f i) : SV_Target { half rawDepth = SAMPLE_DEPTH_TEXTURE(_DepthTexture, i.uv_depth); half depth = Linear01Depth(rawDepth); return fixed4(rawDepth, rawDepth, rawDepth, 1); } ENDCG } } }
UpdateDepthTextureãã¹ãªãã§Depth bufferãåå¾ãããã¨ãã§ãã¾ããã
ã«ã©ã¼ãããã¡ãç»é¢ã«æ¸ãæ»ãã³ã¹ãã¯å¢ãã¦ãã¾ãããããã¼ã³ã¼ã«ãéè¤ãã¦çºè¡ããã³ã¹ãã«æ¯ã¹ãã°å®ãã¨ãããã¾ãã
ãUnityããuGUIããªã¹ããã¥ã¼ã«ãã»ã«ãç»é¢å¤ããå·®ãè¾¼ã¾ããã¢ãã¡ã¼ã·ã§ã³ãã¤ãã
uGUIã§ä½ã£ããªã¹ããã¥ã¼ã«ãã»ã«ãç»é¢å¤ããå·®ãè¾¼ã¾ãããããªã¢ãã¡ã¼ã·ã§ã³ã追å ããæ¹æ³ãå
±æã
æçµçã«ãããªæãã«ãªãã¾ãã