Unity 2022.2.0b1下用C#获取iOS/Android设备IP的代码求助
在Unity 2022.2.0b1中获取iOS/Android设备IP的C#实现方法
一、获取本地IP地址
Unity自带的System.Net类库可实现基础的本地IP获取,适用于多数场景,但需依赖设备已连接网络:
using System.Net; using System.Linq; public static string GetLocalIPAddress() { var host = Dns.GetHostEntry(Dns.GetHostName()); // 优先返回IPv4地址 var ipv4 = host.AddressList.FirstOrDefault(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork); if (ipv4 != null) return ipv4.ToString(); // 若IPv4不可用,返回IPv6地址 var ipv6 = host.AddressList.FirstOrDefault(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6); return ipv6?.ToString() ?? "无法获取本地IP"; }
注意:Android/iOS平台需在Unity Player Settings中开启网络权限,否则可能返回空值。
二、Android平台精准获取当前网络IP
部分Android机型上,通用API可能返回虚拟网卡IP,可通过调用Android原生API获取当前活跃网络的真实IP:
1. 配置权限
在Unity的Player Settings > Publishing Settings > Android中启用自定义主清单,在AndroidManifest.xml添加以下权限:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
2. C#调用代码
using UnityEngine; public static string GetAndroidLocalIP() { try { var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); var context = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); var connManager = context.Call<AndroidJavaObject>("getSystemService", "connectivity"); var activeNetwork = connManager.Call<AndroidJavaObject>("getActiveNetwork"); if (activeNetwork != null) { var linkProps = connManager.Call<AndroidJavaObject>("getLinkProperties", activeNetwork); var linkAddresses = linkProps.Call<AndroidJavaObject>("getLinkAddresses"); int count = linkAddresses.Call<int>("size"); for (int i = 0; i < count; i++) { var linkAddr = linkAddresses.Call<AndroidJavaObject>("get", i); var inetAddr = linkAddr.Call<AndroidJavaObject>("getAddress"); string ip = inetAddr.Call<string>("getHostAddress"); // 过滤环回地址和IPv6链路本地地址 if (!ip.Contains("127.0.0.1") && !ip.StartsWith("fe80:")) { return ip; } } } return "未连接网络"; } catch (System.Exception e) { Debug.LogError("Android IP获取失败: " + e.Message); return "获取失败"; } }
三、iOS平台精准获取当前网络IP
iOS需调用原生getifaddrs函数获取网卡信息,以下是C#绑定实现:
using System; using System.Runtime.InteropServices; using UnityEngine; public static string GetiOSLocalIP() { try { IntPtr ifaddrsPtr = IntPtr.Zero; if (getifaddrs(ref ifaddrsPtr) == 0) { IntPtr currentPtr = ifaddrsPtr; while (currentPtr != IntPtr.Zero) { var ifa = Marshal.PtrToStructure<Ifaddrs>(currentPtr); // 筛选IPv4地址(AF_INET = 2) if (ifa.ifa_addr != IntPtr.Zero && ifa.ifa_addr->sa_family == 2) { string interfaceName = Marshal.PtrToStringAnsi(ifa.ifa_name); // en0为WiFi接口,en1为蜂窝网络接口 if (interfaceName == "en0" || interfaceName == "en1") { var addr = Marshal.PtrToStructure<sockaddr_in>(ifa.ifa_addr); string ip = $"{(addr.sin_addr.s_addr & 0xFF)}.{(addr.sin_addr.s_addr >> 8 & 0xFF)}.{(addr.sin_addr.s_addr >> 16 & 0xFF)}.{(addr.sin_addr.s_addr >> 24 & 0xFF)}"; freeifaddrs(ifaddrsPtr); return ip; } } currentPtr = ifa.ifa_next; } freeifaddrs(ifaddrsPtr); } return "无法获取IP"; } catch (System.Exception e) { Debug.LogError("iOS IP获取失败: " + e.Message); return "获取失败"; } } // 原生结构体与函数绑定 [StructLayout(LayoutKind.Sequential)] private struct sockaddr { public ushort sa_family; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] public byte[] sa_data; } [StructLayout(LayoutKind.Sequential)] private struct sockaddr_in { public ushort sin_family; public ushort sin_port; public in_addr sin_addr; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] sin_zero; } [StructLayout(LayoutKind.Sequential)] private struct in_addr { public uint s_addr; } [StructLayout(LayoutKind.Sequential)] private struct Ifaddrs { public IntPtr ifa_next; public string ifa_name; public uint ifa_flags; public IntPtr ifa_addr; public IntPtr ifa_netmask; public IntPtr ifa_broadaddr; public IntPtr ifa_data; } [DllImport("libSystem.dylib")] private static extern int getifaddrs(ref IntPtr ifap); [DllImport("libSystem.dylib")] private static extern void freeifaddrs(IntPtr ifap);
四、获取公网IP地址
本地API无法直接获取公网IP,需通过访问公共IP查询服务实现,使用UnityWebRequest:
using UnityEngine; using UnityEngine.Networking; using System.Collections; public static IEnumerator GetPublicIP(System.Action<string> onCompleted) { string result = "无法获取公网IP"; using (var request = UnityWebRequest.Get("https://icanhazip.com")) { yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { result = request.downloadHandler.text.Trim(); } else { Debug.LogError("公网IP获取失败: " + request.error); } } onCompleted?.Invoke(result); }
注意:iOS平台需确保Info.plist中
NSAppTransportSecurity允许HTTPS请求(默认已开启),若使用HTTP需添加例外配置。
内容的提问来源于stack exchange,提问作者TheTinniDev
相关产品推荐
相关产品推荐

