[Unreal Engine]複数のカメラのスクリーンショットを自動的に撮るPython

複数のカメラのスクリーンショットを自動的に撮るPython

Log Python: Automation Library: Failed to convert parameter ‘camera’ when calling function ‘AutomationBlueprintFunctionLibrary.TakeHighResScreenshot’ on ‘Default__AutomationBlueprintFunctionLibrary’ TypeError: NativizeProperty: Cannot nativize ‘SceneCaptureActor’ as ‘Camera’ (ObjectProperty) TypeError: NativizeObject: Cannot nativize ‘SceneCaptureActor’ as ‘Object’ (allowed Class type: ‘CameraActor’)

IS FIX Code

import unreal
import time

class OnTick(object):
  """ Register a function and run it on tick, """
  def __init__(self):
    # make a generator function so we can call next on it,
    
    EditorLevelLibrary = unreal.EditorLevelLibrary()
    all_level_actors=EditorLevelLibrary.get_all_level_actors()
    CameraActors=[]
    for actor in all_level_actors:
        #CameraBool=actor.find_camera_component_when_view_target
        CameraComponent=actor.get_component_by_class(unreal.CameraComponent)
        #print("CameraComponent="+str(CameraComponent))
        #className=CameraComponent.get_class() 
        #print("CameraComponent.get_class() ="+str(className))
        if(str(CameraComponent)=="None"):
            pass
        else:
            #if(str(CameraComponent) in "CineCameraComponent"):
            #    pass
            #else: 
            CameraActors.append(actor)
    
    self.CameraActors=CameraActors
    #self.actors = (actor for actor in unreal.EditorLevelLibrary.get_selected_level_actors())
    self.actors = iter(CameraActors)
    
    self.tickcount=0
    self.CapturedCount=0
    # register a callback on tick
    self.on_tick = unreal.register_slate_post_tick_callback(self.__tick__)
    
    
  def __tick__(self, deltatime):
    """ Function we will call every tick, """
    try:
      print(deltatime) # Print the deltatime just for sanity check so we
      # know a tick was made,
        
      # Get the next actor from our generator function,
      actor = next(self.actors)
      """
      actor_location = actor.get_actor_location()
      actor_rotation = actor.get_actor_rotation() 
      # Solve the camera position, and rotation
      position = actor_location + unreal.Vector(0.0, 0.0, 0.0)

      # roll(z), pitch(tate), yaw(yoko)
      rotation = unreal.Rotator(actor_rotation.roll+0.0, actor_rotation.pitch+5.0,actor_rotation.yaw+0.0)
      
      unreal.EditorLevelLibrary.set_level_viewport_camera_info(
        position,
        rotation
      )
      """
      errorBool=False
      try:
          CameraComponent=actor.get_component_by_class(unreal.CameraComponent)
          print("actor= "+str(actor))
          print("CameraComponent= "+str(CameraComponent))
          unreal.AutomationLibrary.take_high_res_screenshot(
            1920,
            1080,
            str(self.CapturedCount)+"_"+actor.get_name() + ".hdr",
            camera=actor,
            capture_hdr=True,
            comparison_tolerance=unreal.ComparisonTolerance.HIGH
          )
          errorBool=False
          
      except Exception as error:
          errorBool=True
          pass
      
      if(errorBool==False):
          # Count
          self.CapturedCount=self.CapturedCount+1
      """
      unreal.EditorLevelLibrary.pilot_level_actor(actor)
      unreal.EditorLevelLibrary.editor_set_game_view(True)
      # Take the screenshot,
      unreal.AutomationLibrary.take_high_res_screenshot(
        1920,
        1080,
        actor.get_name() + ".hdr",
        camera=actor,
        capture_hdr=True,
        comparison_tolerance=unreal.ComparisonTolerance.HIGH,
        delay=0.25
      )
      
      unreal.EditorLevelLibrary.eject_pilot_level_actor()
      """
      # Count
      self.tickcount=self.tickcount+1
      
      CameraActors=self.CameraActors
      CameraActorsLen=len(CameraActors)
      endActor=CameraActors[CameraActorsLen-1]
      print("self.tickcount="+str(self.tickcount)+"  :CameraActorsLen="+str(CameraActorsLen))
      if(str(self.tickcount)==str(CameraActorsLen)):
          print("finish")
          unreal.unregister_slate_post_tick_callback(self.on_tick)
      
    except Exception as error:
      #pass
      print(error)
      try:
          unreal.unregister_slate_post_tick_callback(self.on_tick)
      except Exception as error:
          pass
#if __name__ == '__main__':
instance = OnTick()

関連URL

https://forums.unrealengine.com/t/python-api-highrescreenshot/132783/10

https://docs.unrealengine.com/5.1/en-US/PythonAPI/class/EditorLevelLibrary.html

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

https://docs.unrealengine.com/5.1/en-US/taking-screenshots-in-unreal-engine/

https://docs.unrealengine.com/4.26/en-US/BlueprintAPI/Utilities/Struct/MakeAutomationScreenshotOptions/

pythonの標準モジュールで windowsにクリップボードにコピーするには?

pyperclipを使わないで、pythonの標準モジュールで windowsにクリップボードにコピーするには?

import subprocess 
s="abcdefg"
print("s=__"+s+"__")
subprocess.run("clip", text=True, input=s)

参考

Python script to copy text to clipboard [duplicate]

https://stackoverflow.com/questions/11063458/python-script-to-copy-text-to-clipboard

[clip / pbcopy・pbpaste]クリップボードにコピー

https://xtech.nikkei.com/it/atcl/column/15/042000103/080400036/

[UnrealEngine]C++ シンプルなクラス構文

クラスの定義はヘッダファイルで行います。

#include <string>
using namespace std;
class Class1
{
// 
private:
	string name; //メンバ変数
// 
public:
	void print1(); //メンバ関数のプロトタイプ宣言
	void print2(); //メンバ関数のプロトタイプ宣言
// 
};

cppでのメソッドの実装

void クラス::実装するメソッド名()

#include "Class1.h"
#include <iostream>
using namespace std;

// 
void Class1::print1()
{
	name = "print1";
	cout << name << "が処理されました\n";

	return;
}
// 
void Class1::print2()
{
	name = "print2";
	cout << name << "が処理されました。どうしてニンニク味のガムってないんだろう?\n";

	return;
}

クラスからインスタンスを生成して利用するサンプルです。

Class1 *インスタンス名 = new Class1();

インスタンス名 – > 使用するメソッド名();

#include "Class1.h"

int main() {

	Class1 *cla2 = new Class1();
	cla2->print1(); //print1が処理されました
	cla2->print2(); //print2が処理されました
	delete cla2;

	return 0;
}

[unrealenghine,photoshop]HDRは32bitなので16bitに変換しないとPNGに保存できない、8bitに変換しないと TGA に保存できない

Can Not HDR Traslate To TGA even if CopySave

 function step_8bit(enabled, withDialog) {
    if (enabled != undefined && !enabled)
      return;
    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
    var desc1 = new ActionDescriptor();
    desc1.putInteger(cTID('Dpth'), 8);
    var desc2 = new ActionDescriptor();
    desc2.putInteger(cTID('Vrsn'), 6);
    desc2.putEnumerated(cTID('Mthd'), sTID("hdrToningMethodType"), sTID("hdrtype4"));
    desc2.putDouble(cTID('Rds '), 7.68);
    desc2.putDouble(cTID('Thsh'), 0.52959457138863);
    desc2.putDouble(cTID('Cntr'), 1);
    desc2.putDouble(cTID('Strt'), 20);
    desc2.putDouble(cTID('Dtl '), 30);
    desc2.putBoolean(cTID('Smoo'), false);
    var desc3 = new ActionDescriptor();
    desc3.putString(cTID('Nm  '), "初期設定");
    var list1 = new ActionList();
    var desc4 = new ActionDescriptor();
    desc4.putDouble(cTID('Hrzn'), 0);
    desc4.putDouble(cTID('Vrtc'), 0);
    list1.putObject(cTID('CrPt'), desc4);
    var desc5 = new ActionDescriptor();
    desc5.putDouble(cTID('Hrzn'), 255);
    desc5.putDouble(cTID('Vrtc'), 255);
    list1.putObject(cTID('CrPt'), desc5);
    desc3.putList(cTID('Crv '), list1);
    desc2.putObject(sTID("classFXShapeCurve"), cTID('ShpC'), desc3);
    desc2.putBoolean(sTID("deghosting"), false);
    desc1.putObject(cTID('With'), sTID("hdrOptions"), desc2);
    executeAction(sTID('convertMode'), desc1, dialogMode);
  };  

  //save TGA  (Can Not  HDR Traslate To TGA even if CopySave)
  function step4_save_tga(savePath){
  step_8bit();
  SaveOptions = new TargaSaveOptions();     
  TargaSaveOptions.alphaChannels = true; //include alpha channels, change to false for none    
  TargaSaveOptions.resolution = TargaBitsPerPixels.TWENTYFOUR; //options of SIXTEEN or THIRTYTWO 
  TargaSaveOptions.rleCompression = true; //false for no compression
  var saveFile = File(savePath); 
  app.activeDocument.saveAs(saveFile, TargaSaveOptions, true,Extension.LOWERCASE);      
  }; 

//---------------------------------------------------------------------------------
function step1_16bit(enabled, withDialog) {
    if (enabled != undefined && !enabled)
      return;
    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
    var desc1 = new ActionDescriptor();
    desc1.putInteger(cTID('Dpth'), 16);
    var desc2 = new ActionDescriptor();
    desc2.putInteger(cTID('Vrsn'), 6);
    desc2.putEnumerated(cTID('Mthd'), sTID("hdrToningMethodType"), sTID("hdrtype4"));
    desc2.putDouble(cTID('Rds '), 7.68);
    desc2.putDouble(cTID('Thsh'), 0.52959457138863);
    desc2.putDouble(cTID('Cntr'), 1);
    desc2.putDouble(cTID('Strt'), 20);
    desc2.putDouble(cTID('Dtl '), 30);
    desc2.putBoolean(cTID('Smoo'), false);
    var desc3 = new ActionDescriptor();
    desc3.putString(cTID('Nm  '), "初期設定");
    var list1 = new ActionList();
    var desc4 = new ActionDescriptor();
    desc4.putDouble(cTID('Hrzn'), 0);
    desc4.putDouble(cTID('Vrtc'), 0);
    list1.putObject(cTID('CrPt'), desc4);
    var desc5 = new ActionDescriptor();
    desc5.putDouble(cTID('Hrzn'), 255);
    desc5.putDouble(cTID('Vrtc'), 255);
    list1.putObject(cTID('CrPt'), desc5);
    desc3.putList(cTID('Crv '), list1);
    desc2.putObject(sTID("classFXShapeCurve"), cTID('ShpC'), desc3);
    desc2.putBoolean(sTID("deghosting"), false);
    desc1.putObject(cTID('With'), sTID("hdrOptions"), desc2);
    executeAction(sTID('convertMode'), desc1, dialogMode);
  };

  //save Png 
  function step4_save(savePath,enabled, withDialog) {
  step1_16bit();
  var file_obj = new File(savePath);
  var png_opt = new PNGSaveOptions();
  png_opt.interlaced = false;
  var savedDisplayDialogs = app.displayDialogs;
  app.displayDialogs = DialogModes.NO;
  activeDoc=app.activeDocument;
  app.activeDocument.saveAs(file_obj, png_opt, true, Extension.LOWERCASE);
  
  }
//---------------------------------------------------------------------------------


  // save HDR (HDR to HDR)
  function step4_save(savePath,enabled, withDialog) {
    if (enabled != undefined && !enabled)
      return;
    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
    var desc1 = new ActionDescriptor();
    desc1.putString(cTID('As  '), "Radiance");
    desc1.putPath(cTID('In  '), new File(savePath));
    desc1.putInteger(cTID('DocI'), 70);
    desc1.putBoolean(cTID('LwCs'), true);
    executeAction(sTID('save'), desc1, dialogMode);
  };

参考

Targa形式で保存する

http://www.openspc2.org/book/PhotoshopCC2014/easy/save/010/index.html

[unrealEngine,Maya]で腕や足がスカートを貫通しないようにしたい

あくまで、自分の研究例ですと
スカートで足に追従させたいものは
「膝にスキニングしたほうが作業的に効率的」です。
ジャンプや走るモーションで
前側のスカートは膝で突き破るので、
膝にスキンウェイト当てておきます。
というより

タイトスカートのスキンウェイトは、まず足にスキンウェイトを足の一部のようにスキンウェイトをコピーします。
前側の又の部分は左右の足から同じ左0.5、右0.5になるようにスキンウェイトします。
ロングタイトスカートはこれでできます。

スカートのケージモデルが膝に追従する例です。
ただ、まだ、突き破っているので、スカートモデルと体の隙間をもっと大きくした方がいいでしょう


あとは物理で動かしたい頂点は下のようにします
さらに、フレアスカートの場合は
スカートの左右と後ろ部分は、放射状にジョイントをいれヒザのスキンウェイトとグラデーションするようにスキンウェイトします。あとは、おかずさんのkawaii physics で、マニュアル通り設定します。

関連

AmbitionEarlyHourSky

#アンリアルクエスト に出したゲームのクオリティをアップした。

キャラクターの作り直しを何度もやった。

ハイヒールのカラーをルブタンみたいにして

ニーアみたいなマスクをつけて
kawaiiphysicsでスカートをひらひらさせた。
kawaiiphysicsで胸も揺らした
kawaiiphysicsで髪をなびくようにジョイントを入れ

レベルデザインも少しちゃんとした。

#kawaiiphysics #UE4 #Unrealお兄さん と#塩谷さん と #おかず さん の おかげです。

ダウンロードはこちら

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

最近開いてみたらこんなエラーが出た

This Project requires the ‘ShallowWater’ plugin whitch could not be found.Would you like to desable it continue?If you do you will no longer be able to open any assets created with it. if not the application will close.

このプロジェクトには、見つからなかった「ShallowWater」プラグインが必要です。引き続き無効にしますか?そうすると、それで作成されたアセットを開くことができなくなります。 そうでない場合、アプリケーションは終了します。

ビルドの必要がありそうなので

A案

cd C:\Program Files\Epic Games\UE_5.0\Engine\Build\BatchFiles
Build.bat AmbitionEarlyHourSky Win64 Development "F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\AmbitionEarlyHourSky.uproject" -rocket

B案

cd C:\Program Files\Epic Games\UE_5.0\Engine\Binaries\DotNET\UnrealBuildTool
UnrealBuildTool.exe AmbitionEarlyHourSky Win64 Development "F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\AmbitionEarlyHourSky.uproject" -rocket

ERROR: Unable to find plugin ‘ShallowWater’ (referenced via AmbitionEarlyHourSky.uproject). Install it and try again, or remove it from the required plugin list.

と言われるので。

AmbitionEarlyHourSky.uprojectの Plugin から ShallowWaterを消す。

{
	"FileVersion": 3,
	"EngineAssociation": "5.0",
	"Category": "",
	"Description": "",
	"Modules": [
		{
			"Name": "AmbitionEarlyHourSky",
			"Type": "Runtime",
			"LoadingPhase": "Default",
			"AdditionalDependencies": [
				"Engine"
			]
		}
	],
	"Plugins": [
		{
			"Name": "ShallowWater",
			"Enabled": true
		},
		{
			"Name": "Water",
			"Enabled": true
		},
		{
			"Name": "PythonScriptPlugin",
			"Enabled": true
		},
		{
			"Name": "EditorScriptingUtilities",
			"Enabled": true
		},
		{
			"Name": "Bridge",
			"Enabled": true,
			"SupportedTargetPlatforms": [
				"Win64",
				"Mac",
				"Linux"
			]
		}
	]
}

Build.batできたっぽい


C:\Users\furcr>cd C:\Program Files\Epic Games\UE_5.0\Engine\Binaries\Win64\

C:\Program Files\Epic Games\UE_5.0\Engine\Binaries\Win64>cd ../../

C:\Program Files\Epic Games\UE_5.0\Engine>cd C:\Program Files\Epic Games\UE_5.0\Engine\Build\BatchFiles

C:\Program Files\Epic Games\UE_5.0\Engine\Build\BatchFiles>Build.bat AmbitionEarlyHourSky Win64 Development "F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\AmbitionEarlyHourSky.uproject" -rocket
Using bundled DotNet SDK
Log file: C:\Users\furcr\AppData\Local\UnrealBuildTool\Log.txt
Creating makefile for AmbitionEarlyHourSky (Build.version is newer)
ERROR: Unable to find plugin 'ShallowWater' (referenced via AmbitionEarlyHourSky.uproject). Install it and try again, or remove it from the required plugin list.

C:\Program Files\Epic Games\UE_5.0\Engine\Build\BatchFiles>Build.bat AmbitionEarlyHourSky Win64 Development "F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\AmbitionEarlyHourSky.uproject" -rocket
Using bundled DotNet SDK
Log file: C:\Users\furcr\AppData\Local\UnrealBuildTool\Log.txt
Creating makefile for AmbitionEarlyHourSky (Build.version is newer)
Parsing headers for AmbitionEarlyHourSky
  Running UnrealHeaderTool "F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\AmbitionEarlyHourSky.uproject" "F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\Intermediate\Build\Win64\AmbitionEarlyHourSky\Development\AmbitionEarlyHourSky.uhtmanifest" -LogCmds="loginit warning, logexit warning, logdatabase error" -Unattended -WarningsAsErrors -abslog="C:\Users\furcr\AppData\Local\UnrealBuildTool\Log_UHT.txt" -installed
Reflection code generated for AmbitionEarlyHourSky in 6.3933034 seconds
Building AmbitionEarlyHourSky...
Using Visual Studio 2019 14.29.30141 toolchain (C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133) and Windows 10.0.18362.0 SDK (C:\Program Files (x86)\Windows Kits\10).
[Adaptive Build] Excluded from AmbitionEarlyHourSky unity file: MyBlueprintFunctionLibrary.cpp, SaveToText.cpp, TextFileToString.cpp, AmbitionEarlyHourSky.cpp, AmbitionEarlyHourSkyCharacter.cpp, AmbitionEarlyHourSkyGameMode.cpp
Distributing 23 actions to XGE
--------------------Build System Warning---------------------------------------
License is invalid:
    License information is invalid. Please try reloading your license file using the Coordinator Monitor application on the Coordinator machine, or reinstall IncrediBuild.
    This build will run in standalone mode.

-------------------------------------------------------------------------------

Build ID: {5E64F7BF-47B0-4AF8-8F9B-4464A50705EC}

--------------------Project: Default-------------------------------------------
[1/23] SharedPCH.Engine.ShadowErrors.cpp (0:51.37 at +0:00)
[2/23] OpenImageDenoise.dll (0:00.64 at +0:51)
[3/23] tbb.dll (0:00.26 at +0:52)
[4/23] d3d12SDKLayers.dll (0:00.31 at +0:52)
[5/23] D3D12Core.dll (0:00.28 at +0:52)
[6/23] tbb12.dll (0:00.31 at +0:52)
[7/23] AmbitionEarlyHourSkyCharacter.cpp (0:01.64 at +0:53)
[8/23] AmbitionEarlyHourSkyGameMode.cpp (0:01.01 at +0:54)
[9/23] SaveToText.cpp (0:00.60 at +0:55)
[10/23] MyBlueprintFunctionLibrary.gen.cpp (0:00.62 at +0:56)
[11/23] AmbitionEarlyHourSkyCharacter.gen.cpp (0:00.92 at +0:57)
[12/23] MyBlueprintFunctionLibrary.cpp (0:00.57 at +0:58)
[13/23] TextFileToString.gen.cpp (0:00.62 at +0:58)
[14/23] AmbitionEarlyHourSky.cpp (0:00.70 at +0:59)
[15/23] AmbitionEarlyHourSky.init.gen.cpp (0:00.64 at +1:00)
[16/23] TextFileToString.cpp (0:15.11 at +1:00)
[17/23] AmbitionEarlyHourSkyGameMode.gen.cpp (0:01.00 at +1:15)
[18/23] Default.rc2 (0:00.48 at +1:16)
[19/23] Module.KawaiiPhysics.cpp (0:03.53 at +1:17)
[20/23] Module.KawaiiPhysics.gen.cpp (0:03.40 at +1:20)
[21/23] SaveToText.gen.cpp (0:00.65 at +1:24)
[22/23] AmbitionEarlyHourSky.exe (0:26.03 at +1:24)
   Creating library F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\Binaries\Win64\AmbitionEarlyHourSky.lib and object F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\Binaries\Win64\AmbitionEarlyHourSky.exp
[23/23] AmbitionEarlyHourSky.target (0:00.34 at +1:50)
---------------------- Done ----------------------

    Rebuild All: 1 succeeded, 0 failed, 0 skipped

1 build system warning(s):
   - License is invalid

Total time in XGE executor: 111.50 seconds
Total execution time: 128.20 seconds

C:\Program Files\Epic Games\UE_5.0\Engine\Build\BatchFiles>

リビルドするか聞かれる。リビルドで、30秒後ぐらいに起動した!

スカートのリグなどを頑張ったオリジナル作品のAmbitionSkyWaterをUE5でビルドしなおして、ポスプロなどブラッシュアップして動画を取り直した #UE5 #UnrealEngine5 #スカート #リグ #Rig #skirts

[maya]AnimCurveへの掛け算、足し算

掛け算は scaleKey の valueScale を使う

from maya import cmds 
import pymel.core as pm 

# translate
obj="sphere1"
trans1=".tx"
                    pm.scaleKey([str(obj) + trans1],
                     valuePivot=0, timeScale=1, 
                     hierarchy='none', 
                     float=(min,max), 
                     floatPivot=0, valueScale=-1, 
                     timePivot=0, scaleSpecifiedKeys=1, 
                     shape=1, time=(min,max), 
                     floatScale=1, controlPoints=0)

#rotation
pm.scaleKey([str(obj) + rot2], 
                        valuePivot=0, 
                        timeScale=1, 
                        hierarchy='none', 
                        float=(min,max), 
                        floatPivot=0, valueScale=-1, 
                        timePivot=0, scaleSpecifiedKeys=1, 
                        shape=1, 
                        time=(min,max), 
                        floatScale=1, controlPoints=0)

足し算は pm.pasteKey の valueOffset を使う

#min max
    animCurve_Arr = cmds.ls( type="animCurve" );
    print("animCurve_Arr= "+str(animCurve_Arr))
    min=0
    max=0
    for animCurve in animCurve_Arr:
        newMin = cmds.findKeyframe(animCurve,which="first")
        newMax = cmds.findKeyframe(animCurve,which="last")
        #print("newMin= "+str(newMin))
        #print("newMax= "+str(newMax))
        if(newMin<min):    
            min=newMin
            
        if(newMax>max):
            max=newMax
                
    print("min= "+str(min))
    print("max= "+str(max))

#rotaion
pm.copyKey((obj + rot1), hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
pm.cutKey((obj + rot1), f=(min,max), t=(min,max), cl=1)
pm.pasteKey((obj + rot1), floatOffset=0, option='replace', copies=1, valueOffset=180, connect=1, timeOffset=0)
         
               

以下は Maya2022 >Bonus Tools >Animation >Mirror Animation のmelを

をPythonに変換したもの

例 モーションのアニムカーブのミラーのサンプル


def bt_applyMirrorAnim(axis, method, xforms, ignore, custom):
    
    trans = ""
    rot1 = ""
    rot2 = ""
    connection = []
    lockCheck1 = []
    lockCheck2 = []
    attrListOrig = []
    attrListFinal = []
    objList=cmds.ls(allPaths=1,long=1, selection=1)
    print("objList= "+str(objList))
    attrCount=0
    if xforms[0]==1:
        #attrListOrig[attrCount]=".tx"
        attrListOrig.append(".tx")
        attrCount+=1
        #attrListOrig[attrCount]=".ty"
        attrListOrig.append(".ty")
        attrCount+=1
        #attrListOrig[attrCount]=".tz"
        attrListOrig.append(".tz")
        attrCount+=1
        
    if xforms[1]==1:
        #attrListOrig[attrCount]=".rx"
        attrListOrig.append(".rx")
        attrCount+=1
        #attrListOrig[attrCount]=".ry"
        attrListOrig.append(".ry")
        attrCount+=1
        #attrListOrig[attrCount]=".rz"
        attrListOrig.append(".rz")
        attrCount+=1
        
    if xforms[2]==1:
        #attrListOrig[attrCount]=".sx"
        attrListOrig.append(".sx")
        attrCount+=1
        #attrListOrig[attrCount]=".sy"
        attrListOrig.append(".sy")
        attrCount+=1
        #attrListOrig[attrCount]=".sz"
        attrListOrig.append(".sz")
        attrCount+=1
        
    if (custom == 1) and (len(objList) == 2):
        userAttrList=pm.listAttr(objList[0], userDefined=1)
        #Look for custom attrs on first object
        for uAttr in userAttrList:
            if pm.mel.attributeExists(uAttr, objList[1]):
                #attrListOrig[attrCount]=("." + str(uAttr))
                attrListOrig.append("." + str(uAttr))
                #Check for same attr on second
                attrCount+=1

            
        
    if axis == 1:
        trans=".tx"
        rot1=".ry"
        rot2=".rz"
        
    
    elif axis == 2:
        trans=".ty"
        rot1=".rx"
        rot2=".rz"
        
    
    elif axis == 3:
        trans=".tz"
        rot1=".rx"
        rot2=".ry"
        
    elif axis == 4:
        trans=".ty"
        rot1=".ry"
        rot2=".rz"

    elif axis == 5:
        trans1=".tx"
        trans2=".ty"
        trans3=".tz"
        rot3=".rz"

    elif axis == 6:
        trans=".tx"
        trans1=".tx"
        trans2=".ty"
        trans3=".tz"
        rot1=".rx"
        rot2=".ry"
        rot3=".rz"

    animCurve_Arr = cmds.ls( type="animCurve" );
    print("animCurve_Arr= "+str(animCurve_Arr))
    min=0
    max=0
    for animCurve in animCurve_Arr:
        newMin = cmds.findKeyframe(animCurve,which="first")
        newMax = cmds.findKeyframe(animCurve,which="last")
        #print("newMin= "+str(newMin))
        #print("newMax= "+str(newMax))
        if(newMin<min):    
            min=newMin
            
        if(newMax>max):
            max=newMax
                
    print("min= "+str(min))
    print("max= "+str(max))

    """
    if (custom == 1) and (method == 5):
        # 接続を解除
        for obj in objList:
            deleteConnection(obj+".tx")
            deleteConnection(obj+".ty")
            deleteConnection(obj+".tz")
            deleteConnection(obj+".rx")
            deleteConnection(obj+".ry")
            deleteConnection(obj+".rz")
    """       
    if method == 4:
        print("method= 4   minus Mode...")
        if len(objList) != 2:
            print("Not 2 selected")
        
        """
        elif axis == 4:
        trans=".ty"
        rot1=".ry"
        rot2=".rz"

        """
        for obj in objList:
            print("obj= "+str(obj))
            if xforms[0]:
                lockCheck1=pm.listAttr((str(obj) + trans), l=1)
                
                # invert appropriate attrs and/or curves for objects
                #Translate
                if len(lockCheck1) == 0:
                    print("trans= "+str(trans))
                    #print(u"Inverting static value and/or animation for " + str(obj) + trans + "")
                    AttValue=pm.getAttr(str(obj) + trans)
                    print("AttValue= "+str(AttValue))
                    pm.setAttr((str(obj) + trans), (AttValue * -1))
                    #pm.setAttr((str(obj) + trans), (AttValue ))
                    pm.scaleKey([str(obj) + trans],
                     valuePivot=0, timeScale=1, 
                     hierarchy='none', 
                     float=(min,max), 
                     floatPivot=0, valueScale=-1, 
                     timePivot=0, scaleSpecifiedKeys=1, 
                     shape=1, time=(min,max), 
                     floatScale=1, controlPoints=0)
                    
                  
            if xforms[1]:
                animCurve_rot1=cmds.listConnections((str(obj) + rot1), t="animCurve")
                print("animCurve_rot1="+str(animCurve_rot1))
                lockCheck1=pm.listAttr((str(obj) + rot1), l=1)
                #Rotate
                if len(lockCheck1) == 0:
                    print("rot1= "+str(rot1))
                    print(u"Inverting static values and/or animation for " + str(obj) + rot1 + "")
                    
                    #pm.setAttr((str(obj) + rot1), (pm.getAttr(str(obj) + rot1) ))
                    #cmds.keyframe((str(obj) + rot1),e=True, time=(), r=True, vc=180)
                    """
                    pm.scaleKey([str(obj) + rot1], 
                        valuePivot=0, 
                        timeScale=1, 
                        hierarchy='none', 
                        float=(min,max), 
                        floatPivot=0, valueScale=+180, 
                        timePivot=0, scaleSpecifiedKeys=1, 
                        shape=1, 
                        time=(min,max), 
                        floatScale=1, controlPoints=0)
                    """
                    
                connection=pm.listConnections((obj + rot1), s=True, d=False)
                if(len(connection)>0):
                    if pm.mel.isAnimCurve(connection[0]):
                        print("obj= "+obj + " rot1= "+rot1)
                        pm.copyKey((obj + rot1), 
                            hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
                        pm.cutKey((obj + rot1), 
                            f=(min,max), t=(min,max), cl=1)
                        pm.pasteKey((obj + rot1), 
                            floatOffset=0, option='replace', copies=1, valueOffset=180, connect=1, timeOffset=0)
                        
                   
                    else:
                        val=pm.getAttr(obj + rot3)
                        pm.setAttr((obj + rot3),  val+180)
                    
                    
                    
                animCurve_rot2=cmds.listConnections((str(obj) + rot2), t="animCurve")
                print("animCurve_rot2="+str(animCurve_rot2))     
                lockCheck1=pm.listAttr((str(obj) + rot2), l=1)
                if len(lockCheck1) == 0:
                    print("rot2= "+str(rot2))
                    print(u"Inverting static values and/or animation for " + str(obj) + rot2 + "")
                    pm.setAttr((str(obj) + rot2), (pm.getAttr(str(obj) + rot2) * -1))
                    pm.scaleKey([str(obj) + rot2], 
                        valuePivot=0, 
                        timeScale=1, 
                        hierarchy='none', 
                        float=(min,max), 
                        floatPivot=0, valueScale=-1, 
                        timePivot=0, scaleSpecifiedKeys=1, 
                        shape=1, 
                        time=(min,max), 
                        floatScale=1, controlPoints=0)
                    
                    
    elif method == 2:
        print("method=2   minus Mode...")
        if len(objList) != 2:
            print("Not 2 selected ")
        

        for obj in objList:
            print("obj= "+str(obj))
            if xforms[0]:
                lockCheck1=pm.listAttr((str(obj) + trans), l=1)
                
                # invert appropriate attrs and/or curves for objects
                #Translate
                if len(lockCheck1) == 0:
                    print("trans")
                    #print(u"Inverting static value and/or animation for " + str(obj) + trans + "")
                    AttValue=pm.getAttr(str(obj) + trans)
                    print("AttValue= "+str(AttValue))
                    pm.setAttr((str(obj) + trans), (AttValue * -1))
                    pm.scaleKey([str(obj) + trans], 
                    valuePivot=0, timeScale=1, 
                    hierarchy='none', float=(min,max), 
                    floatPivot=0, valueScale=-1, timePivot=0, 
                    scaleSpecifiedKeys=1, shape=1, 
                    time=(min,max), floatScale=1, 
                    controlPoints=0)
                    
                  
            if xforms[1]:
                lockCheck1=pm.listAttr((str(obj) + rot1), l=1)
                #Rotate
                if len(lockCheck1) == 0:
                    print("rot1")
                    print(u"Inverting static values and/or animation for " + str(obj) + rot1 + "")
                    pm.setAttr((str(obj) + rot1), (pm.getAttr(str(obj) + rot1) * -1))
                    pm.scaleKey([str(obj) + rot1], 
                        valuePivot=0, 
                        timeScale=1, 
                        hierarchy='none', 
                        float=(min,max), 
                        floatPivot=0, valueScale=-1, 
                        timePivot=0, scaleSpecifiedKeys=1, 
                        shape=1, 
                        time=(min,max), 
                        floatScale=1, controlPoints=0)
                     
                lockCheck1=pm.listAttr((str(obj) + rot2), l=1)
                if len(lockCheck1) == 0:
                    print("rot2")
                    print(u"Inverting static values and/or animation for " + str(obj) + rot2 + "")
                    pm.setAttr((str(obj) + rot2), (pm.getAttr(str(obj) + rot2) * -1))
                    pm.scaleKey([str(obj) + rot2], 
                        valuePivot=0, 
                        timeScale=1, 
                        hierarchy='none', 
                        float=(min,max), 
                        floatPivot=0, valueScale=-1, 
                        timePivot=0, scaleSpecifiedKeys=1, 
                        shape=1, 
                        time=(min,max), 
                        floatScale=1, controlPoints=0)
                    
                
            

    elif (method == 1) and (len(objList) == 2):
        print("method 1  base  No minus Mode...")
        print("elif (method == 1) and (len(objList) == 2)")
        
        first=objList[0]
        second=objList[1]
        print("first= "+str(first))
        print("second= "+str(second))
        print(u"Mirroring static values and animation for " + trans + ", " + rot1 + " and " + rot2 + " animation for " + str(first) + " and " + str(second) + "")
        #Check attrs for editability
        count=0
        for attr in attrListOrig:
            lockCheck1=pm.listAttr((first + attr), 
                l=1)
            lockCheck2=pm.listAttr((second + attr), 
                l=1)
            if (len(lockCheck1) != 0) and (ignore == 1):
                print("Ignoring " + str(first) + str(attr) + " because it is locked.")
                continue
                
            
            elif (len(lockCheck1) != 0) and (ignore == 0):
                print("Aborting : " + str(first) + str(attr) + " is locked.  Either unlock attributes or turn on IgnoreLockedAttributs in mirror options")
                
            
            elif (len(lockCheck2) != 0) and (ignore == 1):
                print("Ignoring " + str(second) + str(attr) + " because it is locked.")
                continue
                
            
            elif (len(lockCheck2) != 0) and (ignore == 0):
                print("Aborting : " + str(second) + str(attr) + " is locked.  Either unlock attributes or turn on IgnoreLockedAttributs in mirror options")
                
            
            else:
                #attrListFinal[count]=str(attr)
                attrListFinal.append(str(attr))
                count+=1
                
           
        cmds.select(first, r=1)
        #pm.mel.duplicatePreset(1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1)
        cmds.duplicate(returnRootsOnly=1)
        dup=cmds.ls(sl=True)
        tmpObj=cmds.rename(dup[0], 'tmp_transfer_obj')
        for attr in attrListFinal:
            connection=pm.listConnections((first + attr), s=True, d=False)
            #print("connection= "+str(connection) )
            
            if(len(connection)>0):
                if pm.mel.isAnimCurve(connection[0]):
                    #animCurve_Arr = cmds.ls( type="animCurve" );
                    #print("connection[0]= "+str(connection[0]) )
                    #newMin = cmds.findKeyframe(connection[0],which="first")
                    #newMax = cmds.findKeyframe(connection[0],which="last")
                    print("first= "+first + " attr= "+attr)
                    pm.copyKey((first + attr), 
                        hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
             
                        
                    pm.cutKey((tmpObj + attr),f=(min,max), t=(min,max), cl=1)
                    pm.pasteKey((tmpObj + attr),floatOffset=0, option='replace', copies=1, valueOffset=0, connect=1, timeOffset=0)
                      
                
                else:
                    val=pm.getAttr(first + attr)
                    pm.setAttr((tmpObj + attr),  val)
        
            
        for attr in attrListFinal:
            connection=pm.listConnections((second + attr), s=True, d=False)
            if(len(connection)>0):
                if pm.mel.isAnimCurve(connection[0]):
                    print("second= "+second + " attr= "+attr)
                    pm.copyKey((second + attr), 
                        hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
                    pm.cutKey((first + attr), 
                        f=(min,max), t=(min,max), cl=1)
                    pm.pasteKey((first + attr), 
                        floatOffset=0, option='replace', copies=1, valueOffset=0, connect=1, timeOffset=0)
                    
               
                else:
                    val=pm.getAttr(second + attr)
                    pm.setAttr((first + attr),  val)
                
       
        for attr in attrListFinal:
            connection=pm.listConnections((tmpObj + attr), s=True, d=False)
            if(len(connection)>0):
                if pm.mel.isAnimCurve(connection[0]):
                    print("tmpObj= "+tmpObj + " attr= "+attr)
                    pm.copyKey((tmpObj + attr), 
                        hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
                    pm.cutKey((second + attr), 
                        f=(min,max), t=(min,max), cl=1)
                    pm.pasteKey((second + attr), 
                        floatOffset=0, option='replace', copies=1, valueOffset=0, connect=1, timeOffset=0)
                    
                
                else:
                    val=pm.getAttr(tmpObj + attr)
                    pm.setAttr((second + attr),  val)
                
    
        if xforms[0]:
            lockCheck1=pm.listAttr((str(first) + trans), 
                l=1)
            #if translate is on
            if len(lockCheck1) == 0:
                print("first= "+first + " trans= "+trans)
                #pm.setAttr((str(first) + trans), (pm.getAttr(str(first) + trans) * -1))
                pm.setAttr((str(first) + trans), (pm.getAttr(str(first) + trans) ))
                pm.scaleKey([str(first) + trans], 
                    scaleSpecifiedKeys=1, valuePivot=0, valueScale=1)
                
            lockCheck1=pm.listAttr((str(second) + trans), 
                l=1)
            if len(lockCheck1) == 0:
                print("second= "+second + " trans= "+trans)
                #pm.setAttr((str(second) + trans), (pm.getAttr(str(second) + trans) * -1))
                pm.setAttr((str(second) + trans), (pm.getAttr(str(second) + trans) ))
                pm.scaleKey([str(second) + trans], 
                    scaleSpecifiedKeys=1, valuePivot=0, valueScale=1)
                
            
        if xforms[1]:
            lockCheck1=pm.listAttr((str(first) + rot1), 
                l=1)
            #if rotate is on
            if len(lockCheck1) == 0:
                print("first= "+first + " rot1= "+rot1)
                #pm.setAttr((str(first) + rot1), (pm.getAttr(str(first) + rot1) * -1))
                pm.setAttr((str(first) + rot1), (pm.getAttr(str(first) + rot1) ))
                pm.scaleKey([str(first) + rot1], 
                    scaleSpecifiedKeys=1, valuePivot=0, valueScale=1)
                
            lockCheck1=pm.listAttr((str(first) + rot2), 
                l=1)
            if len(lockCheck1) == 0:
                print("first= "+first + " rot2= "+rot2)
                #pm.setAttr((str(first) + rot2), (pm.getAttr(str(first) + rot2) * -1))
                pm.setAttr((str(first) + rot2), (pm.getAttr(str(first) + rot2) ))
                pm.scaleKey([str(first) + rot2], 
                    scaleSpecifiedKeys=1, valuePivot=0, valueScale=1)
                
            lockCheck1=pm.listAttr((str(second) + rot1), 
                l=1)
            if len(lockCheck1) == 0:
                print("second= "+second + " rot1= "+rot1)
                #pm.setAttr((str(second) + rot1), (pm.getAttr(str(second) + rot1) * -1))
                pm.setAttr((str(second) + rot1), (pm.getAttr(str(second) + rot1) ))
                pm.scaleKey([str(second) + rot1], 
                    scaleSpecifiedKeys=1, valuePivot=0, valueScale=1)
                
            lockCheck1=pm.listAttr((str(second) + rot2), 
                l=1)
            if len(lockCheck1) == 0:
                print("second= "+second + " rot2= "+rot2)
                #pm.setAttr((str(second) + rot2), (pm.getAttr(str(second) + rot2) * -1))
                pm.setAttr((str(second) + rot2), (pm.getAttr(str(second) + rot2) ))
                pm.scaleKey([str(second) + rot2], 
                    scaleSpecifiedKeys=1, valuePivot=0, valueScale=1)
                
            
        pm.delete(tmpObj)
        cmds.select(objList, r=1)
        # Reset frame to current time so that changes are visually updated
        t=cmds.currentTime(query=1)
        cmds.currentTime(t, e=1)

    elif (method == 3) and (len(objList) == 2):
        print("equip_LR_mode------------------------------------------------")
        print("elif (method == 3)")
        
        first=objList[0]
        second=objList[1]
        print("first= "+str(first))
        print("second= "+str(second))
        print(u"Mirroring static values and animation for " + trans + ", " + rot1 + " and " + rot2 + " animation for " + str(first) + " and " + str(second) + "")
        #Check attrs for editability
        count=0
        for attr in attrListOrig:
            print("first= "+str(first)+" attr1= " +str(attr))
            lockCheck1=pm.listAttr((first + attr), 
                l=1)
            lockCheck2=pm.listAttr((second + attr), 
                l=1)
            if (len(lockCheck1) != 0) and (ignore == 1):
                print("Ignoring " + str(first) + str(attr) + " because it is locked.")
                continue
                
            
            elif (len(lockCheck1) != 0) and (ignore == 0):
                print("Aborting : " + str(first) + str(attr) + " is locked.  Either unlock attributes or turn on IgnoreLockedAttributs in mirror options")
                
            
            elif (len(lockCheck2) != 0) and (ignore == 1):
                print("Ignoring " + str(second) + str(attr) + " because it is locked.")
                continue
                
            
            elif (len(lockCheck2) != 0) and (ignore == 0):
                print("Aborting : " + str(second) + str(attr) + " is locked.  Either unlock attributes or turn on IgnoreLockedAttributs in mirror options")
                
            
            else:
                #attrListFinal[count]=str(attr)
                attrListFinal.append(str(attr))
                count+=1
                
           
        cmds.select(first, r=1)
        #pm.mel.duplicatePreset(1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1)
        cmds.duplicate(returnRootsOnly=1)
        dup=cmds.ls(sl=True)
        tmpObj=cmds.rename(dup[0], 'tmp_transfer_obj')
        for attr in attrListFinal:
            connection=pm.listConnections((first + attr), s=True, d=False)
            #print("connection= "+str(connection) )
            
            if(len(connection)>0):
                if pm.mel.isAnimCurve(connection[0]):
                    #animCurve_Arr = cmds.ls( type="animCurve" );
                    #print("connection[0]= "+str(connection[0]) )
                    #newMin = cmds.findKeyframe(connection[0],which="first")
                    #newMax = cmds.findKeyframe(connection[0],which="last")
                    print("tmp_transfer_obj  pasteKey first= "+str(first)+" attr1= " +str(attr))
                    pm.copyKey((first + attr), 
                        hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
             
                        
                    pm.cutKey((tmpObj + attr), 
                        f=(min,max), t=(min,max), cl=1)
                    pm.pasteKey((tmpObj + attr), 
                        floatOffset=0, option='replace', copies=1, valueOffset=0, connect=1, timeOffset=0)
                      
                
                else:
                    val=pm.getAttr(first + attr)
                    pm.setAttr((tmpObj + attr),  val)
        
            
        for attr in attrListFinal:
            connection=pm.listConnections((second + attr), s=True, d=False)
            if(len(connection)>0):
                if pm.mel.isAnimCurve(connection[0]):
                    print("tmp_transfer_obj  pasteKey attr2= " +str(attr))
                    pm.copyKey((second + attr), 
                        hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
                    pm.cutKey((first + attr), 
                        f=(min,max), t=(min,max), cl=1)
                    pm.pasteKey((first + attr), 
                        floatOffset=0, option='replace', copies=1, valueOffset=0, connect=1, timeOffset=0)
                    
               
                else:
                    val=pm.getAttr(second + attr)
                    pm.setAttr((first + attr),  val)
                
       
        for attr in attrListFinal:
            connection=pm.listConnections((tmpObj + attr), s=True, d=False)
            if(len(connection)>0):
                if pm.mel.isAnimCurve(connection[0]):
                    print("tmp_transfer_obj  pasteKey attr3= " +str(attr))
                    pm.copyKey((tmpObj + attr), 
                        hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
                    pm.cutKey((second + attr), 
                        f=(min,max), t=(min,max), cl=1)
                    pm.pasteKey((second + attr), 
                        floatOffset=0, option='replace', copies=1, valueOffset=0, connect=1, timeOffset=0)
                    
                
                else:
                    val=pm.getAttr(tmpObj + attr)
                    pm.setAttr((second + attr),  val)
                
    
        if xforms[0]:
            lockCheck1=pm.listAttr((str(first) + trans), l=1)
            #if translate is on
            if len(lockCheck1) == 0:
                print("else tx   first"+str(first)+" trans1= " +str(trans1))
                pm.setAttr((str(first) + trans1), (pm.getAttr(str(first) + trans1) * -1))
                pm.scaleKey([str(first) + trans1],scaleSpecifiedKeys=1, valuePivot=0, valueScale=-1)
                print("else ty   first"+str(first)+" trans2= " +str(trans2))
                pm.setAttr((str(first) + trans2), (pm.getAttr(str(first) + trans2) * -1))
                pm.scaleKey([str(first) + trans2],scaleSpecifiedKeys=1, valuePivot=0, valueScale=-1)
                print("else tz   first"+str(first)+" trans3= " +str(trans3))
                pm.setAttr((str(first) + trans3), (pm.getAttr(str(first) + trans3) * -1))
                pm.scaleKey([str(first) + trans3],scaleSpecifiedKeys=1, valuePivot=0, valueScale=-1)
                
                print("else tx   second"+str(second)+" trans1= " +str(trans1))
                pm.setAttr((str(second) + trans1), (pm.getAttr(str(second) + trans1) * -1))
                pm.scaleKey([str(second) + trans1],scaleSpecifiedKeys=1, valuePivot=0, valueScale=-1)
                print("else ty   second"+str(second)+" trans2= " +str(trans2))
                pm.setAttr((str(second) + trans2), (pm.getAttr(str(second) + trans2) * -1))
                pm.scaleKey([str(second) + trans2],scaleSpecifiedKeys=1, valuePivot=0, valueScale=-1)
                print("else tz   second"+str(second)+" trans3= " +str(trans3))
                pm.setAttr((str(second) + trans3), (pm.getAttr(str(second) + trans3) * -1))
                pm.scaleKey([str(second) + trans3],scaleSpecifiedKeys=1, valuePivot=0, valueScale=-1)
    
        """    
        if xforms[1]:
            lockCheck1=pm.listAttr((str(first) + rot3), 
            if len(lockCheck1) == 0:
                print("------")
                connection=pm.listConnections((obj + rot1), s=True, d=False)
                if(len(connection)>0):
                    if pm.mel.isAnimCurve(connection[0]):
                        print("obj= "+obj + " rot1= "+rot1)
                        pm.copyKey((obj + rot1), 
                            hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
                        pm.cutKey((obj + rot1), 
                            f=(min,max), t=(min,max), cl=1)
                        pm.pasteKey((obj + rot1), 
                            floatOffset=0, option='replace', copies=1, valueOffset=180, connect=1, timeOffset=0)
                        
                   
                    else:
                        val=pm.getAttr(obj + rot3)
                        pm.setAttr((obj + rot3),  val+180)
                print("------")
        """
        pm.delete(tmpObj)
        cmds.select(objList, r=1)
        # Reset frame to current time so that changes are visually updated
        t=cmds.currentTime(query=1)
        cmds.currentTime(t, e=1)

        

        
    elif (method == 1) and (len(objList) != 2):
        print("Wrong number of objects.  Select 2 transfroms to mirror between")
        
#example
bt_applyMirrorAnim(2, 2, [1,1,0], 1, 1) 
bt_applyMirrorAnim(4, 4, [1,1,0], 1, 1)
bt_applyMirrorAnim(5, 3, [1,1,0], 1, 1)
bt_applyMirrorAnim(2, 2, [1,1,0], 1, 1) 

参考

Maya AnimCurve のデータを Pythonで取得するメモ

https://qiita.com/syoyo/items/376541f60e7cdb346399

[UnrealEngine,Niagara]パーティクルなんてプレイヤーが遠くなったらDeactivateしてしまえば軽量化なんてしなくても大体の場合、負荷のボトルネックにはならないみたい

パーティクルなんてプレイヤーが遠くなったらDeactivateしてしまえば軽量化なんてしなくても大体の場合、負荷のボトルネックにはならないみたい

BluePrint でActor選んで

ビューポートでNaiagaraを配置

SphereColiderを追加して半径を1250から1800に指定

コリジョン設定をOverlapAll

Begin OverlapでNaiagaraのVisibleとActivateしてついでにSet Relative Location 0,0,0

End OverlapでNaiagaraのVisibleとDeactivate

してしまえばNaiagaraがボトルネックになることは避けられる。

Particle Stateの

Kill Particles When Lifetime Has Elapsed
Loop Particles Life Time
Let Infinity Lived Particles Die When Emitter Deactives

ライフタイムが経過したときにパーティクルを殺す <あとからするとうまくいかない
ループ パーティクルの寿命 <意味不明
エミッタが非アクティブになったときに無限に生きたパーティクルを消滅させる <うまくいった。

音楽のランダムの歴史から言って

途切れなくランダムにする方法は理論から行くと長ければ長いほど途切れたと錯覚しやすいので長くする。

エミッタの更新の
Life Cycleは

loop Duration 60

パーティクルのスポーンのInitialize Particleの
lifetimeは

Random Rageにして

5から60の値の設定

関係ないが

Scale Mesh SIzeはパーティクルのスポーン時にMesh AttributeがUniformで1.0になってないと表示されなくなる。

完成したもの

HangingParticulatesで

[work, communication]頻繁なコミュニケーションによる早期退職の法則

リモートワークの職場で毎日毎日、

不要なコミュニケーションをとることは人を嫌いになるチャンスや、

上司との関係ができの悪いタスクによって人間関係が悪くなる事が増える。

未整理の状態のタスクや、

複雑化し、毎日追加されるタスクで煩雑になったコードや

何重にも重なり合うパラメータの状態によるもはや言語化の難しいステータスを

毎日無理に説明させられる事で、

上司は、まだあれはできないのか?

あいつはまだあんな事も説明できないのかと、

毎日部下は言われている気分になるので、

部下は自身の承認欲求をみたせないし、

上司からの評価も下がる事で早期退職の原因になる。。

そもそもこんな状態になるような

ムダなミーティングを増やす人間は

まったくタスク評価が人間関係に影響をあたえる

負の影響を言語化できないどころか想定できていない。

毎日無駄に管理する事による

負の影響がどれだけ人間関係を悪くするかを考えられていない、

上司としてコミュニケーションや、

人間関係に対する管理怠慢である。

コミュニケーションは、

必要以上に頻繁にする事で破綻する事実を知らない。

有名な小説家、村上春樹の家庭ように

それは別居した方が客観性があって結婚生活がうまくいく

夫婦生活の対策のようなモノだという事に

今さら気がついて良かった。

#リモートワークコミュニケーション #テレワークコミュニケーション #夫婦生活 #円満 #人間関係のコツ