You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 11:36:13