2016-11-30 11:03:18 ldy597321444 阅读数 8668
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4712 人正在学习 去看看 张刚

怎么用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

2013-07-20 14:59:28 a2587539515 阅读数 3218
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4712 人正在学习 去看看 张刚

账号被盗,文章被修改,博主已将博文删除

2017-07-06 09:49:27 fuemocheng 阅读数 982
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4712 人正在学习 去看看 张刚

Unity3D判断当前所在平台

官方文档:https://docs.unity3d.com/Manual/PlatformDependentCompilation.html


主要的几个平台:

    #if UNITY_ANDROID
        Debug.Log("安卓设备");
    #endif

    #if UNITY_IOS
        Debug.Log("苹果设备");
    #endif

    #if UNITY_STANDALONE_WIN
        Debug.Log("Windows");
    #endif   

其他平台:

UNITY_EDITOR    #define directive for calling Unity Editor scripts from your game code.
UNITY_EDITOR_WIN    #define directive for Editor code on Windows.
UNITY_EDITOR_OSX    #define directive for Editor code on Mac OS X.
UNITY_STANDALONE_OSX    #define directive for compiling/executing code specifically for Mac OS X (including Universal, PPC and Intel architectures).
UNITY_STANDALONE_WIN    #define directive for compiling/executing code specifically for Windows standalone applications.
UNITY_STANDALONE_LINUX  #define directive for compiling/executing code specifically for Linux standalone applications.
UNITY_STANDALONE    #define directive for compiling/executing code for any standalone platform (Mac OS X, Windows or Linux).
UNITY_WII   #define directive for compiling/executing code for the Wii console.
UNITY_IOS   #define directive for compiling/executing code for the iOS platform.
UNITY_IPHONE    Deprecated. Use UNITY_IOS instead.
UNITY_ANDROID   #define directive for the Android platform.
UNITY_PS4   #define directive for running PlayStation 4 code.

判断多个条件,利用 || 或者 && 组合

#if UNITY_IOS || UNITY_ANDROID
    //这里的代码在IOS和Android平台都会编译
#endif

#if UNITY_ANDROID && UNITY_EDITOR
    //这里的代码只有在发布设置设置的是Android,且在编辑器里运行时才会编译
#endif

运行时判断

详见官网:https://docs.unity3d.com/ScriptReference/RuntimePlatform.html

    if (Application.platform == RuntimePlatform.Android 
        || Application.platform == RuntimePlatform.IPhonePlayer)
    {
    }
2013-01-21 14:53:57 jeksonal 阅读数 16779
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4712 人正在学习 去看看 张刚

unity3D 用3DMax 做的模型时需要注意几点

1:方向问题
2:模型尺寸问题

3:模型所占资源大小问题

 

3DMax 做的东西导入到 Unity3D 中,在 Unity3D 引擎中 X 会被反向旋转 90 度();个人处理方式是建模时先将模型 X 轴旋转 90;再调节模型;

3DMax 做的东西导入到 Unity3D 中,由于 3DMax 默认的单位处理机制与 Unity3D 不一样,而导致显示过小的问题;所以,在制作模型前先调节好 3DMax 中的系统单位设置

具体操作:

 菜单栏: 选择 “自定义”  ,

再选择 “单位设置”-- >

 接着点选 “系统单位设置 ”  --->   将系统单位比例设置成:  ;再点击 “ 确定” 保存!

在模型的制作过程当中,为了使物体的坐标在物体的中心点,要记得冻结物体的坐标属性

当模型制作完成时,导出为 FBX 格式时还需注意:

在导出的 设置面板中 :

点击高级选项,然后出现:

确保 “ 场景单位转化为:”的设置为 "Meters"


模型导出后,模型资源可能很大,原因有以下几个:

1: 检测一下材质贴图的格式是否为:.png 的,不是请改过来 ;

2:看模型当中是否有过多的独立存在的物体,将不需要单独 存在给它合并在一块!


要是模型导入到Unity3D 中后,引擎运行变卡,就得看看模型的面是不是太多了!


2019-09-23 14:03:16 wk201403010114 阅读数 15
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4712 人正在学习 去看看 张刚

学习一下关于Unity3d的当前网络状态的情况,分享如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class NetWorkPlatform : MonoBehaviour
{
    public Text OutPutText;
    // Use this for initialization
    void Start()
    {
        OutPutText.text = "";
        IsNetWorkReachability();
    }


    public void IsNetWorkReachability()
    {
        switch (Application.internetReachability)
        {
            case NetworkReachability.ReachableViaLocalAreaNetwork:
                Debug.Log("当前使用的是WIFI,请放心使用!");
                OutPutText.text = "当前使用的是WIFI,请放心使用!";
                break;
            case NetworkReachability.ReachableViaCarrierDataNetwork:
                Debug.Log("当前使用的是移动网络,是否继续更新!");
                OutPutText.text = "当前使用的是移动网络,是否继续更新!";
                break;
            case NetworkReachability.NotReachable:
                Debug.Log("当前没有联网,请您先联网后进行操作!");
                OutPutText.text = "当前没有联网,请您先联网后进行操作!";
                break;
            default:
                break;
        }
    }
}
 

没有更多推荐了,返回首页