- æ¬è¨äºã§éæãããã¨
- ä»åãããã¨
- æºåç·¨
- å®è£ ç·¨
- å®éã«åããã¦ã¿ã
- ã¾ã¨ãã¨ææ
NTTãã³ã¢ R&Dæ¦ç¥é¨ã®åå·å·§ã§ããä»åã®è¨äºã¯Unreal Engineã§ä½¿ãã Unreal Pythonã¨ãæè¿è©±é¡ã®Recraft AIã使ã£ã¦ãããªã¢ã«ãèªåã§ä½ã£ã¦ã¿ããã¨ããè¨äºã«ãªãã¾ãã ãªããæ¬è¨äºã®å 容ã¯å人ç°å¢ã«ããã試è¡ã§ããæ¥åã«ã¯é¢é£ã®ç¡ãå 容ã¨ãªãã¾ãã
æ¬è¨äºã§éæãããã¨
- Recraft AIãAPIçµç±ã§Pythonãã使ã
- Editor Utility Widgetæ©è½ã§Unreal EditorããRecraft AIã使ã
- Unreal Pythonã§ãã¯ã¹ãã£ã¨ãããªã¢ã«ä½æãèªååãã
以ä¸åç»ã®ããã«UnrealEditorä¸ããç´æ¥ããã³ãããæ¸ãããã®ãã¯ã¹ãã£ã¨ãããªã¢ã«ãã±ã±ã£ã¨çæã§ããããã«ãªãã¾ãã

ä»åãããã¨
ä»åã¯Unreal Editorã§ä½¿ããEditor Utility Widget æ©è½ãæ´»ç¨ããã¨ãã£ã¿ä¸ããç´æ¥ããã³ãããå ¥åãã¦ç»åãçæãçæããç»åã使ã£ããããªã¢ã«ãèªåã§ä½æããã¨ããã¾ã§ä¸æ°é貫ã§å®ç¾ãã¦ã¿ããã¨æãã¾ãã

æºåç·¨
Recraft AIã¨ã¯ï¼
æè¿Recraft AIã話é¡ã«ãªã£ã¦ããã®ã§è§¦ã£ã¦ã¿ãããªã¼ã¨æã£ã¦ãã¾ãããRecraft AIã¯UIãFigmaã®ããã«ãªã£ã¦ãã¦ãã¶ã¤ãã¼ã使ãããããAPIãæ´åããã¦ãã¦ã¨ã³ã¸ãã¢ã¨ãã¦ã使ãããããã¼ã«ã«ãªã£ã¦ãããã¨ããããã¸ãã¹ã¦ã¼ã¹ã«æã£ã¦ãããªãµã¼ãã¹ã«ãªã£ã¦ããå°è±¡ã§ãã詳ããã¯ä»¥ä¸ã®ãããªè¨äºãèªãã§ã¿ã¦ãã ããããªããããªã¼ãã©ã³ã®å ´ååç¨å©ç¨ã¯ä¸å¯ã§ãã®ã§ãæ°ãã¤ããã ããã www.itmedia.co.jp
WebããRecraft AIã使ã£ã¦ã¿ã
ã¾ããæ¬è¨äºã®ä¸»æ¨ããã¯å°ãå¤ãã¾ãããRecraft AIã®ã¤ã¡ã¼ã¸ãè»½ãæ´ãã§ãããããã«Webä¸ã§ä½ã£ã¦ã¿ãç»åãè¼ãã¦ã¿ã¾ããRecraft AIã¯æ¢åç»åã®ã¹ã¿ã¤ã«ã«åããã¦ç»åãçæããæ©è½ããããç»åä¸ã®æ¨ã®ãã¯ã¹ãã£ã¯è飾åæã®å¯å¶½ä¸åå æ¯ æ±æ¸ æ¥æ¬æ©*1ã®ã¹ã¿ã¤ã«ã§çæããç»åã¨ãªãã¾ããçµæ§ããæãã®ã¹ã¿ã¤ã«ã§çæã§ãã¦ããã®ã§ã¯ãªãã§ããããã

Recraft AIã®APIãæºåãã
ããç¨åº¦ãã¯ã¹ãã£çæã®æå¾ ãæã¦ãããªã®ã§ãUnrealEditorãã使ããããã«ãããã¨æãã¾ããã¾ãã¯Recraft AIã«ã¦ã¢ã«ã¦ã³ããä½ã£ãå¾ã«APIã®ãã¼ã¸ãéãã1000Unitsã1ãã«ã§ã«ã¼ã決æ¸ããã ãã§ããï¼ææã¡ã®Visaã¯é§ç®ã§ãMasterã«ã¼ãã¯ä½¿ãã¾ããï¼

Unreal Pythonã¨Unreal Editorã®æºåããã
APIãã¼ãæºååºæ¥ãã®ã§ã次ã«Unreal Pythonä¸ãããã®APIãåããæºåãè¡ãã¾ãã ä»åã¯çæããç»åããã¼ã«ã«ã«ä¿åãã¦æ±ããããå¹¾ã¤ãå¿ è¦ãããªPythonã¢ã¸ã¥ã¼ã«ãã¤ã³ã¹ãã¼ã«ãã¦ããå§ãããã¨ã«ãã¾ãã
ãªããUnreal Pythonã¯Unreal Engineèªä½ã®ãã©ã«ãã«å
å
ããã¦ãããããããã«å¿
è¦ãªã¢ã¸ã¥ã¼ã«ãå°å
¥ãã¦ããã¾ãã
Python(REPL)ãã
import sys print(sys.executable)
ãªã©ã§ä»ä½¿ã£ã¦ããUEããã¸ã§ã¯ãããEditorã®å ´æãæ¢ãã¦ã¿ã¾ãã

ä¸è¨ç»åä¸ã®ã¨ã³ã¸ã³ãã©ã«ãã«ã¦æ¤ç´¢ããUE5.3ã§ã¯ä¸è¨ãã¹ã«Pythonã®å®è¡ç°å¢ããããã¨ããããã¾ããã
C:\Program Files\Epic Games\UE_5.3\Engine\Binaries\ThirdParty\Python3\Win64
次ã«ãã®Pythonã¨åããã£ã¬ã¯ããªã«ã¦å¿ è¦ãªã¢ã¸ã¥ã¼ã«ãã¤ã³ã¹ãã¼ã«ãã¦ããã¾ãã
python -m pip install openai python -m pip install opencv-contrib-python python -m pip install pillow



å®è£ ç·¨
Editor Utility Widgetã§UIãä½ã
Recraft AIãUnrealEditorä¸ãã使ãããã®ã§ããã®ããã®ã¤ã³ã¿ãã§ã¼ã¹ãä½ãã¾ãã ã³ã³ãã³ããã©ã¦ã¶ã§ä»»æã®å ´æããã£ã¬ã¯ããªã§å³ã¯ãªãã¯ããEditor Utility WidgetããRecraftWidgetãã¨ããååã§ä½æãã¾ããããè¦ç´ ã®é ç½®ãè¨å®ããç»é¢ãåºã¦ãããStack Boxãé¸ã³ã¾ãã


RecraftWidgetãä½ã£ãããç·¨éç»é¢ãéãã¨ç»é¢ãã¶ã¤ã³ã¢ã¼ãã«ãªã£ã¦ãã¾ããããã§å³ã®æ§ã«ãEditorUtilityEditableTextã¨EditorUtilityButtonã好ãã«é ç½®ãã¾ããããï¼çè ã®ç°å¢èµ·å ãããã¹ãããã¯ã¹ãæååããã¦ãã¾ããç¡è¦ã§OKã§ãï¼

åè ããRecraft AIã¸éä¿¡ããããã³ããã®è¨å®æ¬ããå¾è ããããã³ããã使ã£ã¦ãããªã¢ã«çæãéå§ãããå½¹å²ãæã¡ã¾ãã
Editor Utility Widgetã®ã¤ãã³ãã°ã©ããæ¸ã
ããã¾ã§ã§ç»é¢ã¬ã¤ã¢ã¦ãã¯å®æããã®ã§ããã®åä½ãæ¸ãã¦ããã¾ããã¾ãã¯ããã¹ãå ¥åæ¬ã®æååãä¿åããPrompt夿°ãä½ãããããæ´æ°ããã¤ãã³ããä½ãã¾ãã
æ´æ°ããã¤ãã³ãã¯ããã¹ãå ¥åæ¬ã鏿ããç¶æ ã§è©³ç´°ããã«ã®OntextCommittedã¤ãã³ãããä½ãã¾ãã

ã¤ãã³ãã°ã©ããéããããã¾ãã¯å·¦ãã¤ã³ã§Prompt夿°ãä½ãã¾ãã

ãã®å¾ãå ¥åãããããã¹ããPrompt夿°ã«åæ ããå¦çãæ¸ãã¾ãã

次ã«ãããªã¢ã«çæéå§ç¨ã®ãã¿ã³ãã¯ãªãã¯ããã¨ãã®å¦çãæ¸ãã¾ãã ãã¡ããããã¹ãå ¥åæ¬ã¨åæ§ããã¿ã³ã鏿ããç¶æ ã®è©³ç´°ããã«ããOnClickedã¤ãã³ãã追å ãããã¨ãã§ãã¾ãã

ããã§ããã¿ã³ãæ¼ããå¾ã®å
¨ã¦ã®ã¤ãã³ãã°ã©ããè¨è¼ããã¨ã以ä¸ã®ããã«ãªãã¾ãã
åºæ¬çã«ã¯ãRecraft AIã®APIã§ãã¯ã¹ãã£çæå¾ãPNGç»åã§ä¿åããPythonã³ã¼ããå®è¡ãâãä¿åãããPNGç»åãå
ã«ãã¯ã¹ãã£ã¢ã»ããåï¼ãããªã¢ã«åããPythonã³ã¼ããå®è¡ãã®äºæ®µæ§æã«ãªã£ã¦ãã¾ããPrompt夿°ã®ä¸èº«ããã¡ã¤ã«åã¯Pythonã³ã¼ãã®å®è¡æã®å¼æ°ã¨ãã¦æ¸¡ãã¦ãã¾ãã
ãã®å³ã®éãã«ã¤ãã³ãã°ã©ããæ§ç¯ãããããã¨ã¯ï¼ã¤Pythonãã¡ã¤ã«ãæºåãã¦ããã¡ã¤ã«ãã¹ããã®ã°ã©ãä¸ã§è¨å®ããã ãã§åããã®ã宿ãã¾ãã
次ã«ããããã®Pythonãã¡ã¤ã«ã®ä¸èº«ãè¦ã¦ããã¾ãã
Recraft AIã§ç»åçæå¾ãã¯ã¹ãã£ãä¿åããã³ã¼ã
ä»åãpromptToTexture.pyã¨ãã¦ä»¥ä¸ã®ãããªã³ã¼ããæºåãã¾ããããã®ã³ã¼ãã¯èµ·åæå¼æ°ã®å 容ãããã³ããã¨ãã¦Recraft AIã§ç»åãçæãçµæãwebpå½¢å¼ã§ãã£ã¬ã¯ããªã«ä¿åå¾ãpngç»åã¸å¤æãã¦ãããã®ã¨ãªãã¾ãã
from openai import OpenAI import requests import os import sys from PIL import Image args = sys.argv def download_image(url, save_path): response = requests.get(url) if response.status_code == 200: with open(save_path, 'wb') as file: file.write(response.content) print(f"ç»åãä¿åãã¾ãã: {save_path}") else: print(f"ç»åã®ãã¦ã³ãã¼ãã«å¤±æãã¾ãããã¹ãã¼ã¿ã¹ã³ã¼ã: {response.status_code}") def convert_webp_to_png(input_path, output_path): with Image.open(input_path) as img: img.save(output_path, 'PNG') print(f"ç»åãPNGå½¢å¼ã§ä¿åãã¾ãã: {output_path}") my_key = "ããã«ããªãã®API Keyãå ¥å" client = OpenAI(base_url='https://external.api.recraft.ai/v1', api_key=my_key) # ããã³ããããç»åãçæãã response = client.images.generate( prompt=args[1], style='digital_illustration', extra_body={'substyle': 'pixel_art'}, ) image_url = response.data[0].url # ä¿åå ã®ãã£ã¬ã¯ã㪠save_directory = 'C:\\Users\\~ã¦ã¼ã¶ã¼å~\\Documents\\Unreal Projects\\AC\\Content\\Python\\downloaded_images' if not os.path.exists(save_directory): os.makedirs(save_directory) # ç»åã®ãã¡ã¤ã«åãè¨å®(第äºå¼æ°ã使ã) file_name = args[2] webp_save_path = os.path.join(save_directory, file_name) # ç»åããã¦ã³ãã¼ããã¦ä¿å download_image(image_url, webp_save_path) # PNGå½¢å¼ã§ä¿å png_save_path = os.path.splitext(webp_save_path)[0] + '.png' convert_webp_to_png(webp_save_path, png_save_path)
次ã¯ãã®pngç»åã使ã£ã¦Materialãçæãã¦ã¿ã¾ãã
ä¿åãããã¯ã¹ãã£ããMaterialãçæããã³ã¼ã
ãã®ã³ã¼ãã¯textureToMaterial.pyã¨ãã¦ä½æãã¾ãããç¹å¾´çãªã®ã¯unrealã¢ã¸ã¥ã¼ã«ãã¤ã³ãã¼ãããã¦ãããã¨ã§ãããã«ãã£ã¦ãã¯ã¹ãã£ãã¢ã»ããã¨ãã¦ã¤ã³ãã¼ãããããMaterialãä½ããã¨ãåºæ±ºã¾ãã
ã³ã¼ãã®æµãã¨ãã¦ã¯ããä¿åãããã¯ã¹ãã£ãã¡ã¤ã«ããã¯ã¹ãã£ã¢ã»ããã¨ãã¦Unreal Editorã«ã¤ã³ãã¼ããâããã¯ã¹ãã£ã¢ã»ããã使ã£ããããªã¢ã«ã使ããã¿ã¤ãªã³ã°ç¨éã«ãã¼ãã調æ´ããã¦ãã¾ãã
import unreal import sys args = sys.argv @unreal.uclass() class MaterialCreatorWidget(unreal.EditorUtilityWidget): @unreal.ufunction(meta=dict(Category="Material Creation")) def create_material_with_tiled_texture(self): # ã³ãã³ãã©ã¤ã³å¼æ°ãããã¯ã¹ãã£ãã¡ã¤ã«ã®ååãåå¾ texture_file_name = args[1] # æ¡å¼µåãé¤å» texture_u_name = unreal.Paths.get_base_filename(texture_file_name) destination_path = "/Game/Python/downloaded_images" # ã¤ã³ãã¼ãã¿ã¹ã¯ã®è¨å® import_task = unreal.AssetImportTask() import_task.filename = "C:\\Users\\~ã¦ã¼ã¶ã¼å~\\Documents\\Unreal Projects\\AC\\Content\\Python\\downloaded_images\\"+texture_file_name import_task.destination_path = destination_path import_task.automated = True # ãã¯ã¹ãã£ãã¡ã¤ã«ã®ã¢ã»ããå unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks([import_task]) # ã¤ã³ãã¼ãçµæã®ç¢ºèª if not import_task.imported_object_paths: unreal.log_error(f"Failed to import texture: {texture_file_name}. Please check the file path and format.") return texture_path = import_task.imported_object_paths[0] texture = unreal.EditorAssetLibrary.load_asset(texture_path) if not texture: unreal.log_warning(f"Texture not found at path: {texture_path}") return # æ°ãããããªã¢ã«ã®ä½æ material_factory = unreal.MaterialFactoryNew() asset_name = f"{texture_u_name}_Mat" package_name = f"{destination_path}/{asset_name}" new_material = unreal.AssetToolsHelpers.get_asset_tools().create_asset(asset_name, destination_path, unreal.Material, material_factory) if not new_material: unreal.log_error("Failed to create new material") return # ãã¯ã¹ãã£ãµã³ãã«ãã¼ãã®è¿½å texture_sample = unreal.MaterialEditingLibrary.create_material_expression(new_material, unreal.MaterialExpressionTextureSample, -384, 0) texture_sample.texture = texture # TextureCoordinateãã¼ãã®è¿½å tex_coord = unreal.MaterialEditingLibrary.create_material_expression(new_material, unreal.MaterialExpressionTextureCoordinate, -768, 0) # Multiplyãã¼ãã®è¿½å ï¼UVã¹ã±ã¼ã«èª¿æ´ç¨ï¼ multiply = unreal.MaterialEditingLibrary.create_material_expression(new_material, unreal.MaterialExpressionMultiply, -576, 0) # Constantãã¼ãã®è¿½å ï¼ã¿ã¤ãªã³ã°åçï¼ tiling_factor = unreal.MaterialEditingLibrary.create_material_expression(new_material, unreal.MaterialExpressionConstant2Vector, -768, 128) tiling_factor.r = 80.0 # Xæ¹åã®ã¿ã¤ãªã³ã°åç tiling_factor.g = 80.0 # Yæ¹åã®ã¿ã¤ãªã³ã°åç # ãã¼ãéã®æ¥ç¶ unreal.MaterialEditingLibrary.connect_material_expressions(tex_coord, "", multiply, "A") unreal.MaterialEditingLibrary.connect_material_expressions(tiling_factor, "", multiply, "B") unreal.MaterialEditingLibrary.connect_material_expressions(multiply, "", texture_sample, "UVs") # Base Colorã«ãã¯ã¹ãã£ãæ¥ç¶ unreal.MaterialEditingLibrary.connect_material_property(texture_sample, "", unreal.MaterialProperty.MP_BASE_COLOR) # ãããªã¢ã«ã®æ´æ°ã¨ä¿å unreal.MaterialEditingLibrary.recompile_material(new_material) unreal.EditorAssetLibrary.save_asset(package_name, True) unreal.log(f"Created new material with tiled texture: {package_name}") # ã¦ã£ã¸ã§ããã®ã¤ã³ã¹ã¿ã³ã¹åï¼ã¨ãã£ã¿ã§ä½¿ç¨ããå ´åï¼ widget = MaterialCreatorWidget() widget.create_material_with_tiled_texture()
å®éã«èªåã§çæãããMaterialãã¡ã¤ã«ãè¦ãã¦ã¿ãã¨ããã£ããã¨ãããªã¢ã«ã°ã©ããæ§ç¯ããã¦ãããã¨ããããã¾ãã

å®éã«åããã¦ã¿ã
ä¸è¨ã®ï¼ã¤ã®Pythonãã¡ã¤ã«ãå ã®RecraftWidgetã®ã¤ãã³ãã°ã©ãä¸ã«è¨å®ããããå®éã«ãã®Widgetãåä½ããã¦ã¿ã¾ããããã¯ç°¡åã§Widgetã®ã¿ãä¸é¨ã®ãã¦ã¼ãã£ãªãã£ã¦ã£ã¸ã§ãããå®è¡ããæ¼ãã ãã§ãããã¹ãããã¯ã¹ã¨ãã¿ã³ãé ç½®ãããã¦ã£ã³ãã¦ãèµ·åãã¾ãã



ã¾ã¨ãã¨ææ
ä»åã¯Recraft AIããMaterialèªå使ããã£ã¦ã¿ãã®ã¨ãå®éã«æ´»ç¨ããã¨ãã®ããã«Unreal Editorãã使ããããã«ãã¦ã¿ã¾ãããæåã¯ãããè¦ãããªï¼ãã¨çåã«æãã¨ãããããã¾ããããå®éã¯ã³ã¯ãªãã¯ã§çæAIã使ããããã«ãã¦ã¿ãã¨ãªããªã便å©ãªæè§¦ã¯ããã¾ããã
ããããªããä»åå®éã«APIçµç±ã§çæãããç»åãè¦ã¦ã¿ãã¨ãã«ã¼ãç»åã«ãªã£ã¦ãªãã£ããæ®éã®çµµã¿ããã«ãªã£ã¦ãããã¨èª²é¡ãå¤ãè¦ãã¾ãããå ãã¦ãã¯ã¹ãã£ã ãã ã¨å®éã«ã¯ä½¿ãç©ã«ã¯ãªããªãããããã¼ãã«ããããã©ããã¹ãããã«ãæãåºãå¿ è¦ãããã§ãããã


ãã®ãããã¯ããã³ããã®å·¥å¤«ããã¤ã³ãã¤ã³ãæ©è½ã»ãã¹ã¯é åã®æå®ã®æ´»ç¨ã»çµã¿åããã«ãã£ã¦è§£æ±ºã§ããããããã¾ãããå®éRecraft AIã®Webä¸ã§çæããç»åã¯ãã£ã¨ããã£ãã®ã§ãè²ã 調æ´ããã°ãªãã¨ããªãããã§ãã
å°æ¥çã«ãã¯ã¹ãã£ãã©ããã¹ãããããã¼ãã«ãããã®ä¸æ¬çæã«çã¾ããã対象ç©å¨è¾ºã®ã¢ã»ããæ å ±ãåèã«ãã¦åã¢ã»ãããèªåã§çæã»ä¿®æ£ããããããªã¨ããã¾ã§ããã°ã夢ããããªã¨æãã¾ããã
*1:ãããªãã¯ãã¡ã¤ã³ã®ãã¼ã¿ã使ç¨ãã¦ãã¾ã