Unity Input System

Unity InputSystemでキーの割り当てを変更する方法です。今回はPlayer InputのCreate Actionsで生成されるInput ActionsのAction Maps -> Player -> Actions -> Fire に Space [Keyboard]を追加してそれを実行後にスクリプトから変更します。

パッケージマネージャーからInput Systemをインストールします。

オブジェクト(GameObject)に Player Input コンポーネントを追加します。Create ActionsボタンをクリックしてInput Actionsを作成します。

Action Maps -> Player -> Actions -> Fire を選択します。All Control SchemesをKeyboardMouseに変更します。Fireの+ボタンをクリックしてAdd Bindingを選択します。PropertiesのBinding – Path をクリックします。Keyboard -> By Location of Key (Using US Layout)のSpaceを選択します。Use in Control Scheme の Keyboard&Mouseをチェックします。

スクリプトを追加、変更します。以下のように変更します。クラスの宣言は省略しています。

    
    public PlayerInput playerInput;
    private InputAction fireInputAction;
    private InputBinding keyboardInputBinding;

 // Start is called before the first frame update
    void Start()
    {
        playerInput = GetComponent<PlayerInput>();

        fireInputAction= playerInput.actions["Fire"];
        keyboardInputBinding= fireInputAction.bindings[5];
        fireInputAction.ApplyBindingOverride(new InputBinding() { path = "<Keyboard>/space", overridePath = "<Keyboard>/q" });
        fireInputAction.ApplyBindingOverride(5, "<Keyboard>/q");
        keyboardInputBinding= fireInputAction.bindings[5];

    }

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

    }

    public void OnMove(InputValue value)
    {
        var wasd = value.Get<Vector2>();
    }

    public void OnLook(InputValue value)
    {

    }

    public void OnFire()
    {
        // Spaceキーの代わりにQキーを押すと以下のコートが実行されます
    }

keyboardInputBinding.path が “<Keyboard>/space” から”<Keyboard>/q” に変更されます。qは大文字、小文字どちらでも構わないようです。keyboardInputBinding.groupsはKeyboard&Mouseとなります。

ApplyBindingOverrideはInputBindingクラスを作成する方法とindexを指定する方法とあります。

ActionsのFireという名前がそのままOnFireというメソッドの名前になります。

運用としてはUIにCanvasを作成してインタラクションコンポーネントを利用して変更することになります。ほかのゲームでは左右に矢印ボタンを配置してクリックして選択したり、キー入力を受け付けたりして変更しています。

Unityの新しい入力システムInputSystemを使ってみる

https://gametukurikata.com/basic/inputsystem

こちらのサイトが参考になります。

Unity Scriptable Render Pipeline

スクリプタブルレンダーパイプラインの概要

https://blogs.unity3d.com/jp/2018/01/31/srp-overview/

こちらのブログについて Unity 2019.1 以降で CullingResults, DrawRendererSettings の個所などでエラーが発生して動作しなくなりました。

これはこのクラスがExperimentalに指定されて、Unity 2019.1 以降のバージョンでは利用できなくなりました。次のように書き換えると動作しました。

BasicAssetPipe.cs

using UnityEngine;
using UnityEngine.Rendering;
// using UnityEngine.Experimental.Rendering;


[ExecuteInEditMode]
public class BasicAssetPipe : RenderPipelineAsset
{
    public Color clearColor = Color.green;

#if UNITY_EDITOR
    [UnityEditor.MenuItem("SRP-Demo/01 - Create Basic Asset Pipeline")]
    static void CreateBasicAssetPipeline()
    {
        var instance = ScriptableObject.CreateInstance<BasicAssetPipe>();
        UnityEditor.AssetDatabase.CreateAsset(instance, "Assets/SRP-Demo/1-BasicAssetPipe/BasicAssetPipe.asset");
    }

#endif

    protected override RenderPipeline CreatePipeline()
    {
        return new BasicPipeInstance(clearColor);
    }
}

public class BasicPipeInstance : RenderPipeline
{
    private Color m_ClearColor = Color.black;

    public BasicPipeInstance(Color clearColor)
    {
        m_ClearColor = clearColor;
    }

    protected override void Render(ScriptableRenderContext context, Camera[] cameras)
    {
        // does not so much yet :()
        // base.Render(context, cameras);

        // clear buffers to the configured color
        var cmd = new CommandBuffer();
        cmd.ClearRenderTarget(true, true, m_ClearColor);
        context.ExecuteCommandBuffer(cmd);
        cmd.Release();
        context.Submit();
    }
}

OpaqueAssetPipe.cs

using System;
using UnityEngine;
using UnityEngine.Rendering;
// using UnityEngine.Experimental.Rendering;

[ExecuteInEditMode]
public class OpaqueAssetPipe : RenderPipelineAsset
{
#if UNITY_EDITOR
    [UnityEditor.MenuItem("SRP-Demo/02 - Create Opaque Asset Pipeline")]
    static void CreateBasicAssetPipeline()
    {
        var instance = ScriptableObject.CreateInstance<OpaqueAssetPipe>();
        UnityEditor.AssetDatabase.CreateAsset(instance, "Assets/SRP-Demo/2-OpaqueAssetPipe/OpaqueAssetPipe.asset");
    }
#endif

    protected override RenderPipeline CreatePipeline()
    {
        return new OpaqueAssetPipeInstance();
    }
}

public class OpaqueAssetPipeInstance : RenderPipeline
{
    protected override void Render(ScriptableRenderContext context, Camera[] cameras)
    {
        // base.Render(context, cameras);

        foreach (var camera in cameras)
        {
            // Culling
            ScriptableCullingParameters cullingParams;

            if (!(camera.TryGetCullingParameters(out cullingParams)))
                 continue;

            var cull = context.Cull(ref cullingParams);

            // Setup camera for rendering (sets render target, view/projection matrices and other
            // per-camera built-in shader variables).
            context.SetupCameraProperties(camera);

            // clear depth buffer
            var cmd = new CommandBuffer();
            cmd.ClearRenderTarget(true, false, Color.black);
            context.ExecuteCommandBuffer(cmd);
            cmd.Release();

            // Draw opaque objects using BasicPass shader pass
            var settings = new DrawingSettings(new ShaderTagId("BasicPass"), new SortingSettings(camera));
            settings.sortingSettings = new SortingSettings() { criteria = SortingCriteria.CommonOpaque };
            var filterSettings = new FilteringSettings(renderQueueRange: RenderQueueRange.opaque);
            context.DrawRenderers(cull, ref settings ,ref filterSettings);

            // Draw skybox
            context.DrawSkybox(camera);

            context.Submit();
        }
    }
}

TransparentAssetPipe.cs

using System;
using UnityEngine;
using UnityEngine.Rendering;
// using UnityEngine.Experimental.Rendering;

[ExecuteInEditMode]
public class TransparentAssetPipe : RenderPipelineAsset
{
#if UNITY_EDITOR
    [UnityEditor.MenuItem("SRP-Demo/03 - Create Transparent Asset Pipeline")]
    static void CreateBasicAssetPipeline()
    {
        var instance = ScriptableObject.CreateInstance<TransparentAssetPipe>();
        UnityEditor.AssetDatabase.CreateAsset(instance, "Assets/SRP-Demo/3-TransparentAssetPipe/TransparentAssetPipe.asset");
    }
#endif

    protected override RenderPipeline CreatePipeline()
    {
        return new TransparentAssetPipeInstance();
    }
}

public class TransparentAssetPipeInstance : RenderPipeline
{
    protected override void Render(ScriptableRenderContext context, Camera[] cameras)
    {
        // base.Render(context, cameras);

        foreach (var camera in cameras)
        {
            // Culling
            ScriptableCullingParameters cullingParams;

            if (!(camera.TryGetCullingParameters(out cullingParams)))
                continue;

            var cull = context.Cull(ref cullingParams);

            // Setup camera for rendering (sets render target, view/projection matrices and other
            // per-camera built-in shader variables).
            context.SetupCameraProperties(camera);

            // clear depth buffer
            var cmd = new CommandBuffer();
            cmd.ClearRenderTarget(true, false, Color.black);
            context.ExecuteCommandBuffer(cmd);
            cmd.Release();

            // Draw opaque objects using BasicPass shader pass
            var settings = new DrawingSettings(new ShaderTagId("BasicPass"), new SortingSettings(camera));
            settings.sortingSettings = new SortingSettings() { criteria = SortingCriteria.CommonOpaque };
            var filterSettings = new FilteringSettings(renderQueueRange: RenderQueueRange.opaque);
            context.DrawRenderers(cull, ref settings, ref filterSettings);


            // Draw skybox
            context.DrawSkybox(camera);

            settings.sortingSettings = new SortingSettings() { criteria = SortingCriteria.CommonTransparent };
            filterSettings = new FilteringSettings(renderQueueRange: RenderQueueRange.transparent);
            context.DrawRenderers(cull, ref settings, ref filterSettings);

            context.Submit();
        }
    }
}

こちらのサイトが参考になりました。

LWRP 4-preview を2019.1で動かすように改造した話

https://connect.unity.com/p/lwrp-4-preview-wo2019-1dedong-kasuyounigai-zao-shitahua

Unity Scriptable Render Pipeline(SRP)はパッケージマネージャーからUniversal Render Pipeline(URP, 2019より前はLightweight Render Pipeline(LWRP))、HD レンダーパイプライン(HDRP)をチェックしなくても利用できます。

flutter 1.15.3 dev, error

flutter_windows_1.17.2-stable では発生しません。

flutter_windows_v1.15.3-dev でビルドをで次のエラーが発生します。

Launching lib\main.dart on Android SDK built for x86 in debug mode...
Running Gradle task 'assembleDebug'...
U
nhandled exception:
Crash when compiling package:firebase_admob/firebase_admob.dart,
at character offset null:
NoSuchM
ethodError: The method 'accept' was called on null.
Receiver: null
Tried calling: accept<DartType>(Instance of '_DemotionNonNullification')
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1      demoteTypeInLibrary (package:front_end/src/fasta/type_inference/type_demotion.dart:65:14)
#2      TypeInferrerImpl.inferDeclarationType (package:front_end/src/fasta/type_inference/type_inferrer.dart:1889:14)
#3      InferenceVisitor.visitVariableDeclaration (package:front_end/src/fasta/kernel/inference_visitor.dart:5337:31)
#4      VariableDeclaration.accept (package:kernel/ast.dart:5495:43)
#5      TypeInferrerImpl.inferStatement (package:front_end/src/fasta/type_inference/type_inferrer.dart:3245:24)
#6      InferenceVisitor._visitStatements (package:front_end/src/fasta/kernel/inference_visitor.dart:299:20)
#7      InferenceVisitor.visitBlock (package:front_end/src/fasta/kernel/inference_visitor.dart:320:30)
#8      Block.accept (package:kernel/ast.dart:4722:43)
#9      TypeInferrerIm
pl.inferStatement (package:front_end/src/fasta/type_inference/type_inferrer.dart:3245:24)
#
10     TypeInferrerImpl.inferLocalFunction (package:front_end/src/fa
sta/type_inference/type_inferrer.dart:2595:43)
#11     Inf
erenceVisitor.visitFunctionNode (package:front_end/
src/fasta/kernel/inference_visitor.dart:1041:21)
#
12     InferenceVisitor.visitFunctionExpression (package:front_end/s
rc/fasta/
kernel/inference_visitor.dart:1065:9)
#13     FunctionExpr
ession.accept1 (package:kernel/ast.dart:4523:9
)
#14     TypeInferrerImpl.inferExpression (package:fr
ont_end/src/fasta/type_inference/type_inferrer.d
art:1988:27)
#15     InferenceVisitor.inferMapEntry (packa
ge:front_end/src/fasta/kernel/inference_visitor
.dart:1998:56)
#16     InferenceVisitor.visitMapLiteral (
package:front_end/src/fasta/kernel/inference_vis
itor.dart:2161:17)
#17     MapLiteral.accept1 (package:
kernel/ast.dart:4431:9)
#18     TypeI
nferrerImpl.inferExpression (package:front_end/src/fasta
/type_inference/type
_inferrer.dart:1988:27)
#19     _ImplicitFieldTypeRoot.
computeType (package:fr
ont_end/src/fasta/kernel/implicit_field_type.dart:138:55)
#20  
   SourceFieldBuilder.inferType (package:front_e
nd/src/fasta/builder/field_builder.dart:334:47)
#21 
    SourceLoader.performTopLevelInference (package:fro
nt_end/src/fasta/source/source_loader.dart:1109:35)
#2
2     KernelTarget.buildOutlines.<anonymous closur
e> (package:front_end/src/fasta/kernel/kernel_target
.dart:312:14)
<asynchronous s
uspension>
#23     withCrashReporting (package:front_end/sr
c/fasta/crash.dart:122:24)
#24     KernelTarget.buildOut
lines (package:front_end/src/fasta/kernel/kernel_tar
get.dart:288:12)
#25     generateKernelInternal.<anonymous
 closure> (package:front_end/src/kernel_generat
or_impl.dart:108:28)
<asynchronous suspension>
#26     withCrashReporting (package:fro
nt_end/src/fasta/crash.dart:122:24)
#27     generateKernelInte
rnal (package:front_end/src/kernel_generator_impl.dart:70:10)
#28     ke
rnelForProgramInternal.<anonymous closure> (package:front_end/src/
api_prototype/kernel_generator.dart:61:35)
#29     Compiler
Context.runWithOptions.<anonymous closure> (package:front_end/sr
c/fasta/compiler_context.dart:135:20)
<asynchronous suspension>

#30     CompilerC
ontext.runInContext.<anonymous closure>.<anonymous closure> (pack
age:front_end/src/fasta/compiler_context.dart:123:
46)
#31     new Future.sync (dart:async/future.dar
t:224:31)
#32     CompilerContext.runInContext.<anonymous c
losure> (package:front_end/src/fasta/compiler_context.dart:123:1
9)
#33     _rootRun (dart:async/zone.dart:1126:13)
#34     _Cus
tomZone.run (dart:async/zone.dart:1023:19)
#35     _
runZoned (dart:async/zone.dart:1518:10)
#36     runZoned 
(dart:async/zone.dart:1465:12)
#37     CompilerContext.
runInContext (package:front_end/src/fasta/compiler_con
text.dart:122:12)
#38     CompilerContext.runWithOpt
ions (package:front_end/src/fasta/compiler_context.da
rt:133:10)
#39     kernelForProgramInternal (package:f
ront_end/src/api_prototype/kernel_generator.dart
:60:32)
#40     kernelForProgram (package:front_end/
src/api_prototype/kernel_generator.dart:52:17)
#
41     compileToKernel (package:vm/kernel_front_end.da
rt:319:41)
#42     FrontendCompiler.compile.<anonymou
s closure> (package:frontend_server/frontend_ser
ver.dart:452:54)
#43     new Future.<anonymous closure>
 (dart:async/future.dart:176:37)
#44     _rootRun
 (dart:async/zone.dart:1122:38)
#45     _CustomZon
e.run (dart:async/zone.dart:1023:19)
#46     _CustomZone.ru
nGuarded (dart:asyn
c/zone.dart:925:7)
#47     _CustomZone.bindCallbackGuarded.<a
nonymous closure> (dart:async/zone.dart:965:23)
#4
8     _rootRun (dart:async/zone.dart:1126:13)
#49   
  _CustomZone.run (dart:async/zone.dart:1023:19)
#
50     _CustomZone.bindCallback.<anonymous closure> (da
rt:async/zone.dart:949:23)
#51     Timer._createTimer.
<anonymous closure> (dart:async-patch/timer_patch.dart:23:15)
#52     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
#53     _Ti
mer._handleMessage (dart:isolate-patch/t
imer_impl.dart:429:5)
#54     _RawReceivePortImpl._handleMess
age (dart:isola
te-patch/isolate_patch.dart:168:12)


#0      Object.noSuchMet
hod (dart:core-patch/object_patch.dart:53:5)
#1      d
emoteTypeInLibrary (package:front_end/src/fasta/type_infe
rence/type_demotion.dart:65:14)
#2      TypeInferrerImpl.inferDec
larationType (package:fr
ont_end/src/fasta/type_inference/type_inferrer.dart:1889:
14)
#3      InferenceVis
itor.visitVariableDeclaration (package:front_end/src/fast
a/kernel/inference_visitor.dart:5337:31)
#4      Var
iableDeclaration.accept (package:kernel/ast.dart:549
5:43)
#5      TypeInferrerImpl.inferStatement (pack
age:front_end/src/fasta/type_inference/type_infe
rrer.dart:3245:24)
#6      InferenceVisitor._visitStatem
ents (package:front_end/src/fasta/kernel/inferen
ce_visitor.dart:299:20)
#7      InferenceVisitor.vi
sitBlock (package:front_end/src/fasta/kernel/inf
erence_visitor.dart:320:30)
#8      Block.accept (package:kernel/ast.dart:
4722:43)
#9      TypeInferrerIm
pl.inferStatement (package:front_end/src/fasta/type_inference/
type_inferrer.dart:3245:24)
#
10     TypeInferrerImpl.inferLocalFunction (package:f
ront_end/src/fasta/type_inference/type_inferrer.dart:
2595:43)
#11     InferenceVisitor.visi
tFunctionNode (package:fro
nt_end/src/fasta/kernel/inference_visitor.dart:1041:2
1)
#12     InferenceVisitor.visitFunctionExpr
ession (package:front_end/src/fas
ta/kernel/inference_visitor.dart:1065:9)
#13     FunctionExpression.accept1 (package:kernel/ast.dart:4523:9)
#
14     TypeInferrerImpl.inferExpression (package:front_end/src/fasta/type_inference/t
ype_inferrer.dart:1988:27)
#15     InferenceVisitor.inferMapEntry (package:front_en
d/src/fasta/kernel/inference_visitor.dart:1998:56)
#16     In
ferenceVisitor.visitMapLiteral (package:front_end/src/fas
ta/kernel/infe
rence_visitor.dart:2161:17)
#17     MapLiteral.accept1 (p
ackage:kernel/ast.dart:4431:9)
#18     TypeInferrerImp
l.inferExpression (package:front_end/src/fasta/type_infer
ence/type_inferrer.dart:1988:27)
#19     _ImplicitFieldT
ypeRoot.computeType (package:front_end/src/fasta/kern
el/implicit_field_type.dart:138:55)
#20     SourceFiel
dBuilder.inferType (package:front_end/src/fasta/buil
der/field_builder.dart:334:47)
#21     SourceLoader.per
formTopLevelInference (package:front_end/src/fasta/sou
rce/source_loader.dart:1109:35)
#22     KernelTarget.buildOu
tlines.<anonymous closure> (package:front_end/src/fa
sta/kernel/kernel_target.dart:312:14)
<asynchronous suspen
sion>
#23     withCrashReporting (package:front_end
/src/fasta/crash.dart:122:24)
#24     KernelTarget.build
Outlines (package:front_end/src/fasta/kernel/kernel_tar
get.dart:288:12)
#25     generateKernelInternal.<anonym
ous closure> (package:front_end/src/kernel_generator_imp
l.dart:108:28)
<asynchronous suspension>
#26     withCr
ashReporting (package:front_end/src/fasta/crash.dart
:122:24)
#27     generateKernelInternal (package:front_en
d/src/kernel_generator_impl.dart:70:10)
#28     ker
nelForProgramInternal.<anonymous closure> (package:fron
t_end/src/api_prototype/kernel_generator.dart:61:35)
#29
     CompilerContext.runWithOptions.<anonymous closure> (packa
ge:front_end/src/fasta/compiler_context.dart:135:20)
<asynchronous s
uspension>
#30     CompilerC
ontext.runInContext.<anonymous closure>.<anonymous closure> (packa
ge:front_end/src/fasta/compiler_context.dart:123:46)
#31     new Futur
e.sync (dart:async
/future.dart:224:31)
#32     CompilerContext.runInContext.<anonymous closur
e> (package:fr
ont_end/src/fasta/compiler_context.dart:123:19)
#33     _rootRun (dart:async
/zone.dart:1126:13)
#34     _
CustomZone.run (dart:async/zone.dart:1023:19)
#35     _runZoned (dart
:async/zone.dart:1518:10)
#36     runZoned (dart:async/zone.dart
:1465:12)
#37     CompilerContext.runInContext (package:front_end/
src/fasta/compiler_context.dart:122:12)
#38     CompilerContext.runWit
hOptions (package:front_end/src/fasta/compiler_context.dart:133:
10)
#39     kernelForProgramInternal (package:fr
ont_end/src/api_prototype/kernel_generator.dart:60:32)
#40     kernelForPr
ogram (package:front_end/src/api_prototype/kernel_generator.dart:52:17)
#41     compileToK
ernel (package:vm/kernel_front_end.dart:319:41)
#42     FrontendCompiler.compile.<anony
mous closure> (package:frontend_server/frontend_server.dart:452:54)
#43     new Futur
e.<anonymous closure> (dart:async/future.dart:176:37)
#44     _rootRun (dart:async/zo
ne.dart:1122:38)
#45     _CustomZone.run (dart:async/zone.dart:1023:19)
#46     _CustomZo
ne.runGuarded (dart:async/zone.dart:925:7)
#47     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:965:23)
#48     _root
Run (dart:async/zone.dart:1126:13)
#49     _CustomZone.run (dart:async/zone.dart:1023:19)
#50     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:949:23)
#51     Timer._createTimer.<a
nonymous closure> (dart:async-patch/timer_patch.dart:23:15)
#52     _Timer._runTimers (dart:isolate-pa
tch/timer_impl.dart:398:19)
#53     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:
429:5)
#54     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

Target kernel_snapshot failed: Exception: Errors during snapshot creation: null
build failed.

FAILURE: Build failed with an exception.

* Where:
Script 'D:\src\flutter\packages\flutter_tools\gradle\flutter.gradle' line: 817

* What went wrong:
Execution failed for task ':app:compileFlutterBuildDebug'.
> Process 'command 'D:\src\flutter\bin\flutter.bat'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 9s
Finished with error: Gradle task assembleDebug failed with exit code 1

flutter_windows_v1.12.13+hotfix.8-stable では発生しません。

dart, add XmlElement

dart, flutter で XmlElementを追加する方法です。

import 'package:flutter/material.dart';
import 'package:xml/xml.dart' as xml;
import 'dart:async';
import 'dart:io';
import 'dart:core';

var bookshelfXml = '''<?xml version="1.0"?>
    <bookshelf>
      <book>
        <title lang="english">Growing a Language</title>
        <price>29.99</price>
      </book>
      <book>
        <title lang="english">Learning XML</title>
        <price>39.95</price>
      </book>
    </bookshelf>''';
var document = xml.parse(bookshelfXml);

var element_book = xml.XmlElement(xml.XmlName('book'));
var element_title = xml.xmlElement(xml.XmlName('title'))..attributes.add(xml.XmlAttribute(xml.XmlName('lang'), 'english'))..children.add(xml.XmlText('My book'));
var element_price = xml.XmlElement(xml.XmlName('price'))..children.add(xml.XmlText('19.95'));
element_book..children.add(element_title);
element_book..children.add(element_price);
document.rootElement.children.add(element_book);

この方法でbook要素に title が My book, price が 19.95 の book が追加されます。

<?xml version="1.0"?>
    <bookshelf>
      <book>
        <title lang="english">Growing a Language</title>
        <price>29.99</price>
      </book>
      <book>
        <title lang="english">Learning XML</title>
        <price>39.95</price>
      </book>
      <book>
        <title lang="english">My book</title>
        <price>19.95</price>
      </book>
    </bookshelf>

children.add に別のXmlDocumentのXmlNode, XmlElement などを配置すると例外が発生します。xml.XmlElement(xml.XmlName(“book”)) 等で生成または、xml.XmlElement.copy() を使用する必要があります。

Call Kotlin method from Flutter(FlutterからKotlinのコード内のメソッドを呼び出す)

MainActivity.kt (Kotlin)

package (your.app)

import android.content.res.Configuration
import android.os.Bundle
import android.os.PersistableBundle
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant

import io.flutter.embedding.android.FlutterFragment
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel

import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result

import io.flutter.plugin.platform.PlatformViewsController


class MainActivity: FlutterActivity() {
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor, CHANNEL).setMethodCallHandler { methodCall, result ->
            val args = methodCall.arguments
            when (methodCall.method) {
                "method1" -> {
                    val number = 10
                    result.success(number)
                }
            }
        }
    }

    companion object {
        private val CHANNEL = "com.your.app.flutter/method1"
    }

}

Dart

static const platform = const MethodChannel('com.your.app.flutter/method1');

Future<void> _Method1() async{
    int _number;
    try {
      final int result = await platform.invokeMethod('method1');
      _number = result;

      setState(() {
        number = _number;
      });

    } on PlatformException catch (e)
    {
      setState(() {
        number = -1;
      });
    }
}

int number;

Widget ShowNumber()
{
  Text(number.toString());
}

_Method1() を呼び出すと Kotlin側のmethod1 -> {} が実行され、結果が Flutter側の result に戻ります。

String testString = “abc”;
platform.invokeMethod(‘method1’, testString); でtestStringを引数にできます。
Kotlin側の methodCall.arguments で引数を取得できます。

io.flutter.app.FlutterActivity の FlutterActivity には FlutterEngine が存在しないのでGeneratedPluginRegistrant.registerWith(this) ではregistできません。またMethodCall の flutterView の代わり(java では getFlutterView() )に flutterEngine.dartExecutor を使用します。

2019-12-05の時点で app/build.gradle 内で Cannot resolve symbol ‘GradleException’ が、MainActivity.kt で Unresolved reference: NonNull がそれぞれ赤字で表示されます。2019-12-07のAndroid Studio アップデートとFlutter Pluginのアップデートで表示されなくなったようです。

こちらのサイトの情報が参考になりました。

https://github.com/flutter/flutter/issues/41102
https://qiita.com/tasogarei/items/bf3761139d46c43d5896
https://qiita.com/unsoluble_sugar/items/ae42b5faf52a491f6470
https://flutter.keicode.com/basics/method-channel-java.php

Google Play Licensing Verification Library (LVL)

Android Studio 3.5 でGoogle Play Licensing Verification Library (LVL) をインポートする方法です。

  1. File – New – Import Module .. を選択して Source directory: に [ANDROID_SDK]/extras/google/market_licensing/library を指定します。Finishをクリックします。プロジェクト内にlibrary ディレクトリーが作成され、インポートされます。
  2. library/src/main/java/com を android/app/src/main/java/com にコピーします。
  3. AndroidManifest.xmlに次の要素を追加します。
<!-- Devices >= 3 have version of Google Play that supports licensing. -->
<uses-sdk android:minSdkVersion="3" />
<!-- Required permission to check licensing. -->
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />

Visual Studio 2017用 Microsoft Angel

Visual Studio 2017用に Microsoft Angel (https://github.com/Microsoft/angle) を修正したものを公開しました。

https://github.com/setokynet/vs2017-winrt-angel_opengl

  • slnファイルの ToolsVersion を14.0から15.0に変更
  • WindowsTargetPlatformMinVersion を10.0.10240.0 から 10.0.10586.0に変更

CoreWindowNativeWindow.cpp を次のように変更しました。

static float GetLogicalDpi()
{
    // ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> displayProperties;
    ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation> displayProperties;

    // if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf())))
    if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(), displayProperties.GetAddressOf())))
    {
        float dpi = 96.0f;
        if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi)))
        {
            return dpi;
        }
    }

    // Return 96 dpi as a default if display properties cannot be obtained.
    return 96.0f;
}

IDisplayPropertiesStaticsとDisplayPropertiesStatics は Windows Phone 8.1 対応が必要となり、Winrt(UWP)では使用できないためIDisplayInformationとDisplayInformationに変更しました。コードの変数はdisplaypropertiesのまま変更していません。

github.com/setokynet/vs2017-winrt-angel_opengl にはCoreWindowNativeWindow.cppは含まれていません。angle-ms-master\src\libANGLE\renderer\d3d\d3d11\winrt\CoreWindowNativeWindow.cpp のGetLogicalDpi()を修正してください。

#include “id/commit.h” が含まれていてコンパイルできない場合、mklink /D /J angle-ms-master\src\id angle-ms-master\src でシンボリックリンクを作成するとコードを修正することなくコンパイルできます。

2018年3月13日現在の内容です。今後の更新で不要になる可能性があります。

Windows Store App でOpenGL(OpenGLES)を使用できます。

Install.Wim, Install.ESD ファイルのマウント

Windows 10 の install.Wim, install.esd ファイルの展開方法です

DISM を使ってイメージをマウントおよび変更する (https://msdn.microsoft.com/ja-jp/library/hh824814.aspx)

DISM イメージ管理のコマンド ライン オプション (https://msdn.microsoft.com/ja-jp/library/hh825258.aspx)


Wimファイル

[例]C:\win10\install.wim ファイルを C:\win10\Mount にマウント
Wimファイルのインデックスを確認

Dism /Get-WIMInfo /WimFile:c:\win10\install.wim

適用したいエディションのインデックスを確認します。以下1に対して適用するものとします。

  • Dism /Mount-Image /ImageFile:C:\win10\install.wim /index:1 /MountDir:C:\win10\Mount
  • Packageを追加(msu ファイル)
    DISM /image:C:\win10\Mount /Add-Package /PackagePath:(path)\xxx.msu
  • Packageを削除
    Dism /image:C:\win10\Mount /Remove-Package /PackageName:xxx
変更を適用(コミット)
  • Dism /Commit-Image /MountDir:C:\win10\Mount
アンマウント(解除)
  • Dism /Unmount-Image /MountDir:C:\win10\Mount /commit

ESDファイル

[例]C:\win10\install.esd ファイルを C:\win10\Mount にマウント
Esdファイルのインデックスを確認

Dism /Get-WIMInfo /WimFile:c:\win10\install.esd

適用したいエディションのインデックスを確認します。以下1に対して適用するものとします。

  • Dism /Apply-Image /ImageFile:C:\win10\install.esd /index:1 /MountDir:C:\win10\Mount
イメージをキャプチャ
  • Dism /Capture-Image /ImageFile:c:\win10\install.wim /CaptureDir:c:\win10\Mount /Name:"Windows 10"

Packageの追加、削除、コミット、アンマウントは上記Wimファイルと同様です。

WimファイルからEsdファイルを作成
  • Dism /Export-Image /SourceImageFile:c:\win10\install.wim /SourceIndex:1 /DestinationImageFile:c:\win10\install.esd /DestinationName:"Windows 10" /Compress:recovery

パフォーマンスカウンタのエラー

パフォーマンスカウンタを起動するとエラーが発生します

イベントビュアーで参照したときに、”Windows ログ”に対して次のようなイベントが書き込まれます

  • イベント 3001, LoadPerf
    レジストリのパフォーマンス カウンタ名文字列の値が正しくフォーマットされていません。問題の文字列は n です。この文字列に対するインデックス値は、データ セクションの最初の DWORD に含まれ、最後の有効なインデックス値は、データ セクションの n 番目と n+1 番目の DWORD に含まれています。
  • イベント 3006, Search
    カウンタが読み込まれていないか、共有メモリ オブジェクトを開けなかったため、パフォーマンス モニタを初期化できませんでした。これによって影響されるのは、パフォーマンス モニタのカウンタの使用可能性のみです。コンピュータを再起動してください。
  • イベント 3006, Search
    カウンタが読み込まれていないか、共有メモリ オブジェクトを開けなかったため、Gatherer オブジェクトのパフォーマンス モニタを初期化できませんでした。これによって影響されるのは、パフォーマンス モニタのカウンタの使用可能性のみです。コンピュータを再起動してください。コンテキスト: アプリケーション、 SystemIndex カタログ
  • イベント 10021, Search
    WSearchIdxPi のインスタンス のパフォーマンス カウンタ レジストリを取得できませんでした。次のエラーが発生しました: この操作を正しく終了しました。 0x0。
  • イベント 8317, MSSQL$SQLEXPRESSレジストリ キー ‘HKLM\SYSTEM\CurrentControlSet\Services\MSSQL$SQLEXPRESS\Performance’ に関連付けられている値 ‘First Counter’ をクエリできません。SQL Server パフォーマンス カウンタが無効です。
  • イベント 3009, LoadPerf
    サービス .NETFramework () のパフォーマンス カウンターの文字列をインストールできませんでした。エラー コードがデータ セクションの最初の DWORD に含まれています。
  • イベント 2007, LoadPerf
    .NETFramework サービスのパフォーマンス カウンターを修復できません。LODCTR ツールを使用してパフォーマンス カウンターを手動で再インストールしてください。

イベント 3001, LoadPerf について n は1846の場合が多いようです。

イベント 3009, LoadPerf のサービスについて .NET CLR Data, .NET CLR Networking, .NET Data Provider for Oracle, .NET Data Provider for SqlServer, aspnet_state, Remote Access, UGHTRSVC, usbhub, WSearch, WSearchIdxPi, WSService においても同様のメッセージが書き込まれることがあります。

  • イベント 2001, usbperf
    usbperf\Performance キーの “First Counter” 値を読み取れません。ステータス コードはデータで戻されました。
  • イベント 1008, perflib
    サービス “RemoteAccess” (DLL “C:\Windows\System32\rasctrs.dll”) の Open プロシージャに失敗しました。このサービスのパフォーマンス データは利用できません。データ セクションの最初の 4 バイト (DWORD) に、エラー コードが含まれています。
  • イベント 2001, perflib
    サービス “W3SVC” (DLL “C:\WINDOWS\system32\inetsrv\w3ctrs.dll”) の Open プロシージャに失敗しました。このサービスのパフォーマンス データは利用できません。データ セクションの最初の 4 バイト (DWORD) に、エラー コードが含まれています。
  • イベント 2002, IIS-W3SVC-PerfCounters
    Web サービス カウンターの設定に失敗しました。Web サービス カウンターが正しく登録されていません。

イベント 1008, perflib に関しては、ほかに aspnet_state, ASP.NET_4.0.30319, ASP.NET, .NETFramework も同様のエラーが発生する場合があります。

  • lodctr /R を実行すると エラー 2 が発生します。
  • lodctr /R を実行すると 「パフォーマンス カウンターの設定をシステムのバックアップストアから再構築できませんでした。エラーコードは 5 です。」と表示される。エラー 80078005 が発生します。
  • perfmon /report でエラー:レポートを作成する際に、エラーが発生します。
    アクセスが拒否されました。
  • Windows 8.1 で perfmon /report を実行すると「レポートを作成しようとしてエラーが発生しました。 オペレーターまたは管理者が要求を拒否しました。」 The operator or administrator has refused the request.
    この件については Event 513, CAPI2 の記事を参照してください。

  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\(Service name)\Performance に First Counter, First Help, Last Counter, Last Help の値が存在しない、または正しく設定されていない場合に発生します。
  • %SystemRoot%\Inf\.NET CLR Data, WmiApRpl などのフォルダーに iniファイルが含まれていない場合に発生します(特にイベント 3009, LoadPerf)。

修復の手順

1. iniファイルのコピー

対応するサービス(%SystemRoot%\Inf のサブフォルダー名)

  • .NET CLR Data
  • .NET CLR Networking
  • .NET CLR Networking 4.0.0.0
  • .NET Data Provider for Oracle
  • .NET Data Provider for SqlServer
  • .NET Memory Cache 4.0
  • .NETFramework
  • ASP.NET
  • ASP.NET State
  • ASP.NET_2.0.50727 (.ini)
  • ASP.NET_4.0.30319
  • ASP.NET_64_2.0.50727 (.ini)
  • aspnet_state
  • BITS (.ini)
  • ESENT (.ini)
  • MSDTC (.ini)
  • MSDTC Bridge 3.0.0.0
  • MSDTC Bridge 4.0.0.0
  • rdyboost (.ini)
  • RemoteAccess (.ini)
  • ServiceModelEndpoint 3.0.0.0
  • ServiceModelOperation 3.0.0.0
  • ServiceModelService 3.0.0.0
  • SMSvcHost 3.0.0.0
  • SMSvcHost 4.0.0.0
  • TAPISRV (.ini)
  • TermService
  • UGatherer (.ini)
  • UGTHRSVC (.ini)
  • usbhub (.ini)
  • Windows Workflow Foundation 3.0.0.0
  • Windows Workflow Foundation 4.0.0.0
  • WmiApRpl (.ini)
  • wsearchidxpi (.ini)

%SystemRoot%\Inf\(ServiceName) フォルダー内のiniファイルの末尾が _d.ini のファイルは 親フォルダーの ini ファイルを参照しています。ほとんどの場合 サイズが 1KByte 以下です。そしてファイルの日時が異なりますが同じ内容となっています。_d.iniファイルが存在しない場合、0409, 0411等のフォルダーのiniファイルに記述があります。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\(name)\PerformanceキーのPerfInFileにパフォーマンスカウンタに使用する.iniファイル名の記載があります。

インストールディスク、または %SystemRoot%\Winsxs のサブフォルダーから該当するファイルをコピーします。この際、下記の通りインストールしている言語パックに対応するフォルダーのみコピーを行います。コピーを行ったファイルに対してcaclsを利用してアクセス権を設定しなおします。ASP.NET_2.0.50727,  ASP.NET_64_2.0.50727, MSDTC Bridge 3.0.0.0, ServiceModelEndpoint 3.0.0.0, ServiceModelOperation 3.0.0.0, ServiceModelService 3.0.0.0, SMSvcHost 3.0.0.0, Windows Workflow Foundation 3.0.0.0 に存在するファイルに対しては行う必要はありません。

[例]
xcopy %SystemRoot%\WinSxS\amd64_netfx4-_dataperfcounters_ini_b03f5f7f11d50a3a_4.0.15522.0_none_69a84f70710ce8f7\_DataPerfCounters_d.ini %SystemRoot%\Inf\.NET CLR Data

アクセス権を変更します。

cacls (file) /S: "D:PAI(A;;FA;;;S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464)(A;;0x1200a9;;;BA)(A;;0x1200a9;;;SY)(A;;0x1200a9;;;BU)(A;;0x1200a9;;;AC)(A;;0x1200a9;;;S-1-15-2-2)" を実行してアクセス権を修正します。

_none は 0000, _en-us は 0409 or 0009, _ja-jp は 0411 or 0011 の対応となります。

  • 000=Neutral
  • 001=Arabic
  • 005=Czech
  • 006=Danish
  • 007=German
  • 008=Greek
  • 009=English
  • 00A=Spanish
  • 00B=Finnish
  • 00C=French
  • 00D=Hebrew
  • 00E=Hungarian
  • 010=Italian
  • 011=Japanese
  • 012=Korean
  • 013=Dutch
  • 014=Norwegian
  • 015=Polish
  • 019=Russian
  • 01D=Swedish
  • 01F=Turkish
  • 804=Chinese (PRC)
  • 404=Chinese (Taiwan)
  • 416=Portuguese (Brazil)
  • 816=Portuguese (Portugal)

ロケール ID (LCID) の一覧

フォルダーの中に ファイルが存在しない、空のフォルダーが存在すると lodctr /R を実行したときに First Counter, First Help, Last Counter, Last Help の値が正しく設定されず消去されてしまいます。空のフォルダーを削除してから実行してください。使用している言語以外の対応するフォルダーを削除します。

2. First Counter, First Help, Last Counter, Last Helpの追加

regedit.exeを開いて次のレジストリーキーを参照します。HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\(name)\Performance を参照します。

(例)

  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UGatherer\Performance
  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WmiApRpl\Performance
  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\usbhub\Performance

First Counter, First Help, Last Counter, Last Help (REG_DWORD) を追加します。値は 0 で問題ありません。

lodctr /R を コマンドプロンプトから実行します。「情報: パフォーマンス カウンタの設定をシステムのバックアップ ストアから正常に再構築しました」が表示されます。HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\(name)\Performance のFirst Counter, First Help, Last Counter, Last Help の値が正しく設定されているか確認します。

Dism /Online /Cleanup-Image /RestoreHealth を実行します。
sfc /scannow を実行します。


依然としてエラーが発生する場合は パフォーマンスカウンタのエラー(setokynet.wordpress.com) の記事を参照してください。


このエラーによるシステムへの影響

正しく構成されていないと システムが不安定になったり、OSの動作が遅くなったりします。単にパフォーマンスカウンタのエラーだけでなく、Windows Update でシステムファイルが更新されないなどの不具合につながるおそれがあります。