Unity如何获取程序外双击文件路径?单例音乐播放器MP3路径获取
Unity 获取外部双击文件路径及单例播放器处理方案
1. 如何在Unity中获取程序外部鼠标双击文件的路径?
获取路径分两种场景处理:
场景A:双击文件启动Unity程序
系统会将目标文件路径作为命令行参数传递给程序,直接通过Environment.GetCommandLineArgs()获取:
void Start() { string[] cmdArgs = Environment.GetCommandLineArgs(); if (cmdArgs.Length > 1) { string targetPath = cmdArgs[1]; Debug.Log("双击启动的文件路径:" + targetPath); // 后续文件逻辑处理 } }
注:cmdArgs[0]是程序自身的路径,cmdArgs[1]及以后是传递的外部参数。
场景B:程序已运行时双击外部文件
这种情况需要监听系统平台的文件激活消息,Unity无原生API,需做平台适配:
Windows平台
通过Windows API监听WM_DROPFILES消息,实现代码如下:
using System; using System.Runtime.InteropServices; using UnityEngine; public class ExternalFileHandler : MonoBehaviour { [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex); [DllImport("user32.dll")] private static extern bool DragAcceptFiles(IntPtr hWnd, bool fAccept); private delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); private WndProcDelegate _oldWndProc; private const int GWL_WNDPROC = -4; private const uint WM_DROPFILES = 0x0233; void Start() { IntPtr windowPtr = UnityEngine.Windows.Window.GetWindowPtr(); _oldWndProc = (WndProcDelegate)Marshal.GetDelegateForFunctionPointer(GetWindowLongPtr(windowPtr, GWL_WNDPROC), typeof(WndProcDelegate)); SetWindowLongPtr(windowPtr, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(new WndProcDelegate(WndProc))); DragAcceptFiles(windowPtr, true); } private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { if (msg == WM_DROPFILES) { char[] pathBuffer = new char[260]; DragQueryFile(wParam, 0, pathBuffer, pathBuffer.Length); string filePath = new string(pathBuffer).TrimEnd('\0'); Debug.Log("接收外部文件路径:" + filePath); DragFinish(wParam); } return _oldWndProc(hWnd, msg, wParam, lParam); } [DllImport("shell32.dll")] private static extern uint DragQueryFile(IntPtr hDrop, uint iFile, char[] lpszFile, uint cch); [DllImport("shell32.dll")] private static extern void DragFinish(IntPtr hDrop); }
macOS平台
通过Objective-C扩展Unity的AppController,监听application:openFile:事件:
- 编写Objective-C插件代码(编译为
.bundle):
#import <Cocoa/Cocoa.h> #import "UnityAppController.h" @interface CustomAppController : UnityAppController @end @implementation CustomAppController - (BOOL)application:(NSApplication *)app openFile:(NSString *)filePath { UnitySendMessage("FileReceiver", "OnGetExternalFile", [filePath UTF8String]); return YES; } @end IMPL_APP_CONTROLLER_SUBCLASS(CustomAppController)
- Unity侧C#接收代码:
public class FileReceiver : MonoBehaviour { public void OnGetExternalFile(string filePath) { Debug.Log("接收外部文件路径:" + filePath); // 后续处理逻辑 } }
2. 运行中的单例MP3播放器获取双击文件路径
基于上述场景B的实现,结合单例播放器逻辑,只需将接收的路径传递给单例实例即可:
步骤1:单例音乐播放器实现
public class MusicPlayer : MonoBehaviour { public static MusicPlayer Instance { get; private set; } void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } public void LoadAndPlay(string mp3Path) { // 实现MP3加载、播放逻辑 Debug.Log("开始播放:" + mp3Path); } }
步骤2:传递路径给单例播放器
- Windows平台:在
WndProc方法中添加调用
private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { if (msg == WM_DROPFILES) { // ... 省略路径获取代码 MusicPlayer.Instance?.LoadAndPlay(filePath); DragFinish(wParam); } return _oldWndProc(hWnd, msg, wParam, lParam); }
- macOS平台:在接收方法中添加调用
public void OnGetExternalFile(string filePath) { MusicPlayer.Instance?.LoadAndPlay(filePath); }
额外注意
需确保程序已完成MP3文件关联注册:
- Windows:通过注册表或安装包配置文件类型关联
- macOS:在
Info.plist中添加CFBundleDocumentTypes,指定UTI为public.mp3
内容的提问来源于stack exchange,提问作者power display
相关产品推荐
相关产品推荐

