맥스스크립트 답변 및 추가

Wire Parameter의 사용

스크립팅하는애님 2025. 5. 24. 20:05
728x90
반응형

안녕하세요, 스크립트 하는 애님입니다.

이게 얼마만에 글을 쓰는건지 모르겠네요.

아주 가끔 질문이 있기는 했엇지만, 대부분이 댓글에 간단하게 답변 하는정도로 끝나는 경우라 새로 글을 쓴적은 없었습니다.

 

이번에 ''라는 분께서 질문을 주셨는데 커스텀 어트리뷰트에서 다른 오브젝트를 컨트롤 하는 법에 대해서 질문을 주셨습니다.

처음에는 간단 할것이라 생각 했는데 간단하지 않아서 제가 어떻게 작업을 진행했는지 설명을 하면 다른 스크립트 작업을 할때 어떻게 추론을 하는지 도움이 될것 같아 내용을 정리 했습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
-- 컨트롤러 오브젝트 생성 및 슬라이더 추가
ctrl = point name:"Ctrl" pos:[0,0,0]
ca = attributes WeightControl
(
    parameters main rollout:params
    (
        weight1 type:#float default:50 ui:spnW1
        weight2 type:#float default:50 ui:spnW2
    )
    rollout params "Blend Weights"
    (
        spinner spnW1 "Weight 1" range:[0,100,50]
        spinner spnW2 "Weight 2" range:[0,100,50]
    )
)
custAttributes.add ctrl ca
 
-- 타겟 오브젝트 생성 및 Position_List 컨트롤러 설정
target = box name:"Target" pos:[100,0,0]
plc = Position_List()
target.position.controller = plc
plc.available.controller = Position_XYZ()
plc.setName 1 "Manual"
plc.available.controller = Position_XYZ()
plc.setName 2 "Procedural"
plc.weight[1= 50
plc.weight[2= 50
 
 
w1 = target.position.controller["Weight: Manual"]
w2 = target.position.controller["Weight: Procedural"]
 
-- Wire Parameter 혹은 expresaion
cs

안녕하세요 애님님 개인작업에 필요하여 이런걸 만들고있는데
마지막 부분을 해결을 못하겠네요ㅜㅜ 로테이션 리스트의 웨이트값은 커스텀어트리뷰트로 조절이 가능한데 포지션은 안되는 이유가 어떤게있을까요?


라는 질문입니다.

내용을 훑어보니 Ctrl이라는 포인트를 생성하고 WeightControl 라는 어트리뷰트를 생성해서 spnW1, spnW2에서 입력(조절하는) spinner값을

Target이라는 오브젝트에 List로 생성한 두개의 Position XYZ의 Weight값에 적용하는 스크립트 인데,

마지막에 Wire Parameter 혹은  expresaio으로 구현 하는 내용이 빠져 있는것 같습니다.

우선 해당 스크립트를 싱행하면 두개의 오브젝트가 생성 됩니다.

 

Ctrl 오브젝트의 경우 Modify탭에서 확인하면

'Blend Weights'라는 내용이 어트리뷰트로 추가 되었습니다.

Target오브젝트의 경우 Motion탭을 확인하면

Assign Controller의 Position이 Position List로 되어있고 하위에 'Manual'과 'Procedural'이 새로 만들어져 기존의 것과 같이 총 3개의 값이 있습니다.

보통 Position XYZ와 Noise Position을 같이 쓰는 것은 봤지만, 3개 모두 Position XYZ로 되어 있어 이부분이 잘 이해가 되지 않았습니다.

이해 부족하면 스크립트 작성하는데 난감한 상황이 있기에 각각의 Weight를 변경해 봤는데,

제일 상단의 Manual에서만 박스가 좌우로 이동을 하는 변화가 있고 나머지 두개는 값을 변경해도 변화가 없어서, 처음에는 맥스의 버그인가 했습니다.

그래서 한 동안 이 부분을 고쳐 달라는 내용인가 해서 고민을 했는데, 버그는 아니고 포토샵의 레이어와 같이 최상단의 값이 결과로 나오기 때문에 같은 Position XYZ를 쓴다면 최 상단의 값만 보여주는게 아닐까 하며 스리슬적 궁금증을 덮어두고 제 마음을 달랬습니다. ㅎㅎㅎ

만약 정말로 공간에서 어떤 3점의 중간 값을 Weight로 조절하면서 찾는거라면 Position List보다는 Position Constraint를 추천 합니다.

마음을 다잡고 Wire Parameter로 Ctrl오브젝트의 Weight 1과 Target의 첫번째 Position레이어의 Weigt값을 연결하기로 했습니다.

하나의 값으로 반대쪽의 값을 일방적으로 움직이는 방법이 심플하지만, 작업을 하는데 있어서 이쪽 저쪽의 값을 양방향으로 작업해야 하는 경우도 있기 때문에 한쪽의 Weight값을 변경하면 다른쪽의 값도 동일 하게 변경하는 양방향 연결로 시도하겠습니다.

Wire Parameter의 설명은https://animaxscript.tistory.com/133

 

Wire Parameter(1)

안녕하세요. 애니메이터가 들려주는 맥스 스크립트의 스크립팅하는 애님입니다. 오늘 할 이야기는 Wire Parameter입니다. Wire Parameter는 리깅 작업할 때 자주 쓰이는 기능인데 프레임마다 실시간으

animaxscript.tistory.com

https://animaxscript.tistory.com/134

 

Wire Parameter(2)

안녕하세요. 애니메이터가 들려주는 맥스 스크립트의 스크립팅하는 애님입니다. 오늘도 Wire Parameter에 대해 이야기하겠습니다. 지난번과 동일하게 Point001과 Point002를 만들고 Wire Parameter로 연결합

animaxscript.tistory.com

에 있기 때문에 자세한 설명은 참고 하세요.

대부분  Wire Parameter는 오브젝트에 기본적으로 존재하는 Parameter값들을 다른 오브젝트에 기본적으로 존재하는 Parameter에 옮기는 것이기 때문에 위 내용으로 충분하지만, 새로 만들어진 어트리뷰트값을 약간은 생소한 Weight에 연결해야 하는것이기 때문에 해당 Parameter에 접근 하는 방법이 필요했습니다.

그래서 다른 사람들은 어떻게 사용하는지 예시를 찾기 위해 paramWire.connect2way(양방향 Wire Parameter명령)로 구글링을 했습니다.

생각보다 인기가 없는지 별다른 내용이 없었습니다.

그럼 다음으로 운이 좋으면 확인 할수 있는 'MaxScript Listener'에서 확인 하기 입니다.

https://animaxscript.tistory.com/7

 

MAXScript Listener

안녕하세요. 오늘은 맥스 스크립트를 간단하게 작성하려고 합니다. 제가 아무리 맥스 스크립트가 어쩌고저쩌고 해도 한번 해보는 것이 좋겠지요. 필요한 준비물로는 3DS MAX가 필요합니다. 각각

animaxscript.tistory.com

의 내용을 확인 하시면 중간쯤에

'이것은 'MAXScript Listener'의 기능 중 하나로 사용자가 맥스에서 어떤 행동을 액션으로 출력하는 기능으로 'MacroRecorder'라고 불립니다.

이 기능은 기본적으로 비활성화되어 있으며 처음에는 크게 필요한 기능은 아닙니다.

가끔 맥스 스크립트로 구현하기 어려운 것을 '액션'출력을 이용해서 해결할 때가 있습니다.'

라는 내용이 있는데 이것을 이용하겠습니다.

MaxScript Listener를 열고 Ctrl+D로 깔끔하게 해줍니다.


Wire Parameter로 Ctrl의 Weight1과 Target의 Manual Weight값을 연결해 줍니다. (Wire Parameter사용방법은 다들 아시리라 생각하고 넘어가겠습니다. ㅎㅎ)

연결을 하면, Target가 화면 밖으로 사라집니다.

이유를 생각해보자면 두 Weight값 모두 float값을 사용하지만, 단위로 보자면 Target의 Weight는 백분률(%)로 사용되는 값이고 Ctrl의 Weight는 그값 그대로 사용 되기 때문에 두 값은 단위가 100배 차이가 납니다.

이부분은 나중에 수정할것 이기 때문에 'MAXScript Listener'를 확인해 보겠습니다.

paramWire.connect2way $.baseObject.WeightControl[#weight1] $Target.pos.controller[#Weight__Manual] "Weight__Manual" "weight1"

이 명령어가 두 값을 연결해주는 것입니다.

이것을 알았으니 마지막 줄에 추가하여 바로 실행해 보겠습니다.

우선은 추가한 스크립트를 실행하기전에 만들어진 오브젝트를 모두 삭제 합니다.

그리고 스크립트를 실행합니다.

에러가 발생합니다.

이유는 $.baseObject가 현재 선택한 오브젝트 인데 아까 오브젝트를 전부 삭제 했기 때문에 선택한 오브젝트라는게 없기 때문입니다.

paramWire.connect2way $Ctrl.baseObject.WeightControl[#weight1] $Target.pos.controller[#Weight__Manual] "Weight__Manual" "weight1"

이렇게 바꾸고 실행하면 될것 같습니다.

다시 오브젝트를 모두 시우고 스크립트를 실행해 봅니다.

다시 에러가 발생합니다.

맥스놈은 자기가 하면 실행되면서 유저가 하니까 에러를 뱉어 냅니다.

'connect requires subAnims'라는 것은 연결하려고 하는데 subAnims형태가 아니라서 문제라고 합니다.

'그런가 보다~~' 하고명령을 뜯어서 실행해 보겠습니다.

'$Ctrl.baseObject.WeightControl[#weight1]' 이부분이 문제가 있는지 'MAXScript Listener'에서 실행해 봅니다.

에러가 없고 정상적으로 값을 뱉어 냅니다.

그리고 SubAnim라고 합니다.

다음으로 '$Target.pos.controller[#Weight__Manual]'를 넣어보고 실행합니다.

'알수 없다'고 뱉어냅니다. (자기가 써 놓고 모른다는 가증스런 맥스녀석)

우리는 다른방식으로 해당 Weight에 접근해야 하기 때문에 Target를 선택하고 Cuve Editer를 열어 봅니다.

이미지의 빨간색 박스에 접근해야 하기 때문에 고민을 하겠습니다.

빨간색 박스는 Target > Transform > Position의 하위레벨에 존재 합니다.

Position까지는 $Target.pos.controller로 접근이 가능합니다.

Weights는 Position의 하위 레벨이기 때문에 '$Target.pos.controller.Weights'라고 하고 실행해 보겠습니다.

확신은 없지만, 무언가 찾아간것 같습니다.

그럼 '$Target.pos.controller.Weights[#Weight__Manual]' 라고 내용을 추가해 보겠습니다.

맥스 스크립트에서 'Weight: Manual'의 중간에 있는 ': '문자는 특수 문자이기 때문에 '__'로 변경한다고 어디선가 들었습니다.

즉 보여질땐 'Weight: Manual'이지만 내부에서 사용할때는 'Weight__Manual'입니다.

정상적으로 값이 나옵니다.

아까 에러의 원인이었던 'SubAnim'도 해결된것 같습니다.

마지막 줄을

paramWire.connect2way $Ctrl.baseObject.WeightControl[#weight1] $Target.pos.controller.Weights[#Weight__Manual] "Weight__Manual" "weight1"

로 변경합니다.

그럼 다시 모든 오브젝트를 삭제하고 스크립트를 실행합니다.

생성된 박스가 순식간에 화면 밖으로 사라지지만 아까 수동으로 Wire Parameter를 연결한것과 같은 결과가 나옵니다.

 

Wire Parameter창을 열여서 확인해도 정상적으로 연결된것을 확인 할 수 있습니다.

이제 100배차이 나는것을 수정해야 겠습니다.

결론부터 얘기하면

paramWire.connect2way ctrl.baseObject.WeightControl[#weight1] $Target.pos.controller.Weights[#Weight__Manual] "Weight__Manual*100" "weight1*0.01"

로 변경하면 됩니다.

이것은 Target오브젝트의 Weight값은 100배 키워서 Ctrl의 Weight에 보내고,

반대로  Ctrl의 Weight는 100배 줄여서 Target오브젝트의 Weight값에 보낸다는 뜻입니다.

모든 오브젝트를 삭제 한 후 수정된 스크립트로 실행해 보겠습니다.

이제 양쪽의 값이 연결되어 변경이 됩니다.Ctrl의 Weight 2값도 동일한 방법으로 작업하면 될것 입니다.(이부분은 값을 변경해도 Target에 영향을 주지 않는것 같아 어떤 의미가 될지는 모르겠습니다.)

수정된 스크립트는 아래와 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
-- 컨트롤러 오브젝트 생성 및 슬라이더 추가
ctrl = point name:"Ctrl" pos:[0,0,0]
ca = attributes WeightControl
(
    parameters main rollout:params
    (
        weight1 type:#float default:50 ui:spnW1
        weight2 type:#float default:50 ui:spnW2
    )
    rollout params "Blend Weights"
    (
        spinner spnW1 "Weight 1" range:[0,100,50]
        spinner spnW2 "Weight 2" range:[0,100,50]
    )
)
custAttributes.add ctrl ca
 
-- 타겟 오브젝트 생성 및 Position_List 컨트롤러 설정
target = box name:"Target" pos:[100,0,0]
plc = Position_List()
target.position.controller = plc
plc.available.controller = Position_XYZ()
plc.setName 1 "Manual"
plc.available.controller = Position_XYZ()
plc.setName 2 "Procedural"
plc.weight[1= 50
plc.weight[2= 50
 
 
w1 = target.position.controller["Weight: Manual"]
w2 = target.position.controller["Weight: Procedural"]
 
-- Wire Parameter 혹은 expresaion
 
paramWire.connect2way ctrl.baseObject.WeightControl[#weight1] $Target.pos.controller.Weights[#Weight__Manual] "Weight__Manual*100" "weight1*0.01"
cs

수고하셧습니다.

다음에 언제 뵐지는 모르지만 모두 건승하세요.

728x90
반응형

'맥스스크립트 답변 및 추가' 카테고리의 다른 글

[추가] 선택한 오브젝트 확인  (0) 2024.06.23
게시판 설명과 잡설  (0) 2024.06.23