FC2ブログ
    06 «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.31.» 08

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

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

     

    【ハルシオンブログ】Unity2020はオブジェクトをコピーしたときの連番の形式が変えられる 

    こんにちは。
    大坂です。

    Unity2020はオブジェクトをコピーしたときの連番の形式が変えられるようです。
    もともと後ろに「(1)」となるのが嫌いだったので良い機能が増えました。

    一応デフォルトは感じですよね


    これを変えるには[Edit]-[ProjectSettings]-[Editor]のNumberingSchemeの設定でできます。


    形式は3種類ですが、「_1」の形式が好きなので変えてみました。

    ちゃんと変わっていますね。

    下の設定のGameObjectDigitsは数字の桁数ですね。「2」にすると「_01」となります。


    地味ですが、ここを変えられるのは嬉しかったので機能の紹介でした。
    ではまたノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】Unityであのスナップするスクロールが簡単に作れるアセットがあったよ!アセットの紹介 

    こんにちは。坂内っす。

    最近使ったUnityのアセットの紹介。

    こういうのよく見ません?特にソシャゲとかであるやつなんすけど。



    バナーが自動でスナップするやつ。

    これが簡単に作れるので紹介です。

    まずはこの無料のアセットを入れます。

    [Simple Scroll Snap]


    ①SSSを追加
    UI -> Simple Scroll-Snap -> Scroll-Snapを追加します。

    こんな感じのものが作られます。



    このまま実行してみましょう。



    こんな感じものが簡単に作られます。

    ②無限に左右移動できるようにしよう

    上記で作成したScroll-Snapのオブジェクトに「SimpleScrollSnap」のコンポーネントがついているので、その中の「InfiniteScrolling」にチェックを入れます。



    これだけで無限スクロールができるようになります。



    ただ、1-5の間に空白がないので、それを追加してあげましょう。



    End Spacingに上部Spacingと同じ値を入れてあげましょう。
    今回は0.25がSpacingに入っているので、それをEndSpacingに入れます。



    はい、こんな感じ。

    これで、簡単にスナップするスクロールが完成です。


    デフォルトはこんな感じの構成になっています。

    初めから表示する内容が決まっているならばこのままでいいのですが、画面起動時に表示する内容を変える場合は、以下の感じでできますね。



    ①まずは、デフォルトについている1~5のオブジェクトをScroll-Snapのオブジェクトから消す。

    ②中身用のクラスを作成
    処理としては、InitImageに渡すファイル名の絵を用意するだけのもの

    [ScrollItem.cs]

    using UnityEngine;
    using UnityEngine.UI;

    public class ScrollItem : MonoBehaviour
    {
    public Image img;

    public void InitImage(string fileName) {
    img.sprite = Resources.Load(fileName);
    }
    }



    ③本処理で、②のScrollItemを作成する
    [Blog20200727.cs]

    using UnityEngine;

    public class Blog20200727 : MonoBehaviour
    {
    public Transform itemBase;
    public ScrollItem itemPrefab;

    void Start()
    {
    for (int i = 0; i < 3; i++) {
    ScrollItem item = Instantiate(itemPrefab, itemBase, false);
    item.InitImage("img" + (i + 1));
    }
    }
    }



    上記の処理だけで、こんな感じのができます。



    また、自動送り機能は以下の感じでできました。

    [Blog20200727.cs]

    using UnityEngine;
    using DanielLochner.Assets.SimpleScrollSnap;

    public class Blog20200727 : MonoBehaviour
    {
    public Transform itemBase;
    public ScrollItem itemPrefab;
    public SimpleScrollSnap scrollSnap;

    const float AUTO_FEEDING_TIME = 3.0f;
    float feedtimer = 0;

    void Start()
    {
    for (int i = 0; i < 3; i++) {
    ScrollItem item = Instantiate(itemPrefab, itemBase, false);
    item.InitImage("img" + (i + 1));
    }
    }

    private void Update() {
    feedtimer += Time.deltaTime;
    if (feedtimer >= AUTO_FEEDING_TIME) {
    feedtimer = 0;
    scrollSnap.GoToNextPanel();
    }
    }
    }






    とても素敵なアセットなので、是非お使いください!!



    あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】DoTweenのFlashって皆さん使ってますか?実はとても素敵な機能「Flash」というのがあるんです 

    こんにちは!坂内っす。
    ポケガ3の開発本格的に始まりそうです。

    今回は1、2よりももうちょっと凝った感じの作りにしていこうかと。

    え?シミュレーションRPGは?それはそれ、ポケガの後につくりますよ!
    やめたわけじゃないからね!

    さて、本日のUnityのお話は、DoTweenで今まで使ったこともなかったFlashについて。

    Flashというメソッドはないのですが、EaseにFlashというものがあります。

    はい、今回もいらすとやさんの絵を使わせていただきます。

    Flashを使うとどんなことができるのかというと、こんなのができます。



    【Blog20200720.cs】

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using DG.Tweening;

    public class Blog20200720 : MonoBehaviour
    {
    public Button btn;
    public Image imgObj;

    void Start()
    {
    btn.onClick.AddListener(VanishAirConditioner);
    }

    void VanishAirConditioner() {
    imgObj.DOFade(0, 1).SetEase(Ease.Flash, 11);
    }
    }



    こんな感じです。

    SetEase(Ease.Flash, 11)

    ここがミソですね。

    DoFadeで1秒後にFadeを0にする。
    その間に11回点滅をする。(厳密には0>1>0>1>0・・・というのを11回(左のやつで4回分))
    って感じのことをやってます。

    なんか今までこれをやろうとすると、こんな感じのことを書いてましたよね。


    imgObj.DOFade(0, 0.1f).SetLoops(5, LoopType.Yoyo);



    実はこんなことしなくても、Flashを使えばよかったのです!

    ということで、簡単なEase.Flashの紹介でした。

    詳しいことはこちらに書いてました。

    [ゲームUIネットさん]
    https://game-ui.net/?p=904

    色々とFlashについて書いてるので、是非参考にいいもの作ってくださいまし。

    では、あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】ファイルパスを作る時や取得するときのお話 

    こんにちは。
    大坂です。

    C#でファイルパスを作ったり取得したりするときのお話。

    まずはファイルパスを作るとき。
    「System.IO.Path.Combine」を使用すると便利です。

    string path_1 = "path_1";
    string path_2 = "path_2";
    string fileName = "test.txt";
    Debug.Log(Path.Combine(path_1, path_2, fileName));



    文字列間を「\」でつないでくれていますね。
    文字列中に「\」があってもちゃんと判断してくれます。

    string path_1 = "path_1";
    string path_2 = "path_2";
    string path_3 = @"path_3\";
    string fileName = "test.txt";
    Debug.Log(Path.Combine(path_1, path_2, path_3, fileName));


    path_3の後ろに「\」があっても付け加えることなくつないでくれます。


    ファイルパスを取得するときは「System.IO.Path.GetDirectoryName」を使用すると、
    ファイル名がパスに含まれていてもファイル名なしのパスが取得できたりします。

    string path_1 = "path_1";
    string path_2 = "path_2";
    string path_3 = @"path_3\";
    string fileName = "test.txt";
    string path = Path.Combine(path_1, path_2, path_3, fileName);
    Debug.Log(Path.GetDirectoryName(path));


    ファイル書き込むときにディレクトリがなければ作るなんて処理を書くときに便利かもしれませんね。

    ということで今週もこの辺でノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】Unity+Playfab Playfabサーバに置いた絵のファイルをアプリ起動時に持ってくるよぅ(ファイル管理の使い方一例) 

    こんにちは。坂内っす。

    蒸し暑い日が続きますね。さすが梅雨って感じです。
    まぁ一日中クーラーの効いた部屋にいるので、あんまり関係ないですが。

    さて、Unity使いで最近Playfabが流行ってきてるみたいですね。
    うちも1年前から使ってます。
    色々とかゆくても手が届かないところも多いPlayfabですが使える機能の一つとして、「ファイル管理」という機能があります。

    画像ファイルやサウンドファイルなどをここにアップロードし、アプリから落として使うといったことに使える機能です。

    まずはPlayfabに画像ファイルをアップロードします。



    コンテンツ>ファイル管理>ファイルをアップロードからアップロードができます。

    ちなみに今回はテスト用にポケガ2のロゴを置いてみました。



    説明にも書いてますが、CDNを使用するため、お金がかかるのでカード等の登録が必要になります。

    ※PlayFab にファイルをアップロードして保存し、グローバル CDN 経由でゲーム クライアントにダウンロードします。CDN の使用コストは、課金期間中にダウンロードされたギガバイトの合計数に基づいて計算され、1 GB あたり 0.10 米ドルのレートで計算されます。CDN へのアップロードと保存は無料で提供されます。

    とのことです。

    ちなみにファイルのダウンロードはPlayfabにアプリ側でログインしないといけない感じです。

    【Blog20200713.cs】

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

    public class Blog20200713 : MonoBehaviour
    {
    public Image img;

    IEnumerator Start()
    {
    yield return StartCoroutine(PlayfabManager.instance.ConnectPlayfab());
    yield return new WaitWhile(() => !PlayfabManager.instance.isLogin && !PlayfabManager.instance.isError);

    StartCoroutine(PlayfabManager.instance.GetImageFromPlayfab(img, "image01.png"));
    }

    }



    画面を開くとログインをし、SpriteをPlayfabから持ってきて表示するだけのもの。

    【PlayfabManager.cs】

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.IO;
    using PlayFab;
    using PlayFab.ClientModels;
    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.Networking;


    public class PlayfabManager : MonoBehaviour {
    public static PlayfabManager instance;
    private void Awake() {
    if (instance == null) {
    instance = this;
    DontDestroyOnLoad(gameObject);
    } else {
    Destroy(gameObject);
    }
    }

    public bool isLogin;
    public bool isError;

    string downloadPath;
    Sprite contentSprite;

    public IEnumerator ConnectPlayfab() {
    if (string.IsNullOrEmpty(PlayFabSettings.TitleId)) {
    PlayFabSettings.TitleId = "TestGame"; // Please change this value to your own titleId from PlayFab Game Manager
    }

    bool isWait = true;

    var request = new LoginWithCustomIDRequest { CustomId = SystemInfo.deviceUniqueIdentifier, CreateAccount = true };
    PlayFabClientAPI.LoginWithCustomID(request, OnSuccess, OnError);

    while (isWait) {
    yield return null;
    }

    void OnSuccess(LoginResult result) {
    isLogin = true;
    isWait = false;
    }
    void OnError(PlayFabError error) {
    isLogin = true;
    isWait = false;
    }
    }

    ///
    /// Playfabから画像を取得
    ///

    ///
    ///
    ///
    public IEnumerator GetImageFromPlayfab(Image img, string fileName) {
    contentSprite = null;
    yield return StartCoroutine(GetContentURL(fileName));
    yield return StartCoroutine(PlayFabContentLoad(fileName));
    if (contentSprite != null) {
    img.sprite = contentSprite;
    }
    }

    ///
    /// 素材ダウンロード用URL取得
    ///

    public IEnumerator GetContentURL(string playfabPath) {
    bool isWait = true;
    GetContentDownloadUrlRequest request = new GetContentDownloadUrlRequest() {
    Key = playfabPath,
    ThruCDN = true,
    };
    PlayFabClientAPI.GetContentDownloadUrl(request, OnSuccess, OnError);

    while (isWait) {
    yield return null;
    }

    void OnSuccess(GetContentDownloadUrlResult result) {
    Debug.Log("GetContentURL:OnSuccess");

    downloadPath = result.URL;
    isWait = false;
    }

    void OnError(PlayFabError error) {
    Debug.Log(error.GenerateErrorReport());
    isWait = false;
    }
    }

    ///
    /// Playfabからファイルを取得
    ///

    ///
    ///
    private IEnumerator PlayFabContentLoad(string fileName) {
    string localFilePath = Application.persistentDataPath + "/" + fileName;
    var getTextureRequest = UnityWebRequestTexture.GetTexture(downloadPath, false);
    yield return getTextureRequest.SendWebRequest();

    while (!getTextureRequest.isDone) {
    yield return getTextureRequest;
    }

    if (getTextureRequest.isNetworkError) {
    Debug.Log("Error:" + getTextureRequest.error);
    } else {
    File.WriteAllBytes(localFilePath, getTextureRequest.downloadHandler.data);
    byte[] bytes = getTextureRequest.downloadHandler.data;
    Texture2D texture = new Texture2D(1, 1);

    if (texture.LoadImage(bytes)) {
    contentSprite = Sprite.Create(texture, new Rect(0.0f, 0.0f, texture.width, texture.height),Vector2.zero);
    } else {
    contentSprite = null;
    }

    }
    }
    }


    ちょっと長いですが、Playfabへのログインとデータを取得するところが書かれています。
    PlayFabContentLoadメソッドの以下の行でローカルに保存していますが、毎回とってくるならこの行入らない感じですね。

    File.WriteAllBytes(localFilePath, getTextureRequest.downloadHandler.data);

    本当は、ローカルに保存し、ファイルがローカルに存在する場合はPlayfabから持ってこないで、ローカルのやつを使用ってやるのがいいかと思います。

    CDNはお金かかるので、無駄に使わないのがいいですね!

    実際に実行するとこんな感じ。



    アプリ起動時にSpriteキャッシュとかに入れといて、実際に使うときにはそこから持ってくる感じにしないと、ロードに時間かかるから気持ち悪いですね。

    ってことで、こんな感じでPlayfabに置いたファイルをもってこれます!

    では今日はこんなところで。

    あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】Awakeより先にメソッドを呼び出したいとき 

    お疲れさまです。
    大坂です。

    Awakeより先にメソッド呼べたらなーと思ったことは・・・たまにあるでしょうか?
    そんなときは「RuntimeInitializeOnLoadMethod」アトリビュートを使用しましょう。
    そのまま使うとAwakeよりあとになってしまうので引数に「RuntimeInitializeLoadType.BeforeSceneLoad」をつけます。

    では一応コードです。

    void Awake() {
    Debug.Log("Awake");
    }

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

    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    static void Test_1() {
    Debug.Log("RuntimeInitializeLoadType.BeforeSceneLoad");
    }

    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
    static void Test_2() {
    Debug.Log("RuntimeInitializeLoadType.AfterSceneLoad");
    }

    結果。


    ちゃんとAwake前に呼ばれていますね!
    おまけで、引数「RuntimeInitializeLoadType.AfterSceneLoad」も書いてみてます。
    こちらはAwakeよりあとになっていますね。

    ということで、Awake前に処理を呼び出す方法の紹介でした。
    ではまたノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】Unity(C#)でDictionaryの紹介。Listばっかり使ってたけどこいつも悪くはねえなぁ 

    こんにちは!坂内っす。

    雨すごいらしいっすね・・・・九州は川も氾濫危険水位に達しているようで・・・・
    皆さんお気をつけてくださいませ。

    UnityというかC#でDictionaryって使ってます?

    ListとかArrayとか配列とかと同じ感じで使えるやつです。
    連想配列って言われるらしいです。

    使うには、usingが必要になります。


    using System.Collections.Generic;


    Listとかとの違いは、添え字の代わりに任意のデータ型を使います。

    ・Listとか

    List<int> intAry = new List<Int>();
    intAry.Add(1);
    intAry.Add(3);
    intAry.Add(5);
    intAry.Add(7);

    Debug.Log(intAry[2]);


    結果は「5」が取れますよね。
    この時intAry[2] という感じに、"3番目"に入っている値という感じで、添え字を使うと思います。

    これがDictionaryだとこんな感じになります。

    ・Dictionaryの場合

    Dictionary<string, int> dic = new Dictionary<string, int>();
    dic.Add("no1", 1);
    dic.Add("no2", 3);
    dic.Add("no3", 5);
    dic.Add("no4", 7);

    Debug.Log(dic["no2"]);


    これも結果は「3」が取れます。

    こんな感じで、文字列など(key)でvalueをとる感じになります。

    また、keyは同じものを入れることができません。


    Dictionary<string, int> dic = new Dictionary<string, int>();
    dic.Add("no1", 1);
    dic.Add("no2", 3);
    dic.Add("no2", 5);


    こういうことができないということです。

    ちなみに初期化時に値を入れる場合はこんな感じでできます。


    Dictionary<string, int> dic = new Dictionary<string, int>()
    {
    {"no1", 1},
    {"no2", 3},
    {"no3", 5}
    }


    valueの更新はこんな感じ。


    Dictionary<string, int> dic = new Dictionary<string, int>()
    {
    {"no1", 1},
    {"no2", 3},
    {"no3", 5}
    }

    dic["no2"] = 100;


    特定のkeyがあるかどうかは、こんな感じで判定できます。


    Dictionary<string, int> dic = new Dictionary<string, int>()
    {
    {"no1", 1},
    {"no2", 3},
    {"no3", 5}
    }

    if(dic.ContainsKey("no2")){
    Debug.Log("no2があるので更新");
    dic["no2"] = 50;
    } else {
    Debug.Log("no2がないので追加");
    dic,Add("no2", 50);
    }


    また、全体をなめる感じの場合は、foreachでいけますね。


    Dictionary<string, int> dic = new Dictionary<string, int>()
    {
    {"no1", 1},
    {"no2", 3},
    {"no3", 5}
    }

    foreach(Dictionary<string, int> data in dic){
    Debug.Log(data.key + ":" + data.value);
    }


    こんな感じで、全部をとることができます。
    Dictionaryでは順不動のようで、上記のように全部をなめる時に順番が変わる可能性があるらしいです。

    登録した順番に何かの処理をする必要がある場合は、DictionaryではなくList等を使わないといけません。

    という感じで、Dictionaryの紹介でした。

    では、あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】Toggleで値を変えたときにonValueChangedで処理したくないとき 

    こんにちは。
    大坂です。

    Toggleの値が変わったらonValueChangedでなにか処理をしたいときがよくありますね。
    が、しかし処理タイミングによっては処理をしたくないときもあります。。
    そんなときは「SetIsOnWithoutNotify」を使うとonValueChangedの処理が呼び出されなくなります。

    public class Test : MonoBehaviour
    {
    public Toggle toggle;

    void Start()
    {
    toggle.onValueChanged.AddListener(a => Debug.Log("Test"));

    // onValueChangedが呼び出される
    toggle.isOn = false;
    // onValueChangedが呼び出されない
    toggle.SetIsOnWithoutNotify(true);
    }
    }



    「toggle.isOn」で変更している一回分のログしか出ていませんね。
    という感じで、「SetIsOnWithoutNotify」を使用すればonValueChangedが呼び出されません。

    他にもSliderやDropdownなら「SetValueWithoutNotify」を使用すればonValueChangedが呼び出されなくなります。
    なにかの参考にしてくださいませ。

    ではではノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0