当前位置: 首页 > news >正文

Unity C#调用Android,IOS震动功能

最近在Unity上需要很原生移动端进行交互,

原理:新建一个android项目,把生成的app module给干掉,然后留下一个vibrationPlugin module,在这个module下写android震动代码,将这个android工程构建出来的 aar移动到Unity项目下的Assets/Plugins/Android下,重新打包,利用 AndroidJavasClass获得unityPlayer,然后通过unityPlayer获得当前unity的activity,将unity activity的context 传递给 vibrationPlugin工程里面

现在开始整个集成的过程:

1: Android

一:新建Android项目

选择No Activity

 

 等待项目编译

编译完毕之后在 app/java/com.lck.unityvibration/目录下新建一个java文件:

package com.lck.unityviabration;import android.content.Context;
import android.os.Vibrator;public class VibrationPlugin {private static VibrationPlugin instance;private Vibrator vibrator;public VibrationPlugin(Context context) {vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);}public static VibrationPlugin getInstance(Context context) {if(instance == null) {instance = new VibrationPlugin(context);}return instance;}public void vibrate(long milliseconds) {vibrator.vibrate(milliseconds);}public void cancel() {vibrator.cancel();}
}

注意在 AndroidManifest.xml中引入 

<uses-permission android:name="android.permission.VIBRATE" />

可以把测试的无关代码删除掉

最终的项目目录:

然后把res/values和xml文件夹删除掉没啥用

 然后把 app module设置成 library

就是在app 的build.gradle中  

plugins {alias(libs.plugins.androidApplication)
} 替换成  apply plugin: 'com.android.library'

另外 module中没有 applicationId 标识,干掉:

minSdkVersion和unity android主工程保持一致

最后 Build/Make Project会生成一个aar文件,将这个文件放到unity工程里面 Plugins/Android/目录下

 二:Unity项目调用

新建Unity AndroidUtils.cs脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class AndroidUtils
{private static AndroidJavaObject vibrationPlugin;// Start is called before the first frame updatepublic static void Init(){if(Application.platform == RuntimePlatform.Android) {using(var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");if(activity != null) {Debug.Log("has activity");}var context = activity.Call<AndroidJavaObject>("getApplicationContext");if(context != null) {Debug.Log("has context");}vibrationPlugin = new AndroidJavaObject("com.lck.unityviabration.VibrationPlugin",context);}}}public static void Vibrate(long milliseconds) {if(vibrationPlugin == null) {Debug.Log("vibrationPlugin is null");}if(Application.platform == RuntimePlatform.Android && vibrationPlugin != null) {vibrationPlugin.Call("vibrate",milliseconds);}}public static void Cancel() {if(Application.platform == RuntimePlatform.Android && vibrationPlugin != null) {vibrationPlugin.Call("cancel");}}
}

在游戏开始的时候初始化 AndroidUtils.Init()

在游戏逻辑中需要的地方调用

AndroidUtils.Vibrate(200);

Android集成完毕

2: IOS

一:IOS项目

同样的道理,跟集成Android很类似,需要在unity项目中的Plugins文件夹创建一个文件夹为IOS文件夹,里面放两个文件就可以了,NativeUtils.h和NativeUtils.mm

#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface NativeUtils : NSObject@endNS_ASSUME_NONNULL_END
#import "NativeUtils.h"
#import <UIKit/UIKit.h>@implementation NativeUtils
extern "C" {void setVibrator(float Intensity) {NSLog(@"设置震动强度:%f",Intensity);UIImpactFeedbackGenerator* generator;generator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleHeavy];[generator impactOccurred];}
}
@end

二:Unity项目集成

在我上面AndroidUtils.cs文件中加入两行代码就行了:

// DllImport 语句用于调用iOS插件中的C函数[DllImport("__Internal")]private static extern void setVibrator(float intensity);

调用:

public static void Vibrate(long milliseconds) {if(vibrationPlugin == null) {Debug.Log("vibrationPlugin is null");}if(Application.platform == RuntimePlatform.Android && vibrationPlugin != null) {vibrationPlugin.Call("vibrate",milliseconds);} else if(Application.platform == RuntimePlatform.IPhonePlayer) {Debug.Log("调用震动功能");setVibrator(1.5f);}}

打包到目标IOS之后会看到Xcode项目里面多了个Libraries文件夹下的Plugins文件夹,里面有IOS/NativeUtils和NativeUtils.mm文件了,这就是正确的IOS调用震动功能的全部代码了。 

相关文章:

Unity C#调用Android,IOS震动功能

最近在Unity上需要很原生移动端进行交互&#xff0c; 原理&#xff1a;新建一个android项目&#xff0c;把生成的app module给干掉&#xff0c;然后留下一个vibrationPlugin module&#xff0c;在这个module下写android震动代码&#xff0c;将这个android工程构建出来的 aar移…...

Ruby 注释

Ruby 注释 在编程中&#xff0c;注释是用于解释代码如何工作以及为什么这样编写的重要工具。Ruby作为一种解释型、面向对象的脚本语言&#xff0c;提供了灵活的注释方式&#xff0c;帮助开发者更好地组织和理解代码。本文将详细介绍Ruby中的注释类型、用法以及最佳实践。 Rub…...

C语言入门系列:特殊的main函数和exit函数

文章目录 一&#xff0c;main函数二&#xff0c;exit函数1&#xff0c;exit函数2&#xff0c;atexit()函数2.1 atexit函数的简介2.2 atexit注册的函数一定会被调用吗2.2.1 正常退出测试2.2.2 异常退出测试 一&#xff0c;main函数 一个C程序至少包含一个函数&#xff0c;这个函…...

JAVA复习3

目录 19. 下列关于 do…while 语句和 while 语句的叙述中错误的是&#xff08; C &#xff09; 20. 若有定义 int a9, b6; System.out.println(a > b) 的结果是&#xff08; D &#xff09; 21. 关于接口和抽象类&#xff0c;下列说法正确的是&#xff08;A&#xff09; …...

Oracle共享内存不释放

Oracle数据库使用共享内存来管理其系统全局区&#xff08;SGA&#xff09;和程序全局区&#xff08;PGA&#xff09;。当Oracle数据库的共享内存没有正确释放时&#xff0c;可能会导致数据库启动失败或性能问题。以下是一些可能的原因和解决方法&#xff1a; /dev/shm空间不足&…...

windows cmd中单引号和双引号的问题

文章目录 前言单引号和双引号的用法单引号双引号 示例对比Linux ShellWindows CMD PowerShell中的引号用法结论 前言 这个问题的起因是在windows cmd中运行一个简单的命令 node -e console.log(process)发现没有输出&#xff0c;但是进入node环境后&#xff0c;直接执行conso…...

Nacos 2.x 系列【15】数据源插件支持达梦、Oracel、PostgreSQL......

文章目录 1. 概述2. 持久层机制2.1 固定语句2.2 数据源插件 3. 案例演示3.1 编译已实现插件3.2 自定义插件3.3 数据库初始化3.4 插件引入3.4.1 方式一&#xff1a;引入到源码3.4.2 方式二&#xff1a;插件加载目录 3.5 修改配置3.6 测试 1. 概述 在实际项目开发中&#xff0c;…...

HJ39判断两个IP是否属于同一子网(中)

提示&#xff1a;文章 文章目录 前言一、背景二、 2.1 2.2 总结 前言 接上文HJ39判断两个IP是否属于同一子网 查了下&#xff0c;atoi可以转换负数。 修改成下面的代码 #include <stdio.h> #include <stdlib.h> #include <stdbool.h>bool isTargetSonN…...

渗透测试基础(二) Linux+Win常用命令介绍

1. Linux常用命令 1.1 解压缩相关 1.1.1 tar命令 解包&#xff1a;tar zxvf FileName.tar 打包&#xff1a;tar czvf FileName.tar DirName1.1.2 gz命令 对于.gz格式的解压1&#xff1a;gunzip FileName.gz解压2&#xff1a;gzip -d FileName.gz压缩&#xff1a;gzip FileN…...

手机usb共享网络电脑没反应的方法

适用于win10电脑&#xff0c;安卓手机上可以 开启usb网络共享选择&#xff0c;如果选择后一直跳&#xff0c;让重复选择usb选项的话&#xff0c;就开启 开发者模式&#xff0c;进到 开发者模式 里设置 默认usb 共享网络 选项 &#xff0c;就不会一直跳让你选。 1.先用数据线 连…...

Scrivener v3 解锁版安装教程 (写作辅助软件)

前言 Scrivener&#xff0c;一个多功能的写作软件&#xff0c;被世界各地的作家广泛采用&#xff0c;从小说家到剧本家&#xff0c;再到非小说类作家和学术研究者&#xff0c;它的用户群跨越了广泛的领域&#xff0c;包括学生、法律专业人士、记者和翻译。这个软件非常注重用户…...

Python开发——用什么数据储存结构复杂的数据

在Python中&#xff0c;当需要储存包含不同类型的数据时&#xff0c;可以使用以下几种数据结构&#xff1a; 1. 字典&#xff08;dict&#xff09; 字典是一种非常灵活的数据结构&#xff0c;允许使用键-值对来存储不同类型的数据。 data {"name": "Alice&quo…...

【0-1系列】从0-1快速了解搜索引擎Scope以及如何快速安装使用(下)

前言 近日&#xff0c;社区版家族正式发布V2024.5版本&#xff0c;其中&#xff0c;社区开发版系列重磅发布Scope开发版以及StellarDB开发版。 为了可以让大家更进一步了解产品&#xff0c;本系列文章从背景概念开始介绍&#xff0c;深入浅出的为读者介绍Scope的优势以及能力…...

前端核心框架Vue指令详解

目录 ▐ 关于Vue指令的介绍 ▐ v-text与v-html ▐ v-on ▐ v-model ▐ v-show与v-if ▐ v-bind ▐ v-for ▐ 前言&#xff1a;在学习Vue框架过程中&#xff0c;大家一定要多参考官方API &#xff01; Vue2官方网址https://v2.cn.vuejs.org/v2/guide/ ▐ 关于Vue指令的…...

SD卡无法读取?原因分析与数据恢复策略

一、SD卡无法读取的困境 SD卡作为便携式的存储介质&#xff0c;广泛应用于手机、相机、平板等多种电子设备中。然而&#xff0c;在使用过程中&#xff0c;我们可能会遭遇SD卡无法读取的困扰。当我们将SD卡插入设备时&#xff0c;设备无法识别SD卡&#xff0c;或者虽然识别了SD…...

线程池的工作原理

线程池可以减少创建和销毁线程的次数&#xff0c;从而减少系统资源的消耗。当一个任务&#xff08;Runnable或Callable对象&#xff09;&#xff08;Runnable无返回值&#xff0c;Callable有返回值&#xff09;被提交到线程池时&#xff1a; 一、首先判断核心线程池中的线程是…...

Nikto一键扫描Web服务器(KALI工具系列三十)

目录 1、KALI LINUX 简介 2、Nikto工具简介 3、信息收集 3.1 目标IP&#xff08;服务器) 3.2kali的IP 4、操作实例 4.1 基本扫描 4.2 扫描特定端口 4.3 保存扫描结果 4.4 指定保存格式 4.5 连接尝试 4.6 仅扫描文件上传 5、总结 1、KALI LINUX 简介 Kali Linux 是一…...

全局变量和局部变量

全局变量未初始化&#xff0c;则它的值为0&#xff1b; 局部变量未初始化&#xff0c;则它的值为随机值&#xff1b; 局部变量的作用域是变量所在的局部范围; 全局变量的作用域是整个工程; 生命周期&#xff1a; 变量的生命周期指的是变量从创建到销毁的整个阶段。 局部变量的生…...

[机器学习算法]支持向量机

支持向量机&#xff08;SVM&#xff09;是一种用于分类和回归分析的监督学习模型。SVM通过找到一个超平面来将数据点分开&#xff0c;从而实现分类。 1. 理解基本概念和理论&#xff1a; 超平面&#xff08;Hyperplane&#xff09;&#xff1a;在高维空间中&#xff0c;将数据…...

Springboot应用的信创适配

CentOS7在2024.6.30停止维护后&#xff0c;可替代的Linux操作系统-CSDN博客 全面国产化之路-信创-CSDN博客 信创适配评测-CSDN博客 Springboot应用的信创适配 Springboot应用的信创适配&#xff0c;如上图所示需要适配的很多&#xff0c;从硬件、操作系统、中间件&#xff08…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...