安卓:
一、准备jar包,供Unity使用

Unity和Android交互,这个jar包就是一个中间商,也就是说,我们获取相册里的相片路径,并告知Unity这个路径,这一部分功能在安卓端实现

(1)androidstudio新建工程,这一系列没有什么好说的,新建一个空工程,值得注意是下图圈起来的两个地方,packagename==>这个必须要和你的Unity工程的包名一样,

不然打出来的包安装完成后会闪退的,还有就是最低支持的API等级,这个也必须和Unity里面的buildsetting里面的对应

Unity ios 图集 unity相册_jar

(2)接下来在MainAcitivy里面复制我下面的代码,这里要注意在复制代码的时候,第一行是包名,这里被我删了,因为每个人包名都不一样,包名需要保留,不能没有

之后你会发现TakePhoto是灰色的,不用管它,这个Unity调用android的入口,这个函数名要是改了话,Unity的C#代码也需要改对应的,不然调不到

然后你还会发现WebViewActivity和UnityPlayerActivity报错,先别慌,稳住,看下一步!

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.unity3d.player.UnityPlayerActivity;

public class MainActivity extends UnityPlayerActivity{
    private static String LOG_TAG = "LOG_My";
    Context mContext = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;
    }

    //Unity中会调用这个方法,用于打开本地相册
    public void TakePhoto(String str)
    {
        Log.d(LOG_TAG,str);
        Intent intent = new Intent(mContext,WebViewActivity.class);
        this.startActivity(intent);
    }

}

(3)导入Unity的classes.jar

先说这个文件在哪,在你所使用的Unity的安装目录里面,这里需要注意呀,不是什么版本的Unity的这个classes.jar都能用的,必须是你Unity工程所使用的版本的安装目录

Unity ios 图集 unity相册_Unity ios 图集_02


将这个jar包赋值一份,并拷贝到刚才新建的Android项目的app\libs文件夹里点击左上角的Android图片,切换到project视图就能找到这个文件夹

Unity ios 图集 unity相册_java_03


然后右键这个classes.jar,选择add as library,会弹出一个框,确定是给app添加的就行,确定后等待编译一会,UnityPlayerActivity就会正常了,这是因为Android需要和Unity通信,就必须得调用Unity的类才行

(4)创建WebViewActivity类,切换回Android视图找到我们的MainActivty,这个都会在app\java\第一个包名的文件夹下

然后右键,new一个javaclass,命名就是WebViewActivity,创建的时候什么都不用管,都是默认就行

Unity ios 图集 unity相册_android_04


然后你就会看到什么报错都没了,接下来把下面的代码复制到WebViewActivity,这里还是一样不能自己的包名给粘贴调哈

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.KeyEvent;

import com.unity3d.player.UnityPlayer;

import java.io.IOException;


public class WebViewActivity extends Activity
{
    public static final int NONE = 0;

    public static final int PHOTORESOULT = 3;

    public static final String IMAGE_UNSPECIFIED = "image/*";



    private String LOG_TAG = "LOG_ZDQ";
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        Intent intent = new Intent(Intent.ACTION_PICK, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_UNSPECIFIED);
        startActivityForResult(intent, PHOTORESOULT);
        Log.d(LOG_TAG, "打开相册!");
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(LOG_TAG, "resultCode :" + resultCode);
        if (resultCode == NONE)
            return;

        if (data == null)
            return;

        
        ContentResolver resolver = getContentResolver();
        Bitmap bm=null;
        
        Uri originalUri = data.getData();
        try {
            bm = MediaStore.Images.Media.getBitmap(resolver, originalUri);
        } catch (IOException e) {
            e.printStackTrace();
        }


        String[] proj = {MediaStore.Images.Media.DATA};

        65         
        Cursor cursor= getContentResolver().query(originalUri,proj,null,null,null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
70         cursor.moveToFirst();
72         String _path = cursor.getString(column_index);

        UnityPlayer.UnitySendMessage("Main Camera", "GetPhoto", _path);
        super.onActivityResult(requestCode, resultCode, data);
78         this.finish();
    }
}

这里需要注意的地方

Unity ios 图集 unity相册_android_05


这是调用Unity的main camera 上的脚本里的Getphoto方法,path是传递过去的参数

unity里面需要在什么地方加这个功能,以及脚本挂载什么对象身上,这些都要先考虑好之后才能打这个jar包,到这里第一阶段Android的功能已经写完了,接下来就是打包了,坑较多,一定要注意了

(5)准备打jar包,新建module file - new - new module - Android Library - next 这里的packagename和最小版本sdk也要设置一下和上面的一样

然后之前写的两个脚本复制到你新建的module的同样的位置,然后切换到project视图,将app\libs里面的classes.jar也复制到new module的libs里面,然后一样的add as library,一样的注意跟Unity一样的包名

Unity ios 图集 unity相册_Unity ios 图集_06


(6)编辑new module的Androidmanifest.xml,复制一下代码粘贴就行,注意包名是自己的,在这里加相册权限,包名和unity的不一样的话,到时候unity打出来apk会闪退

之后打完包之后 这个xml文件需要和打出来的jar包一起放到Unity工程里面的

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.NXNC.Farm" >
    <!--读取相册权限 (必须)-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <application   >
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".WebViewActivity">
        </activity>
    </application>

</manifest>

(7)在build.gradle中加上一下代码,这里注意,这个build.gradle是你新建module的build.gradle

task makejar(type: Copy){

    delete 'libs/test.jar'

    from('build/intermediates/packaged-classes/release/')

    into('libs')

    include('classes.jar')

    rename('classes.jar','FarmGetAndroidPhoto.jar')
}

makejar.dependsOn(build)

这里的坑就是from,有不同的位置,但是基本都是这个目录,如果你最后发现你打包成功之后,却发现没有包,就是这个地方错了

(8)打jar包,这里也是坑最多的地方,网上的解决方法也是五花八门

打包之前建议:

先在Androidstudio的安装目录的bin文件夹下找到studio.exe.vmoptions或者studio64.exe.vmoptions,看你是32位还是64的,就编辑哪个,按如下编辑

Unity ios 图集 unity相册_java_07


gradle.properties注释掉org.gradle.jvmrgs这句话,也许值会不一样,反正注释掉就行

Unity ios 图集 unity相册_Unity ios 图集_08


然后就可以打包了

在Terminal里面输入命令 gradlew makejar 等一会就会提示build successful 这就是包打好了

左上角切换回project视图,在新建module的libs里面就会有新的jar,这个就是我们需要的

最后我们需要的两个东西 就是这个打出来jar和new module的AndroidManifest文件,复制到Unity里面

二、Unity调用

(1)unity工程asset文件下新建文件夹plugins-Android,然后AndroidManifest和jar包放入就行

奉上demo脚本

using UnityEngine;
using System.IO;
using UnityEngine.UI;

public class GetAndroidPhoto : MonoBehaviour
{
    public Button button;
    public RawImage rawImage;

    void Start ()
    {
        button.onClick.AddListener(OpenLibery);
    }

    private void OpenLibery()
    {
        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
        jo.Call("TakePhoto", Application.persistentDataPath);
    }

    public void GetPhoto(string path)
    {
        Debug.Log("android give path ==> " + path);
        FileGetTex(path);
    }

    private void FileGetTex(string path)
    {
        FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
        fileStream.Seek(0, SeekOrigin.Begin);
        byte[] bye = new byte[fileStream.Length];
        fileStream.Read(bye, 0, bye.Length);
        fileStream.Close();

        Texture2D texture2D = new Texture2D((int)rawImage.rectTransform.rect.width, (int)rawImage.rectTransform.rect.height);
        texture2D.LoadImage(bye);
        rawImage.texture = texture2D;
    }
}

TakePhoto、GetPhoto分别和Android工程里的对应的,这里还有一个很玄学的问题,我使用的加载图片试过了www,试过了http,就是不行,最后只能通过文件流的方式加载

写完demo是不能直接在unity运行的,要打出apk真机测试

三、Unity gradle模式下打包apk

(1)检查buildsetting - playersetting - other setting的packagename是否与AndroidManifest里面的一直,不一样的就恭喜自己,要么unity改包名,要么改Android工程,从头再来

(2)检查build setting的build system,一定要是Gradle,因为我们需要与Android交互,就必须选这个,这里埋个坑,就是我们打好的jar现在还不能直接放到unity里打测试包的,会报错的

但是你选internal这个包就能顺利打出来,但是这样放到正式工程中你就不能签名了,所以当你打包出错,并报错

Unity ios 图集 unity相册_Unity ios 图集_09


CommandInvokationFailure: Gradle build failed.

C:/Program Files (x86)/Java/jdk1.8.0_73\bin\java.exe -classpath “C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle\lib\gradle-launcher-4.2.1.jar” org.gradle.launcher.GradleMain “-Dorg.gradle.jvmargs=-Xmx1024m” “assembleRelease”

stderr[
Dex: Error converting bytecode to dex:
Cause: com.android.dex.DexException: Multiple dex files define Lcom/NXNC/Farm/BuildConfig;
UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.DexException: Multiple dex files define Lcom/NXNC/Farm/BuildConfig;
at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:660)
at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:615)
at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:597)
at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:170)
at com.android.dx.merge.DexMerger.merge(DexMerger.java:197)
at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:503)
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:333)
at com.android.dx.command.dexer.Main.runDx(Main.java:288)
at com.android.dx.command.dexer.Main.main(Main.java:244)
at com.android.dx.command.Main.main(Main.java:95)

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ‘:transformDexWithDexForRelease’.

com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.ide.common.process.ProcessException: Error while executing java process with main class com.android.dx.command.Main with arguments {–dex --num-threads=4 --output E:\MX\Project\Unity\TestFarmPhotoFinally\Temp\gradleOut\build\intermediates\transforms\dex\release\0 --min-sdk-version 16 E:\MX\Project\Unity\TestFarmPhotoFinally\Temp\gradleOut\build\intermediates\transforms\preDex\release\0.jar E:\MX\Project\Unity\TestFarmPhotoFinally\Temp\gradleOut\build\intermediates\transforms\preDex\release\3.jar E:\MX\Project\Unity\TestFarmPhotoFinally\Temp\gradleOut\build\intermediates\transforms\preDex\release\2.jar}

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
  • Get more help at https://help.gradle.org

BUILD FAILED in 11s
]
stdout[
Starting a Gradle Daemon (subsequent builds will be faster)
Observed package id ‘tools’ in inconsistent location ‘E:\SDK\android-sdk-windows2017-12-25 (1)\android-sdk-windows2017-12-25\toolsOLD’ (Expected ‘E:\SDK\android-sdk-windows2017-12-25 (1)\android-sdk-windows2017-12-25\tools’)
Already observed package id ‘tools’ in ‘E:\SDK\android-sdk-windows2017-12-25 (1)\android-sdk-windows2017-12-25\tools’. Skipping duplicate at ‘E:\SDK\android-sdk-windows2017-12-25 (1)\android-sdk-windows2017-12-25\toolsOLD’
Observed package id ‘tools’ in inconsistent location ‘E:\SDK\android-sdk-windows2017-12-25 (1)\android-sdk-windows2017-12-25\toolsOLD’ (Expected ‘E:\SDK\android-sdk-windows2017-12-25 (1)\android-sdk-windows2017-12-25\tools’)
Already observed package id ‘tools’ in ‘E:\SDK\android-sdk-windows2017-12-25 (1)\android-sdk-windows2017-12-25\tools’. Skipping duplicate at ‘E:\SDK\android-sdk-windows2017-12-25 (1)\android-sdk-windows2017-12-25\toolsOLD’
:preBuild UP-TO-DATE
:preReleaseBuild UP-TO-DATE
:compileReleaseAidl UP-TO-DATE
:compileReleaseRenderscript UP-TO-DATE
:checkReleaseManifest UP-TO-DATE
:generateReleaseBuildConfig UP-TO-DATE
:prepareLintJar UP-TO-DATE
:generateReleaseResValues UP-TO-DATE
:generateReleaseResources UP-TO-DATE
:mergeReleaseResources UP-TO-DATE
:createReleaseCompatibleScreenManifests UP-TO-DATE
:processReleaseManifest
:splitsDiscoveryTaskRelease UP-TO-DATE
:processReleaseResources
:generateReleaseSources
:javaPreCompileRelease
:compileReleaseJavaWithJavac UP-TO-DATE
:compileReleaseNdk NO-SOURCE
:compileReleaseSources UP-TO-DATE
:lintVitalRelease
:mergeReleaseShaders UP-TO-DATE
:compileReleaseShaders UP-TO-DATE
:generateReleaseAssets UP-TO-DATE
:mergeReleaseAssets
:transformClassesWithPreDexForRelease
:transformDexWithDexForRelease

Running dex as a separate process.

To run dex in process, the Gradle daemon needs a larger heap.
It currently has 1024 MB.
For faster builds, increase the maximum heap size for the Gradle daemon to at least 1536 MB.
To do this set org.gradle.jvmargs=-Xmx1536M in the project gradle.properties.
For more information see https://docs.gradle.org/current/userguide/build_environment.html

:transformDexWithDexForRelease FAILED
20 actionable tasks: 7 executed, 13 up-to-date
]
exit code: 1
UnityEditor.Android.Command.WaitForProgramToRun (UnityEditor.Utils.Program p, UnityEditor.Android.Command+WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg) (at :0)
UnityEditor.Android.Command.Run (System.Diagnostics.ProcessStartInfo psi, UnityEditor.Android.Command+WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg) (at :0)
UnityEditor.Android.AndroidJavaTools.RunJava (System.String args, System.String workingdir, System.Action1[T] progress, System.String error) (at <fdd3823527dc4dde8316302bb5a76d3b>:0) UnityEditor.Android.GradleWrapper.Run (UnityEditor.Android.AndroidJavaTools javaTools, System.String workingdir, System.String task, System.Action1[T] progress) (at :0)
Rethrow as GradleInvokationException: Gradle build failed
UnityEditor.Android.GradleWrapper.Run (UnityEditor.Android.AndroidJavaTools javaTools, System.String workingdir, System.String task, System.Action`1[T] progress) (at :0)
UnityEditor.Android.PostProcessor.Tasks.BuildGradleProject.Execute (UnityEditor.Android.PostProcessor.PostProcessorContext context) (at :0)
UnityEditor.Android.PostProcessor.PostProcessRunner.RunAllTasks (UnityEditor.Android.PostProcessor.PostProcessorContext context) (at :0)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

网上会推荐你讲gradle 换成 internal ,这个建议纯属一派胡言,这并不是解决问题,而是绕过了问题,坚决不能采取这个!!!!!!!

会说你的Android工程的内存分配不够 更会说jdk sdk ndk版本不对,也许你试过一大圈之后发现并没有用,我在这里卡了整整两天,最后…

我的解决方案:

用压缩包打开我们的jar,然后删掉里面的buildconfig.class,最后顺利解决,gradle模式下打包成功,demo在手机上成功运行

这是因为Unity打包编译的时候也会生成这个文件,和包里面的冲突了

Unity ios 图集 unity相册_java_10


IOS读取相册

Unity调用IOS 的相册只需要在Unity的Plugins-IOS文件夹里放两个文本文件,然后改后缀,一个改成.h 一个改成.m 名字一样没关系,咱后缀不一样,一个是C++ 一个OC

Unity ios 图集 unity相册_java_11


.h是头文件 相当于引入 接口 直接复制一下代码

#import<QuartzCore/CADisplayLink.h>
 @interface IOSCameraController : UIViewController<UIImagePickerControllerDelegate,UINavigationControllerDelegate,UIPopoverPresentationControllerDelegate>
 @end

.m是实现文件,功能在这写

#import "IOSCameraController.h"

@implementation IOSCameraController
-(void)OpenCamera:(UIImagePickerControllerSourceType)type{
    //创建UIImagePickerController实例
    UIImagePickerController *picker;
    picker= [[UIImagePickerController alloc]init];
    //设置代理
    picker.delegate = self;
    //是否允许编辑 (默认为NO)
    picker.allowsEditing = YES;
    //设置照片的来源
    picker.sourceType = type;
    //展示选取照片控制器
    if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary &&[[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        picker.modalPresentationStyle = UIModalPresentationPopover;
        UIPopoverPresentationController *popover = picker.popoverPresentationController;
        //picker.preferredContentSize = [UIScreen mainScreen].bounds.size;
        popover.delegate = self;
        popover.sourceRect = CGRectMake(0, 0, 0, 0);
        popover.sourceView = self.view;
        popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
        [self presentViewController:picker animated:YES completion:nil];
    } else {
        [self presentViewController:picker animated:YES completion:^{}];
    }
   
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
    [picker dismissViewControllerAnimated:YES completion:^{}];
    UIImage *image = [info objectForKey:@"UIImagePickerControllerEditedImage"];
    if (image == nil) {
        image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    }
    //图片旋转
    if (image.imageOrientation != UIImageOrientationUp) {
    //图片旋转
        image = [self fixOrientation:image];
    }
    NSString *imagePath = [self GetSavePath:@"Temp.jpg"];
    [self SaveFileToDoc:image path:imagePath];
}
-(NSString*)GetSavePath:(NSString *)filename{
    NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docPath = [pathArray objectAtIndex:0];
    return [docPath stringByAppendingPathComponent:filename];
}
-(void)SaveFileToDoc:(UIImage *)image path:(NSString *)path{
    NSData *data;
    if (UIImagePNGRepresentation(image)==nil) {
        data = UIImageJPEGRepresentation(image, 1);
    }else{
        data = UIImagePNGRepresentation(image);
    }
    [data writeToFile:path atomically:YES];
    UnitySendMessage("Canvas", "Message", "Temp.jpg");
}
#pragma mark 图片处理方法
//图片旋转处理
- (UIImage *)fixOrientation:(UIImage *)aImage {
    CGAffineTransform transform = CGAffineTransformIdentity;
    
    switch (aImage.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;
            
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;
            
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        default:
            break;
    }
    
    switch (aImage.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
            
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        default:
            break;
    }
    
    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
                                             CGImageGetBitsPerComponent(aImage.CGImage), 0,
                                             CGImageGetColorSpace(aImage.CGImage),
                                             CGImageGetBitmapInfo(aImage.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (aImage.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
            break;
            
        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
            break;
    }
    // And now we just create a new UIImage from the drawing context
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    return img;
}
@end
#if defined(__cplusplus)
extern "C" {
#endif
    void IOS_OpenCamera(){
        IOSCameraController *app = [[IOSCameraController alloc]init];
        UIViewController *vc = UnityGetGLViewController();
        [vc.view addSubview:app.view];
        [app OpenCamera:UIImagePickerControllerSourceTypeCamera];
    }
    void IOS_OpenAlbum(){
        IOSCameraController *app = [[IOSCameraController alloc]init];
        UIViewController *vc = UnityGetGLViewController();
        [vc.view addSubview:app.view];
        [app OpenCamera:UIImagePickerControllerSourceTypePhotoLibrary];
    }
#if defined(__cplusplus)
}
#endif

IOS就是这么简单粗暴

然后测试脚本,重点看怎么调用

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System.Runtime.InteropServices;
using UnityEngine.SceneManagement;

public class TestWWWTex : MonoBehaviour {

    [SerializeField] private Button _openCamera; //打开相机按钮
    [SerializeField] private Button _openAlbum; //打开相册按钮
    [SerializeField] private RawImage _image; //用于显示的图片
    //引入在oc中定义的那两个方法
    [DllImport("__Internal")]
    private static extern void IOS_OpenCamera();
    [DllImport("__Internal")]
    private static extern void IOS_OpenAlbum();

    void Awake()
    {
        //为两个button添加点击事件
        _openCamera.onClick.AddListener(IOS_OpenCamera);
        _openAlbum.onClick.AddListener(IOS_OpenAlbum);
    }

    //ios回调unity的函数
    void Message(string filenName)
    {
        31         
        string filePath = Application.persistentDataPath + "/" + filenName;
        34        
        TestFileFunc(filePath);
    }

    void TestFileFunc(string path)
    {
        FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
        fileStream.Seek(0, SeekOrigin.Begin);
        byte[] bye = new byte[fileStream.Length];
        fileStream.Read(bye, 0, bye.Length);
        fileStream.Close();

        Texture2D texture2D = new Texture2D(240, 144);
        texture2D.LoadImage(bye);

        _image.texture = texture2D;

    }
}

这里说一下,www加载会找不到照片,http加载,xcode会报错,看不懂报了什么错,好像是没给权限,xcode建议用https,我就懒得搞了,直接用文件流加载吧

接下来就是打xcode工程 在xcode里找到info.plist文件,加一个相册权限,之后就能真机测试了