[UE5.4.2]UE 5.4.2 – Python を使用して C++ 関数を呼び出す方法

BlancではC++フォルダができなかった。

ThirdPersonでやった。

親クラスに Blueprint Function Libraryを選択

Nameに適当にZFunctionsと入れCreate Class。

VisualStudioへ移動し

ZFunctions.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "ZFunctions.generated.h"

/**
 * 
 */
UCLASS()
class UE542PYTHONCALLCPP1_API UZFunctions : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
//ここから追加////////
public:
	UFUNCTION(BlueprintCallable)
	static void CalledFromPython(FString InputString);
//ここまで追加//////
};

ZFunctions.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "ZFunctions.h"
//ここから追加////////
void UZFunctions::CalledFromPython(FString InputString) {
	UE_LOG(LogTemp, Error, TEXT("%s"), *InputString);
}
//ここまで追加//////

SolutionExplorer > your Project Name (right click)>Build

実行する。(Local Windows Debagger)

Outputlogで実行する unrealのクラス一覧

import unreal
for x in sorted(dir(unreal)):
   print(x)

めっちゃ重い

ZFunction が出る

クラスを使ってみる unreal.ZFunctionsのメソッド一覧

import unreal
for x in sorted(dir(unreal.ZFunctions)):
   print(x)

called_from_python が出てくる。

呼んでみる

unreal.ZFunctions.called_from_python('my test string')

作った関数によりエラーのメッセージが返ってきた。

参考URL

[UE4.21]UE 4.21 – Python を使用して C++ 関数を呼び出す方法

コンテンツブラウザを右クリックしてNew C++ Class

親クラスに Blueprint Function Libraryを選択

Nameに適当にZFunctionsと入れCreate Class。

VisualStudioが起動し

ZFunctions.h

public:
UFUNCTION(BlueprintCallable)
static void CalledFromPython(FString InputString);

を追加してこうなる。

//.Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "ZFunctions.generated.h"



UCLASS()
class UNREALPYTHONPROJECT_API UZFunctions : public UBlueprintFunctionLibrary
{
GENERATED BODY()

public:
   UFUNCTION(BlueprintCallable)
      static void CalledFromPython(FString InputString);
};

ZFunctions.cpp


//.Fill out your copyright notice in the Description page of Project Settings.

#include "ZFunctions.h"

void UZFunctions::CalledFromPython(FString InputString) {
UE_LOG(LogTemp, Error, TEXT("%s"), *InputString);
}

実行する。(Local Windows Debagger)

Outputlogで実行する

import unreal
for x in sorted(dir(unreal)):
   print(x)

ZFunction が出る

import unreal
for x in sorted(dir(unreal.ZFunctions)):
   print(x)

called_from_python が出てくる。

呼んでみる

unreal.ZFunctions.called_from_python('my test string')

呼ばれて作ったエラーメッセージが出た

参考URL

[UE5][C++]Python からブループリント関数を呼び出すことはできますか?

現時点では、Python はブループリント関数にアクセスできませんが、C++ メソッドにはアクセスできます。したがって
、解決策としては、C++ でブループリント関数を として宣言しBlueprintImplementableEvent、ブループリントでそれをオーバーライドします。

BlueprintImplementableEvent先に進む前に、を C++ から呼び出して、それが機能するかどうかを確認することをお勧めします。
次に、 を呼び出すための 2 番目の C++ 関数を作成しますBlueprintImplementableEvent。この関数は、Python に公開されるものであるため、
として実装する必要があります。BlueprintCallable

最後に、C++ とブループリントがコンパイルされたら、Python から呼び出し元関数を呼び出すだけです。
C++ クラスは、次のように通常の C++ モジュールとして表示されます。unreal.YourClassName.yourCallerFunctionName(yourClassInstance, args)
引数と戻り値は、期待どおりに処理されます。
関数を実行するクラス インスタンスを関数に渡す必要があります。特定の AActor インスタンスを操作するときに非常に便利です。


最後にもう 1 つ注意点があります。関数を、私が行ったようにブループリントイベントではなくブループリント関数として実装する必要がある場合は、関数を定数にするか、戻り値 (使用しない場合でも) を指定する必要があります。そうしないと、ブループリントのオーバーライドにイベントとして表示されます。

私のユースケースからの画面。明らかに、ブループリント関数の実装の詳細は関係ありません。
ブループリント関数

.h

.cpp

.py

参考

https://forums.unrealengine.com/t/is-it-possible-to-call-a-blueprint-function-from-python/447078/3

[UE5]LookAtとKawaiiPhysicsで突き抜けないスカートができたよ。ボリュームのあるスカートをKawaiiPhsicsで揺らす

Animブループリント系のLookAtを左右足と対応するスカートのボーンに設定する。

スカートのボーンの向きによるが、LcokAtの矢印が膝にくるように設定したら完成したよ。

走った感じ

作業の様子

参考URL

https://docs.unrealengine.com/4.27/ja/AnimatingObjects/SkeletalMeshAnimation/NodeReference/SkeletalControls/LookAt

管理者用zip

https://drive.google.com/file/d/1y9-PM9VpUy1HCVeuKxWDzk1qEIFJjmoS/view?usp=sharing

[UE5]CPPプロジェクトでプロジェクトのバージョンを上げる方法

[UE5] How to upgrade the project version in a CPP project

.uprojectを右クリックして>その他のオプションを確認>Switch Unreal Engine version …

Right-click on .uproject > Check other options > Switch Unreal Engine version…

モジュールのプロジェクト名は変更しないでください。

	"Modules": [
		{
			"Name": "KPUE532CPP",

KPUE54CPP.uprojectの中身も変更されます。

	"EngineAssociation": "5.4",

こんな感じです

変更前

{
	"FileVersion": 3,
	"EngineAssociation": "5.4",
	"Category": "",
	"Description": "",
	"Modules": [
		{
			"Name": "KPUE532CPP",
			"Type": "Runtime",
			"LoadingPhase": "Default"
		}
	],
	"Plugins": [
		{
			"Name": "ModelingToolsEditorMode",
			"Enabled": true,
			"TargetAllowList": [
				"Editor"
			]
		}
	]
}



変更後

{
	"FileVersion": 3,
	"EngineAssociation": "5.4",
	"Category": "",
	"Description": "",
	"Modules": [
		{
			"Name": "KPUE532CPP",
			"Type": "Runtime",
			"LoadingPhase": "Default"
		}
	],
	"Plugins": [
		{
			"Name": "ModelingToolsEditorMode",
			"Enabled": true,
			"TargetAllowList": [
				"Editor"
			]
		}
	]
}

内部的に他のファイルもたくさん変更されるようです。

maya python 検索用の 正規表現 を作成したテキストフィールドから入力するには?

maya python How can I enter a regular expression for search from the created text field?

import maya.cmds as cmds
import re

def search_objects_by_regex(*args):
    # テキストフィールドから正規表現を取得
    regex_pattern = cmds.textField("regexField", query=True, text=True)

    # シーン内のすべてのオブジェクトを取得
    all_objects = cmds.ls()

    # 正規表現パターンをコンパイル
    try:
        regex = re.compile(regex_pattern)
    except re.error as e:
        cmds.warning(f"Invalid regex pattern: {e}")
        return

    # 正規表現に一致するオブジェクトをフィルタリング
    matching_objects = [obj for obj in all_objects if regex.search(obj)]

    # 結果を表示
    if matching_objects:
        cmds.confirmDialog(title='Search Results', message='\n'.join(matching_objects))
    else:
        cmds.confirmDialog(title='Search Results', message='No matching objects found.')

# UIの作成
if cmds.window("regexSearchWindow", exists=True):
    cmds.deleteUI("regexSearchWindow")

cmds.window("regexSearchWindow", title="Regex Search", widthHeight=(300, 100))
cmds.columnLayout(adjustableColumn=True)
cmds.text(label="Enter Regex Pattern:")
cmds.textField("regexField")
cmds.button(label="Search", command=search_objects_by_regex)
cmds.showWindow("regexSearchWindow")

検索置換の場合

import maya.cmds as cmds
import re

def replace_objects_by_regex(*args):
    # テキストフィールドから正規表現と置換文字列を取得
    regex_pattern = cmds.textField("regexField", query=True, text=True)
    replace_text = cmds.textField("replaceField", query=True, text=True)

    # シーン内のすべてのオブジェクトを取得
    all_objects = cmds.ls()

    # 正規表現パターンをコンパイル
    try:
        regex = re.compile(regex_pattern)
    except re.error as e:
        cmds.warning(f"Invalid regex pattern: {e}")
        return

    # 正規表現に一致するオブジェクトを置換
    replaced_objects = [regex.sub(replace_text, obj) for obj in all_objects]

    # 結果を表示
    if replaced_objects:
        cmds.confirmDialog(title='Replace Results', message='\n'.join(replaced_objects))
    else:
        cmds.confirmDialog(title='Replace Results', message='No objects replaced.')

# UIの作成
if cmds.window("regexReplaceWindow", exists=True):
    cmds.deleteUI("regexReplaceWindow")

cmds.window("regexReplaceWindow", title="Regex Replace", widthHeight=(300, 150))
cmds.columnLayout(adjustableColumn=True)
cmds.text(label="Enter Regex Pattern:")
cmds.textField("regexField")
cmds.text(label="Enter Replace Text:")
cmds.textField("replaceField")
cmds.button(label="Replace", command=replace_objects_by_regex)
cmds.showWindow("regexReplaceWindow")

[UE5]EUW作っていて困る事あるんですが、コンテンツブラウザでなくExplorerのファイルブラウザーとかディレクトリブラウザーパスをユーザーに選ばせたい場合ってどのように実装してますか?

Pythonを使うパターンであれば、tkinterモジュールを使います。

from tkinter import filedialog
"""
# ファイルーダイアログでファイルを選択する
typ = [('テキストファイル','*.txt')] 
dir = 'C:\\pg'
fle = filedialog.askopenfilename(filetypes = typ, initialdir = dir) 
print("WorkData="+fle)
"""
# フォルダーダイアログでフォルダーを選択する
dir = 'D:/Design/WorkData'
fld = filedialog.askdirectory(initialdir = dir) 
print("WorkData="+fld)

参考URL

https://pg-chain.com/python-filedialog-dir
https://pg-chain.com/python-filedialog

[UE5]Pythonからダイアログメッセージを表示 unreal.EditorDialog.show_message

import unreal
class hoge:
    def show_messageDialog(self):
        title="タイトル"
        message="メッセージ"
        message_type=unreal.AppMsgType.OK_CANCEL
        
        unreal.EditorDialog.show_message(title,message,message_type, default_value=unreal.AppReturnType.NO, message_category=unreal.AppMsgCategory.WARNING)

class_Ins=hoge()
hoge.show_messageDialog()

参考URL

https://docs.unrealengine.com/5.3/en-US/PythonAPI/class/EditorDialog.html#unreal.EditorDialog

PERFORCEやgitや共有フォルダに入れる独立した依存関係のないpython.exeのzipからのインストール方法

1. 作業用フォルダを作成する。

PC内のどこでもいいので、作業用フォルダPythonUSBを作成してください。その配下にpythonフォルダとcodeフォルダを作成します。このPythonUSBは最終的に共有フォルダにそのままコピーします。

├directory
│    └ PythonUSB/     <= 作業用フォルダー
│         ├ python/
│         └ code/
│             └ hello.py
│ 

2. pythonをダウンロードして配置する

pythonのページから、OSに合わせたダウンロードページに遷移してください。今回はWindowsで説明します。

Windowsのリンク先に行くと、バージョンがいくつかありますが、OSのbitに合わせたembeddableパッケージをダウンロードします。今回は、執筆時点で最新の3.12.0バージョン、64-bitを上述のpythonフォルダにダウンロードします。ダウンロードが完了したら、解凍しましょう。解凍後のフォルダ名がpython-3.12.0-embed-amd64と長いので、python-3.12.0に変更します。

3. pipを使えるようにする

先程のpython-3.12.0フォルダ内にpython312._pthがありますので、これをメモ帳で開きます。そして、#import site#を削除してimoprt siteに変更して保存します。

続いて、get-pip.pyのリンクを右クリックして「名前をつけてリンク先を保存」でpython-3.12.0フォルダにダウンロードします。
このファイルをコマンドプロンプトで実行するには、python-3.12.0フォルダをエクスプローラーで開き、アドレスに「cmd」と入力してEnterを押して、コマンドプロンプトを出現させます。そして、python.exe get-pip.pyを実行します。
これでpip installが使用することができるようになりました。

4. 使用するライブラリをインストールする

インストールするには、コマンドプロンプトでpython-3.12.0フォルダに移動して、python.exe -m pip install [ライブラリ]を実行します。例えば、p4vを操作するライブラリp4pythonをインストールするには以下のようにします。必要なライブラリを順次インストールしてください。

python.exe -m pip install p4python

5. 実行用バッチファイルを作成する

バッチファイルをクリックするだけでコードが実行できるようにします。execute.batを以下の位置に作成します。メモ帳のテキストファイルからファイル名を変更することで作成できます。今回はhello.pyというpythonファイルを実行する例を紹介します。

├directory
│    └ PythonUSB/     <= 作業用フォルダー
│         ├ python/
│         └ code/
│             └ hello.py
│         └ execute.bat

hello.pyの中身は以下の通りです。最後にinput関数を入れておくことで、コマンドプロンプトが自動で閉じるのを防いでいます。

print('Hello world!')

input('Close window to enter any key.')

execute.batの中身は以下の通りです。
@echo offがないと、set以下の内容がコマンドプロンプト上に表示されてしまいます。見栄えの問題ですね。
set xxx=yyyは変数を定義しています。この変数を利用する際には、%で挟んで上げる必要があります。
%~dp0は実行されるバッチファイルが置かれているカレントディレクトリを示します。今回の場合では、PythonUSBですね。
pyintpathpython.exeまでのパス、codepathcodeまでのパス、pyfileは実行したいpyファイル名の変数を設定します。
%pyintpath%python.exe %codepath%%pyfile%は、上述の変数を組み合わせてよく使うpython xxx.pyの形式になっています。

@echo off
set cwdirpath=%~dp0
set pyintpath=%cwdirpath%python\python-3.12.0\
set codepath=%cwdirpath%code\
set pyfile=hello.py

%pyintpath%python.exe %codepath%%pyfile%

実行結果は以下の通りです。意図通りの動きをしています。


6. 共有フォルダにコピーする

「PythonProj」フォルダを共有フォルダにコピーします。コピー先でもバッチファイルが実行できるか念のため確認しておきましょう。

pythonUSB.zip

https://drive.google.com/file/d/1OK-1uFEXMsj5JLxIMVtaLjgwIyIVfhvF/view?usp=sharing

または

https://github.com/nobolu-ootsuka-unrealengine/pythonUSB

参考サイト

https://qiita.com/r-shiomoto/items/ea8be09ffc21ea10a867

[ue5] python rename 依存関係のあるファイルをチェックアウトしてからリネームする下調べ

rename_asset(asset, newName) 色々あるが基本はこれでいい。むしろこれしか動かず。

editor_util = unreal.EditorUtilityLibrary()
# 新しい名前
newName = newName
                
# リネームしたいアセット
asset = unreal.load_asset(package_name)
                
# rename実行
editor_util.rename_asset(asset, newName)

複数ファイルに対応する。

    def rename_endZ_remove_loop(self):
        editorAssetLib = unreal.EditorAssetLibrary()
        editor_util = unreal.EditorUtilityLibrary()
        #editorStaticMeshLib = unreal.EditorStaticMeshLibrary()
        MaterialEditingLibrary = unreal.MaterialEditingLibrary()
        asset_registry = unreal.AssetRegistryHelpers.get_asset_registry()

        #import unreal.AssetRegistry
        #AssetRegistry=unreal.AssetRegistry()
        
        EnvName=unreal.Name.cast("/Game/Effects")

        #EnvName=unreal.Name.cast(readDirPath)
        EnvArr=unreal.AssetRegistry.get_assets_by_path(asset_registry,EnvName,True,False)
        
        #EnvArr = asset_registry.get_assets()
        #EnvArr =self.SelectedAssets
        
        unreal.log_warning("main_way_start2 040  unreal.AssetRegistry.get_assets_by_path(asset_registry,EnvName,True,False)")
        unreal.log_warning("main_way_start2 041  get_assets_by_path() EnvArr len= "+str(len(EnvArr)))

        NGlist=[]       
        checkout_Arr=[] 
        checkout_Arr_Str=""
        rename_data_Arr=[]
        total_frames = len(EnvArr)
        text_label = "Rename Execution!"
        with unreal.ScopedSlowTask(total_frames, text_label) as slow_task:
            slow_task.make_dialog(True)               # まだダイアログが表示されていない場合は表示します
            for i in range(total_frames):
                if slow_task.should_cancel():# ユーザーが UI の [Cancel] を押した場合は True
                    break
                slow_task.enter_progress_frame(1)# 1 フレーム次に進めます。
                

                AssetData=EnvArr[i]
                print("AssetData= "+str(AssetData))
                package_name=str(AssetData.package_name)
                print("package_name= "+str(package_name))
                package_name_Arr=package_name.split("/")
                package_name_Arr_len=len(package_name_Arr)
                print("package_name_Arr_len= "+str(package_name_Arr_len))
                assetName=package_name_Arr[package_name_Arr_len-1]
                print("assetName= "+str(assetName))
                assetNameStr=str(assetName)+"."
                
                # 新しい名前
                newName=assetNameStr.replace("Z.","")
                
                # リネームしたいアセット
                asset = unreal.load_asset(package_name)
                
                # 新しいパッケージパス
                new_package_path = package_name+"."
                new_package_path=new_package_path.replace("Z.","")
                
                editor_util.rename_asset(asset, newName)
                
                # リネームデータを作成
                #rename_data = unreal.AssetRenameData(asset, new_package_path, new_name)
                #unreal.EditorUtilityLibrary.rename_asset(rename_data)
                #rename_data_Arr.append(rename_data)
        
        #rename_assets(rename_data_Arr)

依存関係のあるファイルをチェックアウトしてからリネーム

# -*- coding: utf-8 -*- 
import unreal
import sys
import os
import re
import codecs
import os
import datetime
unreal.log("--------------py--start000-----------------")
unreal.log("    ")

class RefferenceCounter():

    def mainWay(self):
        
        self.AssetRegistryLoaded=False
        #----------------------------------------------------------
        self.tickhandle = None
        self.tickhandle = unreal.register_slate_pre_tick_callback(self.testRegistry)
        print("tickhandle="+str(self.tickhandle))

        
    def testRegistry(self,deltaTime):
        unreal.log_warning("ticking...mainWay")
        asset_registry = unreal.AssetRegistryHelpers.get_asset_registry()
        if asset_registry.is_loading_assets():
            unreal.log_warning("still loading...mainWay")
        else:
            unreal.log_warning("ready!.....mainWay")
            if(self.AssetRegistryLoaded==False):
                self.AssetRegistryLoaded=True
                self.textLoad2()
                #self.textLoad()
                
            unreal.unregister_slate_pre_tick_callback(self.tickhandle)
            unreal.unregister_slate_pre_tick_callback(self.tickhandle)

    def getProject_SavedDir(self):
        project_saved_dir=unreal.Paths.project_saved_dir()
        print("project_saved_dir= "+project_saved_dir)
        HD_project_saved_dir=os.path.abspath(project_saved_dir)
        print("HD_project_saved_dir= "+HD_project_saved_dir)
        HD_project_saved_dir_slash=HD_project_saved_dir.replace('\\', '/')
        print("HD_project_saved_dir_slash= "+HD_project_saved_dir_slash)
        return HD_project_saved_dir_slash

    def get_project_dir(self):
        project_dir=unreal.Paths.project_dir()
        print("project_dir= "+project_dir)
        HD_project_dir=os.path.abspath(project_dir)
        print("HD_project_dir= "+HD_project_dir)
        HD_project_dir_slash=HD_project_dir.replace('\\', '/')
        print("HD_project_dir_slash= "+HD_project_dir_slash)
        return HD_project_dir_slash

    def textLoad2(self):
        import codecs
        readPath=self.getProject_SavedDir()+'/RefferenceCounter/SelectedAsset.txt'
        print("readPath= "+readPath)
        fin = codecs.open(readPath, 'r', 'utf_8')
        
        SelectedAssetArr=[]
        for line in fin:
            line=line.replace(" ","")#Space
            line=line.replace(" ","")#TAB
            line=line.replace("\r","")
            line=line.replace("\n","")
            if(line==""):
                pass
            else:
                SelectedAssetArr.append(line)
        #txtData=fin.read()
        print("SelectedAssetArr= "+str(SelectedAssetArr))
        #rejectLines=txtData
        #print("SelectedAssets= "+SelectedAssets)
        self.SelectedAssets=SelectedAssetArr
        self.main_way_start2()

     
    def main_way_start2(self):

        editorAssetLib = unreal.EditorAssetLibrary()
        editor_util = unreal.EditorUtilityLibrary()
        #editorStaticMeshLib = unreal.EditorStaticMeshLibrary()
        MaterialEditingLibrary = unreal.MaterialEditingLibrary()
        asset_registry = unreal.AssetRegistryHelpers.get_asset_registry()

        #import unreal.AssetRegistry
        #AssetRegistry=unreal.AssetRegistry()
        
        EnvName=unreal.Name.cast("/Game/Materials")
        EnvName_Str=editor_util.get_current_content_browser_path()
        EnvName=unreal.Name.cast(EnvName_Str)
        
        #EnvName=unreal.Name.cast(readDirPath)
        EnvArr=unreal.AssetRegistry.get_assets_by_path(asset_registry,EnvName,True,False)
        

        
        unreal.log_warning("main_way_start2 040  unreal.AssetRegistry.get_assets_by_path(asset_registry,EnvName,True,False)")
        unreal.log_warning("main_way_start2 041  get_assets_by_path() EnvArr len= "+str(len(EnvArr)))

        NGlist=[]       
        checkout_Arr=[] 
        checkout_Arr_Str=""
        total_frames = len(EnvArr)
        text_label = "reference And Dependency Checking!"
        with unreal.ScopedSlowTask(total_frames, text_label) as slow_task:
            slow_task.make_dialog(True)               # まだダイアログが表示されていない場合は表示します
            for i in range(total_frames):
                if slow_task.should_cancel():# ユーザーが UI の [Cancel] を押した場合は True
                    break
                slow_task.enter_progress_frame(1)# 1 フレーム次に進めます。
                

                #package_name=EnvArr[i]
                AssetData=EnvArr[i]
                print("AssetData= "+str(AssetData))
                package_name=str(AssetData.package_name)
                print("package_name= "+str(package_name))
                package_name_Arr=package_name.split("/")
                package_name_Arr_len=len(package_name_Arr)
                print("package_name_Arr_len= "+str(package_name_Arr_len))
                assetName=package_name_Arr[package_name_Arr_len-1]
                print("assetName= "+str(assetName))
                
                
                dependency_options=unreal.AssetRegistryDependencyOptions(include_soft_package_references=True, include_hard_package_references=True, include_searchable_names=False, include_soft_management_references=False, include_hard_management_references=False)
                #
                asset_registry = unreal.AssetRegistryHelpers.get_asset_registry()
                dependencies=unreal.AssetRegistry.get_dependencies(asset_registry,package_name, dependency_options)
                referencers=unreal.AssetRegistry.get_referencers(asset_registry,package_name, dependency_options)
                
                dependencies_len=len(dependencies)
                referencers_len=len(referencers)
                print("----------------referencers_len= "+str(referencers_len)+"-------------------")

                dependencies_str=self.array_to_str(dependencies)
                referencers_str=self.array_to_str(referencers)
                all_ref_dependencys_str=dependencies_str+"|"+referencers_str
                all_ref_dependencys_len=referencers_len+dependencies_len
                #A=assetName+","+assetPath
                A=assetName+","+str(referencers_len)+","+referencers_str+","+str(dependencies_len)+","+dependencies_str+","
                A=A+str(all_ref_dependencys_len)+","+all_ref_dependencys_str
                
                checkout_Arr_Str=checkout_Arr_Str+all_ref_dependencys_str+"|"+package_name+"|"
                #A=A+","+str(package_name)
                #for dep in dependencies:
                #    A=A+","+str(dep)
                NGlist.append(A)
                unreal.log_warning(A)
        
        # チェックアウト
        checkout_Arr=checkout_Arr_Str.split("|")
        for checkout_file_path in checkout_Arr:
            if checkout_file_path=="":
                pass
            else:
                unreal.EditorAssetLibrary.checkout_asset(checkout_file_path)
    
        
        self.rename_endZ_remove_loop(EnvName_Str)     
        
    def rename_endZ_remove_loop(self,EnvName_Str):
        editorAssetLib = unreal.EditorAssetLibrary()
        editor_util = unreal.EditorUtilityLibrary()
        #editorStaticMeshLib = unreal.EditorStaticMeshLibrary()
        MaterialEditingLibrary = unreal.MaterialEditingLibrary()
        asset_registry = unreal.AssetRegistryHelpers.get_asset_registry()

        #import unreal.AssetRegistry
        #AssetRegistry=unreal.AssetRegistry()

        EnvName=unreal.Name.cast(EnvName_Str)
        
        #EnvName=unreal.Name.cast(readDirPath)
        EnvArr=unreal.AssetRegistry.get_assets_by_path(asset_registry,EnvName,True,False)
        
        #EnvArr = asset_registry.get_assets()
        #EnvArr =self.SelectedAssets
        
        unreal.log_warning("main_way_start2 040  unreal.AssetRegistry.get_assets_by_path(asset_registry,EnvName,True,False)")
        unreal.log_warning("main_way_start2 041  get_assets_by_path() EnvArr len= "+str(len(EnvArr)))

        NGlist=[]       
        checkout_Arr=[] 
        checkout_Arr_Str=""
        rename_data_Arr=[]
        total_frames = len(EnvArr)
        text_label = "Rename Execution!"
        with unreal.ScopedSlowTask(total_frames, text_label) as slow_task:
            slow_task.make_dialog(True)               # まだダイアログが表示されていない場合は表示します
            for i in range(total_frames):
                if slow_task.should_cancel():# ユーザーが UI の [Cancel] を押した場合は True
                    break
                slow_task.enter_progress_frame(1)# 1 フレーム次に進めます。
                

                AssetData=EnvArr[i]
                print("AssetData= "+str(AssetData))
                package_name=str(AssetData.package_name)
                print("package_name= "+str(package_name))
                package_name_Arr=package_name.split("/")
                package_name_Arr_len=len(package_name_Arr)
                print("package_name_Arr_len= "+str(package_name_Arr_len))
                assetName=package_name_Arr[package_name_Arr_len-1]
                print("assetName= "+str(assetName))
                assetNameStr=str(assetName)+"."
                
                # 新しい名前
                newName=assetNameStr.replace("Z.","")
                
                
                # リネームしたいアセット
                asset = unreal.load_asset(package_name)
                
                # 新しいパッケージパス
                new_package_path = package_name+"."
                new_package_path=new_package_path.replace("Z.","")
                
                editor_util.rename_asset(asset, newName)
                
                # リネームデータを作成
                #rename_data = unreal.AssetRenameData(asset, new_package_path, new_name)
                #unreal.EditorUtilityLibrary.rename_asset(rename_data)
                #rename_data_Arr.append(rename_data)
        
        #rename_assets(rename_data_Arr)

Class_Ins=RefferenceCounter()
Class_Ins.mainWay()

CGWORLD.JPさんから引用、「リネームとリダイレクタはある意味密接な関係にある…

KAEditorUtilityBlueprintLibrary.h

#pragma once
 
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "KAEditorUtilityBlueprintLibrary.generated.h"
 
UCLASS()
class KAEDITORUTILITYTEST_API UKAEditorUtilityBlueprintLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
public:
	//RedirectorをFixUpする
	UFUNCTION(BlueprintCallable, Category = "KAEditorUtility")
	static void FixupRedirectors(const TArray<FAssetData>& Assets, bool bCheckoutDialogPrompt);
};

KAEditorUtilityBlueprintLibrary.cpp

#include "KAEditorUtilityBlueprintLibrary.h"
#include "AssetToolsModule.h"
 
void UKAEditorUtilityBlueprintLibrary::FixupRedirectors(const TArray<FAssetData>& Assets, bool bCheckoutDialogPrompt)
{
	FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>(TEXT("AssetTools"));
	//Redirectorの取得
	TArray<UObjectRedirector*> Redirectors;
	for (FAssetData Object : Assets)
	{
		if (UObjectRedirector* Redirector = Cast<UObjectRedirector>(Object.GetAsset()))
		{
			Redirectors.Emplace(Redirector);
		}
	}
 
	if (Redirectors.Num() > 0)
	{
		AssetToolsModule.Get().FixupReferencers(Redirectors, bCheckoutDialogPrompt);
		return true;
	}
	return false;
}

参考URL

https://cgworld.jp/regular/202312-ue5tool-01.html

https://docs.unrealengine.com/5.0/en-US/PythonAPI/class/EditorAssetLibrary.html