他人様のコードを読んで構造体におけるconstメンバの使い方が勉強になったのでメモ
//こういった構造体の宣言をして
struct hoge{
public const int size = 8;
public int aaa;
public int bbb;
}
//変数の宣言をして
hoge abc;
//構造体のサイズを出力する(二通り)
Debug.Log( Marshal.SizeOf(abc) ); //8
Debug.Log( hoge.size ); //8
結果から、constメンバは構造体の実体には含まれない。
"構造体 const メンバ"でググっても解説の類が見つからないのだけど
物凄く基本的な使い方なのだろうか。
Marshal.SizeOfメソッドを使わない分軽いだろうし、
size変数といった形で使うのはとてもわかりやすく使いやすいように思えた。
この場合、abc.sizeとできたほうがより直観的だとは思うけど、
それだとその分構造体の容量増えちゃうしね。
2015年9月7日月曜日
2015年7月29日水曜日
[Visual Studio] .shader, .compute, .cgincのシンタックスハイライト/カラーリング
ネタ元
http://forum.unity3d.com/threads/tutorial-how-to-use-nshader-with-unity-shaders.108995/
〇 Visual Studio 2013
S-edさんが添付している $NShader.zip に格納されている
NShader.vsix をダブルクリックしてインストール。
〇 Visual Studio 2015
samizzoさんがリンクを張っている NShader_2015.zip に格納されている
NShader.vsix をダブルクリックしてインストール。
※ 自分は2015は入れてないので試してないのですが、
Enterprise版で動かない、Community版では動いたというコメントが返ってきているみたいです。
NShader は HLSL, GLSL, Cg で書かれたファイルをハイライト/カラーリングしてくれるVisual Studio 2008/2010 の拡張みたい。
NShader
http://nshader.codeplex.com/
S-edさん、samizzo さんのはNShaderをさらに拡張させているみたいですね。
……よくわからず書いてるから歯切れが悪い!
http://forum.unity3d.com/threads/tutorial-how-to-use-nshader-with-unity-shaders.108995/
〇 Visual Studio 2013
S-edさんが添付している $NShader.zip に格納されている
NShader.vsix をダブルクリックしてインストール。
〇 Visual Studio 2015
samizzoさんがリンクを張っている NShader_2015.zip に格納されている
NShader.vsix をダブルクリックしてインストール。
※ 自分は2015は入れてないので試してないのですが、
Enterprise版で動かない、Community版では動いたというコメントが返ってきているみたいです。
NShader は HLSL, GLSL, Cg で書かれたファイルをハイライト/カラーリングしてくれるVisual Studio 2008/2010 の拡張みたい。
NShader
http://nshader.codeplex.com/
S-edさん、samizzo さんのはNShaderをさらに拡張させているみたいですね。
……よくわからず書いてるから歯切れが悪い!
2015年7月27日月曜日
[Unity] unsafeコードの動かし方
手順1.
Visual Studioの場合、 Project > Property > Build > Allow unsafe code にチェックを入れる。
手順2.
Assetsフォルダ直下にsmcs.rspとgmcs.rspを作成する。
どちらも中身は -unsafe とだけ入力する。
手順3.
UnityのEdit > Project Settings > Player を開き、
Other Settings > Configuration > Scripting Define Symbols の欄に unsafe と入力しEnter。
Reference Sites
http://forum.unity3d.com/threads/how-do-i-enable-unsafe-code.210781/
https://github.com/Banbury/UnityPsdImporter/issues/9
http://anchan828.tumblr.com/post/32669868103/define
※補足
Scripting Define Symbols の下にある項目、Api Compatibility Level が
.NET 2.0 Subset の場合、smcs.rspだけ
.NET 2.0 の場合、 gmcs.rspだけで動きます。
[Unity] How to build unsafe code
Step 1.
(In the case of Visual Studio) Check "Project > Property > Build > Allow unsafe code"
Step 2.
Make a file "Assets/smcs.rsp" and "Assets/gmcs.rsp" .
Inside only '-unsafe' .
Step 3.
Add 'unsafe' in Unity's "Edit > Project Settings > Player > Other Settings > Configuration > Scripting Define Symbols" .
Reference Sites
http://forum.unity3d.com/threads/how-do-i-enable-unsafe-code.210781/
https://github.com/Banbury/UnityPsdImporter/issues/9
2015年5月19日火曜日
[Particle Playground] ループしないsnapshotsの作り方
少し前にUnity AssetStoreでセールになっていたアセット
Particle Playground version 2.26 の話です。Unity は ver 5.0.1。
http://polyfied.com/work/particle-playground/
demo動画 https://www.youtube.com/watch?v=S3JABGu44zI
demo動画でも見られるparticleを別のparticleに遷移させる機能としてsnapshotsが備わっている。
このgifはParticle Playgroundで作ったparticleで、その場に滞留して弾けるようになっており、
「滞留」と「弾ける」はそれぞれsnapshotになっている。
この「弾ける」ようなループしない一度きりのsnapshotを作成するには手順に一手間が必要だったのでここにメモる。
Particle Playground version 2.26 の話です。Unity は ver 5.0.1。
http://polyfied.com/work/particle-playground/
demo動画 https://www.youtube.com/watch?v=S3JABGu44zI
demo動画でも見られるparticleを別のparticleに遷移させる機能としてsnapshotsが備わっている。
このgifはParticle Playgroundで作ったparticleで、その場に滞留して弾けるようになっており、
「滞留」と「弾ける」はそれぞれsnapshotになっている。
この「弾ける」ようなループしない一度きりのsnapshotを作成するには手順に一手間が必要だったのでここにメモる。
ラベル:
Particle Playground,
unity
2015年4月23日木曜日
BlenderのFBXエクスポートが難しすぎる
・Blender 2.7.3 バイナリ出力
一部アニメーション(ジャンプなど宙に浮くアニメ)が
上下逆さ(X軸180度回転)したものになる。
しかし!出力時にそれらアニメを開いている状態だと逆さにならない!
不思議!わからん!でも解決するならいっか、
と思ったが他の平常だったアニメでXY平面にズレが生じたりする!わーい!
・Blender 2.7.4 バイナリ出力
全てのアニメが前後逆に。後ろ歩き!クール!
じゃあエクスポート時の前後を変えればいいんだろう!変えた!アニメ変わんない!後ろ歩き!クール!
・Blender 2.7.4 ASCII出力
マテリアル名が「マテリアル名__テクスチャ(?)名」になる。
このテクスチャ名ってのも各マテリアルそれぞれで使用しているものでなく、
直近で編集したのだか開いていた画像名になるので安定しない。
そして非表示になっているオブジェクトのマテリアルはこの影響を受けないっぽい?
うむ、さっぱりわからん。
とりあえず
・Blender 2.7.4 バイナリ出力
でrotation 180度回転させるのが安定した選択に思える。
と色々試して選択した結果を適用しようとしたところ、
ゲーム上でアニメが動かなくなった。
アニメーション単体の動作確認はできるのだが、animatorのゲージも動いてる、遷移している。
しかし、モデルがさっぱり動かない。
…ハハハッ!
追記:animatorのstatesのWrite Defaultsをチェック外して入れ直したらまた動くようになった
一部アニメーション(ジャンプなど宙に浮くアニメ)が
上下逆さ(X軸180度回転)したものになる。
しかし!出力時にそれらアニメを開いている状態だと逆さにならない!
不思議!わからん!でも解決するならいっか、
と思ったが他の平常だったアニメでXY平面にズレが生じたりする!わーい!
・Blender 2.7.4 バイナリ出力
全てのアニメが前後逆に。後ろ歩き!クール!
じゃあエクスポート時の前後を変えればいいんだろう!変えた!アニメ変わんない!後ろ歩き!クール!
・Blender 2.7.4 ASCII出力
マテリアル名が「マテリアル名__テクスチャ(?)名」になる。
このテクスチャ名ってのも各マテリアルそれぞれで使用しているものでなく、
直近で編集したのだか開いていた画像名になるので安定しない。
そして非表示になっているオブジェクトのマテリアルはこの影響を受けないっぽい?
うむ、さっぱりわからん。
とりあえず
・Blender 2.7.4 バイナリ出力
でrotation 180度回転させるのが安定した選択に思える。
と色々試して選択した結果を適用しようとしたところ、
ゲーム上でアニメが動かなくなった。
アニメーション単体の動作確認はできるのだが、animatorのゲージも動いてる、遷移している。
しかし、モデルがさっぱり動かない。
…ハハハッ!
追記:animatorのstatesのWrite Defaultsをチェック外して入れ直したらまた動くようになった
Mesh.CombineMeshesでエラー BlenderでUV頂点を数える
メッシュの結合を行うMesh.CombineMeshesでエラーが起きた。
エラー文は count <= std::numeric_limits<UInt16>::max()
原因はこちらを参考にした。(対策案も書かれているがここではその手法について考えない)
http://rotorz.com/tilesystem/guide?ref=6b89bd45-1d5c-4221-aaa4-38073a6aab37
要するに一つのMeshで扱える頂点数がUInt16(65535)を超えてしまった、ということであった。
メッシュの頂点数を疑ったが、メッシュにくまなくUVを貼っている場合、
・メッシュ頂点数 ≦ UV頂点数
となる点に注意したい。
実際私の場合、頂点数を確認したところUV頂点数がオーバーしていた。
(なお、UV頂点数はmesh.uv.lengthで出力できる。)
ここでは対策として、Blenderを使用し、UV頂点数の削減を行うことにした。
しかし、削減の指標となるUV頂点数がBlenderでは標準で表示されない。
そのため、UV頂点数を確認する手段を設けることにした。
〇BlenderでUV頂点を数えるpythonコード
import bpy
import bmesh
bpy.ops.object.mode_set(mode='OBJECT')
mesh = bpy.context.object.data
bm = bmesh.new()
bm.from_mesh(mesh)
uv_layer = bm.loops.layers.uv.active
num = 0
for face in bm.faces:
for vert in face.loops:
num+=1
print(vert[uv_layer].uv)
print(num)
・参考
http://blender.stackexchange.com/questions/19724/uv-vertex-using-python
こうして作成したこちらのコードを動かしてみたが、得られた頂点数はUnity上とは異なる数であった。
この方法で得られるUV頂点は 三角面の数x3 + 四角面の数x4 というわかりやすい数で、
どうやらBlender上では重複するUV頂点をまとめていないようだ。
Unityで使用するためにエクスポートしたFBXでは
重複UV頂点をまとめている(?)からかUV頂点数は少なくなっている。
(実際はよくわかってないです。想定以上に減らなかったりして、
まとめているにしても全てをまとめているわけではなさそう)
結局のところ、Blender上でFBX出力時の正確なUV頂点数は得られない。というところに落ち着いた。
とはいえ、おおよその指標として上記pythonコードは使用できる。
完
エラー文は count <= std::numeric_limits<UInt16>::max()
原因はこちらを参考にした。(対策案も書かれているがここではその手法について考えない)
http://rotorz.com/tilesystem/guide?ref=6b89bd45-1d5c-4221-aaa4-38073a6aab37
要するに一つのMeshで扱える頂点数がUInt16(65535)を超えてしまった、ということであった。
メッシュの頂点数を疑ったが、メッシュにくまなくUVを貼っている場合、
・メッシュ頂点数 ≦ UV頂点数
となる点に注意したい。
実際私の場合、頂点数を確認したところUV頂点数がオーバーしていた。
(なお、UV頂点数はmesh.uv.lengthで出力できる。)
ここでは対策として、Blenderを使用し、UV頂点数の削減を行うことにした。
しかし、削減の指標となるUV頂点数がBlenderでは標準で表示されない。
そのため、UV頂点数を確認する手段を設けることにした。
〇BlenderでUV頂点を数えるpythonコード
import bpy
import bmesh
bpy.ops.object.mode_set(mode='OBJECT')
mesh = bpy.context.object.data
bm = bmesh.new()
bm.from_mesh(mesh)
uv_layer = bm.loops.layers.uv.active
num = 0
for face in bm.faces:
for vert in face.loops:
num+=1
print(vert[uv_layer].uv)
print(num)
・参考
http://blender.stackexchange.com/questions/19724/uv-vertex-using-python
こうして作成したこちらのコードを動かしてみたが、得られた頂点数はUnity上とは異なる数であった。
この方法で得られるUV頂点は 三角面の数x3 + 四角面の数x4 というわかりやすい数で、
どうやらBlender上では重複するUV頂点をまとめていないようだ。
Unityで使用するためにエクスポートしたFBXでは
重複UV頂点をまとめている(?)からかUV頂点数は少なくなっている。
(実際はよくわかってないです。想定以上に減らなかったりして、
まとめているにしても全てをまとめているわけではなさそう)
結局のところ、Blender上でFBX出力時の正確なUV頂点数は得られない。というところに落ち着いた。
とはいえ、おおよその指標として上記pythonコードは使用できる。
完
2015年4月12日日曜日
Unity C#のプロパティなどをインスペクターに表示するエディタ拡張「VFW」の使い方
Unityのエディタ拡張「VFW」を紹介します。
(※ビデオコーデックのVFWではありません!)
説明の前に、まずは一例
VFWには他にも色々なエディタ拡張の機能を備えています。
ここでは、VFWのダウンロードからプロパティをインスペクターに表示するまでを説明します。
(※ビデオコーデックのVFWではありません!)
説明の前に、まずは一例
〇 サンプル
サンプルコード
カスタム属性[Show]を設定した読み取り専用のプロパティmaxHPを宣言。
インスペクター上で数値を変更
Levelの増減に合わせてMaxHPも増減するのがわかります。
また、読み取り専用なのでMaxHPを直接変更することはできないようになっています。
このようにして[SerializedField]属性では対応できない読み取り専用プロパティを
インスペクターに表示できることが確認できました。
サンプルで示したmaxHPのような他の変数に依存する変数は、
プロパティ(getアクセサ)とVFWを用いることで
インスペクター上で数値を確認しながら調整を行うことができるようになります。
VFWには他にも色々なエディタ拡張の機能を備えています。
ここでは、VFWのダウンロードからプロパティをインスペクターに表示するまでを説明します。
2015年4月8日水曜日
Unity 1つのGameobject、ビルボードでダメージ表示
GUIでダメージなどの表示をすると重なった場合にドローコールが増える、らしい。
なので、ローポリ同士でバッチされてDrawCallの増加を1に抑えることを狙い、
板ポリにテクスチャを張り付け、ビルボードとして数値を表示する。
そのとき一桁ずつGameObjectを生成し、破棄するのはコストが高い
(1つのGameObjectで実現するよりも、多分)
と考え、1つのGameObjectで実現する。
…ふわふわとした走り出しだ!
なので、ローポリ同士でバッチされてDrawCallの増加を1に抑えることを狙い、
板ポリにテクスチャを張り付け、ビルボードとして数値を表示する。
そのとき一桁ずつGameObjectを生成し、破棄するのはコストが高い
(1つのGameObjectで実現するよりも、多分)
と考え、1つのGameObjectで実現する。
…ふわふわとした走り出しだ!
2015年4月7日火曜日
unity Instantiate後、スクリプトから登録したparentが使えるタイミングの確認
スクリプトからプレハブの実体を生成し、子に設定した際、
子から親のポジションなど変数が利用できるタイミングを確認した。
〇 親にアタッチしたスクリプト
public class TestParent : MonoBehaviour {
public GameObject child_prefab; //インスペクターから子プレハブを登録
void Update () {
Debug.Log(Time.frameCount + " " + name + " : Update Start ");
if (Input.GetKeyDown("space"))
{
Debug.Log(Time.frameCount + " " + name + " : Instatiate ");
GameObject go = Instantiate(child_prefab);
Debug.Log(Time.frameCount + " " + name + " : set Parent ");
go.transform.parent = transform;
}
Debug.Log(Time.frameCount + " " + name + " : Update End ");
}
}
〇 子プレハブにアタッチしたスクリプト
public class TestChild : MonoBehaviour {
void Awake()
{
Debug.Log(Time.frameCount + " " + name + " : Awake ");
if (transform.parent != null) Debug.Log(Time.frameCount + " : Parent is not null ********************");
}
void Start () {
Debug.Log(Time.frameCount + " " + name + " : Start ");
if (transform.parent != null) Debug.Log(Time.frameCount + " : Parent is not null ********************");
}
void Update () {
Debug.Log(Time.frameCount + " " + name + " : Update ");
if (transform.parent != null) Debug.Log(Time.frameCount + " : Parent is not null ********************");
}
}
〇 結果
154フレーム目にスペースキーが押された。
154フレームの流れは
・親のUpdateが開始し、
Instantiateで子を生成
・子のAwakeが起動
・親が子にParentをセットし、
親のUpdateが終了
・子のStartが起動、ここでparentが有効
となっており、子のStart時にはparentを使用できることが確認できた。
*を連続で並べたのはログから見つけ易くするため。
Insta"n"tiate 脱字です。
子から親のポジションなど変数が利用できるタイミングを確認した。
〇 親にアタッチしたスクリプト
public class TestParent : MonoBehaviour {
public GameObject child_prefab; //インスペクターから子プレハブを登録
void Update () {
Debug.Log(Time.frameCount + " " + name + " : Update Start ");
if (Input.GetKeyDown("space"))
{
Debug.Log(Time.frameCount + " " + name + " : Instatiate ");
GameObject go = Instantiate(child_prefab);
Debug.Log(Time.frameCount + " " + name + " : set Parent ");
go.transform.parent = transform;
}
Debug.Log(Time.frameCount + " " + name + " : Update End ");
}
}
〇 子プレハブにアタッチしたスクリプト
public class TestChild : MonoBehaviour {
void Awake()
{
Debug.Log(Time.frameCount + " " + name + " : Awake ");
if (transform.parent != null) Debug.Log(Time.frameCount + " : Parent is not null ********************");
}
void Start () {
Debug.Log(Time.frameCount + " " + name + " : Start ");
if (transform.parent != null) Debug.Log(Time.frameCount + " : Parent is not null ********************");
}
void Update () {
Debug.Log(Time.frameCount + " " + name + " : Update ");
if (transform.parent != null) Debug.Log(Time.frameCount + " : Parent is not null ********************");
}
}
〇 結果
154フレーム目にスペースキーが押された。
154フレームの流れは
・親のUpdateが開始し、
Instantiateで子を生成
・子のAwakeが起動
・親が子にParentをセットし、
親のUpdateが終了
・子のStartが起動、ここでparentが有効
となっており、子のStart時にはparentを使用できることが確認できた。
*を連続で並べたのはログから見つけ易くするため。
Insta"n"tiate 脱字です。
2015年4月3日金曜日
unity Gameobjectのlayerがスクリプトから変更できないとき
コリダーとの衝突時に条件に応じて、
レイヤーを変更する処理を行ったところ、エラーが出て成功しない。
ここから前置きのエラー説明。
gameObject.layer = LayerMask.NameToLayer("Enemy");
だとか
gameObject.layer = 15;
といったコードでは
layer numbers must be between 0 and 31
とエラーメッセージが出る。エラー発生元を明かさず凄い勢いで。
LayerMask.NameToLayer("Enemy")を
ウォッチ式で見ても値は15で、本来はこれで動くはず。
試しに15ビット目に1を立ててみる。
gameObject.layer = 1 << 15;
では
A game object can only be in one layer.
The layer needs to be in the range [0...31]
とエラーメッセージが出る。
2^15=32768なのでこれはエラーの通り。
ここまで前置き。
で、エラーを吐き出しているところを調べるために
各コンポーネントのON/OFFを切り替えていたところ、
対称にアタッチしてあるCharacterControllerが吐き出していたことがわかった。
そして、OFF/ONを行うことでエラーが起きなくなることもわかった。
CharacterController hoge = GetComponent<CharacterController>();
gameObject.layer = LayerMask.NameToLayer("Enemy");
hoge.enabled = false;
hoge.enabled = true;
以上のようにすることで、エラーは無くなった。
また、細かい検証はしていないが、
Rigidbody + BoxColliderでは同様のエラーは出なかった。
他にも細かい原因が絡んでいるかもしれないが、
レイヤー変更後のキャラクターコントローラーは一度再起動させる
のが良い、かもしれないとあやふやに終わる
2015/04/29 追記---------------------------------------------------
改めてやるとダメっぽいので確認
そんなことなかった
enabledが抜けてるところがあっただけだった
レイヤーを変更する処理を行ったところ、エラーが出て成功しない。
ここから前置きのエラー説明。
gameObject.layer = LayerMask.NameToLayer("Enemy");
だとか
gameObject.layer = 15;
といったコードでは
layer numbers must be between 0 and 31
とエラーメッセージが出る。エラー発生元を明かさず凄い勢いで。
LayerMask.NameToLayer("Enemy")を
ウォッチ式で見ても値は15で、本来はこれで動くはず。
試しに15ビット目に1を立ててみる。
gameObject.layer = 1 << 15;
では
A game object can only be in one layer.
The layer needs to be in the range [0...31]
とエラーメッセージが出る。
2^15=32768なのでこれはエラーの通り。
ここまで前置き。
で、エラーを吐き出しているところを調べるために
各コンポーネントのON/OFFを切り替えていたところ、
対称にアタッチしてあるCharacterControllerが吐き出していたことがわかった。
そして、OFF/ONを行うことでエラーが起きなくなることもわかった。
CharacterController hoge = GetComponent<CharacterController>();
gameObject.layer = LayerMask.NameToLayer("Enemy");
hoge.enabled = false;
hoge.enabled = true;
以上のようにすることで、エラーは無くなった。
また、細かい検証はしていないが、
Rigidbody + BoxColliderでは同様のエラーは出なかった。
他にも細かい原因が絡んでいるかもしれないが、
レイヤー変更後のキャラクターコントローラーは一度再起動させる
のが良い、かもしれないとあやふやに終わる
2015/04/29 追記---------------------------------------------------
そんなことなかった
enabledが抜けてるところがあっただけだった
2015年3月29日日曜日
unity EventTriggerのイベントをスクリプトから登録
EventTriggerのイベントをスクリプトから登録したい!
そんなときにはこちら
参考元
http://answers.unity3d.com/questions/854251/how-do-you-add-an-ui-eventtrigger-by-script.html
参考元ままなんですけど以下コード
EventTrigger trigger = Hoge.GetComponent<EventTrigger>();
EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.Select; //イベントのタイプSelectが発生した際に
entry.callback.AddListener((eventData) => { mySelect(); }); //mySelectメソッドを実行するよう
trigger.delegates.Add(entry); //EventTriggerに登録
他にもイベントを追加したいときは
EventTrigger.Entryの作成のところから新しく追記する。
using UnityEngine.EventSystems;
も忘れずに。
他のUnityAnswersで見た(アドレス紛失)のですが、
スクリプトから登録したイベントについてはインスペクターで確認できないみたい。
実際にできませんでした。
試してないのですが、AddをRemoveにすれば登録解除もできるのかな
そんなときにはこちら
参考元
http://answers.unity3d.com/questions/854251/how-do-you-add-an-ui-eventtrigger-by-script.html
参考元ままなんですけど以下コード
EventTrigger trigger = Hoge.GetComponent<EventTrigger>();
EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.Select; //イベントのタイプSelectが発生した際に
entry.callback.AddListener((eventData) => { mySelect(); }); //mySelectメソッドを実行するよう
trigger.delegates.Add(entry); //EventTriggerに登録
他にもイベントを追加したいときは
EventTrigger.Entryの作成のところから新しく追記する。
using UnityEngine.EventSystems;
も忘れずに。
他のUnityAnswersで見た(アドレス紛失)のですが、
スクリプトから登録したイベントについてはインスペクターで確認できないみたい。
実際にできませんでした。
試してないのですが、AddをRemoveにすれば登録解除もできるのかな
2015年3月24日火曜日
Asset MobileSingleStickControlのバーチャルスティックのズレ
Asset MobileSingleStickControlのバーチャルスティックが消える
の続き
今回は、バーチャルスティックを左だろうと下だろうとどう動かしても
右上に入力されていることになってしまっていた。
原因は、画面に対して描画領域を比率で固定し、黒帯表示を行っていたから。
タッチした画面の座標を Canvas の座標に変換してやらないとならない。
対策として、スクリプト Joystick 内の OnDrag() を編集した。
以下、変更部分のソース。
※補足1:Canvas Scalerで900 x 600 (3:2画面) と設定していた例
※補足2:MobileJoystick の RectTransform は左下をアンカーの基準にする。
public void OnDrag(PointerEventData data)
{
Vector3 newPos = Vector3.zero;
if (m_UseX)
{
//ここからが書き換えた部分
int nWidth = Screen.width;
int obi = 0;
if ((Screen.width * 2) > (Screen.height * 3)) //左右に黒帯ができる場合
{
nWidth = (int)(Screen.height * 1.5f); //黒帯を除いた描画幅を取得
obi = (int)((Screen.width - nWidth) / 2f); //黒帯の片側の大きさを取得
}
int delta = (int)((data.position.x - obi) / nWidth * 900f - m_StartPos.x); //座標空間の変換
//ここまでが書き換えた部分
delta = Mathf.Clamp(delta, - MovementRange, MovementRange);
newPos.x = delta;
}
if (m_UseY)
{
//ここからが書き換えた部分
int nHeight = Screen.height;
int obi = 0;
if ((Screen.width * 2) < (Screen.height * 3)) //上下に黒帯ができる場合
{
nHeight = (int)(Screen.width * 0.667f);
obi = (int)((Screen.height - nHeight) / 2f);
}
int delta = (int)( (data.position.y - obi)/ nHeight * 600f - m_StartPos.y);
//ここまでが書き換えた部分
delta = Mathf.Clamp(delta, -MovementRange, MovementRange);
newPos.y = delta;
}
transform.GetComponent<RectTransform>().anchoredPosition3D = new Vector3(m_StartPos.x + newPos.x, m_StartPos.y + newPos.y, m_StartPos.z + newPos.z);
UpdateVirtualAxes(transform.GetComponent<RectTransform>().anchoredPosition3D);
}
描画領域の比率を変更することはそうそうないだろうけど、
これからStart()でCanvasScalerから持ってくるように変更しよう。
の続き
今回は、バーチャルスティックを左だろうと下だろうとどう動かしても
右上に入力されていることになってしまっていた。
原因は、画面に対して描画領域を比率で固定し、黒帯表示を行っていたから。
タッチした画面の座標を Canvas の座標に変換してやらないとならない。
対策として、スクリプト Joystick 内の OnDrag() を編集した。
以下、変更部分のソース。
※補足1:Canvas Scalerで900 x 600 (3:2画面) と設定していた例
※補足2:MobileJoystick の RectTransform は左下をアンカーの基準にする。
public void OnDrag(PointerEventData data)
{
Vector3 newPos = Vector3.zero;
if (m_UseX)
{
//ここからが書き換えた部分
int nWidth = Screen.width;
int obi = 0;
if ((Screen.width * 2) > (Screen.height * 3)) //左右に黒帯ができる場合
{
nWidth = (int)(Screen.height * 1.5f); //黒帯を除いた描画幅を取得
obi = (int)((Screen.width - nWidth) / 2f); //黒帯の片側の大きさを取得
}
int delta = (int)((data.position.x - obi) / nWidth * 900f - m_StartPos.x); //座標空間の変換
//ここまでが書き換えた部分
delta = Mathf.Clamp(delta, - MovementRange, MovementRange);
newPos.x = delta;
}
if (m_UseY)
{
//ここからが書き換えた部分
int nHeight = Screen.height;
int obi = 0;
if ((Screen.width * 2) < (Screen.height * 3)) //上下に黒帯ができる場合
{
nHeight = (int)(Screen.width * 0.667f);
obi = (int)((Screen.height - nHeight) / 2f);
}
int delta = (int)( (data.position.y - obi)/ nHeight * 600f - m_StartPos.y);
//ここまでが書き換えた部分
delta = Mathf.Clamp(delta, -MovementRange, MovementRange);
newPos.y = delta;
}
transform.GetComponent<RectTransform>().anchoredPosition3D = new Vector3(m_StartPos.x + newPos.x, m_StartPos.y + newPos.y, m_StartPos.z + newPos.z);
UpdateVirtualAxes(transform.GetComponent<RectTransform>().anchoredPosition3D);
}
描画領域の比率を変更することはそうそうないだろうけど、
これからStart()でCanvasScalerから持ってくるように変更しよう。
2015年3月23日月曜日
LitJson 配列の配列
※記憶があやふやなうえに少し時間が経っているので話半分に
LitJsonの使用を考えている場合、
2次元配列ではなく配列の配列を使用したほうがよい。
2次元配列は正常に書き出し、読み込みができない。
ここで言う
2次元配列は hoge[x , y]
配列の配列は hoge[x][y] (ジャグ配列)
というような記法の配列のこと。
JavaScriptが多次元配列をサポートしていないらしいので、
JavaScriptがベースのJSON
あるいはLitJsonでサポートしていないのだろう。
LitJsonの使用を考えている場合、
2次元配列ではなく配列の配列を使用したほうがよい。
2次元配列は正常に書き出し、読み込みができない。
ここで言う
2次元配列は hoge[x , y]
配列の配列は hoge[x][y] (ジャグ配列)
というような記法の配列のこと。
JavaScriptが多次元配列をサポートしていないらしいので、
JavaScriptがベースのJSON
あるいはLitJsonでサポートしていないのだろう。
Asset MobileSingleStickControlのバーチャルスティックが消える
一度触れたら、画面の左下だったり原点に移動してしまう。
解決策は、
まず、ヒエラルキーに置いたMobileSingleStickControlに
Layout > Canvas Scaler をアタッチする。
設定は Ui Scale Mode を Scale With Screen Size
他は各々の環境に合わせた値に。
次に、MobileSingleStickControl の子 MobileJoystick に
アタッチされているスクリプト JoyStick を編集する。
編集内容は置換するだけ。
置換前: transform.position
置換後: transform.GetComponent<RectTransform>().anchoredPosition3D
4か所が置換されるはず。
(参考)
http://forum.unity3d.com/threads/unity-5-new-mobile-assets-joystick-problem.307627/
http://answers.unity3d.com/questions/917671/unity5-joystick-prefab-snapping-to-bottom-left-cor.html#answer-919202
JoyStick 内の OnEnable を Start に書き換えただけで直った!
という人もいるみたい。自分は駄目でした。
GetComponentがやらしいので
変数にキャッシュするのがいいでしょう、多分。
transformも実際はGetComponentが動いているらしいのでなおさら。
これと関係してか、しなくてか、
触れた途端Range内の右上に一旦移動してしまう。
これから模索。
続き
Asset MobileSingleStickControlのバーチャルスティックのズレ
最新?のではこんなバーチャルスティック
解決策は、
まず、ヒエラルキーに置いたMobileSingleStickControlに
Layout > Canvas Scaler をアタッチする。
設定は Ui Scale Mode を Scale With Screen Size
他は各々の環境に合わせた値に。
次に、MobileSingleStickControl の子 MobileJoystick に
アタッチされているスクリプト JoyStick を編集する。
編集内容は置換するだけ。
置換前: transform.position
置換後: transform.GetComponent<RectTransform>().anchoredPosition3D
4か所が置換されるはず。
(参考)
http://forum.unity3d.com/threads/unity-5-new-mobile-assets-joystick-problem.307627/
http://answers.unity3d.com/questions/917671/unity5-joystick-prefab-snapping-to-bottom-left-cor.html#answer-919202
JoyStick 内の OnEnable を Start に書き換えただけで直った!
という人もいるみたい。自分は駄目でした。
GetComponentがやらしいので
変数にキャッシュするのがいいでしょう、多分。
transformも実際はGetComponentが動いているらしいのでなおさら。
これと関係してか、しなくてか、
触れた途端Range内の右上に一旦移動してしまう。
これから模索。
続き
Asset MobileSingleStickControlのバーチャルスティックのズレ
登録:
投稿 (Atom)