ネーミングルールをスクリプト目線から決めてみよう

INDEX

はじめに

こんにちは。モノリスソフト テクニカルアーティストの広森です。

今回はCGやゲームを制作する際に頻繁に耳にする「ネーミングルール」について、実際に決める際の基準を、ツールを作成する立場の目線でまとめてみました。

これから新規のネーミングルールの仕様を切らなければならない人や、既存のネーミングルールに合わせてスクリプトを作成する際に力になればと思います。

スクリプト自体はcmdsで記述している為Mayaでしか動作しませんが、UE4や3dsMaxなどゲームエンジンやDCGツールでも運用することができる考え方になっています。

初めてスクリプトを作る方にも分かるよう、ツールの基本操作やコツもまとめていますので、ぜひお読みください。

※既にプロジェクトにネーミングルールがある場合は必ずそのルールを守ってください。あくまでも新規で決める際の参考にお願いします。

この記事を読むことで得られる内容

  • ネーミングルールを決める際、スクリプトの作成や使用時のことも考慮できるようになる。

  • ネーミングルールだけでなく、別の手段を用いたオブジェクト管理の仕方を学ぶことができる。

  • ネーミングルールを利用してオブジェクトを選択したり、追加の処理を行うなどのスクリプトの知識を身に着けることができる。

  • プログラマーやTAに対して、効率的なツール作成依頼などができるようになる。

良いネーミングルールとそうでないネーミングルールの例

まず2枚の画像を用意しました。

良い例 悪い例
tech_47_02.jpg tech_47_03.jpg
  1. 名前が簡潔

  2. 繋がった単語の頭文字が大文字になっているため、視認性が高い

  3. アンダースコア(_)で区切られた要素が統一されているためオブジェクトの内容を理解しやすい

  1. 名前が長い

  2. 単語の区切りが分かりづらく視認性が低い

  3. アンダースコア(_)で区切られた要素がバラバラなためオブジェクトの内容を理解しにくい

上記2つを見比べてみて左の方が綺麗な名前になっていますね。右の場合だと読みづらい仕様になっており、スクリプト目線以前にかなり扱いづらそうです。

今回はかなり極端な例を用意しましたが、実際に現場で見かけることも多い問題です。以降の章で、ネーミングルールを整理するコツを紹介します。

名前に含めたい要素とそうでない要素を決めてできるだけ短く記述しよう

先ほどの悪い例を見てみると、オブジェクト名に含む必要がなさそうな要素がいくつかみられますね。必要な情報でも、すべてを名前に埋め込んで管理するようなことは避け、名前以外の管理方法を検討しましょう。

名前以外の管理方法が気になる方は、おまけの章にいくつかのやりかたを用意しておきます。

今回は以下の要素は名前に含まなくて良いものとしています。理由としてオブジェクトを構成する要素には関係がなく、アウトライナーを用いて作業する際に使用しない為です。

  1. 大きさ

    • 今回の名前ではheight171やsice1_cm、size3cmが該当します

  2. キャラクター名

    • 今回の名前ではcharacterNameが該当します。

  3. 性別

    • 今回ではboyが該当します。

tech_47_04.jpg

キャラクター名を消して本当に良いのか・・・?

キャラクター名は不要な要素にして良いのか?と疑問に持った方はとても良い目線です。1つのシーンで複数のキャラクターを配置した場合見分けが付かなくなるので、区別がつく名前が必要になりますね。

ただ、オブジェクトを作成する際に毎回名前を付けてあげたりする手間がかかってしまいとても面倒くさそうです。そこで名前で管理せずネームスペースで運用してあげましょう。

ネームスペースで管理することでキャラクター専用の名前を含まず同じルールで骨の名前を運用できるので、オブジェクトを作成するスクリプトの使いまわしができるようになります。

単語の区切りを示唆することで視認性を上げよう

小文字だけ、大文字だけなどで表記すると単語の区切りの判別が難しく視認性が下がります。そこで、プログラミングでも使われている表記方法を利用することで視認性を高めましょう。

筆者はMayaでオブジェクトを作成した際と同じルールである、ローワーキャメルケースを採用しています。

スネークケースをMayaオブジェクトの名前に採用できない理由は後の章で紹介します。

ローワーキャメルケース

ローワーキャメルケースとは、最初の頭文字を小文字でスタートし、単語ごとの頭文字を大文字で記載する書き方です。

tech_47_05.jpg

アッパーキャメルケース

アッパーキャメルケースとは、最初の頭文字を大文字でスタートし、単語ごとの頭文字を大文字で記載する書き方です。

tech_47_06.jpg

なぜキャメルケースと呼ばれるの?

頭文字が大きい様子をラクダの背中のこぶに例えて表現したからと言われています。

スネークケース

スネークケースとは大文字は使用せず全て小文字で記載し、単語間をアンダースコア(_)で区切る手法です。視認性が一番高い手法でPythonでも一部スネークケースを推奨の書き方としています。

tech_47_07.jpg

なぜスネークケースと呼ばれるの?

小文字で構成された文字が平板な様子を蛇に例えて表記したからと言われています。

名前の要素を切り分けて、要素の順番を決めてみよう

名前の視認性が高まったので、実際にスクリプト側からオブジェクトを取得してみましょう。cmdsに強い方は「何故抽出しやすくなるの?」まで読み飛ばして頂ければと思います。

そもそもなぜcmdsなの?

melという名前を聞いたことがある方は、なぜcmdsを選択しているの?と考えると思います。確かにmelでも簡単なスクリプトを書く分には問題はないと思いますが以下の懸念がある為、Pythonを選択しています。

  • 大きなスクリプトを作ろうとした場合にmelには機能が少なく、pythonなら機能が充実している。

  • Pythonでのスクリプト作成に便利なエディタがそのまま使える。

  • オブジェクト指向と呼ばれるものが使える(今回は詳細に触れませんが大きなメリットなので、名前だけでも覚えておいてください)。

  • melはMayaでしか使えないがPythonならMaya以外でも使えるので、習得すればいろいろな方面で活かすことできる。

  • 業界全体でmelからPythonベースに移行している傾向があり、melの機能や書き方を忘れてしまっている人が多い為、PythonならプログラマーやTAに相談した際にmelか...と悲しい顔をされない。

コマンドにはオプションを設定できる機能があり、設定することで追加の機能を呼び出すことができます。このオプションがmelと一致していることもあり、melには日本語ドキュメントが存在しているので良いとしています。

Mayaを使用中にどんなコマンドが動いているのかを確認したい場合はスクリプトエディタを確認してください。

スクリプトエディタとは

melやPythonを記載する為のエディタです。以下の画像の丸で囲われた箇所をクリックすると立ち上がります。

tech_47_08.jpg

以下の画像でよく使うボタンを説明します。

  1. Maya内で作業を行うと対応するコマンドが表示される場所です。

  2. melやpythonを記述する場所です。今回用意したスクリプトをコピペする場所はこちらです。

  3. ①の内容を綺麗にするコマンドです。

  4. ②に記載された内容を全て実行します。

  5. ②に記載されたコマンドをドラッグしていた部分のみ実行します。

  6. 新しくコマンドを記載するタブを作成します。

  7. ⑥をクリックすると出てくるウィンドウです。今回はPythonを選択してください。

tech_47_09.jpg

作業をしても上記の画像の④にコマンドが表示されない場合は以下の機能を使ってみてください。

tech_47_10.jpg

melでしか実行できないコマンドも数は少ないですが存在します。いずれ必要になるかもしれませんが最初は問題ないと思います。

cmdsコマンドを探すコツ

実際に検索する手順として以下のように進めるとわかりやすいかと思います。

  1. maya上で行いたい作業を実際にする。

  2. スクリプトエディタにmelコマンドが逐一出るので要素を抽出していく。

  3. 「Autodeskの公式ページ内のPythonコマンドページ」で同じコマンド名を検索し、実際に呼び出して機能を習得する。

  4. cmdsに存在しなかった場合は代わりの機能を調べる。

  5. 代わりの機能がどうしても見つからない場合は以下のコマンドを使用し、pythonから直接melコマンドを実行する。

eval

import maya.mel as mel

#'実行したいコマンドを文字列で記載する。記載方法はmelの文法で書く'
mel.eval()

実際にコードを書いてみよう

今回は"JNT"という文字列が名前に含まれるオブジェクトのみをシーン内から抽出して自動で選択するスクリプトを作りました。行の解説は1行目以外、上に記載しています。

コピペして編集する場合はスペースの位置などには充分注意して編集してみてください。

pythonの書き方に沿っていない場合は# Error: invalid syntax # とスクリプトエディタに表示されます。スペースや文字列の書き方、半角で記入など書き方があっているかチェックしましょう。

スクリプトエディタに貼り付けてPython形式で実行してみてください。

nodeNameSelect

# -*- coding: utf-8 -*-
# ↑1行目に書くことでスクリプト内に日本語が使えるようになります。日本語を使わない場合は記載しなくても良いです。

# maya.cmdsに含まれる機能を使いたいので読み込む処理。毎回maya.cmdsと記載するのが面倒くさいのでこの行以降はcmdsの文字と記載するだけでOKにする記述を書く。
import maya.cmds as cmds

# ネーミングルールに沿った名前のノードを入れる容器みたいなもの。リスト型と呼ばれ、[]で記載する。
select_target_node = []

# シーンに存在する全てのノードを取得する。cmds.ls(selection=True)と記載すると現在選択しているオブジェクトのみ取得してくる。
all_nodes = cmds.ls()

# 全てのノードがall_nodesの中に入っているのでループ処理をする。改行されて、半角スペース4つずれている箇所がループ中に行われる内容。以降半角スペース4つずれている事をインデントと書きます。
# for文を書く場合は必ず最後に:をつけましょう。
for node in all_nodes:
    # nodeの中にはmayaのノード名が含まれています。
    # ノードの名前の中に文字列JNTが入っているか調べる。文字列を指定する場合""で囲むか''で囲みましょう。
    # if文を記載する場合はfor文と同じく最後に:をつけましょう。
    if "JNT" in node:
        # インデントがずれている箇所が上記のJNTが名前に含まれる場合の処理です。
        # ネーミングルールに沿った名前のみ選択してあげたいので、正しいものはこのリストに追加する。追加するリストに.append(入れたい要素)でOK
        select_target_node.append(node)
    # else文を記載する場合はfor文と同じく最後に:をつけましょう。
    else:
        # インデントがずれている箇所が上記のJNTが名前に含まれなかった場合の処理です
        # 今回はとくに何もしないのでpassと記載します。初心者向けなので記載していますがpassの場合はelse文自体を省略できます。
        pass

# ループが終わったら文字列JNTが含まれているオブジェクトのみを選択してみます。cmds.select(選択したいもの)と記載すればよいです。
cmds.select(select_target_node)

# 処理が終わったことをテキストでスクリプトエディタに表示します。表示したい内容をprintの横に書きましょう(この書き方はpython3での書き方です)。
print ("Finish!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")

実際に動作しましたか?

意図した通りの要素が選択できたでしょうか?これでネーミングルールに沿ってスクリプトから自動で選択することができましたね。

今回は選択する処理を最後に記載しましたが、cmds.delete(消したいもの)と記載することでネーミングルールに沿った、シーン内に要らないものを削除することもできます。

if文の中に処理を行いたい内容を記載することで要素ごとに処理もできます。

複数の条件分岐を行いたい場合の例として以下に編集した例を載せます。(コメントを記載していない箇所は上のスクリプトと同じです。)

nodeNameSelect2

# -*- coding: utf-8 -*-

import maya.cmds as cmds

select_target_node = []

all_nodes = cmds.ls()

for node in all_nodes:
    if "JNT" in node:
        select_target_node.append(node)
    # if文以外に条件を記載する場合はelifと記載することで別の条件を指定することができます。
    elif "CTL" in node:
        # cmds.setAttr(設定したいノード名とアトリビュート名)で値をセットすることができます
        # 今回はノード名だけ変わるのでf-stringsの書き方を採用。文字列の前にfを記載し、{}で囲われた場所が指定した値に変わった状態で文字列を生成することができます
        # f"{node}.rotate"と書くことで、for文のnodeの値が参照され、事前に設定したいアトリビュート名rotateと付け足して書くことができます。
        # デフォルトでは1つしか値を受け取らないので、rotateなど3つ同時に数値を設定したいときはtype="double3"と明記する
        # CTLがノード名に含まれる場合に回転値を全て0に設定する
        cmds.setAttr(f"{node}.rotate",0,0,0,type="double3")
        
    # 更に条件を設けたい場合は同じelifの記載で問題ないです。
    elif "NUL" in node:
        # NULがノード名に含まれる場合にスケールXの値を1に設定する
        cmds.setAttr(f"{node}.scaleX",1)
    else:
        pass

cmds.select(select_target_node)

print ("Finish!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")

スクリプトを動作させてみて

名前で検索した場合、今回はinの機能で検索しているので文字が含まれていたらそのオブジェクトも対象にしてしまいます。 

  • 例1)nulで検索したらantennula(触覚)も検索対象になってしまった。
  • 例2)  01で検索したら文字列側に含んでいた数字が対象になってしまった。

完全に一致した場合のif文を書いて対応することもできますが、毎回毎回その文章を書くのは効率が悪いのと、書き方がスマートでないですね。

これらを解決するために筆者はアンダースコア(_)で区切ることで要素を抽出しやすくしています。

  • 例1) shoulderTwistLeftJoint00 → sholderTwist_Left_Joint_00
  • 例2) pinkyLeftJoint02 → pinky_Left_Joint_02

何故抽出しやすくなるの?

pythonには特定の文字列で文字を切り分ける機能があります。.split()でカッコ内に切り分けたい要素を渡すと切り分けた状態の要素が含まれた配列(リスト)型で返ってきます。

要素が切り分けられなかった場合は、切り分けたい要素が配列内に含まれた状態で返ってきます。返ってきた値を扱う際に注意点があり、pyhtonでは配列の始まりは0番目からスタートしますので順番を指定する際は気を付けてください。

そして、-1で配列の最後の要素を指定することができます。

余談ではありますが、スクリプト言語によっては1番目からスタートする言語もあります。混在しないように気をつけてください。

スクリプトを使って実際に抽出してみよう

以下に、実際に選択しているノードの名前を抽出し、最初に選んだノードの名前をアンダースコア(_)で切り分けて表示するスクリプトを用意したので実際に動作確認してみてください。

nodeNameSplit

# -*- coding: utf-8 -*-

import maya.cmds as cmds

sel_nodes = cmds.ls(selection=True)
# sel_nodesはリスト型で返ってくるので最初のノードを指定する。
node = sel_nodes[0]

# node_nameに含まれる値を.split(分割したい値)で切り分ける。
node_names = node.split("_")

print (node_names)
# node_namesに含まれる値の2番目を表示する
print (node_names[2])

選択しているノードの名前がアンダースコア(_)で区切られていた場合に、切り分けた状態のリストが返ってきているのを確認できましたか?これでより精度の高い抽出を行うことができます。

この機能を使って要素を区切る場合はきちんとアンダースコア(_)の数を統一しておきましょう。数が違うと取得したい文字列が取得できず、悲劇を招くことになりますので注意しましょう。

今回は、アンダースコア(_)で要素を切り分けためにsplitメソッドを使用しました。このメソッドはファイルパスの文字列を切り分ける際にも使用できたりと、何かと便利なので覚えておきましょう。

全ての要素を切り分ける必要があるのか?

下の例題を見て頂くと分かりやすいですが、きちんと細かくするなら、sholderとTwistの間にも入れた方が要素として細かくなりますよね?

  • 例1)sholderTwist_Left_Joint_00

もちろんアンダースコア(_)を増やすことで精度は上がりますが、アンダースコア(_)の数を統一しなければならない都合上、何の意味も含んでいないものにも要素名を付けることになってしまいます。

筆者としては作業時の手間を考慮して含まないようにしており、名前も余分に増えてしまうことを避ける意図もあります。

どこまで短くするかは好みではありますが今後ネームスペースが付く可能性もあり、名前は長くなりがちです。アウトライナーの視認性を高めためにも、筆者は要素をできるだけ排除しています。

要素を切り分けたので更に文字を短くしよう

Left、Rightなどは必ず埋め込む情報になり、長いのでLとRなど1文字に省略してしまいましょう。

名前のパターンが決まっている要素は3文字にしてあげると名前の重複を防ぎつつ、短くできると思います。

  • 例1) Joint→JNT
  • 例2) nurbsCurve → CRV

数字は2桁運用で十分だと思います。3桁になるような階層構造を持つものは切り分けて階層を変える工夫を取った方が良いと思います。

階層構造以外で競合する要素は名前の要素にA、B、C・・・と英単語を付けることがあります。26個以上要素がある場合はAAなどで管理するか、もう少し要素を切り分けましょう。

要素の順番を変えていい?

ネーミングルールを決める際にこの要素の順番で無ければならないルールはありません。統一したルールがあり、統一化されているのであれば自由にして良い要素です。

筆者が運用する場合は以下のように切り分けています。名前の最初の方に部位名などの重要な要素を配置し、末尾になるにつれ連番など重要度の低い要素がくる構成としています。

  • sholderTws_L_JNT_00

数字を最後にしておくとMaya内で複製した際に自動で数字が変わるので運用しやすいかと思います。

以上ですっきりとしたネーミングルールになると思います。ここからは運用しやすい形式に加工してみてください。

おまけ

名前の要素に含みたくはないがオブジェクトにどうしても情報を埋め込みたい場合に使える手法を3つ紹介します。それぞれにメリット、デメリットがあるのでケースに応じて検討してみてください。

どの手法で運用する場合もスクリプト化し、ヒューマンエラーを防ぐようにしておくことを推奨します。 

また、アトリビュートで管理する場合や、接続で管理する際は情報が不用意に変わらないよう値をロックすることを心がけましょう。

以下の内容を意識すると良いでしょう。

  1. 文字列型のアトリビュートを追加して、直接情報を管理する。

    • 例)身長や種族、性別など1つのノードに含まれていれば十分な要素。

  2. setsを使ってアトリビュートではない要素で管理。

    • 例)一括で選択したいオブジェクトをまとめる。

  3. ネットワークノードを使って、情報を管理する。

    • 例)リグの分類や関連性があるオブジェクトを紐づけたい場合。

1.文字列型のアトリビュートを追加して、直接情報を管理する。

文字列型のアトリビュートで管理するメリット、デメリットを紹介します。

  • メリット
    • オブジェクトのエクストラアトリビュートを確認するだけで何の情報を持っているか確認できる。
    • 追加が比較的容易、かつ簡単。
  • デメリット
    • ノード数が増えた際、アトリビュートを持っているノードを全検索すると処理が重くなる。
    • アトリビュートをロックしておかないと情報がヒューマンエラーによって書き換えられてしまう可能性がある。
    • タイプミスを起こしていた場合、値やアトリビュート名を文字列で比較するとエラーになる。

実際の手順

  1. 文字列を埋め込みたい場合はAddAtributeの機能で情報を埋め込めます。文字列の場合はstringにしてあげてください。

    tech_47_11.jpg

  2. 実際に埋め込まれた例です。

    tech_47_12.jpg

ここからはスクリプトで使用する例を載せます

スクリプトで埋め込む場合は以下のようになります。

addAttr

# -*- coding: utf-8 -*-

import maya.cmds as cmds
sel_nodes = cmds.ls(selection=True)

node = sel_nodes[0]
# アトリビュートを追加する
cmds.addAttr(node,longName="monsterType",dt="string")

アトリビュートが存在しているかどうかの確認。

hasAttr

# -*- coding: utf-8 -*-
import maya.cmds as cmds
sel_nodes = cmds.ls(selection=True)

node = sel_nodes[0]
node_attrs = cmds.listAttr(node)

#所持しているか調べたいアトリビュート名
attr_name = "monsterType"
#ノードが所持しているアトリビュート名に該当のアトリビュート(今回はmonsterType)が存在するか調べる
if attr_name in node_attrs:
    print (f"{attr_name}は存在します")
else:
    print (f"{attr_name}は存在しません")

埋め込こんだ値を取得する場合。

getAttr

# -*- coding: utf-8 -*-
import maya.cmds as cmds
sel_nodes = cmds.ls(selection=True)

node = sel_nodes[0]
node_attrs = cmds.listAttr(node)

#所持しているか調べたいアトリビュート名
attr_name = "monsterType"
#ノードが所持しているアトリビュート名に該当のアトリビュート(今回はmonsterType)が存在するか調べる
if attr_name in node_attrs:
    #アトリビュートが存在していたら値を取得する
    monster_type_state = cmds.getAttr(f"{node}.{attr_name}")
    print(monster_type_state)

この要素を使えば名前に対してアトリビュートを設定したり、値を比較して処理したり、アトリビュートを所持しているか確認する処理が行えますね。

2.setsを使って管理する。

ここではsetsを使って情報を管理するメリット、デメリットを紹介しています。

  • メリット
    • setsで管理すれば関連するオブジェクトを一括で選択できる機能がある。
    • アトリビュートの追加の必要性が無い。
    • 追加、削除が簡単。かつ管理が簡単。
  • デメリット
    • 単一で管理したい要素には向いておらず、sets側から検索しなければならない。
    • 作業用に選択を管理するsetを作成しているなど、開発者によってはsetsを多用しているケースがあり、不必要なsetsが作業の効率化を下げる恐れがある。
      • 対処方法としてきちんと親子関係を持たせることで表示数を少なくすることができる。
    • アウトライナーがsetsの分増えるのですっきりしない。複数のリグなどを読み込む方にはその分setsが増えていくので辛いかも。

実際の手順

  1. リレーションシップエディタから「セットの作成」でできます。作成されたセットに「選択した項目の追加」で要素を追加できます。

    tech_47_13.jpg

  2. setsを選択し、右クリックのメニューから「セットメンバーを選択」で抽出できます。

    tech_47_14.jpg

ここからはスクリプトで使用する例を載せます

セットのメンバーを取得するコマンド例です。

getSetsMember

# -*- coding: utf-8 -*-
import maya.cmds as cmds
sel_nodes = cmds.ls(selection=True)
node = sel_nodes[0]
# setsからメンバーを取得し、名前のリストを返す。
member = cmds.sets(node,q=True)

print (member)

3.ネットワークノードを使って、情報を管理する。

この章ではネットワークノードを使って複数の要素を管理するメリット、デメリットを載せています。

  • メリット
    • ノードを検索する場合紐づけたネットワークノードを指定し、刺さっているアトリビュートを取得すれば検索の負荷が少ない。
    • アトリビュートの名前で管理していないので、ネットワークノード側のアトリビュート名が正しければ、情報がきちんと取得できる。
    • また、値も接続で管理している為、情報が編集されづらい構成になっているので、情報の信憑性が高い。
    • どれに紐づいているのかノードで管理しているのでノードエディタで検索ができる。
    • DAGノードではないのでアウトライナーの表示設定次第で表に出さないことができる。
  • デメリット
    • 事前準備が手間。
    • 単一で管理したい要素には向いておらず、ノードを辿らなければいけない。
    • 情報を埋め込む場合は管理したいアトリビュートごとに追加する必要がある。
    • アウトライナーに表示させないオプションを有効にしている場合に削除しているかの区別がつかない。

実際の手順

  1. ノードエディタからnetworkを打ち込み、作成する。

    tech_47_15.jpg

  2. 作成されたネットワークノードはアトリビュートが空なので自分で追加したい要素をアトリビュートに追加し、紐づけたいアトリビュートを接続する。

    tech_47_16.jpg

ここからはスクリプトで使用する例を載せます

コマンドでノードに対してコネクションされているノードを抽出する例です。

listConnections

# -*- coding: utf-8 -*-
import maya.cmds as cmds
sel_nodes = cmds.ls(selection=True)

node = sel_nodes[0]
# 選択しているノードにコネクションされているノード全てを抽出する。
inputs = cmds.listConnections(node, source=True, destination=False) or []
print(inputs)

まとめ

今回紹介した内容は以下の要素になります。これらが守られていれば素敵なネーミングルールを付けることができるようになっていると思います。

  1. 人が見た際にもわかりやすい、短く簡潔なネーミングルールにしよう。
  2. 名前に含めたい要素とそうでない要素を決めてあげよう。 
  3. アンダースコア(_)を使って要素を切り分けて要素に順番を持たせよう。
  4. スクリプトを使って処理してみよう。

また、今回はスクリプトの書き方を解説しました。コマンドを知っていけばどんどん自動化できることが増えていくので反復作業の苦痛から解放されることができます。

自分でもスクリプトが作成できるようになれば、より効率良く物事が進められるので、ぜひ試してみてください。

参考

Maya ヘルプ | Autodesk

cmdsコマンドの調べ方

上記のリンク先ページ内にある テクニカルドキュメント > Pythonコマンド からcmdsコマンドを調べることができます。

tech_47_17.jpg


執筆者:広森

映像業界を経てモノリスソフトへ入社。 以来、テクニカルアーティストとして主にリギング・セットアップ関連の業務を担当。 好きな飲み物は赤ワイン。

ABOUT

モノリスソフト開発スタッフが日々取り組んでいる技術研究やノウハウをご紹介

RECRUIT採用情報