カテゴリー: Tips (2ページ / 3ページ)

Blenderで人のモデリングも終わった

めっちゃかかった

人間二人にまる二日くらい。
先日のポストの動画とサイトさんを両方参考にしながらやりました。

Blenderで人のモデリング

・・・動画の方だと、もはや一日でアニメーションまで終わらせているけどなー。

いつかああなれるのか?

UnityでC#するのと、同じくらい楽しいね。今はむしろこっちのが楽しいです。

順番はこう

テクスチャー用意

モデリング

UVテクスチャーマッピング

感想

表情があんまり不要なので

目と口と鼻は、特にポリゴン割りせず、テクスチャーで描いているのですが。

何だろー。うーん。顔のパーツない方が可愛い気がした。

最初のテクスチャーよりは、顔がふっくらしている感じにしたから・・・顔ない方が愛嬌がありそう。ということでカオナシバージョン。

うん。カオナシがしっくりきます。

ポリゴンは細かくない

カクカクした感じを出したかったです。ここでスムーズ入れればどれくらい差があるのかとやってみました。

これが、現在のカクカクバージョン。

こちらがスムーズ追加したバージョン。うん。靴だけかな。靴だけ。ポリゴンの数が増えただけで大差ない見栄えをしているので、やっぱり荒めのままにします。

乙女ゲームの背景

背景をフォトショとかSaiとかのドロイングツールでいきなりかけないので、Blenderで作ってしまって、Png吐き出して色ぬりすればいいやと気づいた。

そうだ。そうしよう。格段に早い。

そしてLive2DとBlenderでの人のモデリングの時間も大差ない気がした。どうしよう。

完成版がこちら

もともと女性の髪色は茶髪だったけど、せっかくなので目立たせるべく、金髪!

Blenderで人のモデリング

世の中には神がいっぱい

先日より作り始めた、5等身くらいの人型3Dモデル。

Blenderは全くの初めてだったので、いきなり人で大丈夫かと思いましたが、世の中には本当に、親切心で溢れている方が多い!

神様!BlenderもUnityも海外の人多いからYouTubeに良質な講座が山ほどある!!

Blenderで3Dモデルを作りたい

この前の参考サイトさんではうまく作れなかったので(ショートカットキーがわからずついていけなかった)、探してすぐ発見したのが、こちらの方。

英語が聞き取れない!という方でも大丈夫!キーボタンは親切にも字幕で表示されています。

何より全く、難しいこと喋ってないので、「Alt」とか「ctrl」とか聞き取れれば本当に、問題ない。

この講座は20分くらいですが、私は4時間かかっています。

慣れればこの早さになるのか?

テクスチャー貼り付けしていなけど、完成。

一番、今までで一番わかりやすい講座だった。あとは女性を作って、テクスチャー貼って、動かすという工程でしょうか。

背景を描くことが苦手なので、Blenderで作って、png吐き出させて色ぬりした方が綺麗かなと思った。おそらく、作業時間的にもそこまで大差ないし、綺麗になると思う。

トゥーンシェダーをかければ、3Dっぽさも軽減できるでしょう。

Lightwaveで3Dモデリングの経験がありますが、Lightwaveよりだいぶわかりやすいというのか率直な感想。何だろう。私には使えない豪華な機能が全くないからか、求めるものができるレベルで収まっているからでしょうか。

しかしこれで無料とかBlender恐ろしい。

3Dモデルいっぱい作って公開できるといいな。

Unity ドラッグを試す その2

ドラッグ先のものを残す

せっかくだからドラッグ処理をもっと深掘りしようと思います。

いや、ちょっとだけ触って見てこのまま使わなかったら完全に忘れるからそのまとめ。

前回やったのは、ドラッグの動きを簡単に動かすこと。

Unity ドラッグを試す その1

ドラッグをするとちょっと自由に動きしすぎる(求める以上に自由に動ける)ので、やはり今回のアプリでは使わない予定。・・・Y軸固定とかすればいいけど。

とりあえず、やろう。

ドラッグ先のオブジェクトを残す

この状態だど、ドラッグするオブジェクトを丸ごと動かす状態。

今画像で動かして「1」をそのまま残してドラッグの動きをさせたい。参考にしたのは、こちら。

・記事名:uGUIでドラッグドロップ
・サイトリンク:http://qiita.com/ayumegu/items/c07594f408363f73008c

ドラッグ先のオブジェクトのコピーを作り

ドラッグ先のオブジェクトを残したい、つまり、ドラッグするものを新たに作り(コピーして)それを動かす

もしくは、ドラッグ先のオブジェクトの初期状態のコピーを作りを固定させてあげて、元のオブジェクトを動かすか。その2択かな?

私は、まずコピーを作りその子を動かすことにしました。(その方がDragEndの時破壊しやすい・・・?)

「1」のボタン(あれはボタンです)をドラッグすると、テキストオブジェクト「COPY!」が現れます。

結果物がこちら。

以下はそのソースC#です。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class DragAndDrop: MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {

	private Transform canvasTran;
	private GameObject CopyTextObject;
	private Text CopyText;

	private Text thisText;
	private RectTransform thisTextRect;
	private Vector3 thisTextPosition;
	private Vector3 mousePosition;

	// Use this for initialization
	void Start () {
		canvasTran = transform.parent;
	}
	
	// Update is called once per frame
	void Update () {
		
	}

	// ドラック開始時
	public void OnBeginDrag(PointerEventData eventData)
	{
		Debug.Log("drag Start");

		//ドラッグ先テキスト
		thisText = this.GetComponentInChildren<Text> ();
		thisTextRect = GetComponent<RectTransform>();
		thisTextPosition = thisTextRect.localPosition;

		CreateDragObject ();

	}

	// ドラック中
	public void OnDrag(PointerEventData eventData)
	{
		Debug.Log("dragging");


		mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10);

		CopyText.transform.position = Camera.main.ScreenToWorldPoint (mousePosition);
	}

	// ドラック終了時
	public void OnEndDrag(PointerEventData eventData)
	{
		Debug.Log("dragEnd");

		Debug.Log("thisText = " + thisText.text);
		Debug.Log("copyText = " + CopyText.text);
	}

	private void CreateDragObject(){
		CopyTextObject = new GameObject ("copyText");
		CopyTextObject.transform.SetParent (canvasTran);
		//最前面表示
		CopyTextObject.transform.SetAsLastSibling ();
		CopyTextObject.transform.localScale = Vector3.one;

		CopyTextObject.transform.localPosition = thisTextPosition;

		CopyText = CopyTextObject.AddComponent<Text> ();

		CopyText.text = "Copy!";

		CopyText.font = Resources.FindObjectsOfTypeAll<Font>()[0];
		CopyText.fontSize = thisText.fontSize;
		CopyText.color = Color.white;
		CopyText.alignment = TextAnchor.MiddleCenter;

	}
}

噛み砕いて行こう

あくまで私の理解ですよ。間違いも多々あると思います。

さて、まず、宣言のところ。

	private Transform canvasTran;
	private GameObject CopyTextObject;
	private Text CopyText;

ゲームのオブジェクトを配置しているキャンバスと親子関係を持たせるための「canvasTran」。
ドラッグ先のコピー用テキストのゲームオブジェクトしての宣言のための「CopyTextObject」。
そのゲームオブジェクトにつけるコピー用テキスト「CopyText」。

初めは、「CopyText」だけでゲームオブジェクトとして成り立つかと思ったのですが、どうやら、ゲームオブジェクトの中のテキストという位置付けのよう。単体では表示されませんでした。

	private Text thisText;
	private RectTransform thisTextRect;
	private Vector3 thisTextPosition;

ドラッグ先の(コピー元の)テキスト情報を保持するためのもの。位置(ポジション?)情報などをコピー先に渡すためのもの。

	void Start () {
		canvasTran = transform.parent;
	}

スクリプトでオブジェクトを作成するのですが、他オブジェクトと同じくキャンバスさんの子供として扱って欲しいのです。なので、親子関係の情報を取って置きます。コピーオブジェクトにも持たせてやるから。

ドラッグのたびにやる必要はないので、スタートで取っておく。

・記事名:オブジェクトの親子関係のまとめ
・サイトリンク:http://qiita.com/hiroyuki7/items/95c66aee26115cf24a19

	// ドラック開始時
	public void OnBeginDrag(PointerEventData eventData)
	{
		Debug.Log("drag Start");

		//ドラッグ先テキスト
		thisText = this.GetComponentInChildren&lt;Text&gt; ();
		thisTextRect = GetComponent&lt;RectTransform&gt;();
		thisTextPosition = thisTextRect.localPosition;

		CreateDragObject ();

	}

ドラッグを開始したら、ドラッグ先のテキスト情報を取っておいて、コピーオブジェクト作成メソッドへ。

	private void CreateDragObject(){
		CopyTextObject = new GameObject ("copyText");
		CopyTextObject.transform.SetParent (canvasTran);
		//最前面表示
		CopyTextObject.transform.SetAsLastSibling ();
		CopyTextObject.transform.localScale = Vector3.one;

		CopyTextObject.transform.localPosition = thisTextPosition;

		CopyText = CopyTextObject.AddComponent&lt;Text&gt; ();

		CopyText.text = "Copy!";

		CopyText.font = Resources.FindObjectsOfTypeAll&lt;Font&gt;()[0];
		CopyText.fontSize = thisText.fontSize;
		CopyText.color = Color.white;
		CopyText.alignment = TextAnchor.MiddleCenter;

	}

ここでちょっと手こずった。やはりuGUIは偉大ですねぇ。スクリプトオブジェクト作るの面倒臭い。全部設定してやらないと出てこない。

初期状態の位置とか、どう表示させるか、フォントのサイズから種類から真ん中寄席の情報やら。

先に枠だけおいておいた「CopyTextObject」をチャット、ゲームオブジェクトして名前を与えて宣言してあげます。これによって、ドラッグを開始した時に初っ端はなかった「copyText」というオブジェクトがキャンバスにできます。

まだ、DragEnd処理で削除とかしないので、ドラッグが終わってもそのままオブジェクトは残っています。

	// ドラック中
	public void OnDrag(PointerEventData eventData)
	{
		Debug.Log("dragging");


		mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10);

		CopyText.transform.position = Camera.main.ScreenToWorldPoint (mousePosition);
	}

前回はドラッグ先オブジェクトにmousepositionを入れていたけど、それをCopyTextさんに設定すればこの状態に。

こんなものかな

コピーオブジェクトがずっと残りっぱなしだとうっとおしので、削除する処理をちらりと入れました。

	// ドラック終了時
	public void OnEndDrag(PointerEventData eventData)
	{
		Debug.Log("dragEnd");

		Destroy (CopyTextObject);
	}

これだけ。
あとは、コピーオブジェクトのテキストを、ドラッグ先のテキストにしてやりました。あとはカーソルのせいで文字がうまく見えないので大きくして見た。

結果はこう。

終わり。

ドロップ処理は、今のところ予定ない。

Unity ドラッグを試す その1

イメージと実際のものは違ったりする

勝手に、こうすればすぐできるだろうと思うこむことがよくあって、変に詰まることがよくある。本当によくある。

この思い込みでものすごい時間をかけたりする。

今日は「ドラッグ&ドロップ」をやってみようと思いました。

簡単なパズルゲーム(またもや算数系アプリで)を作ってみようと思っているのですが、ドラッグ&ドロップを使うかは、まだ未定。だったのですが。

ドラッグの動きを見て「これじゃない」と思ったので、ドロップまで行かなかった。使わないと思った瞬間からやりたくなくなったから。

とりあえず、やって見たところまでは記事にします。

ちなみに、ゲームそのものは、純粋にクリックするだけの動きにしようとも思っています。

参考にしたサイト。
・記事名:uGUIでドラッグについてちょっとだけ詳しく
・サイトリンク:http://qiita.com/okuhiiro/items/4c313038798da6923205

オブジェクトをドラッグしてみよう

まずはuGUI配置と簡単な実装

配置したuGUIの「Text」さんは、下の四つのボタンを押すと、押したボタンの数字に変化するようにしました。

で、私がこの「ドラッグ&ドロップ」でここから何がやりたかったというと、「1」のボタンをドラッグして「2」のボタンにトロップさせると、「3」になるという足し算仕組み。

実装しよう

ソースはこちら。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class DragAndDrop: MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
		
	}

	// ドラック開始時
	public void OnBeginDrag(PointerEventData eventData)
	{
		Debug.Log("drag Start");

	}

	// ドラック中
	public void OnDrag(PointerEventData eventData)
	{
		Debug.Log("dragging");
	}

	// ドラック終了時
	public void OnEndDrag(PointerEventData eventData)
	{
		Debug.Log("dragEnd");
	}
}

drag&dropは「EventSystems」にある機能らしい。なので、使わせての宣言をする。
これを抜かして怒られました。

using UnityEngine.EventSystems;

ドラッグ開始時は「OnBeginDrag」というメソッドで、ドラッグ中は「OnDrag」、ドラッグ完了後(離した後?)「OnEndDrag」でそれぞれ行われます。これを実際に動かしてみると、以下の通り。

「1」にこのスクリプトをアタッチしています。ただ、オブジェクトが動く処理は入れていないので・・・。
Debugは吐き出しているけど、動いているのかいまいちわからない状態に。

オブジェクトを動かす

「1」を動かすよう、「OnDrag」処理に位置情報を追加してやります。

	// ドラック中
	public void OnDrag(PointerEventData eventData)
	{
		Debug.Log("dragging");
		Vector3 mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10);
		this.transform.position = Camera.main.ScreenToWorldPoint(mousePosition);
	}

スクリプトが付いているオブジェクトさんをマウスポジションに動かしてあげます。

どこ?!

ドラッグっぽい動きを0.1秒くらいして消えました。左下にいます。「1」さん。

数字すら見えない状態。ということは、もしかして位置情報が、uGUIさんたちと、マウスさんで噛み合っていないということかしら。

ということで、調べると、おそらくこれでしょう。

今回もお世話になります、椿さんのテラシュールブログ。

World SpaceをScreenSpace-Cameraへ変更

Canvasの「Render Mode」wp「ScreenSpace-Camera」へ変更。

「Render Camera」カメラは、一つあるMain Cameraを追加してあげます。そうするとほら。治った。

やってみるとわかる

やはり、簡単なテストプロジェクトを開いて作って見てからやればどんな感じなのかわかりますね。

ドラッグ&ドロップ処理をしようとして、ドラッグの時点でこれじゃないと思ったので、ドロップ処理は、無視。

こんなに滑らかに動いてほしい訳でもなく、自由に色々動いて欲しい訳でもなく、範囲を決めて動かせればいいじゃんという感じの動きでもない。もっと硬い感じで動いて欲しかった。

結局使わなかったけれど、おそらくこれが一番参考になるのではと思った記事。

・記事名:uGUIでドラッグドロップ
・サイトリンク:http://qiita.com/ayumegu/items/c07594f408363f73008c

Unity ドラッグを試す その2

Unity CSVを読み込んでシナリオを書き出す

CSV読むのは簡単だった

いつもながらハマるけど。何にハマったのかというと、今回は宣言。

◆記事:UnityでCSVを読み込むときの軽いメモ
◆サイトリンク:http://qiita.com/tt-coder/items/68e81a64664b769f3755

言われた通りにやればできました。
ソースは全くいじっていない。宣言が必要でしたね。

初っ端にこれを宣言する。

なんでこれがわかったのかというと、エラーが教えてくれました。
エラーの内容でググれば出てきた(外国のサイトが)。

using System.IO;

Unityでアプリ開発の良さって、情報が溢れていることね。

初心者でもちょっとの山(うまくいかないときのあの山)を越えれば、すんなりできると思います。
私ができているからにはできるんじゃないかな。

C#とか、大学以来やるけどなんだかんだいけますね。

今やっているのは、これを読み込んで会話シーンを作ることですが、忘れそうだったのでメモメモ。

iTweenで表現する方法でやっている

昨日の、シナリオ書き出しをCSVからとって表示する方法にしました。

Unity ノベルゲームのようなものを作ってみる

結果はこの通り。上がCSV読み取り。下が素敵なブロガーさんのそのままのソース。

もともソースからの修正箇所はほぼない

CSV読み込みソースも、テキスト表示ソースも-ほぼ-そのまま。

やったといえば、publicでシナリオを書き込むんじゃ無くしただけ。
scenariosの情報をスクリプトで設定するようにしただけ。

[SerializeField] string[] scenarios;	// 会話内容

この部分を、無くした。CSVの配列を設定してやるから。
こうして、Startの部分のCSV読みこむ。

	void Start()
	{
		Debug.Log ("start");

		CSVName = "sample"; 
		CSVNumber = "0"; 
		// Resouces/CSV下のCSV読み込み 
		csvFile = Resources.Load("CSV/" + CSVName + CSVNumber) as TextAsset; 
		StringReader reader = new StringReader(csvFile.text);

		while(reader.Peek() > -1) {
			string line = reader.ReadLine();
			// 配列に格納
			csvDatas.Add(line.Split(',')); 
			// 行数加算
			height++; 
		}
	}

uGUIのところから入れていたシナリオの長さは、CSVの行数を入れればよい。
なので、あとは、表示したいcsvDatasの2列目(このcsvの1列目には人の名前が、2列目にセリフを入れたつもり)をuiTextに表示するシナリオに格納させる。

	/// 初期化
	void Initialize()
	{
		isCompleteLine = false;
		uiText.text = "";

		//currentText = senarios[currentline];
		currentText = csvDatas[currentLine][1];

		textSpeed = TEXT_SPEED + (currentText.Length * TEXT_SPEED_STRING);

		LineUpdate();
	}

	/// 会話シーン更新
	IEnumerator ScenarioCoroutine()
	{
		while(true)
		{
			yield return null;

			// 画面を押した時、次の内容へ
			if(isCompleteLine && Input.GetMouseButton(0))
			{
				yield return new WaitForSeconds(completeLineDelay);

				//if(currentLine > scenarios.Length - 1)
				if(currentLine > height - 1)
				{
					ScenarioEnd();
					yield break;
				} 

				Initialize();
			}

			// 表示中にボタンが押されたら全部表示
			else if(!isCompleteLine && Input.GetMouseButton(0)) 
			{
				iTween.Stop();
				TextUpdate(currentText.Length); // 全部表示
				TextEnd();
				yield return new WaitForSeconds(completeLineDelay);
			}
		}
	}

ということで、 「//currentText = senarios[currentline];」
これを潰して、csvの配列を指定。「currentText = csvDatas[currentLine][1];」

もう一つ、「//if(currentLine > scenarios.Length – 1)」の長さは、「hight」がルノで、それに変更。「if(currentLine > height – 1)」

日本語がおかしい気がする。
今日の私は理解して書いているけど、明日の私がわかるだろうか。

Unity GoogleAdsの表示非表示

ものすごくハマった

ことの事象

「Disable Ads」ボタンで、広告を非表示にするような課金が可能です。

課金して、アプリを再稼働させれば「Disable Ads」ボタンも「Google Ads」の広告バナーも非表示になりました。

が、購入したすぐには、「Disable Ads」ボタンだけ消えて、バナー広告が残り続ける。広告が非表示なるのはアプリを再起動させた時だけ!

現在は修正できましたので、そのメモ書き。

DestroyとHideの差異?

すでに表示されているのAdmobの広告バナーを見せないためには「Destroy」と「Hide」がある。

◆公式サイト:https://firebase.google.com/docs/admob/unity/start?hl=ja#ad_events

私の理解が、「Destroy」が完全に今の広告バナーの情報を消し去るということだったので、課金が終わればDestroyしてもらうことにしていました。

どうやら、今見せていた広告を見せないのは「Hide」であって、「Destory」は参照していたという情報(状態?)を初期化するようです。メモリー解放とか。この言葉であっているのか・・・。

思った通りに動かなかったソースがこれ。c#。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GoogleMobileAds.Api;
using UnityEngine.UI;
 
public class AdmobScript : MonoBehaviour {
 
    //UnitID情報
    string adUnitId;
    BannerView bannerView;
    AdRequest request;
 
    //広告非表示購入用ボタン
    public Button disableAdsButton;
 
    //課金有無確認用
    int AdsFalse;
 
    // Use this for initialization
    void Start () {
 
        //if UNITY_ANDROID
        adUnitId = "ca-app-pub-XXXXXXXXXXX";
 
        // Create a 320x50 banner at the top of the screen.
        bannerView = new BannerView(adUnitId, AdSize.Banner, AdPosition.Bottom);
        // Create an empty ad request.
        request = new AdRequest.Builder().Build();
 
        AdsFalse = PlayerPrefs.GetInt ("adsFalse", 0);
 
        if (AdsFalse == 0) {
            //広告表示
            RequestAdmob ();
        } else {
            //購入ボタン非表示
            disableAdsButton.gameObject.SetActive (false);
        }
    }
     
    // Update is called once per frame
    void Update () {
         
    }
 
    public void RequestAdmob() {
        //Admod表示
        bannerView.LoadAd(request);
    }
 
    public void PurchaseOK (){
 
        //課金情報を記録
        PlayerPrefs.SetInt ("adsFalse", 1);
 
        //Admod非表示
        bannerView.Destroy();
        //購入ボタン非表示
        disableAdsButton.gameObject.SetActive (false);
    }
}

ということで、「Disable Ads」ボタンを押した時に動く「Purchase OK」のところを少し修正しました。

bannerView.Destroy();

を、

bannerView.Hide();

になりました。あとは、広告を表示するところを少し修正。
万が一のために、非表示判定時に「Destroy」を追加。といった感じでしょう。

あー。やっぱりなんでハマったのか、解決したあとだとよくわかりません。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GoogleMobileAds.Api;
using UnityEngine.UI;

public class AdmobScript : MonoBehaviour {

	//UnitID情報
	string adUnitId;
	BannerView bannerView;
	AdRequest request;

	//広告非表示購入用ボタン
	public Button disableAdsButton;

	//課金有無確認用
	int AdsFalse;

	// Use this for initialization
	void Start () {

		//if UNITY_ANDROID
		adUnitId = "ca-app-pub-XXXXXXXXXXX";

		// Create a 320x50 banner at the top of the screen.
		bannerView = new BannerView(adUnitId, AdSize.Banner, AdPosition.Bottom);
		// Create an empty ad request.
		request = new AdRequest.Builder().Build();

		AdsFalse = PlayerPrefs.GetInt ("adsFalse", 0);

		if (AdsFalse == 0) {
			//広告表示
			bannerView.LoadAd(request);
			bannerView.Show();
		} else {
			//購入ボタン非表示
			bannerView.Destroy();
			disableAdsButton.gameObject.SetActive (false);
		}
	}
	
	// Update is called once per frame
	void Update () {
		
	}

	public void PurchaseOK (){
		//課金情報を記録
		PlayerPrefs.SetInt ("adsFalse", 1);
		PlayerPrefs.Save ();

		//Admod非表示
		bannerView.Hide();
		//購入ボタン非表示
		disableAdsButton.gameObject.SetActive (false);
	}
}

Unity の「PlayerPrefs」のおかけ?

未検証なので、私が思ったまで

一度だけ課金できるボタンがあります。一度だけ。

課金したら、そのボタンそのものが消えます。もう表示されません。じゃあ、買ったはいいけど、一度アンインストールして、再インストールしたらそれはどうなるのや。

結果的にはアンインストールして、再インストールしても一度課金した情報は残っていました。なので、ボタンは表示されなかった。

※これはあくまで一つの端末でのお話。

二つ、予想としては、課金したと、課金したという情報をUnityの「PlayerPrefs」でセーブしているのですが、これが、アンインストールしてもローカルに残り続けるということかな?

あくまで予想です。未検証です。デバッグ吐き出しはしていません。

実際に検証しないといけないと思うけど、やり方がわからないからとりあえず忘れる前に書き留めておきます。

「PlayerPrefs」はアプリをアンインストールしても残る?

課金が完了した場合、今後は広告も、広告非表示用課金ボタン表示させない。

これを組み込む時の私の心配が、じゃあ、アプリをアンイントールしてしまえば、もう一度インストールした時にその設定が消えてしまうこと。

ベータ版テスト時にアンインストールを繰り返したので、それで確認した感じだと、再インストールしたら一度課金したら広告も、広告非表示用のボタンも表示されなかった

そこで、自分のソースを見返して見る。

※初回ポスト時点とソースが変わっています。

sing System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GoogleMobileAds.Api;
using UnityEngine.UI;

public class AdmobScript : MonoBehaviour {

	//UnitID情報
	string adUnitId;
	BannerView bannerView;
	AdRequest request;

	//広告非表示購入用ボタン
	public Button disableAdsButton;

	//課金有無確認用
	int AdsFalse;

	// Use this for initialization
	void Start () {

		//if UNITY_ANDROID
		adUnitId = "ca-app-pub-XXXXXXXX";

		// Create a 320x50 banner at the top of the screen.
		bannerView = new BannerView(adUnitId, AdSize.Banner, AdPosition.Bottom);
		// Create an empty ad request.
		request = new AdRequest.Builder().Build();

		AdsFalse = PlayerPrefs.GetInt ("adsFalse", 0);

		if (AdsFalse == 0) {
			//広告表示
			bannerView.LoadAd(request);
			bannerView.Show();
		} else {
			//購入ボタン非表示
			bannerView.Destroy();
			disableAdsButton.gameObject.SetActive (false);
		}

	}
	
	// Update is called once per frame
	void Update () {
		
	}

	public void PurchaseOK (){

		//課金情報を記録
		PlayerPrefs.SetInt ("adsFalse", 1);
		PlayerPrefs.Save ();

		//Admod非表示
		bannerView.Hide();
		//購入ボタン非表示
		disableAdsButton.gameObject.SetActive (false);

	}

}

私のイメージだと、アンインストールした場合、セーブに使う「PlayerPrefs」も消えてしまうと思っていたけど、そうでもないかもしれない。(データの残りっぱなし?)

※アプリを終了して再稼働させた時に「PlayerPrefs」が生きていることは確認済み

◆公式サイト説明:https://docs.unity3d.com/ja/current/ScriptReference/PlayerPrefs.html

ローカルに保存されるよね・・・。アンインストールしたら、消えるんじゃないの?むしろなんで消えないの?

結果的にはそれでいいけど・・・。

じゃあ、同じGoogleIDで別端末でインストールして見たらどうなるのだろうか。が、確認できていない(笑)。

端末もう一ついるのね!テストできない。

Unity IAPで簡単な課金を実装する(その2 – 完)

課金をGooglePlayと連携する

前提

実機でテストがしたい。ということをしたい場合は、GooglePlayにベータ版を登録する必要がある。

実機ない感じだと、Unity内部のでもが動いてくれるので問題ない。

GooglePlayでのベータ版テストでの課金テストはなんか怖いもんねー。本当に課金しちゃうかもしれないじゃん(そして実際一度テストではなく、購入されちゃいました)。

私の場合、「Admobを課金で非表示にしたい」ということだったんですよね。

Admob自体が実機じゃないと表示されなかったので、もう、実機でテストするしかありませんでした。なので、ベータ版を登録してテストするから、ベータ版のバージョンが5まで上がってしまった・・・。

それでは、前回に引き続きの感じで課金の実機テストをします。

Unity IAPで簡単な課金を実装する(その1)

Unityで作成した課金情報を連携する

課金のIAP CatalogからGooglePlayに連携する課金データを吐き出します。

UnityでCSVファイルを作成してくれるので、GooglePlayではそれを登録してあげればいいだけ。

ここで一つ、Csvを吐き出そうとした怒られました。課金情報の中身が気に入らないらしい。

IAP Catalogの「Store ID Overrides」のGooglePlayに連携するIDが数字じゃないといや見たい。課金アイテムID「Disable Ads」とGooglePlayIDを一緒にしていたのですが、ダメらしい。

今回は課金用アイテムは「広告非表示」1つだけなので、適当に「0」にしました。

GooglePlayよう課金アイテムカタログCSV(長い)なるものが吐き出されます。(場所は選択できます。)

開いて見るとこんな感じ。

GooglePlayにCSVを登録する

こんな風に、ベータ版テストを登録完了している状態です。

オプトインURLが割あたえられたら、テストの準備は完了。課金の情報を登録します。上記画面の左側メニューにある「ストアでの表示」の「アプリ内サービス」を開く。

後撮りになった(ハードコピー撮り損ねた)ので、すでに課金情報が入っている状態。初っ端は「追加してね」と表示されるだけ。

CSVをインポートしたいので、インポート/エクスポートを押す。

CSVをインポートを押して、先ほどUnityで作成したCSVを入れる。

正常終了時はこんな感じ。中にエラーがあれば怒られる(確か、CSVの中身を見ていた時にスペース入れて怒られた記憶・・・)

すると、以下の状態になります。

以上で作業は完了しました。

この後、端末にインストールして実機テストを行い、課金のテストをすればいいだけ。

テスト課金した時のメール

件名にちっさく「Test」と書いている。もっと堂々と書いてくれ。不安になる・・。

GooglePlay ベータ版テストでアプリページにアクセスできない

パソコンから端末にインストールさせる

ベータ版を登録しても、アプリページのアドレスが設定されて、さらにそのページが表示され、アプリがダウンロードできるまでは、そうですね。おおよそ1時間くらいは必要かと。

私の場合1つの端末で、テストアカウントと開発用(アプリ登録用)アカウントを使い分けています。

名前隠しているテスターが実名(笑)登録した、デベロッパーアカウント。その下がテスト用のアカウントです。

オプトインURLにアクセスすることでベータ版をダウンロードし、アプリをインストールすることができます。

が、かなりの確率で、Android端末からアクセスしようとすると、時間が経過しても「リクエストされたURLは、このサーバー上に見つかりませんでした。」と出てきます。

ちなみに画像は、パソコンでエラーになった時のキャプチャー。

どうすべきか相当悩んで、見つけた方法が、パソコンからアプリページにアクセスし、無理やり端末にインストールさせるという。

ただし、この方法が「パソコンからはページにアクセスできる」ということが前提ですよ。パソコンからも端末からもアプリページにアクセスできない場合は、「テスター登録」がうまくされたないことが多いと思います。

次からテストする時これでいこう。

「インストール済み」となっているボタンが、この直前まで「インストールする」担っています。パソコン上でそれを押すと「XX (端末の種類)にインストールしますか?」が出てくるので、それを了承する。

ハードコピー撮り損ねました・・・。

すると、「端末にインストールします」というふうに切り変わります。

で、それを確認した後に、Android端末からアプリページにアクセスしてみると。アクセス可能になりました。

その上、「インストール中…」となり、すぐインストールが開始されました。

すぐ切り替わらないとイライラしちゃうのはカルシウムが足りないからかしらね。

 

Unity IAPで簡単な課金を実装する(その1)

課金で広告を非表示にする

今回も、Androidのみです。iOSでもほぼ変わりないけど、Xcodeビルドの時の対応が必要のようです。

えーっと。実装は恐ろしく簡単でした。

ただ、初めてのテストにどこにハマったのか思い返せないけどどハマりして4日も無駄にしましたね。

たまにあるよね。しょうもないことにハマって気づいたらどうでもよかったということ。・・・はー。思い出すだけで悲しいです。

参考にしたのは、こちら。

◆記事名:UnityでPurchase(課金)を実装する
◆サイトリンク:http://qiita.com/KotaroInc/items/b13426216c92518bb189

◆記事名:新しいUnityIAPを触ってみた。その①~ボタンを作ってみる~
◆サイトリンク:http://blog.livedoor.jp/nyangostar/archives/67154370.html

前提

・実機テストが可能であること
・GooglePlay β版(またはα版)を登録していること

まずはUnity側の実装

GooglePlayから対応する人もいたけど、これはベータテスト版をGooglePlayに完全登録してから云々やらねばいけないから修正が発生したとき恐ろしく面倒臭いので、Unity側の対応から始めます。

1.Unity IAPをImport

ほんの数年前までは課金組み込むのがすごく大変だったようです。これまた個人の好意で公開してもらったものを使いまわしたりしていたよう(調べた感じだと)。

とりあえずプロジェクトを開いて、左の「Services」から「In-App Purchasing」を「On」にします。初期状態は「OFF」です。

インストールしていいか?って聞かれるので「Enable」します。

お子様向けかい?って聞かれます。私は「親の端末で子供(13歳未満)がゲームすることがある」と考えてアプリを作成しました。「端末は親のもの」つまり、課金を押すのは、端末の持ち主である「親」であると。

という建前。

子供向けアプリだと相当審査が厳しいです。その代わり、審査を通ると、いろんな承認マークをもらえますけどね。

子供用アプリページの一覧にも乗れるんじゃなかったけな?

次に進みます。Unity IAPで対応できるのは、Amazon AppsとかGooglePlayとかiOSAppStoreとかとからしいので、とりあえず「Import」。

インストールしてもらいましょう。

すると、Pluginsに「Unity Purchasing」フォルダが出来上がります。これでUnity IAPが使用できる状態になりました。

2.課金ボタンを作成する

まず、この課金は「GooglePlay」用であるとしておきましょう。

「window」の「Unity IAP」から「Android」の「Target Google Play」を選択。

そして、課金クリック用ボタンを作成します。方法は2つ。

普通のボタンに[Add Component]でIAP Buttonをつけてやるのか、最初から[IAP Button]作成するか。・・・差はないけどねー。ボタンじゃなくてテキストにクリックトーグル作ってやるのありですし。

わかりやすく、「Create IAP Button」にしました。

こんなボタンが(普通のボタンです)が出来上がるので、自分なりに調整。

こうなりました。

あとはボタンを押すことで行われる課金の情報を設定します。「課金のカタログ」を作ってその中の一つをボタンに設定してあげるようなイメージを持ちました。

今はなんのカタログもないので、IAP Catalogボタンで「Disable Ads」というカタログIDの課金情報を作成しました。

課金のタイプは「Non Consumable」で一回の課金でそれ以降は使えない状態にします。なんども課金できるのは「Consumable」。

ちなみに、こちらはGoogleアカウントに紐付いているので、一度だけ購入タイプはもう二度とテストができなかった(笑)。

アプリの内部で一度課金が入ったらボタンそのものを非表示にさせますので、このアプリに関してはあまり意味がないです。

英語と韓国語でローカライズ対応をしておきました。窓を消せばそれで終わり。セーブとかはいりません。

カタログを作成し終わると、IAP Buttonでカタログが選べるようになります。

Product IDを先ほど作成したカタログをつけてあげます。あとは、課金が成功したとき「On Purchase Complete」用の処理を作ります。

3.課金処理を実装する

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GoogleMobileAds.Api;
using UnityEngine.UI;

public class AdmobScript : MonoBehaviour {

	//UnitID情報
	string adUnitId;
	BannerView bannerView;
	AdRequest request;

	//広告非表示購入用ボタン
	public Button disableAdsButton;

	//課金有無確認用
	int AdsFalse;

	// Use this for initialization
	void Start () {

		//if UNITY_ANDROID
		adUnitId = "ca-app-pub-XXXXXXXXXXX";

		// Create a 320x50 banner at the top of the screen.
		bannerView = new BannerView(adUnitId, AdSize.Banner, AdPosition.Bottom);
		// Create an empty ad request.
		request = new AdRequest.Builder().Build();

		AdsFalse = PlayerPrefs.GetInt ("adsFalse", 0);

		if (AdsFalse == 0) {
			//広告表示
			bannerView.LoadAd(request);
			bannerView.Show();
		} else {
			//購入ボタン非表示
			bannerView.Destroy();
			disableAdsButton.gameObject.SetActive (false);
		}
	}
	
	// Update is called once per frame
	void Update () {
		
	}

	public void PurchaseOK (){
		//課金情報を記録
		PlayerPrefs.SetInt ("adsFalse", 1);
		PlayerPrefs.Save ();

		//Admod非表示
		bannerView.Hide();
		//購入ボタン非表示
		disableAdsButton.gameObject.SetActive (false);
	}
}

簡単に説明。未来の私のために。

まず、このスクリプトは、Admob表示用のスクリプト。

UnityでAdmobのバナー広告を表示する

この子に課金時の対応を入れました。
「adsFalse」というint型の変数は課金すると「1」になります。これはアプリが終了しても引き継がれる情報(アンインストールされると初期化される)。

そのadsFalseをgetしてAdsFalseに入れておいてから、課金がされたかの判定をします。このこが「0」の時は、課金されていないことになるので、広告と広告非表示用課金ボタンは表示されます。

課金が正常に行われた場合は、「PurchaseOK」メソッドを動かします。

それで、非表示になる。

//Admod非表示
		bannerView.Destroy();

Admodを非表示にするのは、Destroyする。

さらにボタンを非表示にするのはSetActive。

Unity ボタンを非表示にしたい

IAP ButtonのPurchasing Complete(購入完了)の所に、先ほどのスクリプトが付いているオブジェクトを設定して、メソッドを稼働させる。

4.Unityで動きを確認しよう

Debug.logを入れて動きを確認してみました。

AdsFalse は今のところ、「0」なので、課金ボタンが表示されます(Admobも表示されている)

課金用のボタン「Disable Ads」を押すと、この、Unity用の確認ボタン画面が表示されます。ちなみのこれはプラットフォームによって、表示が違うので、iPhoneなのかAndroid端末なのかによっても違います。

私のハマりポイント1でしたね。この見栄えで大丈夫かってなった。とりあえず、Buyを押します。

購入が正常完了しました。「AdsFalse」の値も「1」になり、課金用ボタンも非表示になりました。

これで、Unityの対応は完了。

このあと、ボタンが非表示になった時のボタンのバランスがイマイチだったので、そこだけ修正しました。

Unityに実装するよりこのページ書くほうが時間がかかります。

次の作業はこちら。長すぎて分割。

Unity IAPで簡単な課金を実装する(その2 – 完)

2 / 3ページ

© Copyright 2017 「It Happens」 All rights reserved.