ImageMagick なる外部ライブラリーがありこれを使おうかと色々調べたがあまりAndroid C#で利用している情報が見つからず結果断念。

https://github.com/MolotovCherry/Android-ImageMagick7

 

代わりに ImageSharp を利用することに

Visual Stuido の NuGet より、SixLabors.ImageSharp を選択して、Version 1.0.4 を指定してダウンロード

(最新だと、netstandard2.0  をサポートしていない?)

Package より netstandard2.0 フォルダーより以下のファイルをAssets/Plugins に保存

SixLabors.ImageSharp.dll
System.Numerics.Vectors.dll
System.Buffers.dll
System.Runtime.CompilerServices.Unsafe.dll
System.Memory.dll
System.Text.Encoding.CodePages.dll

あとは、Android でビルド

以下が画像を変換するコード(楽ちん)

  // 色々な画像をPNGに変換 
    public static byte[] ConvertToPNG(byte[] imageData)
    {
        using (var image = SixLabors.ImageSharp.Image.Load(imageData)) {
            using (var outputStream = new MemoryStream()) {
                image.Save(outputStream, new PngEncoder());
                return outputStream.ToArray();
            }
        }
    }

iOS でももちろん動作します。

The app references non-public selectors in Payload/*.app/Frameworks/UnityFramework.framework/UnityFramework: applicationWillFinishLaunchingWithOptions:, didReceiveRemoteNotification:

App ストアにアップすると謎エラー

 

ググると、Xcode のバグではないかと…

対処方法は、メソッド名を変更

didReceiveRemoteNotification -> didReceiveRemoteNotificationToUnity

applicationWillFinishLaunchingWithOptions も applicationWillFinishLaunchingWithOptionsToUnity に名前変更

 

Unity ver2020.3.38f1

xcode ver14.0.1

mac ver 12.6

 

一旦、エラーが消えてUP出来ていたが再度、謎エラー

The app references non-public selectors in Payload/*.app/Frameworks/UnityFramework.framework/UnityFramework: loadPlugink

最終的に、 xcode ver13.4.1  にDowngradeして無事アップ成功

Quickstart for Google Cardboard for Unity

https://developers.google.com/cardboard/develop/unity/quickstart

Unity ver.2020.3.38

Mac ver.12.6

Xcode ver.14.0.1

Google Cardboard のデモを iOS 用にビルドしたら以下のエラー

Showing Recent Messages
Undefined symbol: google::protobuf::MessageLite::ParseFromArray(void const*, int)
Undefined symbol: google::protobuf::RepeatedField<float>::InternalSwap(google::protobuf::RepeatedField<float>*)
Undefined symbol: google::protobuf::RepeatedField<float>::Add(float const&)
Undefined symbol: google::protobuf::RepeatedField<float>::Clear()
Undefined symbol: google::protobuf::RepeatedField<float>::MergeFrom(google::protobuf::RepeatedField<float> const&)
Undefined symbol: google::protobuf::RepeatedField<float>::RepeatedField(google::protobuf::Arena*)
Undefined symbol: google::protobuf::RepeatedField<float>::RepeatedField(google::protobuf::RepeatedField<float> const&)
Undefined symbol: google::protobuf::RepeatedField<float>::~RepeatedField()
Undefined symbol: google::protobuf::stringpiece_internal::StringPiece::LogFatalSizeTooBig(unsigned long, char const*)
Undefined symbol: google::protobuf::io::EpsCopyOutputStream::WriteRawFallback(void const*, int, unsigned char*)
Undefined symbol: google::protobuf::io::EpsCopyOutputStream::EnsureSpaceFallback(unsigned char*)
Undefined symbol: google::protobuf::io::EpsCopyOutputStream::WriteStringMaybeAliasedOutline(unsigned int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned char*)
Undefined symbol: google::protobuf::Arena::AllocateAlignedWithHook(unsigned long, std::type_info const*)
Undefined symbol: google::protobuf::Arena::AllocateAlignedWithCleanup(unsigned long, std::type_info const*)
Undefined symbol: google::protobuf::internal::LogMessage::LogMessage(google::protobuf::LogLevel, char const*, int)
Undefined symbol: google::protobuf::internal::LogMessage::~LogMessage()
Undefined symbol: google::protobuf::internal::LogMessage::operator<<(char const*)
Undefined symbol: google::protobuf::internal::LogFinisher::operator=(google::protobuf::internal::LogMessage&)
Undefined symbol: google::protobuf::internal::WriteVarint(unsigned int, unsigned long long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
Undefined symbol: google::protobuf::internal::ArenaStringPtr::DestroyNoArenaSlowPath()
Undefined symbol: google::protobuf::internal::ArenaStringPtr::Set(google::protobuf::internal::ArenaStringPtr::EmptyDefault, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, google::protobuf::Arena*)
Undefined symbol: google::protobuf::internal::ArenaStringPtr::Mutable(google::protobuf::internal::ArenaStringPtr::EmptyDefault, google::protobuf::Arena*)
Undefined symbol: google::protobuf::internal::LookUpEnumName(google::protobuf::internal::EnumEntry const*, int const*, unsigned long, int)
Undefined symbol: google::protobuf::internal::LookUpEnumValue(google::protobuf::internal::EnumEntry const*, unsigned long, google::protobuf::stringpiece_internal::StringPiece, int*)
Undefined symbol: google::protobuf::internal::ReadTagFallback(char const*, unsigned int)
Undefined symbol: google::protobuf::internal::ThreadSafeArena::~ThreadSafeArena()
Undefined symbol: void google::protobuf::internal::InternalMetadata::DoMergeFrom<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Undefined symbol: void google::protobuf::internal::InternalMetadata::DoClear<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >()
Undefined symbol: google::protobuf::internal::PackedFloatParser(void*, char const*, google::protobuf::internal::ParseContext*)
Undefined symbol: google::protobuf::internal::UnknownFieldParse(unsigned int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, char const*, google::protobuf::internal::ParseContext*)
Undefined symbol: google::protobuf::internal::VarintParseSlow64(char const*, unsigned int)
Undefined symbol: google::protobuf::internal::EpsCopyInputStream::DoneFallback(int, int)
Undefined symbol: google::protobuf::internal::InitializeEnumStrings(google::protobuf::internal::EnumEntry const*, int const*, unsigned long, google::protobuf::internal::ExplicitlyConstructed<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >*)
Undefined symbol: google::protobuf::internal::InitProtobufDefaultsSlow()
Undefined symbol: google::protobuf::internal::InlineGreedyStringParser(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, char const*, google::protobuf::internal::ParseContext*)
Undefined symbol: google::protobuf::internal::fixed_address_empty_string
Undefined symbol: google::protobuf::internal::init_protobuf_defaults_state
Undefined symbol: google::protobuf::MessageLite::InitializationErrorString() const
Undefined symbol: google::protobuf::RepeatedField<float>::Get(int) const
Undefined symbol: google::protobuf::RepeatedField<float>::data() const
Undefined symbol: google::protobuf::RepeatedField<float>::size() const
Undefined symbol: typeinfo for google::protobuf::MessageLite
Undefined symbol: vtable for google::protobuf::MessageLite

google::protobuf が見つからない

対応としては、iOS 用のビルドフォルダに移動

pod init
pod install

podfile を以下に変更

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'Unity-iPhone' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for Unity-iPhone

  target 'Unity-iPhone Tests' do
    inherit! :search_paths
    # Pods for testing
  end

end

target 'UnityFramework' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!
  # add
  pod 'Protobuf-C++', '3.18.0'

  # Pods for UnityFramework

end

# add
post_install do |installer|
  installer.pods_project.targets.each do |target|
    # print "target=", target, "\n"
    if target.name == "Protobuf-C++"
      target.build_configurations.each do |config|
        config.build_settings['HEADER_SEARCH_PATHS'] = '$(SRCROOT)/Protobuf-C++/src'
      end
    end
  end
end

xcworkspace が作成されるので以下のコマンドで open

pod update
open Unity-iPhone.xcworkspace

あとは、署名してビルド

 

https://developers.google.com/cardboard/develop/unity/quickstart

 

Unity ver.2020.3.38

Mac ver.12.6

Android Sdk ver.30

 

Google Cardboard  のデモをAndroid 用にビルドしたら以下のエラー

> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
> Android resource linking failed
/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:3:5-94: AAPT: error: resource android:color/system_neutral1_1000 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:4:5-94: AAPT: error: resource android:color/system_neutral1_900 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:5:5-93: AAPT: error: resource android:color/system_neutral1_0 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:6:5-94: AAPT: error: resource android:color/system_neutral1_800 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:7:5-94: AAPT: error: resource android:color/system_neutral1_700 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:8:5-94: AAPT: error: resource android:color/system_neutral1_600 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:9:5-94: AAPT: error: resource android:color/system_neutral1_500 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:10:5-94: AAPT: error: resource android:color/system_neutral1_400 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:11:5-94: AAPT: error: resource android:color/system_neutral1_300 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:12:5-94: AAPT: error: resource android:color/system_neutral1_200 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:13:5-94: AAPT: error: resource android:color/system_neutral1_100 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:14:5-93: AAPT: error: resource android:color/system_neutral1_50 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:15:5-93: AAPT: error: resource android:color/system_neutral1_10 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:16:5-102: AAPT: error: resource android:color/system_neutral2_1000 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:17:5-102: AAPT: error: resource android:color/system_neutral2_900 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:18:5-101: AAPT: error: resource android:color/system_neutral2_0 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:19:5-102: AAPT: error: resource android:color/system_neutral2_800 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:20:5-102: AAPT: error: resource android:color/system_neutral2_700 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:21:5-102: AAPT: error: resource android:color/system_neutral2_600 not found.

/Users/falco/.gradle/caches/transforms-2/files-2.1/a0ebba694f8e6a95bc427eaef4894530/material-1.6.1/res/values-v31/values-v31.xml:22:5-102: AAPT: error: resource android:color/system_neutral2_500 not found.

リソースが見つからない…

 

対応としては、ライブラリーをダウングレード

// implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.gms:play-services-vision:20.1.3'
// implementation 'com.google.android.material:material:1.6.1'
implementation 'com.google.protobuf:protobuf-javalite:3.19.4'

implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'

これでビルド出来た。

development build を on にする

上記の設定で adb shell の run-as package-name が使えるようになる。

 

Unity の Android Plugin を Java で作成

Kotlin に移植したら以下のエラー

03-27 16:34:55.789  3261  3261 W Unity   : Native libraries not loaded - dropping message for ScriptObject.OnLoadImageFromFolder

class MainActivity : Activity() {

class MainActivity : UnityPlayerActivity() {

継承もとのクラスが間違ってた…

ゲームパットの動作の検証用に新しく購入。

Android や、Windows、Mac 対応なので、Android アプリのジョイステック機能を PC 上のジョイステックでデバックをするのが目的

かなり接続に苦戦!

Macの接続は、A + Start ボタンを押して、LEDが点滅したらSELECTボタンを3秒

認識は、DUALSHOCK4 Wireless Controller ?

はじめに説明書を適当に読んで接続したら Pro Controller と認識してジョイスティック機能が使えなかった。

何度か使ってると認識は、8BitDo Zero 2 gamepad になりました。

Android の接続は、B+Start ボタンを押して、LEDが点滅したらSELECTボタンを3秒

認識は、8BitDo Zero 2 gamepad

取り敢えず無事認識して使えました。

これで Android アプリのジョイステックのデバックが捗りそう。

原因としては、Active(true) と Active(false) を繰り返すとVirtual Joystick が使えなくなる

There is already a virtual axis named Horizontal1 registered.
UnityEngine.Debug:LogError(Object)
UnityStandardAssets.CrossPlatformInput.VirtualInput:RegisterVirtualAxis(VirtualAxis) (at Assets/Standard Assets/CrossPlatformInput/Scripts/VirtualInput.cs:39)
UnityStandardAssets.CrossPlatformInput.CrossPlatformInputManager:RegisterVirtualAxis(VirtualAxis) (at Assets/Standard Assets/CrossPlatformInput/Scripts/CrossPlatformInputManager.cs:59)
UnityStandardAssets.CrossPlatformInput.Joystick:CreateVirtualAxes() (at Assets/Standard Assets/CrossPlatformInput/Scripts/Joystick.cs:64)
UnityStandardAssets.CrossPlatformInput.Joystick:OnEnable() (at Assets/Standard Assets/CrossPlatformInput/Scripts/Joystick.cs:30)
UnityEngine.GameObject:SetActive(Boolean)
MainControl:onClickVr() (at Assets/_main/MainControl.cs:353)
UnityEngine.EventSystems.EventSystem:Update() (at /Applications/Unity/Hub/Editor/2019.4.20f1/Unity.app/Contents/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/EventSystem.cs:377)

とりあえずの対処

        public void RegisterVirtualAxis(CrossPlatformInputManager.VirtualAxis axis)
        {
            // Modified By M.Hotaka
            // check if we already have an axis with that name and log and error if we do
            if (m_VirtualAxes.ContainsKey(axis.name))
            {
                Debug.Log("There is already a virtual axis named " + axis.name + " registered.");
                UnRegisterVirtualAxis(axis.name);
            }
            // else
            {
                // add any new axes
                m_VirtualAxes.Add(axis.name, axis);

                // if we dont want to match with the input manager setting then revert to always using virtual
                if (!axis.matchWithInputManager)
                {
                    m_AlwaysUseVirtual.Add(axis.name);
                }
            }
        }

300円位のジョイスティック mocute-032 を購入したが、実際のボタンの値が分からず確認の為のスクリプトを作成
おそらく、汎用的に確認できます。

この値段で充電式は、驚き!

モードはゲームモードでAndroid 

void Update()
    {
        UpdateGetKey();
        // UpdateKey();
    }    

void UpdateGetKey()
    {
        float horizontal = Input.GetAxis("Horizontal");     // joystick horizontal
        float vertical = Input.GetAxis("Vertical");      // joystick vertical

        Debug.Log("x y:" + horizontal + "," + vertical);
        foreach (KeyCode value in Enum.GetValues(typeof(KeyCode)))
        {
            if (Input.GetKey(value))
            {
                String name = Enum.GetName(typeof(KeyCode), value);
                Debug.Log("Input.GetKey:" + name);
            }
            if (Input.GetKeyDown(value))
            {
                String name = Enum.GetName(typeof(KeyCode), value);
                Debug.Log("Input.GetKeyDown:" + name);
            }
            if (Input.GetKeyUp(value))
            {
                String name = Enum.GetName(typeof(KeyCode), value);
                Debug.Log("Input.GetKeyUp:" + name);
            }
        }
    }
adb logcat | grep Joy

02-24 13:42:55.463  1346  1358 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 
02-24 13:45:54.033  2993  3016 I Unity   : Input.GetKey:JoystickButton2 
02-24 13:45:54.033  2993  3016 I Unity   : Input.GetKeyDown:JoystickButton2 
02-24 13:45:54.033  2993  3016 I Unity   : Input.GetKey:Joystick1Button2 
02-24 13:45:54.033  2993  3016 I Unity   : Input.GetKeyDown:Joystick1Button2 
02-24 13:45:54.051  2993  3016 I Unity   : Input.GetKeyUp:JoystickButton2 
02-24 13:45:54.051  2993  3016 I Unity   : Input.GetKeyUp:Joystick1Button2 

02-24 13:45:55.333  2993  3016 I Unity   : Input.GetKey:JoystickButton0 
02-24 13:45:55.333  2993  3016 I Unity   : Input.GetKey:Joystick1Button0 
02-24 13:45:55.352  2993  3016 I Unity   : Input.GetKey:JoystickButton0 
02-24 13:45:55.352  2993  3016 I Unity   : Input.GetKey:Joystick1Button0 
02-24 13:45:55.367  2993  3016 I Unity   : Input.GetKey:JoystickButton0 
02-24 13:45:55.367  2993  3016 I Unity   : Input.GetKey:Joystick1Button0 
02-24 13:45:55.383  2993  3016 I Unity   : Input.GetKey:JoystickButton0 
02-24 13:45:55.383  2993  3016 I Unity   : Input.GetKey:Joystick1Button0 
02-24 13:45:55.402  2993  3016 I Unity   : Input.GetKeyUp:JoystickButton0 

 

null で更新

    public void updateScore(int id, ExeMode method, int? score) {
        string item = CommonDao.GetScoreItemName(method);
        // How to string format
        string sql = $"UPDATE LessonTable SET {item} ={(score == null ? "null" : score.ToString())} WHERE ID ={id}";

        dbManager.Execute(sql);
    }
© 2023 Falco Tech Blog Suffusion theme by Sayontan Sinha