08 «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.» 10

ハルシオンシステムの気ままBlog

株式会社ハルシオンシステムのメンバーが送る、UnityやらJavaやらの技術的話題から、自社開発のアプリの宣伝とかとかのブログです。ほんと気ままにいきたいと思います。更新日は毎週 月 木でっす!

 

【Unity】オブジェクトをふにゃふにゃ動かすのに、iTweenPath使ったんだぜぇ~ ワイルドだr(自粛 

おはようございます。
本日は昼まで祝日とは知りませんでした。テヘ
曜日感覚とかやばくなってきました。坂内です。
みなさんはハロウィンはっちゃけました?
俺は家でゲームしてました。
誰だよハロウィンとか広めたの!ちょっと前まで、コンビニとかでちょっとお菓子がハロウィン用になるくらいだったのに、最近わけーのもいい年のもはっちゃけすぎだろ!落ち着けお前ら!
とまぁ 苦言を一つ。

本日はiTweenPathを初めて使ったので、そのことについてちょちょっと書いてみます。

まずはこちらで「iTween Visual Editor」をインストールします。

もちろんタダ。タダ、これ最強也。

この時すでにiTweenを単体で入れていた場合、「iTweenクラスかぶってんぞ おぃ!」って怒られるので気を付けてください。

ここにiTweenクラスは入ってます。(ちなみに俺はここのiTweenを残しました)

あとはもう簡単!
適当なオブジェクトを作って、それにiTweenPathをつけます。

実際の使い方は以下の通り。

iTweenPathのNodeCountがPathになる座標です。
こちら10個まで設定できるようです。
座標を好きに移動させて、こんな動きのパスを作ってみました。

あとは、コードで動かす感じですね。

TestITweenPathっていうクラス作って、iTweenPathをつけたオブジェクトにつけました。
using UnityEngine;
using System.Collections;

public class TestITweenPath : MonoBehaviour {
public GameObject sphere;
// Use this for initialization
void Start () {
Hashtable hash = new Hashtable();
hash.Add("path",iTweenPath.GetPath("TestPath"));
hash.Add("time",5f);
hash.Add("easetype",iTween.EaseType.linear);
iTween.MoveTo(sphere,hash);
}
}

で、玉(Sphere)を1個作って、こちらのsphereにアサインしときます。
あ、Pathの名前は「TestPath」にしました。

これ、ちゃんとパス通りに動きますよ!
すごいね!
やったね!

しかしだ、1点問題がありまして。
複数回同じPathを取得するとエラーが出ます。
普通に複数回上記のコードで流す分にはいいのですが、InstantiateしたオブジェクトにてiTweenPathを行った際の問題(?)です。


先ほどのiTweenPathをつけたオブジェクトと、玉を1つのオブジェクトに突っ込んで、Prefab化します。
「TestITweenPath」クラスを以下のように修正しておきます。
これで、ボールの動きが終わったら丸々Destroyするようにします。
using UnityEngine;
using System.Collections;

public class TestITweenPath : MonoBehaviour {
public GameObject sphere;

void Start () {
Hashtable hash = new Hashtable();
hash.Add("path",iTweenPath.GetPath("TestPath"));
hash.Add("time",5f);
hash.Add("easetype",iTween.EaseType.linear);
hash.Add("oncompletetarget",gameObject);
hash.Add("oncomplete","EndPath");
iTween.MoveTo(sphere,hash);
}

public void EndPath(){
Destroy(gameObject);
}
}


で、ボタンを用意し、ボタンを押すことで上記オブジェクトが出てくるようにします。

これで実行をすると、ボタンを押すと玉が出てきて、Path通りに動き、最後には消えます。
そこで、もう一度ボタンを押したところ、以下のようなエラーが発生しました。
ArgumentException: An element with the same key already exists in the dictionary.
System.Collections.Generic.Dictionary`2[System.String,iTweenPath].Add (System.String key, .iTweenPath value)
(at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/
Dictionary.cs:404)
iTweenPath.OnEnable () (at Assets/iTweenEditor/iTweenPath.cs:17)
UnityEngine.Object:Instantiate(Object)
PathTest2:StartPath() (at Assets/Scripts/PathTest2.cs:8)
UnityEngine.EventSystems.EventSystem:Update()

なんかDictionaryに同じキーが入ってるよーってエラーぽいですね。
まったく同じPathを取得するときにエラーがでてるのかな?
ってことで、次のようにすると動くようになりました。

using UnityEngine;
using System.Collections;

public class TestITweenPath : MonoBehaviour {
public GameObject sphere;

void Start () {
Hashtable hash = new Hashtable();
hash.Add("path",iTweenPath.GetPath("TestPath"));
hash.Add("time",5f);
hash.Add("easetype",iTween.EaseType.linear);
hash.Add("oncompletetarget",gameObject);
hash.Add("oncomplete","EndPath");
iTween.MoveTo(sphere,hash);
}

public void EndPath(){
iTweenPath.paths.Clear();
Destroy(gameObject);
}
}


これ追加しました ⇒ iTweenPath.paths.Clear();
iTweenPath.pathsをクリアーしてやりました。

ってお話でしたと。

では アデュ~ノシ
スポンサーサイト

Category: 開発日記(Unity)

Tag: Unity  iTween 
tb 0 : cm 0   

【Unity】ResourcesフォルダからInstantiateしてます?意外と便利っすよね? 

午前中は昼過ぎまで打ち合わせ、午後は仕様検討の会議してたらこんな時間になってしまいました!
坂内っす。

現在本格育成シミュレーションゲーム制作中です。
何が本格かって?
放置育成じゃないっすよ?それだけなんですけどね。

で、本日の話題ですが、みなさんオブジェクトをInstantiateするときって、ふつうにPrefabをPublicとかにくっつけて、Instantiateしてます?
俺はずっとそうやってました。

でもInstantiateするオブジェクトが多岐にわたる場合とかめんどいっすよね。

って時に、ReosourcesフォルダからInstantiateしちゃえるらしいっす。

例えば、以下のようにResourcesフォルダにPrefabを置いておきます。
今回はCubeというPrefabを用意しました。


んで、なんか適当にPrefabをInstantiateしてみます。

using UnityEngine;
using System.Collections;

public class PrefabTest : MonoBehaviour {

const string DIR_CUBE_PREFAB = "Prefabs/";
const string NAME_CUBE_PREFAB = "Cube";
readonly Vector2[] RANDOM_POSI = {new Vector2(-5f,-10f),new Vector2(5f,10f)};
const float POSI_Z = 20f;

void Start () {
// Cube生成
for(int i = 0 ; i < 5 ; i++){
GameObject cube =
Instantiate(Resources.Load(DIR_CUBE_PREFAB + NAME_CUBE_PREFAB))
as GameObject;
float x = Random.Range(RANDOM_POSI[0].x,RANDOM_POSI[1].x);
float y = Random.Range(RANDOM_POSI[0].y,RANDOM_POSI[1].y);

cube.transform.localPosition = new Vector3(x,y,POSI_Z);
}
}
}


こんな感じで実行すると、こうなります↓


もちろんランダムなので、実行の度にCubeの場所が変わります。

GameObject cube = Instantiate(Resources.Load(DIR_CUBE_PREFAB + NAME_CUBE_PREFAB)) as GameObject;
の場所ですが、もちろん以下でもおk!

GameObject pref = Resources.Load(DIR_CUBE_PREFAB + NAME_CUBE_PREFAB);
GameObject cube = Instantiate(pref) as GameObject;

Resources.Load(Prefabの場所と名前);

で、できるようっす。

これで、prefabの名前に0とか10とかつけて、ランダムのオブジェクトが生成できるってことっすね。

あ、ちなみにこうやってInstantiateした時でも、Resources.UnloadUnusedAssets()とかで、リソース解放しないとダメなんですかね?

リソース解放まわりよく分かっていないんですよね・・・・・どなたか教えて頂ければ幸いです!

え?今頃こんなネタ書くなって?すいません

ネタ探しの旅に出ますorz アデュ~ノシ

Category: 開発日記(Unity)

Tag: Unity 
tb 0 : cm 0   

【Unity】みなさん、データの保存ってどうやってます?俺はこうやっちゃってます。 

こんにちは!坂内です。
台風19号でかいっすね。直撃御免って感じですが、みなさん大丈夫でしょうか?
いきなり肌寒くなってきて、風邪にも注意でごわす。

さて、本日はUnityにおけるデータの保存についてちょこっと書いてみます。

皆さんUnityでゲームを作る際、データの保存はどのように行ってますか?
基本、少ないデータならばPlayerPrefs、もしくはテキストとかのデータファイルに書き込みってのが一般的なんですかね?
他にもDBとしてSQLiteとか使えるようですが、使ったことありません。うひひ

PlayerPrefsですと、「string」「int」「float」くらいしか使えませんよね?
これってめんどいですよね。色々なデータをわざわざintとかfloatに変えないと保存できないし、ロードの際にも逆に変換とかしないといけないと・・・・・
そういえば、どこかにPlayerPrefsXというのもありましたね。以前ちょっと使ったことはあります。

ってことで、僕はいつも以下のクラスを使っております。(これどこかのサイトで見つけたんだと思ったけど・・・どこか忘れました)

「FileController.cs」

using UnityEngine;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public class FileController : MonoBehaviour{

public FileController(){
}

public static bool Save<T>( string prefKey, T serializableObject ){
MemoryStream memoryStream = new MemoryStream();
#if UNITY_IPHONE || UNITY_IOS
System.Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
#endif
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize( memoryStream, serializableObject );

string tmp = System.Convert.ToBase64String( memoryStream.ToArray() );
try {
PlayerPrefs.SetString ( prefKey, tmp );
} catch( PlayerPrefsException ) {
return false;
}
return true;
}

public static T Load<T>( string prefKey ){
if (!PlayerPrefs.HasKey(prefKey)) return default(T);
#if UNITY_IPHONE || UNITY_IOS
System.Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
#endif
BinaryFormatter bf = new BinaryFormatter();
string serializedData = PlayerPrefs.GetString( prefKey );

MemoryStream dataStream = new MemoryStream( System.Convert.FromBase64String(serializedData) );
T deserializedObject = (T)bf.Deserialize( dataStream );

return deserializedObject;
}

public void save(SaveData data) {
// 保存用クラスにデータを格納.
FileController.Save("{PlayerPrefsに保存するキー}", data);
PlayerPrefs.Save();
}

public SaveData load() {
SaveData data_tmp = FileController.Load("{PlayerPrefsに保存するキー}");
if( data_tmp != null){
return data_tmp;
}else{
return null;
}
}


「SaveData.cs」実際に保存されるクラス
using System.Collections;

[System.Serializable()]
public class SaveData{
[System.Serializable()]
public class InnerClass{
public string ppppppp;
public int ggggggg;
}

public int aaaaaaa;
public float bbbbbb;
public string cccccccc;
public int[] ddddddd;
public InnerClass eeeeeeee;

}

と、まぁどんな形のクラスでもいいですが、シリアライズできるならそのままマルっと保存できちゃいます。
もちろん上記のように内部クラスがあっても問題ナッシング!
なんでも保存できちゃうのが素敵っすよね!
もちろん、AndroidiOSどっちも対応してます。

ということで、Unityのデータ保存ライフ楽しんで! アデュ~ノシ

Category: 開発日記(Unity)

Tag: Unity  Android  iOS 
tb 0 : cm 0   

【Unity】Excel使ってローカライズ試してみたんだが・・・・どうなんでしょかねorz 

おはようございます。坂内です。
だいぶ涼しくなってまいりました。
過ごしやすい季節ですがな!

現在あっぷるさんに申請だしているアプリは、ipadの時に広告がスゲー画面のど真ん中にでちゃうんでふざけんなってリジェクトされてます。
ええ、ipadなんてありませんから、試しようがないんですよね テヘ
ちくしょーーーー!!!!

とりあえず10月入ったらipadの1を知り合いからもらう予定・・・・
ちなみに今は、育成ゲーム作ってます。
いくつか絵ができ次第、予約TOP10に出そうかなとは思ってます。

で、今日の話題は、Excelファイルを使ってローカライズしてみよう?ってこと。
ちなみにUnity4.6ベータ使い続けてます。

色々と文字が多いアプリを作る際にめんどくさい(管理しやすいよう)にExcelファイルにて文字を管理しちゃいたいんですが、ローカライズはどうするの?って思った一瞬があったんですよね。
で、色々考えたんですが、ここにたどり着きました。ってお話です。

まずは、Excelが使えるように以下を落としてプロジェクトに入れちゃってください。
http://tsubakit1.hateblo.jp/entry/20131010/1381411760
こちら、テラシュールウェアさんのブログからです。テラさんスゲーよなーなんでも作っちゃうしー

で、上記の準備ができたら、適当なローカライズ用クラスを作ります。
using UnityEngine;
using System.Collections;

public class Localize : MonoBehaviour {

const int LOCALIZE_EN = 0; // ENシート
const int LOCALIZE_JA = 1; // JAシート

public static int localize;

void Awake () {
if (Application.systemLanguage != SystemLanguage.Japanese) {
localize = LOCALIZE_EN;
}else{
localize = LOCALIZE_JA;
}
}
}

んで、↓こんなエクセルをつくります。シートは「ENシート」と「JAシート」を作りました。
ENシートには英語の文言、JAシートには日本語の文言が入ってます。
エクセルのファイル名は「test.xls」にしました


test.xlsをインポートします。
インポートするときに、クラス名を決めます。
今回はクラス名を「LocalizeData」とかにしときました。


で、できあがったのがこちら。


ScriptableObjectなるものが出来上がるらしいです。

さてさて、お次はこいつを実際に使ってみます。


とりあえずTextおいておきます。
で、以下のLocalizeTestクラスを作ります。
using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class LocalizeTest : MonoBehaviour {

public LocalizeData localizeData;

void Start () {
GameObject.Find("Text").GetComponent().text = localizeData.sheets[Localize.localize].list[0].title;
}
}

ここでは、実際にローカライズしたデータを使用するコードを書いときます。
localizeData.sheets[Localize.localize]
のところで、先ほどのLocalizeで日本語なのか英語なのかのシート分けを行っています。
今回は適当に、CanvasにこのLocalizeTestをつけました。


んで、public LocalizeData localizeData;に当たるものには、先ほど作ったScriptableObjectをつけます。
そのまま実行すると


のように日本語が出ます。

これ、Androidとかで英語にして実行するとちゃんと英語がでます。

と、こんな感じでローカライズできるんですかね?
でも、この方法だと1個1個のオブジェクトに対して無駄なコードを書いているような・・・・
もっと簡単な方法ないんですかね!?

ってところで、アデュ~ノシ

Category: 開発日記(Unity)

Thread: Unityゲーム制作

Janre: コンピュータ

Tag: Unity 
tb 0 : cm 0   

【Unity】NGUIでのロングタップ処理 

モンスラが好評です!ありがとうありがとう!
あと少しで1万DLいきまっす!!
現在は来年1,2月にリリースをしたいと思っている
RPGを開発中!RPG開発中!大事なことなので2回言いました。
これまた面白いものになりますので楽しみにしてください!

モンスラの新機能を考えながら新しいアプリのリリース!
はたまたiphoneにモンスラを移植するか・・・
何に手を付けたらいいのか悩んでいる坂内です。

さて、今日はNGUIにおけるロングタップについてです。
まぁ簡単なのでみなさんすでに実装されていると思いますが、
今回ロングタップを実装しようとして、なにか簡単にやる方法はないかと
ぐーぐる先生に聞いたのですが、なんも教えてもらえなかったので
適当に実装してみました。

手順は以下です。
NGUIでボタンつくりまーす
②スクリプト用意しまーっす。
③UIButtonだと、On Clickしかないため、UIButton Messageを用意しまーす。
④もいっこUIButton Messageを用意しまーっす。
終わり。

では順番に説明をば。
【1 ボタンつくりまーす】
 これはそのままですね、ボタンをNGUIのWigetWizardから作成します。

 適当な絵を用意したので、Labelは消しております。

 
【2 スクリプトを用意しまーっす】
 今回用意したスクリプトは以下になります。
 
using UnityEngine;
using System.Collections;

public class LongTap : MonoBehaviour {
float longTapDuration = 2.0f;
float lastTap;
bool tapFlg;

void OnTap(){
tapFlg = true;
lastTap = Time.realtimeSinceStartup;
}

void OnRelease(){
tapFlg = false;
}

void Update(){
if(tapFlg && Time.realtimeSinceStartup - lastTap > longTapDuration){
print("aaaaa");
tapFlg = false;
}
}

}

 はじめのlongTapDurationは、ロングタップの時間を指定しています、2秒ロングタップすれば
 ロングタップ時の処理を実行するってことっすね。
 lastTapは、タップを始めた時間を保存するやつっす。
 メソッドといえば、OnTapが押された時、OnReleaseは離された時の処理っす。
 Updateにて、「押されている、且つ押され始めてからlongTapDurationの時間が経った場合」の条件で
 print分を処理しています。
 この際、tapFlgをfalseにしないとずっと押されていると処理が行われてしまいまっす。
 
【3 UIButtonだと、On Clickしかないため、UIButton Messageを用意しまーす】
 ButtonにUIButton Messageを追加します。
 「Add Component」⇒「NGUI」⇒「Interaction」⇒「Button Message」で追加できます。
 追加したら、先ほどのスクリプトを設定しているオブジェクトを「Target」に設定し、
 「Trigger」をOnPressに変更し、「Function Name」に先ほどのスクリプトで作った
 OnTapにします。

 
【4 もいっこUIButton Messageを用意しまーっす】
 3と同じくUIButton Messageを追加します。
 追加したら先ほどと同じ感じで「Target」の設定を行います。
 「Trigger」はOnReleaseに変更し、「Function Name」にはOnReleaseを設定します。


これでおしまいっ!
いちおうこれでできましたが、もっと簡単な方法あったらおせーてくださいませっ!

ではっ ノシ

Category: 開発日記(Unity)

Thread: 日記

Janre: 日記

Tag: Android  Unity  NGUI  タップ 
tb 0 : cm 0