Objective C用于Unity的iOS插件

Cre*_*gic 4 c# xcode objective-c unity-game-engine ios

我在使用我制作的Objective C插件在Xcode中构建Unity3d项目(在设备上测试)时遇到了问题.
这是文件:

TestPlugin.h文件中:

#import <Foundation/Foundation.h>

@interface TestPlugin : NSObject

+(int)getGoodNumber;
@end
Run Code Online (Sandbox Code Playgroud)

TestPlugin.m文件中:

#import "TestPlugin.h"

@implementation TestPlugin

+(int)getGoodNumber
{
    return 1111111;
}

@end
Run Code Online (Sandbox Code Playgroud)

最后是团结的C#脚本,它应该打印出getGoodNumber()返回的值:

using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;

public class PluginTest : MonoBehaviour
{
    [DllImport ("__Internal")]
    public static extern int getGoodNumber();

    void OnGUI()
    {
        string goodNum = getGoodNumber().ToString();
        GUILayout.Label (goodNum);
    }

}
Run Code Online (Sandbox Code Playgroud)

我可以告诉我,代码不应该有任何问题.但即使我遵循了许多不同的教程,当我尝试编译时,我在Xcode中得到一个错误:

Undefined symbols for architecture armv7:
  "_getGoodNumber", referenced from:
      RegisterMonoModules() in RegisterMonoModules.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)

我尝试了一百万种不同的东西,似乎没有任何帮助.尽管我可以从其他教程中读到,但我不需要对Xcode进行任何特殊设置,我可以将它们保留为没有插件的Unity项目.

我还想澄清一些事情:

  • 插件文件位于/Plugins/iOS/Unity3d的文件夹中
  • 构建目标是具有最新iOS的iPad Air 2,因此不会出现任何问题.还在最新的OS X版本上使用最新的Xcode.
  • 我有最新版本的Unity3d,如果这很重要 - 我确实有Unity版本的Unity3d.
  • 如果插件被删除,该项目是有效的,因此Unity3d和Xcode之间不存在问题.
  • 我不认为我需要extern "C"在Objective-C代码中使用包装器,因为它是一个" .m"文件,而不是" .mm",所以不应该存在名称错误的问题.
  • 该插件是通过"Cocoa Touch Static Library"模板在Xcode中创建的.在将其导入Unity3d之前,我能够成功构建Xcode项目.

如果有人遇到了解决它的问题,我很乐意听到解决方案.

pet*_*ept 7

你已经编写了一个"objective-c"类和方法,但是不能向Unity公开.您需要创建一个"c"方法(如果需要,可以调用objective-c方法).

例如:

plugin.m:

long getGoodNumber() {
  return 111;
}
Run Code Online (Sandbox Code Playgroud)

这是一个更全面的例子,演示了获得陀螺仪的参数.

让我们做一个运动经理来获得陀螺(暂时伪造).这将是标准目标-c:

MyMotionManager.h

@interface MyMotionManager : NSObject { }

+(MyMotionManager*) sharedManager;
-(void) getGyroXYZ:(float[])xyz;

@end
Run Code Online (Sandbox Code Playgroud)

MyMotionManager.m:

@implementation MyMotionManager

+ (MyMotionManager*)sharedManager
{
    static MyMotionManager *sharedManager = nil;
    if( !sharedManager )
        sharedManager = [[MyMotionManager alloc] init];
    return sharedManager;
}

- (void) getGyroXYZ:(float[])xyz
{
    // fake
    xyz[0] = 0.5f;
    xyz[1] = 0.5f;
    xyz[2] = 0.5f;
}

@end
Run Code Online (Sandbox Code Playgroud)

现在让我们通过C外部引用公开它(不需要extern,因为它在.m(不是.mm)中:

MyMotionManagerExterns.m:

#import "MyMotionManager.h"

void GetGyroXYZ(float xyz[])
{
    [[MyMotionManager sharedManager] getGyroXYZ:xyz];
}
Run Code Online (Sandbox Code Playgroud)

最后,在Unity C#中调用它:

MotionPlugin.cs:

using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;

public class MotionPlugin 
{
    [DllImport("__Internal")]
    private static extern void GetGyroXYZ(float[] xyz);

    public static Vector3 GetGyro()
    {
        float [] xyz = {0, 0, 0};
            GetGyroXYZ(xyz);
            return new Vector3(xyz[0], xyz[1], xyz[2]);
    }
}
Run Code Online (Sandbox Code Playgroud)