Unity 与 Android IOS交互笔记

Posted Var_al

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity 与 Android IOS交互笔记相关的知识,希望对你有一定的参考价值。

一、C#调OC:

1、为了使用DllImport,需要 using System.Runtime.InteropServices;
2、这些函数前面要加入[DllImport(“__Internal”)],说明这是从dll导入的函数,并且来源于游戏本身的dll。函数必须声明为
private static extern 。
3、需要在c#中声明OC的函数:

[DllImport("__Internal")]
private static extern void iosMethod(); //IosMethod 对应的OC中的函数名

二、OC调Unity C#代码:

1、当C#调用OC方法,OC方法处理完后,需要向C#返回处理的结果,这就需要使用Unity提供的发送回调事件的方法。
2、从Unity导出的xcode工程中,UnityInterface.h中声明了一个方法:

// obj-游戏物体名字,method-方法名字,msg-数据,通常把需要的数据打包成一个json字符串
void UnitySendMessage(const char* obj, const char* method, const char* msg);

三、C#调android

1、AndroidJavaClass主要是读取arr包或者jar包中的类对象,用来读取静态属性或方法
2、AndroidJavaObject主要作用于生成实例对象,用来读取对象的实例属性或方法

//加载com.al.player.MainActivity类
AndroidJavaClass _JC = new AndroidJavaClass("com.al.player.MainActivity");
 
//实例com.al.player.test对象
AndroidJavaObject _JO = new AndroidJavaObject("com.al.player.test");

//调用com.al.player.MainActivity类中的Test静态方法
_JC.CallStatic("Test");

//调用com.al.player.MainActivity类中的Test静态方法,带返回值(不带返回值去掉<bool>)
bool flag = _JO.CallStatic<bool>("Test");

//调用com.al.player.test类中的TestInstance实例方法,带返回值(不带返回值去掉<string>),"TestString"-传值
string str = _JO.Call<string>("TestInstance", "TestString");

// 获取Unity导出的Activity对象
AndroidJavaClass _JC = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = _JC.GetStatic<AndroidJavaObject>("currentActivity");

四、Android调Unity C#代码:

// obj-游戏物体名字,method-方法名字,msg-数据(可空”“)
UnityPlayer.UnitySendMessage(string obj, string method, string msg);

五、C#请求摄像机权限代码:

	// 请求摄像机使用权限
    public void RequestPermission()
        // 是否已同意摄像机使用权限
        if (!Permission.HasUserAuthorizedPermission(Permission.Camera))
        
            // 请求摄像机权限
            Permission.RequestUserPermission(Permission.Camera);
        
    

六、Unity C#修改Xcode项目配置代码:

1、XCodeProject文件要放在Editor文件夹下

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using UnityEngine.Android;
using System.Runtime.InteropServices;

public class XCodeProject : MonoBehaviour

    [PostProcessBuild]
    private static void OnBuildFinsh(BuildTarget buildTarget, string buildPath)
    
        Debug.Log("构建完成:"+buildPath+" 路径:"+ buildPath);
#if UNITY_IPHONE
    SetXCodeProject(buildPath);
#endif
    
    public static void SetXCodeProject(string buildPath)
    
        PBXProject project = new PBXProject();
        project.ReadFromString(File.ReadAllText(PBXProject.GetPBXProjectPath(buildPath)));

        // 添加库
        string targetGuid = project.GetUnityFrameworkTargetGuid();
        project.AddFrameworkToProject(targetGuid, "AVKit.framework", false);
        project.WriteToFile(PBXProject.GetPBXProjectPath(buildPath));
		
		// 设置签名证书
        project.SetBuildProperty(targetGuid, "CODE_SIGN_IDENTITY", "test123");

        // 为目标文件设定编译标识
        string fileGuid = project.FindFileGuidByProjectPath("MainApp/main.mm");
        project.SetCompileFlagsForFile(targetGuid, fileGuid, new List<string>() "xxx");

        // 添加权限
        PlistDocument plist = new PlistDocument();
        plist.ReadFromString(File.ReadAllText(Path.Combine(buildPath, "Info.plist")));
        plist.root.SetString("NSCameraUsageDescription", "请求摄像机权限");
        project.WriteToFile(Path.Combine(buildPath, "Info.plist"));
    

[脚本] iOS 与unity交互 ,陀螺仪

// ***********************************************************
// Written by Heyworks Unity Studio http://unity.heyworks.com/
// ***********************************************************
using UnityEngine;
/// <summary>
/// Gyroscope controller that works with any device orientation.
/// </summary>
public class GyroController : MonoBehaviour
{
    #region [Private fields]
    private bool gyroEnabled = true;
    private const float lowPassFilterFactor = 0.2f;
    private readonly Quaternion baseIdentity = Quaternion.Euler(90, 0, 0);
    private readonly Quaternion landscapeRight = Quaternion.Euler(0, 0, 90);
    private readonly Quaternion landscapeLeft = Quaternion.Euler(0, 0, -90);
    private readonly Quaternion upsideDown = Quaternion.Euler(0, 0, 180);
    private Quaternion cameraBase = Quaternion.identity;
    private Quaternion calibration = Quaternion.identity;
    private Quaternion baseOrientation = Quaternion.Euler(90, 0, 0);
    private Quaternion baseOrientationRotationFix = Quaternion.identity;
    private Quaternion referanceRotation = Quaternion.identity;
    private bool debug = true;
    #endregion
    #region [Unity events]
    protected void Start()
    {
        AttachGyro();
    }
    protected void Update()
    {
        if (!gyroEnabled)
            return;
        transform.rotation = Quaternion.Slerp(transform.rotation,
            cameraBase * (ConvertRotation(referanceRotation * Input.gyro.attitude) * GetRotFix()), lowPassFilterFactor);
    }
    protected void OnGUI()
    {
        if (!debug)
            return;
        GUILayout.Label("Orientation: " + Screen.orientation);
        GUILayout.Label("Calibration: " + calibration);
        GUILayout.Label("Camera base: " + cameraBase);
        GUILayout.Label("input.gyro.attitude: " + Input.gyro.attitude);
        GUILayout.Label("transform.rotation: " + transform.rotation);
        if (GUILayout.Button("On/off gyro: " + Input.gyro.enabled, GUILayout.Height(100)))
        {
            Input.gyro.enabled = !Input.gyro.enabled;
        }
        if (GUILayout.Button("On/off gyro controller: " + gyroEnabled, GUILayout.Height(100)))
        {
            if (gyroEnabled)
            {
                DetachGyro();
            }
            else
            {
                AttachGyro();
            }
        }
        if (GUILayout.Button("Update gyro calibration (Horizontal only)", GUILayout.Height(80)))
        {
            UpdateCalibration(true);
        }
        if (GUILayout.Button("Update camera base rotation (Horizontal only)", GUILayout.Height(80)))
        {
            UpdateCameraBaseRotation(true);
        }
        if (GUILayout.Button("Reset base orientation", GUILayout.Height(80)))
        {
            ResetBaseOrientation();
        }
        if (GUILayout.Button("Reset camera rotation", GUILayout.Height(80)))
        {
            transform.rotation = Quaternion.identity;
        }
    }
    #endregion
    #region [Public methods]
    /// <summary>
    /// Attaches gyro controller to the transform.
    /// </summary>
    private void AttachGyro()
    {
        gyroEnabled = true;
        ResetBaseOrientation();
        UpdateCalibration(true);
        UpdateCameraBaseRotation(true);
        RecalculateReferenceRotation();
    }
    /// <summary>
    /// Detaches gyro controller from the transform
    /// </summary>
    private void DetachGyro()
    {
        gyroEnabled = false;
    }
    #endregion
    #region [Private methods]
    /// <summary>
    /// Update the gyro calibration.
    /// </summary>
    private void UpdateCalibration(bool onlyHorizontal)
    {
        if (onlyHorizontal)
        {
            var fw = (Input.gyro.attitude) * (-Vector3.forward);
            fw.z = 0;
            if (fw == Vector3.zero)
            {
                calibration = Quaternion.identity;
            }
            else
            {
                calibration = (Quaternion.FromToRotation(baseOrientationRotationFix * Vector3.up, fw));
            }
        }
        else
        {
            calibration = Input.gyro.attitude;
        }
    }
    /// <summary>
    /// Update the camera base rotation.
    /// </summary>
    /// <param name=‘onlyHorizontal‘>
    /// Only y rotation.
    /// </param>
    private void UpdateCameraBaseRotation(bool onlyHorizontal)
    {
        if (onlyHorizontal)
        {
            var fw = transform.forward;
            fw.y = 0;
            if (fw == Vector3.zero)
            {
                cameraBase = Quaternion.identity;
            }
            else
            {
                cameraBase = Quaternion.FromToRotation(Vector3.forward, fw);
            }
        }
        else
        {
            cameraBase = transform.rotation;
        }
    }
    /// <summary>
    /// Converts the rotation from right handed to left handed.
    /// </summary>
    /// <returns>
    /// The result rotation.
    /// </returns>
    /// <param name=‘q‘>
    /// The rotation to convert.
    /// </param>
    private static Quaternion ConvertRotation(Quaternion q)
    {
        return new Quaternion(q.x, q.y, -q.z, -q.w);
    }
    /// <summary>
    /// Gets the rot fix for different orientations.
    /// </summary>
    /// <returns>
    /// The rot fix.
    /// </returns>
    private Quaternion GetRotFix()
    {
#if UNITY_3_5
        if (Screen.orientation == ScreenOrientation.Portrait)
            return Quaternion.identity;
        if (Screen.orientation == ScreenOrientation.LandscapeLeft || Screen.orientation == ScreenOrientation.Landscape)
            return landscapeLeft;     
        if (Screen.orientation == ScreenOrientation.LandscapeRight)
            return landscapeRight;
        if (Screen.orientation == ScreenOrientation.PortraitUpsideDown)
            return upsideDown;
        return Quaternion.identity;
#else
        return Quaternion.identity;
#endif
    }
    /// <summary>
    /// Recalculates reference system.
    /// </summary>
    private void ResetBaseOrientation()
    {
        baseOrientationRotationFix = GetRotFix();
        baseOrientation = baseOrientationRotationFix * baseIdentity;
    }
    /// <summary>
    /// Recalculates reference rotation.
    /// </summary>
    private void RecalculateReferenceRotation()
    {
        referanceRotation = Quaternion.Inverse(baseOrientation) * Quaternion.Inverse(calibration);
    }
    #endregion
}

 

以上是关于Unity 与 Android IOS交互笔记的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio 编写aar 到Unity 笔记

关于iOSAndroid的交互 实践篇——主动调用

iOS与Unity3d交互

[脚本] iOS 与unity交互 ,陀螺仪

[脚本] iOS 与unity交互 ,陀螺仪

Android与Unity的交互