- 投稿日:2021-03-15T23:45:48+09:00
CommandInvokationFailure: Unable to install APK to device. Please make sure the Android SDK is installed and is properly configured in the Editor. See the Console for more details.
エラーと環境
CommandInvokationFailure: Unable to install APK to device. Please make sure the Android SDK is installed and is properly configured in the Editor. See the Console for more details.
Player SettingsのScripting BackendをIL2CPPに変更したところ、
上記のエラーが発生し、Build And Runが実行できなかった。エディター : Windows 10、 Unity 2020.1.17f1
実機 : Android 11解決策
接続先のAndroidにある同じアプリ(正確には同じパッケージ名のもの)をアンインストール。
これでできた。
- 投稿日:2021-03-15T22:13:41+09:00
場面遷移用のUI縞模様(ストライプ)シェーダ
場面遷移で使える縞模様(ストライプ)のシェーダを書いたので、コードを貼っておきます。スプライトではなくストライプ。
せっかくなので、u1wからの新要素として「ストライプの角度指定」も入れておいた。使い処が増えたかな。
— MIYAKE (@ScreenPocket) March 14, 2021
Qiitaは近々書きます。 pic.twitter.com/E6xyTBgWoO今回も前回の放射シェーダと同じく、builtInシェーダのUI-Defaultから作成したUI用のシェーダとなっています。
重ね合わせとかを考えると、ポストプロセスよりも多分UIの方が扱いやすいはず。
そして、色についても前回と同じく、「アタッチしたUI.Graphicのcolor」と「マテリアルの_Color」の2色で色付けが可能です。コード
UI-Stripe.shaderShader "ScreenPocket/UI/Stripe" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} _Color ("Tint", Color) = (1,1,1,1) _Step ("Step", Range(-1,1)) = 0 _Angle ("Angle", Range(0,360)) = 0 _LineCount ("Line Count", Float) = 32 _StencilComp ("Stencil Comparison", Float) = 8 _Stencil ("Stencil ID", Float) = 0 _StencilOp ("Stencil Operation", Float) = 0 _StencilWriteMask ("Stencil Write Mask", Float) = 255 _StencilReadMask ("Stencil Read Mask", Float) = 255 _ColorMask ("Color Mask", Float) = 15 [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 } SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" "CanUseSpriteAtlas"="True" } Stencil { Ref [_Stencil] Comp [_StencilComp] Pass [_StencilOp] ReadMask [_StencilReadMask] WriteMask [_StencilWriteMask] } Cull Off Lighting Off ZWrite Off ZTest [unity_GUIZTestMode] Blend One OneMinusSrcAlpha ColorMask [_ColorMask] Pass { Name "Default" CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 2.0 #include "UnityCG.cginc" #include "UnityUI.cginc" #pragma multi_compile_local _ UNITY_UI_CLIP_RECT #pragma multi_compile_local _ UNITY_UI_ALPHACLIP struct appdata_t { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; float4 worldPosition : TEXCOORD1; half4 mask : TEXCOORD2; UNITY_VERTEX_OUTPUT_STEREO }; sampler2D _MainTex; half4 _Color; half4 _TextureSampleAdd; float4 _ClipRect; float4 _MainTex_ST; float _MaskSoftnessX; float _MaskSoftnessY; float _Angle; float _Step; float _LineCount; v2f vert(appdata_t v) { v2f OUT; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); float4 vPosition = UnityObjectToClipPos(v.vertex); OUT.worldPosition = v.vertex; OUT.vertex = vPosition; float2 pixelSize = vPosition.w; pixelSize /= float2(1, 1) * abs(mul((float2x2)UNITY_MATRIX_P, _ScreenParams.xy)); float4 clampedRect = clamp(_ClipRect, -2e10, 2e10); float2 maskUV = (v.vertex.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy); OUT.texcoord = float4(v.texcoord.x, v.texcoord.y, maskUV.x, maskUV.y); OUT.mask = half4(v.vertex.xy * 2 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * half2(_MaskSoftnessX, _MaskSoftnessY) + abs(pixelSize.xy))); OUT.color = v.color; return OUT; } half4 frag(v2f IN) : SV_Target { half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd); half cosValue = cos(radians(_Angle)); half sinValue = sin(radians(_Angle)); half2x2 rotate = half2x2(cosValue, -sinValue, sinValue, cosValue); //中央にずらして(-0.5)、回転した後で元の位置に戻す(+0.5) IN.texcoord = mul(IN.texcoord - 0.5, rotate) + 0.5; float rate = round(frac(IN.texcoord.y * _LineCount)); color *= lerp(_Color, IN.color, rate); #ifdef UNITY_UI_CLIP_RECT half2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(IN.mask.xy)) * IN.mask.zw); color.a *= m.x * m.y; #endif //交互にくり抜く rate = ((rate-0.5)*2); color.a = 1-abs(ceil(IN.texcoord.x - rate * _Step)-1); #ifdef UNITY_UI_ALPHACLIP clip (color.a - 0.001); #endif color.rgb *= color.a; return color; } ENDCG } } }ほとんどがUI-Defaultのままですが、追加した部分でのポイントは
- _Angleで回転行列を作る
- 作った回転行列でIn.texcoordを回転
- round(frac())と_LineCountの掛け算で帯模様を作る
- abs(ceil())と_Stepで良い感じに左右を切り抜く ← これが難しかった;
な感じですかね。
使い方
前回の放射シェーダと同じく、上記のシェーダを充てたマテリアルを作成し、UIのImageかRawImageにマテリアルを設定する事で表示をすることが可能となります
各パラメータの用法は下記です
パラメータ名 用法 _Color ストライプの帯の色を決めます。この色とアタッチしたGraphic(Image、RawImage)のColorを交互に置いた縞模様となります _Step 帯の表示をずらすことが出来ます。0で面をすべて覆いきった見た目になり、-1か1で帯が退出しきった見た目になります。この数値をDOTweenなどで滑らかに動かすことで、場面遷移に効果的に使用できます。 _Angle 帯の角度を決めることが出来ます0(360)か180で横帯、90か270で縦帯となります _LineCount 帯の数を決めます。例えば10を入力すると、帯の色がそれぞれ10ずつ(つまり2色合わせると20本)表示されます 実際ゲームでどう使っているかは、拙作を遊んでみて下さい。
DOTweenと連携
例えばこんな感じ。u1wのコードを一部抜粋します。
StripePanel.csの一部を抜粋//侵入アニメーション再生 public void PlayIn( Action onComplete ) { //Inフラグ立てる _isIn = true; //入力ロック UIManager.instance.InputLocker.Lock(); //パネルをActive化 gameObject.SetActive(true); //Image(ストライプ本体)をActive化 _image.gameObject.SetActive(true); //アニメーション(-1~0までを0.4秒かけて_Stepに伝える) DOTween.To(()=>-1f, f => { _bgMaterial.SetFloat("_Step", f); }, 0f, 0.4f).SetEase(Ease.OutQuad).OnComplete(() => { //入力ロック解除 UIManager.instance.InputLocker.Unlock(); //完了コールバック onComplete?.Invoke(); }); } //退避アニメーション再生 public void PlayOut(Action onComplete) { //入力ロック UIManager.instance.InputLocker.Lock(); //アニメーション(0~1を0.4秒かけて_Stepに伝える) DOTween.To(()=>0f, f => { _bgMaterial.SetFloat("_Step", f); }, 1f, 0.4f).SetEase(Ease.InQuad).OnComplete(() => { //Inフラグ下ろす _isIn = false; //入力ロック解除 UIManager.instance.InputLocker.Unlock(); //帯本体非アクティブ化 _image.gameObject.SetActive(false); //パネル自体を非アクティブ化 gameObject.SetActive(false); //完了コールバック onComplete?.Invoke(); }); }こんな感じの関数を用意しておけば、
- 場面転換前にPlayIn()を呼び、
- PlayIn()が完了したら画面切り替え処理を行い、
- 画面切り替え処理が終わったらPlayOut()を呼び、
- PlayOut()が完了したら次の画面の処理を開始する。
という流れが組み立てやすくなる、という感じですね。
参考資料
_Angleの実装は下記を参考にさせて頂きました。
- 投稿日:2021-03-15T15:00:08+09:00
サイバーエージェントの3dayハッカソンに参加してきたので所感
初投稿です(CAの方にブログ書くのをお勧めしていただいたのではじめの一歩!)
3/12-3/14の三日間でサイバーエージェントの3dayハッカソンに参加してきました。
技術的な話はしませんが、これからCAの説明会やインターンシップに出ようと思ってる人は是非今回初めてサーバーサイドの人と連携してゲーム制作をしました。ランキングとユーザー認証の実装を必須とし、お題はシューティングorパズルで、自分のチームはシューティングを作りました。
(僕はインゲーム部分担当)
初めてサーバーサイドと一緒に開発して思ったことは、互いに互いの言語や、使い方の知識がなく、情報共有が大変でした。
また、自分のチームはガチャの実装もしたので、初めてソシャゲを1から作る体験をしたような実習となりました。ガチャやランキングがあることで意識するゲームデザインなども出てくるので、普段とはかなり違う目線でゲーム開発を出来たと思います。3日目終了後にはCAのSGE(ゲーム系子会社の協力体制的な)の説明や、社員さんによるLT会を開いていただきました。特に木原さんのお話(エンジニアとして大事なこと)は、個人の本音を聞いてる感じがしてとてもよかったです。
最後にグループに分かれて懇親会をしました。コロナ中の新卒研修のお話や、リモートワークのお話などを聞けて、短い時間でしたがとても楽しかったです。こんな感じでふわふわした感じで終わってしまいますが、技術的なことを何も載せないのはあれなので最後に社員さんにお勧めされた書籍の紹介を(ダイマ)
Unityの技術書ですが、これからUnityを始める人向けではなく、ある程度やってる人が製品レベルまで完成度を上げる際に参考にする書籍かなと思います。
では
- 投稿日:2021-03-15T12:30:39+09:00
[Unity]ECS(0.17.0) 子の要素に指定のIComponentData(それ以外も可能)が含まれているか
Unity v.2020.2
Entity v.0.17.0なんやかんや新しくなったら検索阻害防止のため、予告なく削除します。
<重要>
・PrefabのGameobjectからEntityへ変換されると
ChidとかLinkedEntityGroupが勝手につけられて関連性が持たれるようです。デバッグ機能で確認。(公式ドキュメントとか知りませんが動きます)
EntityManagerの拡張メソッドにしました。こんなやり方で取れるよっていう参考程度に。
(どうせみんないなくなる)例えばEntityのLODのマテリアルをまとめて変更したいときとか。
コードは以下の通りです。
EntityManagerExtends.csusing Unity.Entities; namespace TbsFramework { public static class EntityManagerExtends { public static Entity FindChild<T>(this in EntityManager manager, in Entity t) { if (!manager.HasComponent<LinkedEntityGroup>(t)) return Entity.Null; foreach (var linkentity in manager.GetBuffer<LinkedEntityGroup>(t)) if (manager.HasComponent<T>(linkentity.Value)) return linkentity.Value; return Entity.Null; } public static Entity[] FindChildAll<T>(this in EntityManager manager, in Entity t) { var entityList = new Entity[0]; if (!manager.HasComponent<LinkedEntityGroup>(t)) return entityList; var entites = new Unity.Collections.NativeList<Entity>(Unity.Collections.Allocator.Temp); var linkGroupList = manager.GetBuffer<LinkedEntityGroup>(t); foreach (var linkentity in linkGroupList) if (manager.HasComponent<T>(linkentity.Value)) entites.Add(linkentity.Value); entityList = entites.ToArray(); entites.Dispose(); return entityList; } } }HowToUse.csvar entities = EntityManager.FindChildAll<Unity.Rendering.RenderMesh>(targetEntity); if (entities.Length > 0) Debug.Log("Hit!"); else Debug.Log("Nothing");