ラベル Unity-Sample集 の投稿を表示しています。 すべての投稿を表示
ラベル Unity-Sample集 の投稿を表示しています。 すべての投稿を表示

2016年10月22日土曜日

リフレクションプローブ


Unity5でリフレクションプローブ(ReflectionProbe)を使うメモ。

使用環境:Unity5.4.2f1

どんなことができるか

室内において、金属などの反射オブジェクトの映り込みを調整したい場合等に有効。

通常反射物は室内でもスカイボックスの影響を受けてしまう。
(基本的にスカイボックスはシーン上のオブジェクトすべてに影響する為)。


そのような際にリフレクションプローブを配置することで室内の風景を映り込ませることで解決できる。
他、車が空下からトンネルに入った際などの映り込みの切り替えなど。



リフレクションプローブ概要

リフレクションプローブを置いた地点から360度視界のCubemapを内部で自動生成してくれる。
Cubemapはスカイボックスで使われている6面ボックスのマップと同じ概念で、自分でCubemapを指定することも可能。
Cubemap生成範囲は指定可能なので部屋の壁、床、天井などを範囲に設定すると良い感じ。

あたかも部屋専用のスカイボックス=Cubemapがあるようになる(ただし実際にシーン上では見えない)。

リフレクションプローブの有効範囲内にあるオブジェクトは、先のCubemapが映り込むようにできる。
結果的に部屋内の景観(壁、床、天井、置物類)が映り込むような状態にできる。

映り込み先の(反射する)オブジェクトは移動するものでも可。

リフレクションの種類指定は3つでコンポーネントのTypeで指定。
  • Baked
    事前に設定されているリフレクション空間から静的な(映り込ませ用の)Cubemapを自動生成してくれる。ただし映り込む周囲景観オブジェクトはstatic限定。
    しかしその分軽量でモバイルでも使える可能性がある。
  • Custom
    ユーザが用意したCubemapを手動で指定できる。
  • Realtime
    static以外の周囲景観オブジェクトも映り込む。動的にCubemapを生成することになる為、負荷は上がる。

主にBakedを使うことが多くなりそうな気がします。 


リフレクションプローブ設置手順(Baked)

リフレクションプローブの設置と設定


部屋の中に設置すると仮定して、


Empty Objectを作る。

コンポーネント ReflectionProbe を追加する。

コンポーネント ReflectionProbe のTypeはBakedにしておく。

これを部屋の真ん中付近に置く。
※この置いた地点を中心に360度視点のCubeマップを自動生成してくれるようになる。
※あえて映り込ませたいようなオブジェクトアイテムがある場合はその中心に配置するとそこを中心にCubemapを生成してくれるので良い感じ。
コンポーネント ReflectionProbe でCubemap生成範囲を設定する。
図中#2ボタン押しでシーン内に調整点がでてくるので、それを掴んでドラッグで調整。



映り込む側オブジェクトの設定

部屋の壁、天井、床などの周囲景観として映り込ませたいオブジェクトの設定。

オブジェクトを static に設定する。


映り込まれる側オブジェクトの設定

  • Mesh Renderer
    Reflection Probes: BlendProbes
  • Material
    Shader: Standard シェーダー使用(リフレクションプローブ対応のシェーダー要)
    Reflections: チェック入れSmoothness: 1  ※1に近いほど映り込む。
    Metalic: 1 ※1に近いほど鏡面反射な映り込みになる。





追加補足

・CubemapのBake(?)に結構時間がかかる。
多分CubemapのBakeだと思われますが、生成に結構時間がかかる。
Unityウィンドウ右下ステータスバーにさりげなく進行状況が出てくるのでチェック。
その間もエディタは使えるし再生もできる。ただし再生してもまだ反映されてないので注意。
Bakeが終わるまで気長に待つしかなさそう。
※作業中はいろいろ間引いて高速化は可能だが、最終微調整はどうしても時間がかかる。

・リフレクションプローブが複数ある場合、近い方が優先してブレンド。

・1つのリフレクションプローブだけ映し込みたい場合は、そのオブジェクトの Mesh Renderer の Anchor Override に そのリフレクションプローブのオブジェクトをドラッグ&ドロップする。ないしはプルダウンで選択する。

・映り込ませる(反射)オブジェクトは staticである必要はないので移動できる。
ただし映り込み方に注意(Bakedの場合)。
リフレクション空間に突入すると映り込むようになる。
その際、そもそもリフレクションプローブのボックス6面に事前内部生成したテクスチャをリフレクションプローブの中心点で観測したように映り込ませる様子。
なので映り込まされるオブジェクトは、リフレクションプローブ空間内のどこに移動しても同じように表面に投影されている。つまり位置による補正が無いので周囲の景観具合やまじまじ見るとおかしいのがバレてしまう可能性がある。
ただカメラ視点変化での反射には追従してるので一見するとバレにくい。ここが軽量且つそれっぽくみせるコツかも。

・リフレクションしてるオブジェクトはさらに別なオブジェクトでリフレクションしない
  1. リフレクションプローブの効果で既に反射しているオブジェクトAがあるとする。
  2. その近くにもう1つ同じように反射しているオブジェクトBがあるとする。
  3. この時、オブジェクトBにオブジェクトAは映り込める位置にあるとしても、映り込まない。
映り込みは1世代までみたいです(なので軽量とも?)。この辺は利用時注意。
逆に意図的に「映り込ませない」ような演出にもできるかも?
※Blender等ではこのIllumination映り込みの反射回数指定みたいなのを有効化すると結局レイトレーシング計算していたような記憶。軽量化の為、反射ネスト1回まで演算はうなずけます。それでも結構な演算負荷に見えるので。

サンプルプロジェクト

簡単なサンプルをGitHubにアップロード。
使用環境:Unity5.4.2f1。
https://github.com/maruton/Sample_ReflectionProbe

画面右の「Clone and download」からプルダウン内「Download ZIP」で落とせます。



参考URL: リフレクションプローブリフレクションプローブの使用

この記事では「ユニティちゃん」コンテンツを利用した画像を含んでいます。 © UTJ/UCL




2015年8月3日月曜日

Shadow Projector活用サンプル~地面から離れると小さく消失する影~

Unity提供のアセット(Shadow Projector)で「丸い影」を落とすサンプル。

ただし上昇して地面から離れるほど影を小さくして消失させます。







サンプル

環境: Windows7x64。Unity5.1.1f1 personal。

プロジェクトのダウンロードはGitHubサイト右下 Download ZIP
https://github.com/maruton/Sample_ShadowProjector



概要

普通(?)にShadow Projectorを利用して「丸い影」を落としたのが下の図1。影を上から照射しています。

この場合、上昇していくと影は次第に大きくなります。
(ある程度の高さを超えると影は薄くなり見えなくなります)

図1


上昇していくと小さくなり、やがて消失する影を考えてみます。

図2は影を下から照射しています。
下方から照射しても床の裏側だけでなく、表側にも影がレンダリングされることを利用します。

図2



光の回折

現実世界で太陽光下(無限遠から平行に照射)のような状況にて、光の回折を考えた場合。
高度が上がるほどに太陽光は真下に回り込むようになります。

結果、上昇していくと影は徐々に小さくなりいずれ完全に消失します。
(電灯などの近接してる非並行な光では逆に影は大きくなったりするので図1の方が自然な感覚)

Unityで屋外フィールド上をキャラクタが上昇/下降するような場合、演出的にも影が小さくなることで高度が上がってる感が出しやすそうです。


とはいえ「誰も影なんかそこまで見てない」という意見が最も的確な気もしますが、


ちょっとやってみたくなったので ⊂⌒~⊃。Д。)⊃


と、強引な動機付けが済んだところで、以後簡単に補足説明。

※夏休みの自由研究に格子回折とかちょっと面白いかもしれません(´∀`)




使用するアセット

Shadow projectorのAssetはUnityに標準で提供されていますが、パッケージ名がUnity5で変わったようです。

Shadow projectorを含むAssetは上部メニューから、

Assets > Import Package > Effects

で、インポート。



Shadow projectorの配置

ここではCubeをキャラクタに見立てて配置しています(オブジェクト名Character)。

インポートしたAssetに含まれる BlobShadowProjector をCharacterオブジェクトにドラッグ&ドロップして子Objectにします。



BlobShadowProjector が下から影を照射するように配置。



Floorオブジェクトに影の照射はしつつもCharacterオブジェクトには照射したくないのでレイヤで調整します。

ここでは簡単に、
  • レイヤ名Characterを新しく作り、Characterオブジェクトをそのレイヤに設定。
  • 子オブジェクト BlobShadowProjector はDefaultレイヤのまま。
さらに 子オブジェクトBlobShadowProjector を選択、Inspector内の Ignore Layersに レイヤ名 Character を指定。

これで レイヤ名 Character に配置したCharacterオブジェクトには影が照射されなくなります。


この状態で床下、床上を見ると以下のようになります。

影は床の表裏ともにレンダリングされているので、床上でも影が見えます。

ここでオブジェクトCharacterを上に移動していくと影が小さくなり、BlobShadowProjector が床よりも上に出た時点で影は消失するようになります。


この辺の微調整は BlobShadowProjector の Inspector内の Field Of View で行います。
他、照射の距離範囲はNear Clip Plane、Far Clip Plane等々。




ここまでで一応、上昇すると影が小さくなりやがて消失する影が簡単にできます。

しかし、Characterオブジェクトが傾むく動作をすると、子オブジェクトのBlobShadowProjector はぶら下がった振り子のような挙動になる為、真下に影が照射されません。

サンプルプロジェクトではこの辺も対応しています。



補足

  • 地面から遠くなるにつれて影の輪郭がハッキリしてしまう
    本当は徐々にぼやけていくべきですが、しくみの都合上仕様です。
    がんばってシェーダーをいじればぼかすこともできるかもしれませんが、軽量低負荷簡単手抜きという目的もあるので割り切ってしまう方が得策と思います。
    シーン上での見せ方とか、高速移動してるとどうせわからないとか、ごまかす手段はいろいろありますタブン|∀゚)
     
  • キャラクタ本体のScaleに注意
    親Objectであるキャラクタ本体と BlobShadowProjector  のScale値が等しくない場合、子オブジェクトの距離指定時に相互Scaleの比率で倍率がかかります。詳細は割愛しますがUnity4頃からこうなっているので仕様なようです。
    距離に倍率をかけて補正すれば良いだけですが無駄な演算が増えるのでScaleは共に <1,1,1>にした方が無難です。
     
  • 本体キャラが縦長の場合
    影そのものはBlobShadowProjector のInspector内のAspect Ratioで縦横比を簡単に変更できます。問題はキャラ本体の向きに追従させなければならない点ですが、サンプルでは軽量化の為考慮してません。
    BlobShadowProjector の向きをキャラ本体の向きに合わせるように制御すれば可能だと思います。
     
  • 本体キャラがロール/ピッチ変動する場合
    サンプルのiTween移動のようにロール/ピッチ角が変動すれば影の縦横比も変動すべきですが、これも軽量化の為に常に丸影です。
    まじめにAspect Ratioを動的に変えてやればそれっぽい楕円な影が落とせそうです。(でもロール/ピッチの両方はちょっと面倒そうです。Field Of Viewも動的にいじらないとダメかも?)


    しかし所詮「丸影」なのでそこまでする必要性は要検討です。

結局なんちゃって影なので、凝るのはほどほどにしておくのが良さそうです(´∀`)


2015年6月16日火曜日

iTweenパス上を前を向きながら移動するサンプル

iTweenパス上を前を(進行方向を)向きながら移動するサンプル。





環境

Unity 5.0.1f1 Personal.
iTween Visual Editor.
※Asset Storeからインポート。




概要

乗り物等の移動物をちょっと動かす際に便利。
移動経路の作成にはAsset Store にある iTween Visual Editor を使用。
 (参考: iTweenパス上をユーザー操作で移動するサンプル) 


結論から言ってしまうと、

iTween.MoveTo(gameObject, table);

で、引き渡す table に、

table.Add( "orienttopath", true );
table.Add( "lookTime", 1.0f );

を追加するだけでできてしまう。

lookTime で与える数値で姿勢転換の強度を指定。
  • 小さい値: 姿勢転換が早くなる。
  • 大きい値: 姿勢転換が緩やかになる。

姿勢転換の挙動は移動パスのカーブの孤の大きさや、移動速度(time)にも関係するので要調整。

移動するオブジェクトの向き(XYZ)と姿勢の関係は、
  • Z+: 前
  • Y+: 上
  • X+: 右
となっているので、予めこのようにモデリング/エクスポートしておくか、空のGameObjectを作って中に放み込み&向き調整等で。




サンプル


サンプルソース
-----
/*
 * @file csMoveHeadingToPath.cs
 * @note  None 
 * @attention 
 *    [csMoveHeadingToPath.cs]
 *    Copyright (c) [2015] [Maruton]
 *    This software is released under the MIT License.
 *    http://opensource.org/licenses/mit-license.php
 */
using UnityEngine;
using System.Collections;

public class csMoveHeadingToPath : MonoBehaviour {
 string pathName = "MyPath";
 float pathTime = 18.0f;//5.0f
 Hashtable table = new Hashtable();
 void SetupPath(){
  table.Add( "path", iTweenPath.GetPath(pathName) );//ITween path hash data
  table.Add( "time", pathTime );
  table.Add( "easetype", iTween.EaseType.easeInOutSine );
  table.Add( "onstart", "cb_iTweenStart" );  //Handler func when iTween start
  table.Add( "onstartparams", "Start" );   //parameter of Handler func when iTween start
  table.Add( "oncomplete", "cb_iTweenComplete" ); //Handler func when iTween end
  table.Add( "oncompleteparams", "Complete" ); //parameter of Handler func when iTween end
  
  table.Add( "orienttopath", true ); //Head to forwarding vector (*Important*)
  table.Add( "lookTime", 1.0f ); //Time value for heading nose (*Important*)
  
  iTween.MoveTo(gameObject, table);
 }
 void cb_iTweenStart(string param){
  Debug.Log("[iTween] cb_iTweenStart: "+param);
 }
 void cb_iTweenComplete(string param){
  Debug.Log("[iTween] cb_iTweenComplete: "+param);
  iTween.MoveTo(gameObject, table);//Restart iTween.
 }

 void Start () {
  SetupPath();
 }
 void Update () {
 }
}
-----

Unity5用プロジェクトのダウンロード。
Git-Hub:https://github.com/maruton/Sample_iTween_HeadingPath



2014年8月19日火曜日

iTweenパス上をユーザー操作で移動するサンプル

UnityにてObjectをiTweenを使用してユーザー操作でパス上をいったりきたり移動するサンプル。





概要

  • 使用言語: C#。

  • パスの作成: iTween Visual Editor。

  • 作成したパス上でCube ObjectをiTweenで移動させる。

  • 移動指示はユーザー操作で行う

  • 操作:
    PCならキーボードのA、D。
    Androidなら左右の傾き(加速度センサ)。
    Unity上の再生、実機又は、UnityRemote4で動作確認。

準備:

  1. Unityで新規プロジェクト作成。

  2. iTween Visual Editor パッケージをAsset Storeからインポート。
    1. CTRL+9でAsset Storeを開く。
    2. iTween Visual Editor」 で検索&インポート。
      ※iTween本体も同梱。別途入れる必要なし。入れるとエラーがでる。
  3. 一応ライトを追加しておく。
    Hierarchyウィンドウ内のCreateボタンから、
    Create > Direction Light
     


動かすObjectの追加

ここでは簡単にする為、Cubeを使う。

Hierarchyウィンドウ内のCreateボタンから、

Create > Cube

にて、追加。


iTween Visual Editorでパス作成


■iTween Visual Editor スクリプトを追加


動かす Cube オブジェクトに iTween Visual Editor スクリプトを追加する。
  1. Hierarchy上でCubeを選択状態にする。

  2. 上部メニューバーから、
    Component > Scripts > ITween Path

  3. Inspector上で ITween Path (Script) が追加される。
これで、パス作成の操作ができるようになる。


■パス名、ノード数を指定

  1. Cubeを選択状態にする
  2. Inspector で ITween Path (Script) が表示されていることを確認。
    以後この欄内の設定を行う。

    • Path Name:
      パスの名前。ここでは、

      MyPath

      としておく。
      ※1つのオブジェクトに複数のパスを持つこともできる。その際はパス名で区別する。
    • Path Color:
      パスの表示色。とりあえずデフォルトのまま。
      ※複数パスを作成した際に色で区別しやすくできる。
    • Node Count:
      パスの基点の数。ここでは5箇所とする為、

      5

      としておく。
      これで基点、中間点3つ、終点の計5箇所を設定できるようになる。
    • Node 1 ~ 5
      Node Countで 5 を指定したので、ここは Node 1 ~ 5 の5行になる。

■パスを作る

この段階で、シーン上に5つのXYZ矢印を示すパスカーソルが重なって配置されている。
これらはInspector上の Node1~5に対応している。

シーン上でこれらを操作して好みの移動パスを作成する。

CubeやDirection Lightが重なっていると選択しにくいので、これらを少しずらすと選択しやすい。


各パスを動かすと Inspector上の対応する Node n の欄XYZも変動する。
逆に Inspector上のNode nのXYZ値を変更するとパスカーソルもその位置に動く。

パスを増やしたい場合は Node Count を増やすことでNode n が増える。

※大量のNodeを配置する場合はとりあえず Node Countを少なめにして序盤のパスを配置後、Node Countを増やすという方法でもできる。


下図はパスを設定した画面

制御スクリプトの追加

  1. 新規スクリプトの追加
    Projectウィンドウ内にて、

    Create > C# Script

    にて、C#スクリプトを追加。

  2. スクリプト名を変更。
    ここでは cs_PathControl とした。

  3. スクリプト cs_PathControl をダブルクリックして開く。

  4. 後述のC#ソースをコピー&ペーストする。

  5. スクリプト追加
    Cubeオブジェクトを選択状態として上部メニューより、
    Component > Scripts > cs_Path Control

----- cs_PathControl
/*
 * @file cs_PathControl
 * @attention なし 
 * @note  なし 
 */

using UnityEngine;
using System.Collections;

public class cs_PathControl : MonoBehaviour {
 Vector3[] NodeData;
 iTweenPath cp_ITweenPath; //!< Instance pointer for 'ITween Path' Script
 float PositionPercent = 0; //!< 0.00~1.00. パス全体の移動距離に対し%で指定する値 
 
 /*!
  * Visual Path Editorで作成済みのパスデータを取得
  *  @param[in] pathname 取得するパス名
  *  @return     取得結果  true:成功  false:失敗
  *  @note     Visual Path Editorで作成済みのパスデータ Node 1~n を NodeData[]へ格納する 
  *  @attention    呼び出しタイミングはStart()以降とすること。 
  *        iTweenPath.GetPath()内部のパス名リスト更新が OnEnable()のタイミングで行われている。 
  *        よってAwakeではまだ確定していない場合がありえる為、Start()以降のタイミングで呼び出すこと。 
  */
 bool SetPathPosition_from_ITweenPath(string pathname){
  if(cp_ITweenPath==null){
   cp_ITweenPath = GetComponent<iTweenPath>(); // このObject内の ITween path スクリプトコンポーネントのインスタンスを取得 
   if(cp_ITweenPath==null){
    Debug.Log("[NO SCRIPT] No there script 'ITween Path' on this object");
    return(false);
   }
  }
  // GetPath()はStatic宣言されているので直呼び出し  
  NodeData = iTweenPath.GetPath(pathname); // Visual Path Editor のパス名を指定してパスデータを取得する。 
  if(NodeData==null){
   Debug.Log ("[NOT FOUND/null] path name '"+pathname+"'");
   return(false);
  }
  return(true);
 }
 const float addSpeed = 0.005f;
 void Drive_Increase(){
  //Debug.Log ("Drive_Increase");
  PositionPercent += addSpeed;
  if(PositionPercent>1.0f) PositionPercent = 1.0f;
 }
 void Drive_Decrease(){
  //Debug.Log ("Drive_Decrease");
  PositionPercent -= addSpeed;
  if(PositionPercent<0.0f) PositionPercent = 0.0f;
 }
 
 void Watch_UI_Input(){
  bool drive_Fwd = false;
  bool drive_Bwd = false;
  
  //Begin: Control by Keyboard
  bool input_Key_A = Input.GetKey(KeyCode.A);
  bool input_Key_D = Input.GetKey(KeyCode.D);
  if( !(input_Key_A & input_Key_D) ){ // Disable multi press
   drive_Fwd |= input_Key_A;
   drive_Bwd |= input_Key_D;
  }
  //End: Control by Keyboard
  #if UNITY_ANDROID
  //#if UNITY_IPHONE
  //Begin: Control by Accel Sensor
  float accel_X = Input.acceleration.x; // 加速度センサ 横傾き 
  //Debug.Log ("accel_X:"+accel_X);
  if(accel_X <-0.2f){
   drive_Fwd |= true;
  }
  else if(accel_X >0.2f){
   drive_Bwd |= true;
  }
  //End: Control by Accel Sensor
  #endif
  
  if (drive_Fwd) Drive_Increase();
  if (drive_Bwd) Drive_Decrease();
  if(drive_Fwd|drive_Bwd) Debug.Log("Position is "+PositionPercent*100.0f+"%"); //移動したなら表示 
 }
 
 void Start () {
  SetPathPosition_from_ITweenPath("MyPath");
 }
 
 void Update () {
  Watch_UI_Input();
  transform.position = iTween.PointOnPath(NodeData, PositionPercent); // Get target position 
 }
}
-----


Unity5用プロジェクトサンプル: https://github.com/maruton/Sample_iTween_PointOnPath




その他メモ


移動速度

このサンプルでは移動速度は一定にしている。

const float addSpeed = 0.005f;

の数値を動的に可変してやれば、加減速の調節できる。

パスの座標指定について

このサンプルの動作の肝は、iTween のPointOnPath()で、

transform.position = iTween.PointOnPath(NodeData, PositionPercent);

にて、パス全体の移動長さに対して 0~1.0の間で移動位置を指定する部分。

この時与える NodeData は単なる Vector3の配列でしかない。
つまり、このデータ列が用意できるなら、特に iTween Visual Editor を使わなくても動作できる。

例えば、通過ポイントのようなオブジェクトがシーンに既に存在しているような場合、それらのXYZを得て、Vector3の配列に収めれておけば引数に利用できる。

iTweenPathスクリプト


iTween Visual Editorパッケージに含まれている。

このスクリプトのメンバ関数

static GetPath(string requestedName)

を使うと、Visual Editor でシーン上に配置したNodeの配列(Vector3)が簡単に得られる。
(関数型がStaticに注意。パスを複数作成すると、iTweenPathスクリプトも複数Component追加する為、それらのパス名を一意に管理する為にこうなっているようだ)

このスクリプトは単純に、シーン上でビジュアルエディットしたNodeの配置を単純なVector3配列で受け取れるものと解釈できるので、他の用途にも利用価値があるかもしれない。



2014年5月11日日曜日

テクスチャをスクロールするサンプル

Unityにてテクスチャをスクロールするサンプル。言語はC#



使用する関数は SetTextureOffset()。
テクスチャをオフセットして貼り付けることでスクロールを実現する。

SetTextureOffset("_MainTex", new Vector2(offsetX ,offsetY));

  • オフセット値(offsetX, offsetY
    テクスチャの縦横ピクセルサイズに関わらず、0~1.0未満の比率で指定となる。
    1.0は0.0と同義になる感じなのでテクスチャをREPEATで貼っておけば1.0以上でもオフセット指定はできる感じだが、一応0~1.0未満範囲で指定しておいたほうが間違いないと思う。
     
  • オフセット対象 ("_MainTex"
    シェーダーが「Bumped Diffuse」等の場合で、テクスチャとノーマルマップを共に使う場合は両方をオフセットする必要有り。
    _MainTex" はテクスチャを、"_BumpMap"はノーマルマップを指定する。

    シェーダーが Mobile/Bumpoed Diffuse の場合は、"_MainTex"指定だけで Normal Map も同時にオフセットする。

Androidアプリ等向けだと Mobile/ほにゃらら をよく使いそうなので、"_BumpMap"は使わないかもしれない。
※逆にこれの意味するところは、ノーマルマップを固定のままで、テクスチャだけはずらせない制限とも言えそう。

-----
/*
 *    @file    TexAnimate_Test.cs
 *    @note        なし 
 */
using UnityEngine;
using System.Collections;

public class TexAnimate_Test : MonoBehaviour {
    void Awake(){}
    void Start (){
        Init();
    }
    void OnApplicationFocus(){}
    void OnApplicationQuit(){}
    void OnApplicationPause(bool pauseStatus) {
        if(pauseStatus){ //Suspend (back to OS)
        }
        else{ //Resume (From OS)
        }
    }
    void OnGUI(){
        DrawGUI(); // 操作ボタン、2D文字描画
    }
    void Update() {
        //Debug.Log ("Update:");
        if(Application.platform == RuntimePlatform.Android && Input.GetKey(KeyCode.Escape)){//戻るボタン対応
            Application.Quit();
        }
        AnimateTexture(); // テクスチャスライド
    }
    //============================================================

    public float tex_offsetX = 0.0f; //!< テクスチャオフセット X。※Editorから操作も可
    public float tex_offsetY = 0.0f; //!< テクスチャオフセット Y。※Editorから操作も可

    public float C_tex_Add = 0.001f; //!< テクスチャ スライド分解能
    float tex_Add;
    void Init(){
        tex_Add = -C_tex_Add;
    }
    void AnimateTexture(){
        tex_offsetX += tex_Add;
        if(tex_offsetX<=0.0f){
            tex_offsetX = 1.0f - C_tex_Add;
        }
        if(tex_offsetX>=1.0f){
            tex_offsetX = 0.0f;
        }
        //    See detail: https://docs.unity3d.com/Documentation/ScriptReference/Material.SetTextureOffset.html
        //renderer.material.SetTextureOffset("_BumpMap", new Vector2(tex_offsetX, tex_offsetY));// Mobile/Bumpoed Diffuseでは不要
        renderer.material.SetTextureOffset("_MainTex", new Vector2(tex_offsetX, tex_offsetY));// Mobile/Bumpoed Diffuse ではNormal Mapも同時に動く
    }

    string DebugMessage = "";
    void DrawGUI(){
        //if(true)return;
        //Debug.Log ("OnGUI:");
        GUIStyle labelStyle;    //!< GUIフォント表示用スタイル
        int fontRetio = 18;
        
        labelStyle = new GUIStyle();
        labelStyle.fontSize = Screen.width / fontRetio; // Font size
        labelStyle.normal.textColor = Color.grey;
        labelStyle.wordWrap = true;
        GUI.Label(new Rect(0, 0, Screen.width-100, Screen.height-100), "Offset X="+tex_offsetX+"\nOffset Y="+tex_offsetY, labelStyle);

        float ScrnHor = (float)Screen.width;
        float ScrnVert = (float)Screen.height;
        Rect rectBtn = new Rect(ScrnHor*0.12f,ScrnVert*0.10f,ScrnHor*0.76f,ScrnVert*0.05f);
        if(GUI.Button(rectBtn, "[SLOW FWD]")) {
            tex_Add = -C_tex_Add;
        }
        rectBtn = new Rect(ScrnHor*0.12f,ScrnVert*0.15f,ScrnHor*0.76f,ScrnVert*0.05f);
        if(GUI.Button(rectBtn, "[SLOW BWD]")) {
            tex_Add = C_tex_Add;
        }
        rectBtn = new Rect(ScrnHor*0.12f,ScrnVert*0.20f,ScrnHor*0.76f,ScrnVert*0.05f);
        if(GUI.Button(rectBtn, "[STOP]")) {
            tex_Add = 0.0f;
        }
        rectBtn = new Rect(ScrnHor*0.12f,ScrnVert*0.25f,ScrnHor*0.76f,ScrnVert*0.05f);
        if(GUI.Button(rectBtn, "[FAST FWD]")) {
            tex_Add = -C_tex_Add * 10.0f;
        }
        rectBtn = new Rect(ScrnHor*0.12f,ScrnVert*0.30f,ScrnHor*0.76f,ScrnVert*0.05f);
        if(GUI.Button(rectBtn, "[FAST BWS]")) {
            tex_Add = C_tex_Add * 10.0f;
        }
    }
}
-----


Unity5用 Project: GitHubサイト右下の「Download ZIP」からダウンロード可。
https://github.com/maruton/Sample_TextureSlide

Unity4用 Project: Google Drive


※追記:Android実機用前提ソースのままなので、Unity上だとノーマルマップはスライドしません。
     ソース内 AnimateTexture() で"BumpMap"指定部分がコメントになっています。
     このコメントを外せば、Unity上でノーマルマップもスライドします。





2014年4月15日火曜日

外部ブラウザからTweetするサンプル

Unityにて外部ブラウザからTweetするサンプル。言語はC#。

※文字数のチェックはしていないので注意。

-----

/*
 * @file Sample_Twitter.cs
 * @attention 
 * @note Open Twitter site sample
 */
using UnityEngine;

public class Sample_Twitter : MonoBehaviour {
 string tweetText = "つい~とのテスト"; //!< Tweet strings

 /*! Unity builtin function
  *  OnGUI()  */
 void OnGUI(){
  if(ScrnHor!=Screen.width){ ReCalcScrn(); } // ReCalculation size of screen

  GUI.Box(rectBg, "Twetter"); // Draw background

  if(GUI.Button(rectURL, "Tweet: "+tweetText)) { // Tweet button
   Application.OpenURL("https://twitter.com/intent/tweet?text="+WWW.EscapeURL(tweetText)); // Call browser for tweet
  }
 }
 //============================================================
 float ScrnHor; //!< Currently size of screen horizontal
 float ScrnVert; //!< Currently size of screen vertical
 Rect rectBg; //!< Background rectangle
 Rect rectURL; //!< URL button rectangle
 /*! ReCalculation size of screen */
 void ReCalcScrn(){
  ScrnHor = (float)Screen.width;
  ScrnVert = (float)Screen.height;
  rectBg = new Rect(ScrnHor*0.1f,ScrnVert*0.1f,ScrnHor*0.8f,ScrnVert*0.8f);
  rectURL = new Rect(ScrnHor*0.12f,ScrnVert*0.16f,ScrnHor*0.76f,ScrnVert*0.1f);
 }
 /*! Unity builtin function
  *  Awake()  */
 void Start () {
  Screen.orientation = ScreenOrientation.AutoRotation; // Auto rotation
  ReCalcScrn();
 }
 /*! Unity builtin function
  *  Update() */
 void Update () {
  // Exit app when hit back button(Android) ※機種判定を外すとESCでアプリ終了(Windows)
  if(Application.platform == RuntimePlatform.Android && Input.GetKey(KeyCode.Escape)){ // Back button
   Application.Quit();
  }
 }
 //============================================================
}
-----

外部ブラウザからURLを開くサンプル

Unityにて外部ブラウザからURLを開くサンプル。言語はC#。

使う関数は、Application.OpenURL("URL")
※URLはきちんと生成しないとAndroid機でうまく開けないので注意。

-----

/*
 * @file Sample_OpenURL.cs
 * @attention 
 * @note Sample for Open URL
 */
using UnityEngine;

public class Sample_OpenURL : MonoBehaviour {
 //string TestURL = "www.google.co.jp";    //Win OK / Android NG
 //string TestURL = "http://www.google.co.jp"; // Win OK / Android OK
 //string TestURL = "https://www.google.co.jp"; // Win OK / Android OK
 string TestURL = "http://www.google.co.jp/"; // Win OK / Android OK ***** URL ******
 void OnGUI(){
  if(ScrnHor!=Screen.width){ ReCalcScrn(); }
  
  GUI.Box(rectBg, "Menu");
  
  if(GUI.Button(rectURL, "Open URL: "+TestURL)) {
   Application.OpenURL(TestURL); // ***** Open URL ******
  }
 }
 //============================================================
 float ScrnHor, ScrnVert;
 Rect rectBg, rectURL;
 void ReCalcScrn(){
  ScrnHor = (float)Screen.width;
  ScrnVert = (float)Screen.height;
  rectBg = new Rect(ScrnHor*0.1f,ScrnVert*0.1f,ScrnHor*0.8f,ScrnVert*0.8f);
  rectURL = new Rect(ScrnHor*0.12f,ScrnVert*0.16f,ScrnHor*0.76f,ScrnVert*0.1f);
 }
 void Start () {
  //Screen.orientation = ScreenOrientation.Portrait;
  Screen.orientation = ScreenOrientation.AutoRotation;
  ReCalcScrn();
 }
 void Update () {
  //「戻るキー」でアプリ終了 (Android) ※機種判定を外すとESCでアプリ終了(Win)
  if(Application.platform == RuntimePlatform.Android && Input.GetKey(KeyCode.Escape)){//戻るボタン対応
   Application.Quit();
  }
 }
 //============================================================
}
-----

2014年3月30日日曜日

メッシュテキストを使うサンプル

Unityにてメッシュテキストのサンプル。言語はC#。

サンプルではフォントファイル MPLUS-1MN-REGULAR を使用。
フォントファイルは以下のAssetsフォルダに配置。
/Assets/Resources/Font/MPLUS-1MN-REGULAR


/*
 * @file cs_MeshText.cs
 * @attention なし
 * @note  なし
 */
using UnityEngine;
using System.Collections;

public class cs_MeshText : MonoBehaviour {
 public GameObject go_MeshTxt;  //!< GameObject
 public TextMesh cp_TxtMesh;   //!< Mesh text components
 public MeshRenderer cp_TxtRender; //!< Mesh renderer components

 string Text = "This is mesh strings.";

 void Start () {
  go_MeshTxt = gameObject; // Use current gameobject

  go_MeshTxt.transform.parent = transform; // transformをこのオブジェクトを親として登録
  cp_TxtMesh = go_MeshTxt.AddComponent<TextMesh>(); // Mesh textコンポーネントを追加
  cp_TxtRender = go_MeshTxt.GetComponent<MeshRenderer>(); // Mesh textのrendererコンポーネントを追加

  go_MeshTxt.transform.eulerAngles = new Vector3(90,0,0);//向き調整(角度)
  cp_TxtMesh.alignment = TextAlignment.Center; // テキスト Allign設定
  cp_TxtMesh.anchor = TextAnchor.LowerCenter; // テキスト アンカー位置設定
  cp_TxtMesh.fontSize = 80; //フォントサイズ
  cp_TxtMesh.characterSize = 0.1f; //キャラクタサイズ
  cp_TxtMesh.text = Text; // 表示テキスト文字列
  cp_TxtMesh.color = new Color(1,0,0);// 色指定

  cp_TxtMesh.font = Resources.Load<Font>("Font/MPLUS-1MN-REGULAR"); // フォント指定
  cp_TxtRender.material = Resources.Load<Material>("Font/MPLUS-1MN-REGULAR"); //マテリアルにもフォント指定
 }
}

 

2014年3月20日木曜日

言語設定値の取得

Unityにて端末に設定されている、言語値の取得サンプル(C#)。


/*
 * @file GetLang.cs
 * @attention 
 * @note  言語設定取得サンプル
 */
using UnityEngine;
public class GetLang : MonoBehaviour {
 GUIStyle labelStyle;

 void Start () {
  labelStyle = new GUIStyle();
  labelStyle.fontSize = 40;// Font size
  labelStyle.normal.textColor = Color.white;
 }

 void OnGUI(){
  float x = Screen.width / 8 ;
  float y = Screen.height / 8;

        string text = Application.systemLanguage.ToString(); //設定言語値取得
        /*  取得値については公式サイト参照
            http://docs.unity3d.com/Documentation/ScriptReference/SystemLanguage.html
        */

  GUI.Label(new Rect(x, y, x, y), text, labelStyle);
 }
}