UE4: ãã¤ããªã¼é å¸ãå®è¡æãªã³ã¯åãã®ã©ã¤ãã©ãªã¼ã UE4 ããã¸ã§ã¯ãã¸çµã¿å ¥ããæ¹æ³ã mecab ã§è§£èª¬
æ¦è¦
UE4 ã®ããã¸ã§ã¯ãã® C++ ã³ã¼ã㸠UE4 ã¨ã¯ç¹ã«é¢ä¿ã®ç¡ãä¸è¬ã®ã©ã¤ãã©ãªã¼ããªã³ã¯ããã®ã¯å°ã
é¢åãªäºãããããããã¼ãªã³ãªã¼ãªã©ã¤ãã©ãªã¼ãä¾ãã° Eigen
ã stb
ããã㯠Boost
ã®ä¸é¨ããªã³ã¯ãããããªå ´åã¯å°ããªãããããããã¤ããªã¼é
å¸ãå®è¡æãªã³ã¯åãã®ã©ã¤ãã©ãªã¼ãä¾ãã° OpenCV
ã pcl
ãªã©ãçµã¿å
¥ãããå ´åã«ã¯å°ã
é¢åã
ãã®è¨äºã§ã¯ UE4 ã«ã¯çµã¿è¾¼ã¾ãã¦ããªããæ¯è¼çå°ãããã«ããç°¡åã§ã UE4 ããã¸ã§ã¯ãã¸ã®çµã¿å
¥ãã試ãã®ã«æé 㪠mecab
ãä¾ã«ãå
·ä½çãªææ³ãæ´çããã
Note: mecab
ã¯æ¥æ¬èªã®å½¢æ
ç´ è§£ææ©è½ãæä¾ããã©ã¤ãã©ãªã¼ã§ãããå½¢æ
ç´ è§£æã«ã¤ãã¦ã¯æ¬è¨äºã®ä¸»é¡ã§ã¯ãªãã®ã§è§£èª¬ãã¾ããã
解説ã®ç¯å²
mecab
ã®ãã¤ããªã¼ã©ã¤ãã©ãªã¼ã®ãã«ãããâãããªã®ã UE4 ã§ãã¹ããã¬ã¤ã§ããã¾ã§ã
æ¹æ³
大éæãªæé :
mecab
ã®ã½ã¼ã¹ããã¦ã³ãã¼ãmecab
ããã«ã- çµã¿å ¥ããUE4 ããã¸ã§ã¯ã ãä½æï¼æ¢ã«ããããã¸ã§ã¯ãã§ãå¯ï¼
- UE4 ããã¸ã§ã¯ãã¸
mecab
ã®ãã¡ã¤ã«ãé ç½® - UE4 ããã¸ã§ã¯ãã®
<project-name>.Build.cs
ãããã£ã¦mecab
ãæ±ããããã«ç´°å·¥ãã
mecab
ã®ãã«ãã¾ã§
ã½ã¼ã¹ã®å ¥æ:
- http://taku910.github.io/mecab/#download
- mecab-0.996.tar.gz å·çæç¹ 2018-03-13 ã«ãããé å¸ç
ãã«ã:
cd src
- fix: Makefile.msvc.in
X86
->X64
@DIC_VERSION@
->102
@VERSION@
->0.996
- fix: feature_index.cpp
case 't': os_ << (size_t)path
->case 't': os_ << (unsigned int)path
- fix: writer.cpp
case 'L': *os << latice->size()
->case 'L': *os << (unsigned int)latice->size()
nmake -f Makefile.msvc.in
ãã«ããå®äºãã㨠libmecab.dll
ãªã©ã®ãã¡ã¤ã«ãçæããã¦ãã¾ãã
Note: Windows 7 64bit に MeCab (和布蕪) と Python のバインディングを導入 (2016/08/18) - Qiita ãåèã«ãã¾ããããã®ã¾ã¾ãã«ãããããã½ã¼ã¹ã§ã¯ãªããã¤ããªã¼é å¸çãå ¥æãã㨠x86 ã«ãªãã¾ãã
UE4 ããã¸ã§ã¯ã㸠mecab
ãçµã¿å
¥ãã
mecab
ãçµã¿å
¥ããã UE4 ããã¸ã§ã¯ãã®ãã£ã¬ã¯ããªã¼ç´ä¸ã« ThirdParty
ãã£ã¬ã¯ããªã¼ãçæãã次ã®ããã«ãµããã£ã¬ã¯ããªã¼ãç¨æãã¾ãããã <my-project-dir>
ç´ä¸ã§ãã Sources
ã Plugins
ã®ä¸ã§ã¯ããã¾ããã
<my-project-dir> |- ThirdParty |- mecab |- Includes |- Libraries
mecab
ã®ãã¡ã¤ã«ç¾¤ãé
ç½®ãã¾ãã
- Includes:
mecab
ã®src
ã®.h
ãã¡ã¤ã«ç¾¤ãå ¨ã¦æ¾ãè¾¼ã - Libraries:
libmecab.lib
ã¨libmecab.dll
ãæ¾ãè¾¼ã
<my-project>.Build.cs
ã«ç´°å·¥ãã¾ãã
// 1. åé ã« using ã追å ãã¦ããã¾ãã using System.IO;
// 2. ctor ã« public class MyProject : ModuleRules { public MyProject(ReadOnlyTargetRules Target) : base(Target) { // ... 追å ãã以åããããä½ããä»åã®ä»¶ã¨ã¯é¢ä¿ã®ç¡ãå®ç¾©ãªã© ... // ... // ããããä»åã®è¿½å é¨å var base_path = Path.GetDirectoryName( RulesCompiler.GetFileNameFromType( GetType() ) ); string third_party_path = Path.Combine( base_path, "..", "..", "Thirdparty"); PublicIncludePaths.Add( Path.Combine( third_party_path, "mecab", "Includes") ); switch ( Target.Platform ) { // ä»ã®ãã©ãããã©ã¼ã ã«ã対å¿ãããå ´å㯠case ãå¢ããã¾ãã // ä»åã¯ä¾ã¨ã㦠Win64 ã®ã¿å¯¾å¿ãã¾ãã case UnrealTargetPlatform.Win64: PublicLibraryPaths.Add( Path.Combine( third_party_path, "mecab", "Libraries", "Win64" ) ); PublicAdditionalLibraries.Add( "libmecab.lib" ); string mecab_dll_path = Path.Combine( third_party_path, "mecab", "Libraries", "Win64", "libmecab.dll" ); RuntimeDependencies.Add( new RuntimeDependency( mecab_dll_path ) ); string binaries_directory = Path.Combine( base_path,"..","..", "Binaries", "Win64" ); if ( ! Directory.Exists( binaries_directory ) ) System.IO.Directory.CreateDirectory( binaries_directory ); string mecab_dll_destination = System.IO.Path.Combine( binaries_directory, "libmecab.dll" ); CopyFile( mecab_dll_path, mecab_dll_destination ); PublicDelayLoadDLLs.AddRange( new string[] { "libmecab.dll" } ); break; default: throw new System.Exception( System.String.Format( "Unsupported platform {0}", Target.Platform.ToString() ) ); } } // ãã®é¢æ°ã追å private void CopyFile( string source, string destination ) { System.Console.WriteLine( "Copying {0} to {1}", source, destination ); if ( System.IO.File.Exists( destination ) ) System.IO.File.SetAttributes( destination, System.IO.File.GetAttributes( destination ) & ~System.IO.FileAttributes.ReadOnly ); try { System.IO.File.Copy( source, destination, true ); } catch ( System.Exception e ) { System.Console.WriteLine( "Failed to copy file: {0}", e.Message ); } } }
ãã®è¨äºã«èå³ãæã£ã¦èªãã§ããã¦ããæ¹ã¯ C# ã®çµé¨ãè±å¯ã§ãªãã¨ããã®ç¨åº¦ã®ã³ã¼ãã¯èªãã°ãããã¨æãã¾ãã®ã§èª¬æã¯çç¥ãã¾ãã
Note: Using thirdparty libraries in our UE4 mobile/desktop project – Parallelcube ãåèã«ãã¾ããã
ãã㧠<my-project> ããã«ãï¼ã³ã³ãã¤ã«ï¼ããã¨ã mecab
ã®ãã¤ããªã¼ã©ã¤ãã©ãªã¼ãé
ç½®ããããã¸ã§ã¯ãã® C++ ã³ã¼ããã使ç¨å¯è½ã¨ãªãã¾ãã
ãã¾ã: mecab
ã使ã UE4/C++ ã³ã¼ããæ¸ã㦠Blueprint (UMG) ãã mecab
ãã
mecab
ã Blueprint ã§ä½¿ã UE4/C++ ã³ã¼ãã¯ãããªæã:
// MyUtility.h #pragma once #include "CoreMinimal.h" UCLASS() class UMyUtility : public UBlueprintFunctionLibrary { GENERATED_BODY() public: UFUNCTION( BlueprintCallable, Category="My Utility" ) static FString Experiment( const FString& in ); }
// MyUtility.cpp #include "MyUtility.h" // warning 群ã ããã®ã§(´ã»Ï:;.:... #ifdef TEXT #undef TEXT #endif #define _APISET_RTLSUPPORT_VER 0 #define _APISET_INTERLOCKED_VER 0 #define _WIN32_WINNT_WINTHRESHOLD 0 #define _APISET_SECURITYBASE_VER 0 #define NTDDI_WIN7SP1 0 #include "mecab.h" FString UMyUtility::Experiment( const FString& in ) { // mecab æºå; (â 1) å¾è¿°ã§è¿½è¨ãã static auto tagger = MeCab::createTagger( "" ); if ( ! tagger ) { auto e = MeCab::getLastError(); return FString( "Tagger Error:" ) + FString( e ); } // mecab çã«ããã§è¿ã£ã¦ããæåå㯠utf8 auto result = tagger->parse( TCHAR_TO_UTF8( *in ) ); // utf8 -> wchar // note: ä»å㯠<my-project>.Build.cs 㧠Win64 ã«çµã£ã¦ããã®ã§ Windows API ã使ç¨ãã¦ãã¾ãã const auto size = ::MultiByteToWideChar( CP_UTF8, 0, result, -1, nullptr, 0 ); std::vector< wchar_t > buffer( size + 1 ); ::MultiByteToWideChar( CP_UTF8, 0, result, -1, buffer.data(), buffer.size() ); return FString( buffer.data() ); }
UE4Editor ã§é©å½ãª UMG ãä½ã£ã¦:
Note: Canvas ã« Image, Text, Text Box (Multi-Line) ã§ãã
input
ã® On Text Committed
ã« MyUtility::Experiment
ããçµæã result
ã¸åºåãã Blueprint ãæ¸ãã¦:
ãã¹ããã¬ã¤:
ãã§ããããã§ããð
追è¨1: (â 1) mecab
ã® MeCab::createTagger( "" );
ã®å¼æ°ã«ã¤ãã¦
ããã§æ¸¡ã "mecab ã®ã³ãã³ãã©ã¤ã³å¼æ°" ããã®ä¾ã®ããã«ç©ºæååã«ããå ´åã¯ã mecab
ããã«ãæã«ã«ã¹ã¿ãã¤ãºãã¦ããªãå ´å㯠"C:\Program Files (x86)\MeCab\etc\mecabrc" ãã mecab
ã®è¨å®ãèªã¿è¾¼ã¿ããã®è¨å®ããè¾æ¸ãèªã¿è¾¼ãåä½ã¨ãªãã¾ãã
mecabrc
ãè¾æ¸ãå¥ã®å ´æã«ç¨æãããå ´åã«ã¯ãã³ãã³ãã©ã¤ã³å¼æ°ã®è§£èª¬ https://taku910.github.io/mecab/mecab.html ãåèã«æ¬¡ã®ããã«å¼æ°ã¨ã㦠mecab
ã®ã³ãã³ãã©ã¤ã³å¼æ°ã渡ãã¾ã:
// mecab ã®ã³ãã³ãã©ã¤ã³å¼æ°ãã¾ã¨ãã¦1ã¤ã®æååã§æ¸¡ã static auto tagger = MeCab::createTagger( "-r C:\\mecab\\etc\\mecabrc" );
ãªãããã®ããã« mecab
ã®ã³ãã³ãã©ã¤ã³å¼æ°ã渡ãããå ´åã«ããã¹æååã«ç©ºç½æåãå
¥ã£ã¦ããå ´åãªã©ã¯ã mecab
ã®ã³ãã³ãã©ã¤ã³å¼æ°ãã¼ãµã¼ ( src/param.cpp
ã® open
é¢æ°ãåç
§ ) ããã¾ãå¨ç¨ã«ãã¼ã¹ãã¦ãããã«åä¸ã®æååã§ä¸ãããã¿ã¼ã³ã§ã¯ã¨ã¹ã±ã¼ããããã失æãã¾ãããã®ãããªå ´åã«ã¯ "ãããã argc, argv ãã¿ã¼ã³" ã§ã³ãã³ãã©ã¤ã³å¼æ°ãåé¢æ¸ã¿ã®å½¢æ
ã§ä¸ããã°æå¾
åä½ãã¾ãã
// mecabrc ã®ãã¹ã "me cab" ã®ããã«ç©ºç½æåãå«ãã§ãããã¿ã¼ã³ std::array< char*, 3 > arguments = { "", "-r", "C:\\me cab\\etc\\mecabrc" }; static auto tagger = MeCab::createTagger( arguments.size(), arguments.data() );
追è¨2: mecabrc ã®å¿ è¦æä½éã®è¨è¿°ã¨è¾æ¸ã®é ç½®æ¹æ³
mecabrc: é©å½ãªå ´æã«ããã¹ããã¡ã¤ã«ãä½ãã°ãã
; ã»ãã³ãã³å§ã¾ããã³ã¡ã³ãè¡ ; æä½éãè¾æ¸ã®ãã£ã¬ã¯ããªã¼ã®ãã¹ãè¨è¿°ãã¦ããã°ããã ; $(rcpath) å¤æ°ã¯ãã® mecabrc ã®ãã¹ã«ç½®ãæãã¦å¦çãããã dicdir = $(rcpath)\..\dic\ipadic
è¾æ¸ã¯å
¬å¼ã®ãã¦ã³ãã¼ã http://taku910.github.io/mecab/#download ãããIPA è¾æ¸ããååãã¦ã㦠mecabrc ã§å®ç¾©ãããã£ã¬ã¯ããªã¼ãªãã MeCab::createTagger
ã«ã³ãã³ãã©ã¤ã³å¼æ°ã§ç´æ¥æ¸¡ããªããããã£ã¬ã¯ããªã¼ã¸æ¾ãè¾¼ãã°ããã
ãã®ãã¡ããã¡ããããããã¡ã¤ã«ãå ¥ã£ã¦ãããã£ã¬ã¯ããªã¼ã dicdir ã¸é ç½®ãããä¸è¬çãªé ç½®ãã¹ã¯ mecabrc ã¨ä½µãã¦æ¬¡ã®ãã:
<somewhere> |- mecab |- etc | |- mecabrc |- dic |-ipadic | |- ... .csv ã»ãé å¸ã®è¾æ¸ã®ãã£ã¬ã¯ããªã¼ã®ä¸èº«ã®ããããã®ãã¡ã¤ã« |-<something the other dic 1> |-<something the other dic 2> |-<something the other dic 3> |- ...
ããä¾ã¨ãã¦ã§ã¯ãªããå®éã« mecab ã UE4 ããã¸ã§ã¯ãã§ä½¿ç¨ãããå ´åã«ã¯ã mecabrc ã dic 㯠FPaths::ProjectDir()
ããé©å½ãªç¸å¯¾ãã¹ãè¨å®ããé
å¸ããã±ã¼ã¸ã«å«ããã°ããã§ãããã ThirdParty ã©ã¤ãã©ãªã¼ãçµã¿å
¥ããä¾ã¨ãã¦è©¦ãã ãã§ããã°ã©ããé©å½ãªå ´æã«é
ç½®ãã¦ãã¹ããã¬ã¤ã§ããã°ããã§ãããã
// mecab 㯠Windows ç°å¢ã§ã¯ / åºåãã®ãã¹ã¯æ±ããªãã®ã§ã²ã¨æé追å ãã // ï¼å¾®å¦ã«æ··ãã£ã¦ãã¦ãæ±ããäºã¯ããããã©ï¼ cosnt auto mecabrc = FPaths::ConvertRelativePathToFull( FPaths::ProjectDir() / TEXT( "mecab/etc/mecabrc" ) ) #ifdef _WIN32 .Replace( TEXT( "/" ), TEXT( "\\" ) ) #endif ; std::array< char*, 3 > arguments = { "", "-r", TCHAR_TO_UTF8( *mecabrc ) }; static auto tagger = MeCab::createTagger( arguments.size(), arguments.data() );