unity3d实现手机精准定位_unity3d 怎么实现手机触摸 - CSDN
  • Unity3D中使用Profiler精确定位性能热点的优化技巧 本文由博主(SunboyL)原创,转载请注明出处:http://www.cnblogs.com/xsln/p/BeginProfiler.html 简介     在使用Pro...

    Unity3D中使用Profiler精确定位性能热点的优化技巧

    本文由博主(SunboyL)原创,转载请注明出处:http://www.cnblogs.com/xsln/p/BeginProfiler.html

    简介

        在使用Profiler定位代码的性能热点时,很多同学往往忽略Profiler的提供接口,当发现某个Update函数特别耗时时,没有有效的手段进一步定位热点出自该Update函数的哪一个模块或哪一段代码。 

        使用Profiler评估客户端性能时,推荐使用Profiler提供的性能采样接口,来更精确地分析定位客户端存在的性能问题。

     
        举个例子说明精确定位的优势:
        测试源代码:
    复制代码
     1 using UnityEngine;
     2 using System.Collections;
     3 using System.Collections.Generic;
     4 
     5 public class TestProfiler : MonoBehaviour {
     6     int t = 10000;
     7     
     8     // 每帧Update都会进行校验和运行
     9     void Update () {
    10         Check(t); // 校验
    11         Run(); // 运行
    12     }
    13 
    14     void Check(int n) {
    15         ProfilerSample.BeginSample("Check");
    16         CheckA(); // 校验模块A
    17 
    18         ProfilerSample.BeginSample("Calculate b");
    19         // 数值运算
    20         int b = n - 100;
    21         if (b < 10)
    22             b = 10;
    23         ProfilerSample.EndSample();
    24 
    25         CheckB(b); // 校验模块B
    26         ProfilerSample.EndSample();
    27     }
    28 
    29     void CheckA() {
    30         ProfilerSample.BeginSample("CheckA");
    31         Debug.Log("校验模块A");
    32         ProfilerSample.EndSample();
    33     }
    34 
    35     void CheckB(int loopCount) {
    36         ProfilerSample.BeginSample("CheckB(loopCount={0})", loopCount);
    37         Debug.Log("校验模块B");
    38 
    39         ProfilerSample.BeginSample("new List<string>");
    40         List<string> strList = new List<string>();
    41         ProfilerSample.EndSample();
    42 
    43         for (int i = 0; i < loopCount; ++i) {
    44             ProfilerSample.BeginSample("Add str to list");
    45             string str = string.Format("CheckB:{0}", i);
    46             strList.Add(str);
    47             ProfilerSample.EndSample();
    48         }
    49 
    50         Debug.Log(string.Format("list count: {0}", strList.Count));
    51         ProfilerSample.EndSample();
    52     }
    53 
    54     void Run() {
    55         ProfilerSample.BeginSample("Run");
    56         Debug.Log("开始运行");
    57         DoSomething();
    58         ProfilerSample.EndSample();
    59     }
    60 
    61     void DoSomething() {
    62     }
    63 
    64     void OnGUI() {
    65         GUILayout.BeginVertical();
    66         if (GUILayout.Button("Enable/Disable ProfierSample.")) {
    67             ProfilerSample.EnableProfilerSample = !ProfilerSample.EnableProfilerSample;
    68         }
    69 
    70         if (GUILayout.Button("Enable/Disable Profier sting format.")) {
    71             ProfilerSample.EnableFormatStringOutput = !ProfilerSample.EnableFormatStringOutput;
    72         }
    73     }
    74 }
    复制代码
    View Code

        关闭和开启Profiler性能采样接口的对比截图:

       
        如上图,使用性能采样接口,可以精确发现该Update的耗时热点在Check函数下CheckB函数中,主要由List.Add()导致,被调用了9900次。
        使用Profiler.BeginSample、Profiler.EndSample配对,可以有效定位用户自己编写的代码的性能热点。
       
     
    除此之外,我封装了一套自己的接口,代码在本文最后面。之所以封装一层,原因如下:
        1、提供Profiler性能采样开关,可随时关闭
        2、提供字符串格式化功能,可在Profiler中显示自定义的文本,方便定位问题(使用时需要谨慎,后文叙述
     
    关于格式化字符串
        有时候光知道热点代码位置是不够的,还需要知道代码中变量数据
        例如处理网络协议的OnRecv函数,该函数会根据不同的协议号调用不同的委托函数。此时,我们就可以在Profiler窗口中输出协议号、或者委托的具体函数名,以方便我们定位具体热点。
       
     
    慎用格式化字符串
        如果在Update函数中使用格式化输出,很有可能该Update函数每隔一段时间就会出现一次GC.Alloc。但这可能不是由于Update的实际操作导致,而是由于使用性能采样时的格式化输出导致的。
        需要注意格式化字符串本身会带来内存分配开销,使用格式化字符串采样接口时需考虑自身对代码带来的影响。
     
    使用经验:
    1、在可能的热点函数上插入性能采样代码,建议编译手机版本来分析结果。当然,在熟悉代码的前提下,可以方便使用PC测试分析GC Alloc等问题。原因如下:
        1)PC性能相对太好,一些手机上的瓶颈函数在PC上几乎不耗时,导致无法准确分析;
        2)一些代码,特别是插件代码,PC和手机的执行流程不同,PC分析的结果不能准确表明手机也是同样结果。
    2、在插入性能采样代码时,特别留意函数中是否存在多个return的现象。这些return如果没有处理好,就有可能导致性能采样的Begin和End不匹配,导致Profiler显示的结果有误。
    3、对于协程函数,BeginSample、EndSample之间注意不能存在yeild return null,否则可能导致Unity客户端卡死、手机卡死等现象。个人分析:Begin和End配对分析的是单帧结果,出现yeild return null代表该区间将会分两帧甚至多帧完成。
     
    封装好的性能采样接口代码(ProfilerSample.cs):
    复制代码
     1 using UnityEngine;
     2 using System;
     3 
     4 public class ProfilerSample { // by SunboyL
     5     public static bool EnableProfilerSample = true;
     6     public static bool EnableFormatStringOutput = true;// 是否允许BeginSample的代码段名字使用格式化字符串(格式化字符串本身会带来内存开销)
     7 
     8     public static void BeginSample(string name) {
     9 #if ENABLE_PROFILER
    10         if (EnableProfilerSample){
    11             Profiler.BeginSample(name);
    12         }
    13 #endif
    14     }
    15 
    16     public static void BeginSample(string formatName, params object[] args) {
    17 #if ENABLE_PROFILER
    18         if (EnableProfilerSample) {
    19             // 必要时很有用,但string.Format本身会产生GC Alloc,需要慎用
    20             if (EnableFormatStringOutput)
    21                 Profiler.BeginSample(string.Format(formatName, args));
    22             else
    23                 Profiler.BeginSample(formatName);
    24         }
    25 #endif
    26     }
    27 
    28     public static void EndSample() {
    29 #if ENABLE_PROFILER
    30         if (EnableProfilerSample) {
    31             Profiler.EndSample();
    32         }
    33 #endif
    34     }
    35 }
    复制代码

     

    展开全文
  • unity

    2019-09-18 23:54:00
    请用三种方法以上方法,实现物体的抛物线运动。(如,修改Transform属性,使用向量Vector3的方法…) (1)修改Transform属性 抛物运动的原理就是水平方向做匀速运动,竖直方向上做加速度不变的运动,例如让一个...

    1、简答并用程序验证

    • 游戏对象运动的本质是什么?

    游戏运动的本质就是使用矩阵变换(平移、旋转、缩放)改变游戏对象的空间属性。

    • 请用三种方法以上方法,实现物体的抛物线运动。(如,修改Transform属性,使用向量Vector3的方法…)

    (1)修改Transform属性

    抛物运动的原理就是水平方向做匀速运动,竖直方向上做加速度不变的运动,例如让一个物体在x轴和y轴组成的平面上做抛物运动,那么就是z轴的坐标不变,x轴和y轴的坐标改变。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class move1 : MonoBehaviour {  //假设斜上抛
        public float v_start = 10f;  //初始速度
        public float angle = 45f; //假设初始的角度为45°
        public float g = 10f; //重力加速度
    
        private float vx; //初始x轴的速度
        private float vy; //初始y轴的速度
        private float vy1; //y的顺时速度
        private float t;  //时间
    
        void Start() {
            vx = v_start * Mathf.Cos(angle); 
            vy = v_start * Mathf.Sin(angle);
            t = Time.deltaTime;
        }
    
        void Update() {
            Vector3 change = new Vector3(t * vx, vy * t + 0.5f * g * Mathf.Pow(t, 2f) , 0);
            vy1 = vy - g * t;
            this.transform.position += change;
        }
    }
    

    (2)使用向量Vector3的方法

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class move1 : MonoBehaviour {  //假设斜上抛
        public float v_start = 10f;  //初始速度
        public float angle = 45f; //假设初始的角度为45°
        public float g = 10f; //重力加速度
    
        private float vx; //初始x轴的速度
        private float vy; //初始y轴的速度
        private float vy1; //y的顺时速度
        private float t;  //时间
    
        void Start() {
            vx = v_start * Mathf.Cos(angle); 
            vy = v_start * Mathf.Sin(angle);
            t = Time.deltaTime;
        }
    
        void Update() {
            Vector3 change = new Vector3(t * vx, vy * t + 0.5f * g * Mathf.Pow(t, 2f) , 0);
            vy1 = vy - g * t;
            this.transform.position = Vector3.Lerp(transform.position, transform.position + change, 1);
        }
    }
    

    (3)使用transform.Translate方法

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class move1 : MonoBehaviour {  //假设斜上抛
        public float v_start = 10f;  //初始速度
        public float angle = 45f; //假设初始的角度为45°
        public float g = 10f; //重力加速度
    
        private float vx; //初始x轴的速度
        private float vy; //初始y轴的速度
        private float vy1; //y的顺时速度
        private float t;  //时间
    
        void Start() {
            vx = v_start * Mathf.Cos(angle); 
            vy = v_start * Mathf.Sin(angle);
            t = Time.deltaTime;
        }
    
        void Update() {
            Vector3 change = new Vector3(t * vx, vy * t + 0.5f * g * Mathf.Pow(t, 2f) , 0);
            vy1 = vy - g * t;
            this.transform.Translate(change);
        }
    }
    
    • 写一个程序,实现一个完整的太阳系, 其他星球围绕太阳的转速必须不一样,且不在一个法平面上。
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class RotateAroundSun : MonoBehaviour
    {
        public Transform Sun;
        public Transform Mercury; //水星
        public Transform Venus; //金星
        public Transform Earth;
        public Transform Mars; //火星
        public Transform Jupiter; //木星
        public Transform Saturn;  //土星
        public Transform Uranus; //天王星
        public Transform Neptune; //海王星
        public Transform moon;
    
        // Start is called before the first frame update
        void Start()
        {
            Sun.position = Vector3.zero;
        }
    
        // Update is called once per frame
        void Update()
        {
            Mercury.RotateAround(Sun.position, new Vector3(0,1,1), 80 * Time.deltaTime);
            Mercury.Rotate(new Vector3(0,1,1) * 5 * Time.deltaTime);
    
            Venus.RotateAround(Sun.position, new Vector3(0,1,2), 70 * Time.deltaTime);
            Venus.Rotate(new Vector3(0,1,2) * 10 * Time.deltaTime);
    
            Earth.RotateAround(Sun.position, new Vector3(0,5,1), 60 * Time.deltaTime);
            Earth.Rotate(new Vector3(0,5,1) * 15 * Time.deltaTime);
    
            Mars.RotateAround(Sun.position, new Vector3(0,3,1), 50 * Time.deltaTime);
            Mars.Rotate(new Vector3(0,3,1) * 20 * Time.deltaTime);
    
            Jupiter.RotateAround(Sun.position, new Vector3(0,10,1), 40 * Time.deltaTime);
            Jupiter.Rotate(new Vector3(0,10,1) * 25 * Time.deltaTime);
    
            Saturn.RotateAround(Sun.position, new Vector3(0,4,1), 30 * Time.deltaTime);
            Saturn.Rotate(new Vector3(0,4,1) * 30 * Time.deltaTime);
    
            Uranus.RotateAround(Sun.position, new Vector3(0,2,1), 20 * Time.deltaTime);
            Uranus.Rotate(new Vector3(0,2,1) * 35 * Time.deltaTime);
    
            Neptune.RotateAround(Sun.position, new Vector3(0,8,1), 10 * Time.deltaTime);
            Neptune.Rotate(new Vector3(0,8,1) * 40 * Time.deltaTime);
    
            moon.transform.RotateAround(Earth.position, Vector3.up, 20 * Time.deltaTime);
        }
    }
    

    视频链接:https://v.youku.com/v_show/id_XNDM2NTE2MTc2OA==.html?spm=a2h3j.8428770.3416059.1

    2、编程实践

    (1)游戏对象:牧师,魔鬼,船,河岸,河水

    (2)玩家动作表:

    条件 事件
    船在岸边且岸上至少有一个角色 上船
    船在岸边且船上至少有一个角色 下船
    所有牧师和魔鬼都到达对岸 胜利
    任意一边的岸上魔鬼数量大于牧师数量 失败

    (3)将游戏对象做成预制:
    在这里插入图片描述

    (4)根据MVC架构,将程序分为三个部分:

    • Model:

    Move_model:控制魔鬼,牧师和船的移动。

    Coast_model:控制角色上下船以及船的离岸和靠岸动作。

    Character_model:控制牧师和魔鬼的上船、上岸等动作。

    Boat_model:控制船的运动以及牧师、魔鬼的上下船动作。

    • Controller:用一个场记My_Scene_controller控制所有角色的行为以及交互,另外还有一个导演Director类实现单例模式。
    • View:与用户交互的界面,包括游戏场景,对象的生成,游戏Continue,Pause,Restart功能。两个类ClickGUI和UserGUI。

    基于门面模式,有两个接口,Scene_controller和User_action。Scene_controller由Director控制

    来实现游戏场景的加载,通过User_action接口来控制用户与游戏的互动。
    在这里插入图片描述

    展开全文
  • unity3d 尝试 基于地理定位的 增强现实

    万次阅读 热门讨论 2018-05-22 22:41:52
    基于地理定位的增强现实,AR全息实景,是一种高大上的说法,说直白点就是山寨类似随便走这样的应用。打开应用,搜索周边信息,然后再把信息叠加在摄像头拍摄到的内容上面。思路:用手机移动来控制unity中的camrea,...

    首先说,这个尝试失败,属于死在去医院的路上那种。


    基于地理定位的增强现实,AR全息实景,是一种高大上的说法,说直白点就是山寨类似随便走这样的应用。

    打开应用,搜索周边信息,然后再把信息叠加在摄像头拍摄到的内容上面。



    思路:用手机移动来控制unity中的camrea,将摄像头拍摄到的内容作为背景。获取地理信息,将信息转化成文字添加到unity的世界中。


    1、用手机移动控制unity中的camrea。

    这段代码中unity的论坛中找到,但是时间很久远,改了下发现能用。

    http://forum.unity3d.com/threads/sharing-gyroscope-controlled-camera-on-iphone-4.98828/

    using UnityEngine;
    using System.Collections;
    
    public class CameraManager : MonoBehaviour {
    
    
    
    	private bool gyroBool;
    	private Gyroscope gyro;
    	private Quaternion rotFix;
    
    	public void Start ()
    	{
    		Transform currentParent = transform.parent;
    		GameObject camParent = new GameObject ("GyroCamParent");
    		camParent.transform.position = transform.position;
    		transform.parent = camParent.transform;
    		GameObject camGrandparent = new GameObject ("GyroCamGrandParent");
    		camGrandparent.transform.position = transform.position;
    		camParent.transform.parent = camGrandparent.transform;
    		camGrandparent.transform.parent = currentParent;
    
    		gyroBool = SystemInfo.supportsGyroscope;
    
    		if (gyroBool) {
    
    			gyro = Input.gyro;
    			gyro.enabled = true;
    
    			if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
    				camParent.transform.eulerAngles = new Vector3 (90, 90, 0);
    			} else if (Screen.orientation == ScreenOrientation.Portrait) {
    				camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
    			} else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
    				camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
    			} else if (Screen.orientation == ScreenOrientation.LandscapeRight) {
    				camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
    			} else {
    				camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
    			}
    
    			if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
    				rotFix = new Quaternion (0, 0,0.7071f,0.7071f);
    			} else if (Screen.orientation == ScreenOrientation.Portrait) {
    				rotFix = new Quaternion (0, 0, 1, 0);
    			} else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
    				rotFix = new Quaternion (0, 0, 1, 0);
    			} else if (Screen.orientation == ScreenOrientation.LandscapeRight) {
    				rotFix = new Quaternion (0, 0, 1, 0);
    			} else {
    				rotFix = new Quaternion (0, 0, 1, 0);
    			}
    
    			//Screen.sleepTimeout = 0;
    		} else {
    			#if UNITY_EDITOR
    			print("NO GYRO");
    			#endif
    		}
    	}
    
    	public void Update ()
    	{
    		if (gyroBool) {
    			Quaternion quatMap;
    			#if UNITY_IOS
    			quatMap = gyro.attitude;
    			#elif UNITY_ANDROID
    			quatMap = new Quaternion(gyro.attitude.x,gyro.attitude.y,gyro.attitude.z,gyro.attitude.w);
    			#endif
    			transform.localRotation = quatMap * rotFix;
    		}
    	}
    }
    


    2、背景摄像头显示摄像机内容

    摄像头的内容可以显示在guitexure上也可以显示在plan上,但是在guitexrue上显示的时候,方向转了90度,最后只好显示在plan上。

    using UnityEngine;
    using System.Collections;
    
    public class WebCamManager : MonoBehaviour {
    
    	// Use this for initialization
    	void Start () {
    
    		WebCamTexture webcamTexture = new WebCamTexture ();
    
    		//如果有后置摄像头,调用后置摄像头
    		for (int i = 0; i < WebCamTexture.devices.Length; i++) {
    			if (!WebCamTexture.devices [i].isFrontFacing) {
    				webcamTexture.deviceName = WebCamTexture.devices [i].name;
    				break;
    			}
    		}
    
    		Renderer renderer = GetComponent<Renderer>();  
    		renderer.material.mainTexture = webcamTexture;  
    		webcamTexture.Play();  
    	}
    }


    3、调用高德地图的地理定位和搜索附近

    详细内容请看我之前的博客

    http://blog.csdn.net/wuyt2008/article/details/50774017

    http://blog.csdn.net/wuyt2008/article/details/50789423


    4、当搜索到内容以后,将名称信息添加到unity的世界里。

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine.UI;
    
    public class ARMange : MonoBehaviour {
    
    	public List<PlaceInfo> places = new List<PlaceInfo>();
    	public GameObject perfab;
    	public PlaceInfo location = new PlaceInfo ();
    
    	public void ShowPlaces(){
    		ClearPlace ();
    
    		for (int i = 0; i < places.Count; i++) {
    
    			GameObject newPlace = Instantiate<GameObject> (perfab);
    			newPlace.transform.parent = this.transform;
    
    			double posZ = places [i].Latitude - location.Latitude;
    			double posX = places [i].Longitude - location.Longitude;
    
    			float z = 0;
    			float x = 0;
    			float y = 0;
    
    			if (posZ > 0) {
    				z = 500f;
    			} else {
    				z = -500f;
    			}
    
    			if (posX > 0) {
    				x = 500f;
    			} else {
    				x = -500f;
    			}
    
    			z = z + (float)(posZ * 1000);
    			x = x + (float)(posX * 1000);
    			y = y + i * 20;
    
    			newPlace.transform.position = new Vector3 (x, y, z);
    			newPlace.transform.LookAt (this.transform);
    			newPlace.transform.Rotate (new Vector3 (0f, 180f, 0f));
    
    			newPlace.gameObject.GetComponentInChildren<Text> ().text = places [i].Name;
    		}
    	}
    
    	private void ClearPlace(){
    		GameObject[] oldPlaces = GameObject.FindGameObjectsWithTag ("Place");
    		for (int i = 0; i < oldPlaces.Length; i++) {
    			Destroy (oldPlaces [i].gameObject);
    		}
    	}
    
    }


    5、这个时候显示内容没问题,但是方向会偏移。于是加了个指南针来矫正方向

    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;
    
    public class CompassManage : MonoBehaviour {
    
    	public Transform cam;
    
    	void Start () {
    		Input.location.Start ();
    		Input.compass.enabled = true;
    	}
    	
    	// Update is called once per frame
    	void Update () {
    		transform.rotation = Quaternion.Euler(0, cam.eulerAngles.y-Input.compass.trueHeading, 0);
    	}
    }


    6、最后遇到的,我无法解决的问题

    简单一句话,就是滤波。这个应用需要准确稳定的判断出当前手机方向位置状态,但是,输入的内容,重力,罗盘,加速度都是在不断变化,并且会有偏移的量,需要滤波。

    虽然大致知道了是应该用互补滤波和卡尔曼滤波,但是,我的水平只能看懂名字,看不懂内容。

    数学无力的我只好放弃。等遇到别人写好的代码再抄下吧。


    这是死在半路上的结果的样子




    这样的结果呢,当然是不甘心的,但是没时间去仔细研究这个问题了,所以只好放弃。如果哪位大侠知道怎么根据重力,罗盘,加速判断手机状态的,在这里跪求先。

    源码和编译的apk:http://download.csdn.net/detail/wuyt2008/9458508

    ====================



    在SearchManage.cs文件中,我把搜索范围限定在了昆明,

    			//txtInfo.text = txtInfo.text + "\r\n";
    			AndroidJavaObject query = amapHelper.Call<AndroidJavaObject>("getPoiSearch",inputQuery.text,"","0871");
    			txtInfo.text = txtInfo.text + "query get...";
    将0871改成其他地方的区号就可以了,(为空是全国范围,但是没验证过)
    展开全文
  • 基于Unity3D的人脸动态贴纸的实现,利用openCv人脸识别库,在人脸的指定位置定位显示动态的动画效果,有3类的动画实现,帧动画、骨骼动画、粒子系统动画
  • 【Unity】unity3d 获取手机地理位置

    千次阅读 2016-11-30 11:03:27
    怎么用unity3d 获取手机地理位置呢?unity的某些场景中,如果需要定位地理位置的话,但是unity却没有提供相应的接口。对于安卓(这里举例,IOS暂没研究)这个时候只能用java写个获取地理位置的方法,然后与unity交互...

    怎么用unity3d 获取手机地理位置呢?unity的某些场景中,如果需要定位地理位置的话,但是unity却没有提供相应的接口。对于安卓(这里举例,IOS暂没研究)这个时候只能用java写个获取地理位置的方法,然后与unity交互。这样就能在unity脚本中获取当前手机的地理位置。 实际开发时,为了方便我直接调用百度的API来获取地理信息。 获取地理位置,有三种方式: 

       1、手机信号塔数据:当移动设备的GPS芯片不能接收到GPS信号时,移动设备就需要与它所连接的手机信号塔通讯和估算它与信号塔之间的距离以不断报告它的地理位置。通过这种方法获得的地理位置数据不如纯粹的GPS数据精确。

         2、WiFi连接:这是一种能够精确获得地理位置数据的方法,但是需要用到有效的WiFi热点。WiFi的地址与GPS坐标是一一对应的。它可以准确地标示出用户所处的位置,因此很多零售商才愿意提供免费的公共WiFi服务,那样它们就能够发布店内移动广告了。

         3、IP地址:地理位置也可以通过与数据连接有关的IP地址来获得。这种方法的准确性会因运营商而异,可靠性也比上述方法要低一些。

         4、GPS:精确,无需连接网络,但是连接时比较耗时。。

        用百度API调用时,首先需要申请一个key。具体的可以去官网试试。根据IP地址调用,比较方便,因为可以直接用http的方式发送请求,然后返回json格式的数据,如下:


    public class AddressTool{
                    //ip为空,默认为本机ip
                    public static IEnumerator GetAddressFromIP(string ipAddress, AddressForQueryIPFromBaidu data)
                    {
                            string baiduKey = "42c43828c02a9f6144dd305643ca73b8";
                            //ip:ip地址(可选,ip不出现,或者出现且为空字符串的情况下,会使用当前访问者的IP地址作为定位参数),ak:用户密钥,
                        //coor:输出的坐标格式(可选,coor不出现时,默认为百度墨卡托坐标;coor=bd09ll时,返回为百度经纬度坐标) 
                            string url = "http://api.map.baidu.com/location/ip?ak="+baiduKey+"&coor=bd09ll&ip=202.198.16.3";
                            WWW w = new WWW(url);
                            //超时时间
                            float t = Time.time;
                            while(!w.isDone){
                                    if(Time.time - t > 15f){
                                            Debug.Log("server time out!");
                                            w.Dispose();
                                            yield break;
                                    }
                                    yield return null;
                            }
                            //接收http请求返回的数据(json格式)
                            string jsonData = w.text;
                //解析成对象
                            AddressForQueryIPFromBaidu result =  (AddressForQueryIPFromBaidu)ValueParse.ParseJsonToClass(typeof(AddressForQueryIPFromBaidu), jsonData);
                    }
            }
            #region AddressForQueryIPFromBaidu
            public class AddressForQueryIPFromBaidu
            {
                    //地址 
                    public string address { get; set; }
                    //详细内容  
                    public Content content { get; set; }
                    //返回状态码
                    public string status { get; set; }
     
    //                public string ToString(){
    //                        return string.Format("根据IP获取地理位置 地址:{0}, 详细内容:{1},返回状态码:{2}",address.ToString(),content,status);
    //                }
            }
            public class Content
            {
                    //简要地址 
                    public string address { get; set; }
                    //详细地址信息
                    public Address_Detail address_Detail { get; set; }
                    //百度经纬度坐标值  
                    public Point point { get; set; }
            }
            public class Address_Detail
            {
                    //城市  
                    public string city { get; set; }
                    //百度城市代码  
                    public string city_Code { get; set; }
                    //区县 
                    public string district { get; set; }
                    //省份
                    public string province { get; set; }
                    //街道
                    public string street { get; set; }
                    //门址
                    public string street_Number { get; set; }
            }
            public class Point
            {
                    public string x { get; set; }
                    public string y { get; set; }
            }


    IP定位的结果精度较差,主要应用获取省份或者城市的位置信息。百度android定位SDK是利用设备当前的GPS信息(GPS定位),网络信息(基站定位 和 Wi-Fi定位)完成定位的。开发者在应用中成功集成百度定位SDK(包括一个armeabi的文件夹也得放在libs中)以后,既可以方便的通过定位SDK的接口向百度定位服务请求位置信息。下载百度定位的SDK,导入到安卓工程中。相关Android代码,如下:

    package com.zs.address;
    import org.json.JSONException;
    import org.json.JSONObject;
    import android.annotation.SuppressLint;
    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.Menu;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    import com.baidu.location.BDLocation;
    import com.baidu.location.BDLocationListener;
    import com.baidu.location.LocationClient;
    import com.baidu.location.LocationClientOption;
    import com.baidu.location.LocationClientOption.LocationMode;
    import com.unity3d.player.UnityPlayer;
    import com.unity3d.player.UnityPlayerActivity;
     
    @SuppressLint("NewApi")
    public class MainActivity extends UnityPlayerActivity{
            public LocationClient mLocationClient = null;
            public BDLocationListener mListener = new MyLocationListener();
     
    //        private TextView text;
    //        private Button againBtn, clearBtn, startBtn, stopBtn;
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    //setContentView(R.layout.activity_main);
                    //initView();
                    //初始化百度定位SDK
                    initLocationService();
            }
             
            @SuppressLint("NewApi")
            public void initLocationService() {
                    // 声明LocationClient类
                    mLocationClient = new LocationClient(getApplicationContext());
                    mLocationClient.registerLocationListener(mListener);//注册监听函数
                     
                    LocationClientOption option = new LocationClientOption();
                    option.setLocationMode(LocationMode.Hight_Accuracy);// 设置定位模式
                    option.setCoorType("gcj02");// 返回的定位结果,默认值gcj02
                    option.setScanSpan(5000);// 设置发起定位请求的间隔时间为5000ms
                    option.setIsNeedAddress(true);// 返回的定位结果包含地址信息
                    option.setNeedDeviceDirect(true);// 返回的定位结果包含手机机头的方向
                    option.setOpenGps(true);//
                    mLocationClient.setLocOption(option);
                    mLocationClient.requestLocation();
            }
             
            //启动定位服务,给unity调用
            public void startLocationService(){
                    mLocationClient.start();
            }
            //停止定位服务,给unity调用
            public void stopLocationService(){
                    mLocationClient.stop();
            }
     
            class MyLocationListener implements BDLocationListener{
                    @Override
                    public void onReceiveLocation(BDLocation location) {
                            // public int getLocType ( )返回值:
                            // 61 : GPS定位结果
                            // 62 : 扫描整合定位依据失败。此时定位结果无效。
                            // 63 : 网络异常,没有成功向服务器发起请求。此时定位结果无效。
                            // 65 : 定位缓存的结果。
                            // 66 : 离线定位结果。通过requestOfflineLocaiton调用时对应的返回结果
                            // 67 : 离线定位失败。通过requestOfflineLocaiton调用时对应的返回结果
                            // 68 : 网络连接失败时,查找本地离线定位时对应的返回结果
                            // 161: 表示网络定位结果
                            // 162~167: 服务端定位失败
                            // 502:key参数错误
                            // 505:key不存在或者非法
                            // 601:key服务被开发者自己禁用
                            // 602:key mcode不匹配
                            // 501~700:key验证失败
                            if (location == null)
                                    return;
                            JSONObject jo = new JSONObject();
                            try {
                                    jo.put("error_code", location.getLocType());
                                    jo.put("time", location.getTime());
                                    jo.put("latitude", location.getLatitude());//获取维度
                                    jo.put("lontitude", location.getLongitude());//获取经度
                                    jo.put("radius", location.getRadius());
                                    jo.put("direction", location.getDirection());
                                    //只有使用GPS定位的情况下,获取移动速度,当前连接的卫星编号
                                    if(location.getLocType() == BDLocation.TypeGpsLocation){
                                            JSONObject gpsInfo = new JSONObject();
                                            gpsInfo.put("speed", location.getSpeed());
                                            gpsInfo.put("satellite", location.getSatelliteNumber());
                                            jo.put("gpsInfo", gpsInfo);
                                    }else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
                                            // 只有使用网络定位的情况下,才能获取当前位置的反地理编码描述。
                                            // 自定位SDK2.6版本之后,支持获取省/市/区分级地理信息:
                                            JSONObject netWorkInfo = new JSONObject();
                                            netWorkInfo.put("address", location.getAddrStr());//获取反地理编码
                                            netWorkInfo.put("province", location.getProvince());//获取省份信息
                                            netWorkInfo.put("city", location.getCity());//获取城市信息
                                            netWorkInfo.put("city_code", location.getCityCode()); //获取城市编码
                                            netWorkInfo.put("district", location.getDistrict()); //获取区县信息
                                            netWorkInfo.put("street", location.getStreet()); //获取街道地址
                                            netWorkInfo.put("street_number", location.getStreetNumber()); //获取街道门牌号
                                            jo.put("netWorkInfo", netWorkInfo);
                                    }
                            } catch (JSONException e1) {
                                    Log.i("address", e1.toString());
                            }
                             
                            Log.i("address", jo.toString());
                            //将获取的地理信息返回给unity
                            UnityPlayer.UnitySendMessage("address", "AddressCallback", jo.toString());
                            //text.setText(jo.toString());
                    }
            }
             
            private void requestLocation() {
                    mLocationClient.requestLocation();
            }
            @Override
            public boolean onCreateOptionsMenu(Menu menu) {
                    // Inflate the menu; this adds items to the action bar if it is present.
                    getMenuInflater().inflate(R.menu.main, menu);
                    return true;
            }
     
    //        private void initView(){
    //                text = (TextView)findViewById(R.id.textView);
    //                againBtn = (Button)findViewById(R.id.button1);
    //                clearBtn = (Button)findViewById(R.id.button2);
    //                startBtn = (Button)findViewById(R.id.button3);
    //                stopBtn = (Button)findViewById(R.id.button4);
    //                againBtn.setOnClickListener(clickListener);
    //                clearBtn.setOnClickListener(clickListener);
    //                startBtn.setOnClickListener(clickListener);
    //                stopBtn.setOnClickListener(clickListener);
    //        }
    //        
    //        private View.OnClickListener clickListener = new View.OnClickListener() {
    //                public void onClick(View v) {
    //                        switch (v.getId()) {
    //                        case R.id.button1:
    //                                requestLocation();
    //                                break;
    //                        case R.id.button2:
    //                                text.setText("");
    //                                break;
    //                        case R.id.button3:
    //                                startLocationService();
    //                                break;
    //                        case R.id.button4:
    //                                stopLocationService();
    //                                break;
    //                        default:
    //                                break;
    //                        }
    //                }
    //        };
    }

    设置AndroidManifest.xml
    在application标签中声明service组件,这是百度SDK的定位service

    <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote">
    </service>
    声明使用权限

    <!-- 这个权限用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
    <!-- 这个权限用于访问GPS定位-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
    <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
    <!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
    <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
    <!-- 用于读取手机当前的状态-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
    <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <!-- 访问网络,网络定位需要上网-->
    <uses-permission android:name="android.permission.INTERNET" />
    <!—SD卡读取权限,用户写入离线定位数据-->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
    <!--允许应用读取低级别的系统日志文件 -->
    <uses-permission android:name="android.permission.READ_LOGS"></uses-permission>

    把MainActivity的一些注释打开,然后继承Activity,就可以直接做成app在手机上运行了。该项目demo,在本文最后。

           接下来就是把该安卓项目的代码打成jar包,然后放在unity项目资源下的Plugins->Android目录下。再把libs(里面只能放百度的第三方jar包,不要把unity的class.jar,和Android的jar包放在里面)、res文件夹、AndroidManifest,也放在Android目录下。在场景中放上一个空物体,名为‘address’(必须和java代码中“UnityPlayer.UnitySendMessage("address", "AddressCallback", jo.toString());”保持一致),编写一个脚本“AddressTest.cs”,绑在该空对象上面。,该脚本如下:

    using UnityEngine;
    using System.Collections;
    using address;
    public class AddressTest : MonoBehaviour {
            //地理信息 
            private string geography = "lala haha wawa";
            private GUIStyle style = new GUIStyle();
     
            private int count = 0;
            private AndroidJavaObject jo;
     
            public void Awake(){
                    //GUI样式 
                    style.fontSize = 30;
                    style.wordWrap = true;
                    //初始化安卓的MainActivity。下面两句话是固定的,不能变动
                    AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
                    jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
            }
     
            //回调函数,接收到地理信息,展示在页面上。 
            public void AddressCallback(string jsonStr){
                    Debug.Log("zs : "+jsonStr);
                    geography = "第"+ (++count).ToString()+"次接受信息:" + jsonStr;
            }
     
            void OnGUI(){
                    GUI.Label(new Rect(0,0,700,300),geography,style);
                    //启动地理服务
                    if(GUI.Button(new Rect(0, 400,60,30)," 启 动 ")){
                            jo.Call("startLocationService");
                    }
                    //关闭地理服务
                    if(GUI.Button(new Rect(140, 400,60,30)," 停 止 ")){
                            jo.Call("stopLocationService");
                    }
            }
    }

    转载地址:http://www.taikr.com/article/351
    展开全文
  • (一张最原始的Unity3D中音乐可视化粒子海的图,想象一下,如果这幅场景出现在虚拟设备中,辅以根据音乐频谱变化的色彩与悦动频率,会是怎样的效果呢?) Unity3D有着非常完备的虚拟三维场景交互开发功能,以...
  • 本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/2bY7A6ihK9IMcA0bOFyB-Q导语xLua是Unity3D下Lua编程解决方案,自2016年初推广以来,已经应用于十多款腾讯...
  • 【参考原文】Unity填坑笔记——记一次“内存泄露”的排查 1.起因 游戏上线之前大约不到一周的时间,安卓和iOS包都提给渠道之后,合作方的质检部门给出了一个测试报告,说我们游戏有严重的内存泄露…… 我裤子都……...
  • 为什么80%的码农都做不了架构师?>>> ...
  • 《物联网IoT解决方案》 版本 作者 参与者 完成日期 备注 YanlzVR_IoT_V01_1.0 严立钻 2020.05.05 ......
  • 网站运营最全总结

    万次阅读 2012-11-25 00:29:15
    老骥伏枥,志在千里;烈士暮年,壮心不已。溪云初起日沉阁,山雨欲来风满楼。疏影横斜水清浅,暗香浮动月黄昏。举头望明月,低头思故乡。吟安一个字,捻断数茎须。 第一部分:网站运营基础知识  ...
  • 使用Unity的50个建议

    2014-12-24 12:25:15
    关于这些建议 这些建议并不适用于所有的项目 ...例如:使用专业化的组合而不是使用实例就很不像Unity的作风,价格也很高。即使看上去挺疯狂的,但我还是看到了这些建议给开发者带来了利益。   过程方面
  • 主要内容第一章 虚拟现实(视景仿真、系统仿真、可视化)系统介绍第二章 虚拟现实系统对硬件技术要求第三章 行业应用VR工作站配置方案&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;VR应用1-视景仿真与训练...
  • 【翻译】Unity2017.3 版本发布说明

    千次阅读 2020-05-26 16:42:50
    简介 推荐 新内容 编辑器与引擎 ...变换工具 (Transform Tool) 图像 (Graphics) ...Unity Teams Unity Analytics 发布说明( Release notes) 原文作者为: Carlos Rincon。 简介 2017.3完善了...
  • 最近两年虚拟现实(Virtual Reality,简称VR)从刚刚走进公众视野到逐渐变得炙手可热,很多不同领域的IT开发者都想进入虚拟现实领域。本篇文章将首先讲解VR入门所需要学习的知识,然后从VR软硬件入手,针对当前的VR...
  • 帮助用户解决unity,cocos2D-x,html5等游戏开发相关技术疑问,同时也有创业者在活动过程中问到了商业化的问题,TestBird工程师也针对其提出的问题进行了回答。以下是本人为大家整理出来的Q&A,看看开发者们在论坛...
  •  ... 每个手机里都有IMU。...IMU实现三自由度(相当于人的前庭系统)算出加速度和方向,就像你走路的时候可以加速减速走,也可以拐弯。 &amp;amp;lt;img src=&#8221;https://pic2.zhimg.com/e0e18
  • 本节书摘来自华章出版社《Unity虚拟现实开发实战》一书中的第3章,第3.6节虚拟现实设备的运行原理,作者[美] 乔纳森·林诺维斯,更多章节内容可以访问云栖社区“华章计算机”公众号查看。 3.6虚拟现实设备的运行原理...
  • 最近做了一个小的APP,并且嵌入了多盟广告平台的广告,以下小结一下如何嵌入多盟广告: ... 步骤一,下载多盟广告SDK,将 domob_android_sdk.jar 导入想要嵌入广告的的工程中。 1. 右键您的工程根目录,选择...
1 2 3 4 5
收藏数 98
精华内容 39
关键字:

unity3d实现手机精准定位