2016-12-15 21:52:28 virus2014 阅读数 11787


一、从Unity中导出安卓工程

导出工程时注意的问题:

(1)PlayerSetting中的bundle identifier要设置一下


(2)工程签名的制作

进入DOS界面,进去D:\ProgramFiles\Java\jdk1.6.0_10\bin>目录下,输入keytool -genkey -alias android.keystore -keyalg RSA -validity 100000 -keystore android.keystore参数意义:-validity主要是证书的有效期,写100000天;空格,退格键都算密码。命令执行后会在 D:\ProgramFiles\Java\jdk1.6.0_10\bin 目录下生成android.keystore文件。

(3)导出



二、将导出的项目利用eclipse接入百度地图SDK并生成jar包

我的eclipse工程目录:


资源的导入是参照百度地图SDK接入指南的:http://lbsyun.baidu.com/index.php?title=androidsdk/guide/introduction

其中res/layout下的布局xml文件来自下载的BaiduLBS_AndroidSDK_Sample,具体路径是BaiduLBS_AndroidSDK_Sample\BaiduMap_AndroidSDK_v4.1.1_Sample\BaiduMapsApiDemo\res\layout

bin目录下生成了jar文件是原理:鼠标工程名字上右键Properties属性,勾选Is Library,之后在每次Project/Build All就可以实现更新;如下图所示:


下面是各个文件里面的代码


主入口文件MainActivity.java

package com.zhf;

import android.content.Intent;
import android.os.Bundle;

import com.unity3d.player.UnityPlayerActivity;

public class MainActivity extends UnityPlayerActivity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}
	
	public String getStringInJava() {
		return "i am a string from java";
	}
	
	public void OpenNewScene() {
		Intent intent = new Intent(MainActivity.this, EmptyScene.class);
		this.startActivity(intent);
	}
	public void OpenBaiduMap() {
		Intent intent = new Intent(MainActivity.this, MyBaiduMapActivity.class);
		this.startActivity(intent);
	}
}


EmptyScene.java

package com.zhf;

import android.app.Activity;
import android.os.Bundle;

public class EmptyScene extends Activity {
	
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}
}

MyBaiduMapActivity.java

package com.zhf;

import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.MapView;

import android.app.Activity;
import android.os.Bundle;

public class MyBaiduMapActivity extends Activity {
	
	MapView mMapView = null;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		
		SDKInitializer.initialize(getApplicationContext());
		setContentView(R.layout.activity_main);
        
        mMapView = (MapView) findViewById(R.id.bmapView);
	}
    @Override
    protected void onDestroy() {
        super.onDestroy();  
        //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理  
        mMapView.onDestroy();
    }
    @Override
    protected void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理 
        mMapView.onResume();
    }
    @Override  
    protected void onPause() {  
        super.onPause();
        //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理  
        mMapView.onPause();  
    }
}


布局文件Activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <com.baidu.mapapi.map.MapView
        android:id="@+id/bmapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true" />

</LinearLayout>


主配置文件AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.zhf" android:versionName="1.0" android:versionCode="1" android:installLocation="preferExternal">
  <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
  <application android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:icon="@drawable/app_icon" android:label="@string/app_name">
    
    <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="F7lsGhPU9a6XWiMIi6EbSTbsORx6zKr8" />
      
    <activity android:label="@string/app_name" android:screenOrientation="fullSensor" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale" android:name="com.zhf.MainActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
      </intent-filter>
      <meta-data android:name="unityplayer.UnityActivity" android:value="true" />			
    </activity>
    
    <activity android:name="com.zhf.EmptyScene" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
    </activity>
    
    <activity android:name="com.zhf.MyBaiduMapActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
    </activity>
    
	</application>
	<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" />
	<uses-feature android:glEsVersion="0x00020000" />
	<uses-permission android:name="android.permission.INTERNET" />
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
	<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
	<uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
	<uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
  
	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
	<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
	<uses-permission android:name="android.permission.WAKE_LOCK"/>
	<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
	<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
	<uses-permission android:name="android.permission.GET_TASKS" />
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
	<uses-permission android:name="android.permission.WRITE_SETTINGS" />
  
</manifest>

Build All 完毕

三、将导出的jar包应用到Unity中,实现SDK接入

需要导入到Unity中的文件(划了黑线的不要,以及armeabi-v7a中libmain.so、libmono.so和libunity.so文件不要):


在Unity中的视图结构:


必须在Plugins下面的Android目录下,注意assets是来自这里:


上面assets目录没有放到Unity工程中,程序运行了就崩溃,耗了一天时间找bug


四、编写C#脚本,实现交互

完成上面的之后新建一个场景,加入一个UGUI的Text控件,新建一个脚本Test

Test.cs代码:

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

public class Test : MonoBehaviour {


    public Text text;
	void Update () {
        if (Input.GetKeyDown(KeyCode.Escape) || Input.GetKeyDown(KeyCode.Home)) {
            Application.Quit();
        }
	}

    void OnGUI() {
        if (GUILayout.Button("Open Map", GUILayout.Height(100)))
        {
            AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
            jo.Call("OpenBaiduMap");
        }

        if (GUILayout.Button("Open New Scene", GUILayout.Height(100)))
        {
            AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
            jo.Call("OpenNewScene");
        }

        if (GUILayout.Button("改变Label___New", GUILayout.Height(100)))
        {
            AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
            text.text = jo.Call<string>("getStringInJava");
        }

    }
}

脚本挂载在相机上,Text控件拖上去,然后开始打包

打包时注意:Player Setting中的 bundle identifier要填上对应的包名



end


2018-11-23 15:57:50 yangxuan0261 阅读数 658

title: unity-接入百度地图定位-android篇(AndroidStudio)
categories: Unity3d
tags: [unity, android, jni, 交互, 百度地图定位]
date: 2018-11-22 17:39:18
comments: false


前置物料

  1. 先准备好keystore的sha1值. 参考 [安卓提取 sha1](#安卓提取 sha1)
  2. 上百度开放平台申请 ak. 填入 开发版 和 发行版 的 sha1 及 应用的报名 (必须和unity中的一致)

使用 android studio 打包 unity 使用的插件jar


接入百度地图

在上面打包jar插件的基础上, 增加几步就ok

  1. 将使用到的百度地图的相关 lib (jar, so动态库) 和 打包出的jar 都拷贝到 Unity 的 Assets\Plugins\Android\libs 目录下

  2. 修改一下 Assets\Plugins\Android 下的 AndroidManifest.xml 文件.

    1. 加入相关的权限. 可以参考官方demo 或者官方文档

    2. 填入申请好的 ak 值

       <!-- AK鉴权 -->
              <meta-data
                  android:name="com.baidu.lbsapi.API_KEY"
                  android:value="EHvsdfsdfsdfsdfsdfsdfsdfsdfsdfsdf" />
      
  3. 然后就可以打包测试了.


安卓提取 sha1

方法一 (推荐)

其实主要就是签名文件 keystore 文件里的信息, 可以直接找到 debug版本(在 %USER%.android 目录下) 和 release版本(自己生成) 的 keystore文件 拿出来查看一下就行.

>keytool -list -v -keystore debug.keystore
证书指纹:
         MD5: 20:06:20aaaaaaaaaaaaaaaaaaaaa
         SHA1: 11:E3:F8:aaaaaaaaaaaaaaaaaaa

方法二

安卓apk 包用 压缩工具打开, 找到 META-INF/ANDROIDD.RSA 文件, 提取出来, 然后使用java工具 keytool.exe (在%JDK%/bin 目录下) 打开,

> keytool -printcert -file ANDROIDD.RSA

参考: http://www.voidcn.com/article/p-gpujntey-ps.html


android studio 如何修改包名

参考: https://www.jianshu.com/p/557e1906db1a


查看 keystore 信息

  • 命令:

    >keytool -list -v -keystore aaa.keystore
    证书指纹:
             MD5: 08:D2:FA:87:aaaaaaaaaaaaaaaaaaaaaa
             SHA1: D8:18:67:Caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    

百度定位踩坑

  • 报错: NetWork location failed because baidu location service check the key is unlegal, please check the key in AndroidManifest.xml

    • 包名不对. android studio 修改包名 (refactor -> rename) 后还得修改 build.gradle(Module) 中的包名 applicationId "com.its.ares"AndroidManifest.xml 中的包名 package="com.its.ares"

    • ak 不对. 必须是百度开放平台申请的

      然后配到 AndroidManifest.xml

      <!-- AK鉴权 -->
      <meta-data
                 android:name="com.baidu.lbsapi.API_KEY"
                 android:value="EHvasdasdasdasdasdasdasd" />
      
    • 相关参考: https://alphagao.com/2017/02/23/get-location-in-service-with-baidu-map/



jar构建踩坑

  • android studio 报错: The ANDROID_DAILY_OVERRIDE value is outdated. Please set the ANDROID_DAILY_OVERRIDE environment variable to "21c0aef24ab2b18140facf573fe8f4f258301e2a"

    将 project 的 gradle 的工具改成其他版本, 不要用 alpha版本

        dependencies {
            classpath 'com.android.tools.build:gradle:2.2.0'
    
  • aapt.exe 意外停止. 报错: com.android.ide.common.process.ProcessException: Failed to execute aapt

    原因:在build.gradle文件中,

    compileSdkVersion 和buildToolsVersion 不匹配
    
  • 报错: Failed to resolve:com.android.support:appcompat-v7

    build.gradle 文件中的这个值改成已有的

    dependencies {
    	...
        compile 'com.android.support:appcompat-v7:26.+'
    
  • 构建 gradle 报错: Execution failed for task ':app:lint'

  • 构建gradle报错: Could not get unknown property 'jniLibs' for source set 'main' of type

    字段 sourceSets 放错位置, 应该在 android 标签内

    参考: https://blog.csdn.net/changcsw/article/details/80020851

  • 构建gradle报错: Error converting bytecode to dex xxx

    Edit First Clean and then Make Project also works.

    参考: https://stackoverflow.com/questions/34352591/android-error-converting-byte-to-dex


2018-01-09 16:21:08 qq_35528646 阅读数 499

看到好多小伙伴似乎都想做六边形地图,我刚好在之前的demo里基于Unity3d实现了一个。

六边形地图编辑器怎么弄我就不发了,可以看看TX爸爸出的这篇博客http://gad.qq.com/program/translateview/7173811。

主要是关于寻路,AStar寻路有很多的优化方法,想要优化什么的自行百度,我就发个基础的代码(哪天我得空了可以再放一下分步讲解)。

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

/// <summary>
/// 六边形地图的A*寻路,在使用时先调用AstarMainFunc方法,之后会根据输入的起始点下表改变路径上需要考虑的cell的父节点;
/// 之后该方法将父节点从终点寻址储存到移动功能类中;
/// 因为该节点是从终点寻址到起点,存在先进后出的读取要求,所以推荐用栈存储;
/// 在存储完后在移动功能类中调用ClearFValueAndGValue方法;
/// 在ClearFValueAndGValue方法被调用后才可以再进行下一次寻路;
/// 因此可以有单位同时移动,但不可以有单位同时寻路=》除非所有节点的父节点元素是一个数组;
/// 如果所有节点的父节点元素是一个数组,则在修改本类源码后,可以有该数组长度的数量的单位同时寻路。
/// 2017年12月14日 14:07:03
/// 最后一次修改人:朱珂杰
/// </summary>
class AStarMain : MonoBehaviour
{
    private HexCell[] cellsForAll;
    private List<int> cellsForOpenContainer;
    private List<int> cellsForOpen;
    private List<int> cellsForClose;
    private int currentCellIndex;
    private int hValue;
    /// <summary>
    /// HexGrid中的width,需要在代码中赋值
    /// </summary>
    private int width = 0;
    private int height = 0;

    /// <summary>
    /// 某一点四周所有点的集合,第一个是该点右上角的点,然后按照顺时针直至该点左上角,y坐标为-x-z
    /// 以下为备用元素,在地图大改时可能会需要
    /// </summary>
    //private HexCoordinates[] aroundHexCoordinates = {
    //    new  HexCoordinates (0, 1),
    //    new HexCoordinates(1, 0),
    //    new HexCoordinates(1, -1),
    //    new HexCoordinates(0, -1),
    //    new HexCoordinates(-1, 0),
    //    new HexCoordinates(-1, 1),
    //};
    //private int[] aroundHexCellForIndex;
    public void Awake()
    {
        cellsForOpenContainer = new List<int>();
        cellsForOpen = new List<int>();
        cellsForClose = new List<int>();
    }
    public void Start()
    {
        GetCells();
        width = GameObject.Find("HexPlaneRoot").GetComponent<HexGrid>().width;
        height = GameObject.Find("HexPlaneRoot").GetComponent<HexGrid>().height;
        Debug.Log("得到cells");
    }
    private void GetCells()
    {
        cellsForAll = GameObject.Find("HexPlaneRoot").transform.GetComponentsInChildren<HexCell>();
    }
    /// <summary>
    /// 寻路主函数,先不考虑行数很低时的情况;
    /// 在运行结束后,根据cellForEndIndex下标对应的cell的父节点寻踪直至起始点得到路径
    /// </summary>
    /// <param name="cell">起始点</param>
    public void AstarMainFunc(int cellForBeginIndex, int cellForEndIndex)
    {
        //1,将cellForBegin添加到关闭列表
        cellsForClose.Add(cellForBeginIndex);
        currentCellIndex = cellForBeginIndex;
        AddCellsToOpen();
        while (!cellsForOpen.Contains(cellForEndIndex))
        {
            //遍历开放列表找出所有点中F最小的点
            int fValueMinIndexInOpen = 0;
            if (cellsForOpen.Count > 1)
                for (int i = 1; i < cellsForOpen.Count; i++)
                {
                    //hValue
                    hValue = cellsForAll[cellForEndIndex].coordinates - cellsForAll[cellsForOpen[i]].coordinates;
                    cellsForAll[cellsForOpen[i]].fValue = cellsForAll[cellsForOpen[i]].gValue + hValue;
                    if (cellsForAll[cellsForOpen[i]].fValue < cellsForAll[cellsForOpen[fValueMinIndexInOpen]].fValue)
                        fValueMinIndexInOpen = i;
                }
            //将该点添加到关闭列表中
            cellsForClose.Add(cellsForOpen[fValueMinIndexInOpen]);
            //将该点从开放列表移除
            //没做,忘了,记得补=。=
            currentCellIndex = cellsForOpen[fValueMinIndexInOpen];
            cellsForOpen.RemoveAt(fValueMinIndexInOpen);
            AddCellsToOpen();
        }
        cellsForOpenContainer.Clear();
        cellsForOpen.Clear();
        cellsForClose.Clear();
        ClearFValueAndGValue();
    }
    private void ClearFValueAndGValue()
    {
        foreach (HexCell cell in cellsForAll)
        {
            cell.fValue = 0;
            cell.gValue = 0;
        }
    }
    /// <summary>
    /// 清理所有节点的父节点,在储存完栈后,于调用寻路的类中被调用
    /// </summary>
    public void ClearCellsFather()
    {
        foreach (HexCell cell in cellsForAll)
        {
            cell.hexCellFather = null;
        }
    }
    /// <summary>
    /// 添加当前点四周可添加的点进入开放列表,这个方法结束后,会针对新添加的点和重复的点刷新它内部的父节点和gValue;
    /// 在调用此方法前,需要先对当前点的下表进行标定。
    /// </summary>
    private void AddCellsToOpen()
    {
        //行数,0开始计数
        int row = currentCellIndex / width;
        //取出当前点四周所有的新点进入开放列表
        //这些写完后抽象成方法,因为这部分可能随着地图生成频繁修改
        //左列
        if (currentCellIndex % width == 0)
        {
            //底行,加两个
            if (currentCellIndex / width == 0)
            {
                cellsForOpenContainer.Add(currentCellIndex + width);
                cellsForOpenContainer.Add(currentCellIndex + 1);
            }
            //顶行
            if (currentCellIndex / width == height - 1)
            {
                //偶行,0开始计数,加两个
                if (row % 2 == 0)
                {
                    cellsForOpenContainer.Add(currentCellIndex - width);
                    cellsForOpenContainer.Add(currentCellIndex + 1);
                }
                //奇行,0开始计数,加三个
                else
                {
                    cellsForOpenContainer.Add(currentCellIndex - width);
                    cellsForOpenContainer.Add(currentCellIndex - width + 1);
                    cellsForOpenContainer.Add(currentCellIndex + 1);
                }
            }
            //中间行
            if (currentCellIndex / width > 0 && currentCellIndex / width < height - 1)
            {
                //偶行,0开始计数,加三个
                if (row % 2 == 0)
                {
                    cellsForOpenContainer.Add(currentCellIndex - width);
                    cellsForOpenContainer.Add(currentCellIndex + 1);
                    cellsForOpenContainer.Add(currentCellIndex + width);
                }
                //奇行,0开始计数,加五个
                else
                {
                    cellsForOpenContainer.Add(currentCellIndex - width);
                    cellsForOpenContainer.Add(currentCellIndex - width + 1);
                    cellsForOpenContainer.Add(currentCellIndex + 1);
                    cellsForOpenContainer.Add(currentCellIndex + width);
                    cellsForOpenContainer.Add(currentCellIndex + width + 1);
                }
            }
        }
        //右列
        if (currentCellIndex % width == width - 1)
        {
            //底行,加三个
            if (currentCellIndex / width == 0)
            {
                cellsForOpenContainer.Add(currentCellIndex + width);
                cellsForOpenContainer.Add(currentCellIndex - 1);
                cellsForOpenContainer.Add(currentCellIndex + width - 1);
            }
            //顶行
            if (currentCellIndex / width == height - 1)
            {
                //偶行,0开始计数,加三个
                if (row % 2 == 0)
                {
                    cellsForOpenContainer.Add(currentCellIndex - width);
                    cellsForOpenContainer.Add(currentCellIndex - 1);
                    cellsForOpenContainer.Add(currentCellIndex - width - 1);
                }
                //奇行,0开始计数,加两个
                else
                {
                    cellsForOpenContainer.Add(currentCellIndex - width);
                    cellsForOpenContainer.Add(currentCellIndex - 1);
                }
            }
            //中间行
            if (currentCellIndex / width > 0 && currentCellIndex / width < height - 1)
            {
                //偶行,0开始计数,加五个
                if (row % 2 == 0)
                {
                    cellsForOpenContainer.Add(currentCellIndex - width);
                    cellsForOpenContainer.Add(currentCellIndex - width - 1);
                    cellsForOpenContainer.Add(currentCellIndex - 1);
                    cellsForOpenContainer.Add(currentCellIndex + width);
                    cellsForOpenContainer.Add(currentCellIndex + width - 1);
                }
                //奇行,0开始计数,加三个
                else
                {
                    cellsForOpenContainer.Add(currentCellIndex - width);
                    cellsForOpenContainer.Add(currentCellIndex - 1);
                    cellsForOpenContainer.Add(currentCellIndex + width);
                }
            }
        }
        //中间列
        if (currentCellIndex % width < width - 1 && currentCellIndex % width > 0)
        {
            //底行,加四个
            if (currentCellIndex / width == 0)
            {
                cellsForOpenContainer.Add(currentCellIndex + width);
                cellsForOpenContainer.Add(currentCellIndex + 1);
                cellsForOpenContainer.Add(currentCellIndex - 1);
                cellsForOpenContainer.Add(currentCellIndex + width - 1);
            }
            //顶行,加四个
            if (currentCellIndex / width == height - 1)
            {
                cellsForOpenContainer.Add(currentCellIndex + 1);
                cellsForOpenContainer.Add(currentCellIndex - 1);
                cellsForOpenContainer.Add(currentCellIndex - width + (int)Math.Pow(-1, row + 1));
                cellsForOpenContainer.Add(currentCellIndex - width);
            }
            //中间行,加六个
            if (currentCellIndex / width > 0 && currentCellIndex / width < height - 1)
            {
                cellsForOpenContainer.Add(currentCellIndex + width + (int)Math.Pow(-1, row + 1));
                cellsForOpenContainer.Add(currentCellIndex + width);
                cellsForOpenContainer.Add(currentCellIndex + 1);
                cellsForOpenContainer.Add(currentCellIndex - 1);
                cellsForOpenContainer.Add(currentCellIndex - width + (int)Math.Pow(-1, row + 1));
                cellsForOpenContainer.Add(currentCellIndex - width);
            }
        }
        //判断容器中所有的点是否是可以添加的点,是就添加到开放列表中,全部判断完清空容器
        for (int i = 0; i < cellsForOpenContainer.Count; i++)
        {
            //关闭列表和不允许通过的地型都不考虑
            if (cellsForAll[cellsForOpenContainer[i]].isEnable == false || cellsForClose.Contains(cellsForOpenContainer[i]))
                continue;
            int currentGValue = GetCurrentGValue(cellsForOpenContainer[i]);
            if (!cellsForOpen.Contains(cellsForOpenContainer[i]))
            {
                cellsForOpen.Add(cellsForOpenContainer[i]);
                cellsForAll[cellsForOpenContainer[i]].hexCellFather = cellsForAll[currentCellIndex];
                cellsForAll[cellsForOpenContainer[i]].gValue = currentGValue;
                continue;
            }
            if (cellsForOpen.Contains(cellsForOpenContainer[i]) && cellsForAll[cellsForOpenContainer[i]].gValue <= GetCurrentGValue(cellsForOpenContainer[i]))
                continue;
            if (cellsForOpen.Contains(cellsForOpenContainer[i]) && cellsForAll[cellsForOpenContainer[i]].gValue > GetCurrentGValue(cellsForOpenContainer[i]))
            {
                cellsForOpen.Add(cellsForOpenContainer[i]);
                cellsForAll[cellsForOpenContainer[i]].hexCellFather = cellsForAll[currentCellIndex];
                cellsForAll[cellsForOpenContainer[i]].gValue = GetGValue(cellsForOpenContainer[i]);
                continue;
            }
        }
        cellsForOpenContainer.Clear();
    }

    /// <summary>
    /// 计算cellsForALL列表中某个点的gValue并且返回
    /// </summary>
    /// <param name="i">该点在列表中的序号</param>
    private int GetGValue(int i)
    {
        int gValue = 0;
        HexCell cellContainer = cellsForAll[i];
        while (cellContainer.hexCellFather != null)
        {
            gValue += cellContainer.mapAssessValue;
            cellContainer = cellContainer.hexCellFather;
        }
        return gValue;
    }
    /// <summary>
    /// 假设列表下标为i的点的父节点为当前点,计算出此时的GValue并且不改变该点的父节点
    /// </summary>
    /// <param name="i"></param>
    private int GetCurrentGValue(int i)
    {
        int gValue = 0;
        HexCell cellContainer = cellsForAll[i];
        gValue += cellContainer.mapAssessValue;
        cellContainer = cellsForAll[currentCellIndex];
        while (cellContainer.hexCellFather != null)
        {
            gValue += cellContainer.mapAssessValue;
            cellContainer = cellContainer.hexCellFather;
        }
        return gValue;
    }
}

我在添加一个地格四周的地格时使用的是笨办法,有经验的读者可以自行优化(比如直接获得四周所有的地格,但如果是NULL就剔除什么的),由于六边形地图每次移动和计算的量并不大,我就不做了。

然后是我地格的类HexCell类,这个类大家看看就好,有一些写得不够好的地方请轻喷,本人还是个萌新。

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

public enum CellTypeForTown
{
    townCenter, //城镇中心
    townCell,   //城镇普通地格
    normalCell,  //野外地格
    buildCell   //已经建有建筑物的地格
}

public class HexCell : MonoBehaviour
{
    public CellTypeForTown cellTypeForTown = CellTypeForTown.normalCell;
    private Town town;
    public HexCoordinates coordinates;
    /// <summary>
    /// 父方格,用于A星寻路
    /// </summary>
    //[System.NonSerialized]
    public HexCell hexCellFather;
    public Color color;
    /// <summary>
    /// 地型评估值,表示到达该地需要付出的地形惩罚,负数表示越走行走值越多;
    /// 比如A点到B点,根据B点地型计算惩罚
    /// </summary>
    public int mapAssessValue = 1;
    public bool isEnable = true;
    /// <summary>
    /// 用于ASTAR寻路
    /// </summary>
    public int fValue = 0;
    public int gValue = 0;
    public void SetTownForCell(Town town)
    {
        this.town = town;
    }
    public Town GetTownForCell()
    {
        return this.town;
    }
    public static HexCell FindCellByCoordinates(HexCell[] cells, HexCoordinates coordinates)
    {
        int row = coordinates.Z * Global.instance.width;
        int colum = coordinates.X + coordinates.Z / 2;
        if (colum < 0 || colum > Global.instance.width - 1)
            return null;
        if (row + colum >= 0 && row + colum < cells.Length)
            return cells[row + colum];
        return null;
    }
    public static HexCell FindCellByCoordinates(HexCoordinates coordinates)
    {
        HexCell[] cells = Global.instance.cells;
        int row = coordinates.Z * Global.instance.width;
        int colum = coordinates.X + coordinates.Z / 2;
        if (colum < 0 || colum > Global.instance.width - 1)
            return null;
        if (row + colum >= 0 && row + colum < cells.Length)
            return cells[row + colum];
        return null;
    }
    /// <summary>
    /// 返回-1表示数组越界
    /// </summary>
    public static int GetCellIndexByCoordinates(HexCell[] cells, HexCoordinates coordinates)
    {
        int row = coordinates.Z * Global.instance.width;
        int colum = coordinates.X + coordinates.Z / 2;
        if (colum < 0 || colum > Global.instance.width - 1)
            return -1;
        if (row + colum >= 0 && row + colum < cells.Length)
            return row + colum;
        return -1;
    }
    /// <summary>
    /// 返回-1表示数组越界
    /// </summary>
    public static int GetCellIndexByCoordinates(HexCoordinates coordinates)
    {
        HexCell[] cells = Global.instance.cells;
        int row = coordinates.Z * Global.instance.width;
        int colum = coordinates.X + coordinates.Z / 2;
        if (colum < 0 || colum > Global.instance.width - 1)
            return -1;
        if (row + colum >= 0 && row + colum < cells.Length)
            return row + colum;
        return -1;
    }
    /// <summary>
    /// 根据一个基础cell和附加坐标,得到基础cell坐标+附加坐标的cell对象;如果数组越界,就返回Null
    /// </summary>
    public static HexCell GetCellByAddCoordinatesVector(HexCell[] cells, HexCell basicCell, HexCoordinates addCoordinates)
    {
        HexCoordinates mHexCoordinates = basicCell.coordinates + addCoordinates;
        return FindCellByCoordinates(cells, mHexCoordinates);
    }

    public static List<HexCell> GetCellsAroundCentetByDistance(HexCell[] cells, HexCell centerCell, int distance)
    {
        List<HexCell> townCells = new List<HexCell>();
        int count = distance * distance * 3 + distance * 3 + 1;
        HexCell[] mCells = new HexCell[count];
        int i = 0;
        for (int z = -distance; z <= distance; z++)
            for (int x = -distance; x <= distance; x++)
            {
                int y = -z - x;
                if (y < -distance || y > distance)
                    continue;
                mCells[i] = HexCell.GetCellByAddCoordinatesVector(Global.instance.cells, centerCell, new HexCoordinates(x, z));
                i++;
            }
        for (i = 0; i < count; i++)
        {
            if (mCells[i] != null)
            {
                townCells.Add(mCells[i]);
            }
        }
        return townCells;
    }
    public bool CanSetEntityObjToCell(GameObject obj)
    {
        return CanSetEntityObjToCell(obj.transform);
    }
    public bool CanSetEntityObjToCell(Transform obj)
    {
        return CanSetEntityObjToCell(obj.tag);
    }
    public bool CanSetEntityObjToCell(string objTagName)
    {
        if (objTagName == "Untagged")
            return true;
        Transform[] sons = transform.GetComponentsInChildren<Transform>();
        for (int i = 0; i < sons.Length; i++)
        {
            if (sons[i].CompareTag(objTagName))
                return false;
        }
        return true;
    }
}


2018-08-06 18:05:23 abc1090275833 阅读数 874

       最近项目需要定位,所以开始来研究Unity的定位,本来想用原生的sdk,但是谷歌被墙了那就没有办法了,接第三方的sdk又太麻烦,百度了一下正好可以通过百度地图API来获取当前IP的地址,不仅是百度地图,同时高德地图,腾讯地图等等也都有类似的API,此次我选择了百度地图,于是在查询了百度地图的相关接口后研究出功能,自学记录一下

       代码如下:

using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Net.NetworkInformation;


public class BaiduTest : MonoBehaviour {


    public Text province;
    public Text city;

    string url = "http://api.map.baidu.com/location/ip?ak=bretF4dm6W5gqjQAXuvP0NXW6FeesRXb&coor=bd09ll";
    string text;

    void Start()
    {
        StartCoroutine(Request());
    }

    // Update is called once per frame
    void Update()
    {

    }
    IEnumerator Request()
    {
        WWW www = new WWW(url);
        yield return www;

        if (string.IsNullOrEmpty(www.error))
        {
            Debug.Log(www.text);
            ResponseBody req = JsonConvert.DeserializeObject<ResponseBody>(www.text);
            Debug.Log("夭寿啦,调到地址啦!!!!!!");
            Debug.Log(req.content.address_detail.city);
            province.text = req.content.address_detail.province;
            city.text = req.content.address_detail.city;
        }
    }

}

public class ResponseBody
{

    public string address;
    public Content content;
    public int status;

}

public class Content
{
    public string address;
    public Address_Detail address_detail;
    public Point point;
}
public class Address_Detail
{
    public string city;
    public int city_code;
    public string district;
    public string province;
    public string street;
    public string street_number;
    public Address_Detail(string city, int city_code, string district, string province, string street, string street_number)
    {
        this.city = city;
        this.city_code = city_code;
        this.district = district;
        this.province = province;
        this.street = street;
        this.street_number = street_number;
    }
}
public class Point
{
    public string x;
    public string y;
    public Point(string x, string y)
    {
        this.x = x;
        this.y = y;
    }
}

 

       需要注意的是,需要引入Json解析,刚好有现成的插件,导入进去运行成功,不过稍有遗憾的是,我只定位到了省份和城市,不知道是不是IP的问题,通过此API调用IP地址的话精度不是太高,如果需要精度很高的定位的话,建议还是安装第三方SDK,调用的网址是"http://api.map.baidu.com/location/ip?ak=bretF4dm6W5gqjQAXuvP0NXW6FeesRXb&coor=bd09ll";  需要替换自己的AK的话将其中的bretF4dm6W5gqjQAXuvP0NXW6FeesRXb替换成自己的就可以了,具体调用百度地图API有详细解释,在这里就不多做介绍了,下面是我的工程文件,unity版本为5.3.6,在Editor和Android环境下都可以正常运行调用,里面还有些获取IP和调用安卓的代码,在此就不做介绍了。

 

       最后放一下工程文件的链接:  https://download.csdn.net/download/abc1090275833/10586792

2015-08-03 11:47:46 fqrq88918329 阅读数 3814

因为工作中接触到了外企的项目,需要使用谷歌地图,国内用百度或者腾讯地图做开发的比较多,起初在弄的时候也是几乎没有找到任何中文的参考资料,这里算是给能看到我博客的并且也需要这方面开发的人一些详细的梳理性的思路吧

嘛,因为我做的是ios的对接,所以本文不牵扯到安卓,不过大体我想应该也只需要一个自定义的jar包,重头戏还是在对接的配置上,也就是我下文需要详细说明的点

首先开发谷歌地图,你需要翻墙,至少我这是打不开谷歌地图的官网,至于用什么翻墙。。。这里不做过多的阐述

你需要知道unity3d如何与ios对接,这里请移步至雨凇sama的博客自行了解 http://www.xuanyusong.com/archives/517

下面我们打开谷歌地图开发的网站,https://developers.google.com/maps/documentation/ios/start#getting_the_google_maps_sdk_for_ios

这里我需要特别说明一点,谷歌地图有2个名字很像的sdk,一个叫做 google maps sdk for ios 另一个叫做 google maps mobile sdks for work。。。,因为for work的

这个sdk有直接下载sdk包的地方,所以当初我也没有多想就下了直接用,结果用错了,这个sdk应该是一个商业化需要另外收费的包,而且用了这个包之后按照一般的

开发流程到了运行的时候就会一直提示key和项目的bundle id不对应,自己也是浪费了好几天时间在这上面,stackoverflow上面很多老外也是没有分清楚work版本和一

般free版本,在论坛上各种询问如何解决key无效的问题,这里提醒大家一定要注意,点醒我的那一篇帖子的地址上 http://stackoverflow.com/questions/24830571/google-

maps-your-key-may-be-invalid-for-your-bundle-id

好了下面我们正式从free版本的sdk开始入手

首先你需要下载sdk,那么可能很多人还没开始入手就已经郁闷了,从1.9.2之后的版本开始,sdk就不是以压缩包的形式提供下载了,(如果大家能够找到之前版

本的压缩包,那就直接跳过下载sdk的部分),官方给的解答是sdk要从CocoaPods上面直接下载使用,没办法接下来我们去弄CocoaPods,想要安装CocoaPods,首先需

要有Ruby环境,好的持续崩溃中,我们去安装Ruby环境。。。http://blog.csdn.net/li_huifeng/article/details/44456925 直接给出链接,安装好Ruby环境之后,我们开始安

CocoaPods, http://code4app.com/article/cocoapods-install-usage这里也给出链接不做过多阐述,2篇文章都写的很清楚。

环境都配置好之后,我们找到u3d导出的xcode工程在文件夹中的位置,在根目录下新建一个文件,取名为Podfile(注意不要有后缀名),打开它,输入pod  ‘Google-

Maps-iOS-SDK’,'1.9.2' 意思是我要下载1.9.2版本的sdk(本来是想下载最新10版本的,可是一直链接不上服务器,没办法只好下载1.9.2的版本,也一样可以使用没有问

题),保存文件之后,我们在终端进入到刚刚有Podfile文件的文件夹,输入pod install命令,等待sdk的下载,下载好了之后,你会发现在“Unity-iPhone.xcodeproj”旁

边,多了一个“Unity-iPhone.xcworkspace”文件,如果需要使用地图,那么我们之后就必须使用新出现的xcworkspace文件,打开一样是xcode工程,只是多了谷歌地图的

sdk,有点像eclipse里面安卓项目关联一个工程包一样。

到这里我们的谷歌地图sdk就已经成功集成在我们的项目里面了,下面就是去申请key,我们打开https://code.google.com/apis/console/b/0/?

noredirect#project:506537762569:services(这是我自己的地址,你们进去之后用谷歌账号登录自己的就可以),在这里你需要在srivices处打开google maps sdks for iOS

权限,然后在api access处用自己项目的bundle id新建一个for iOS的key

这篇博文就写到这了,有的人可能会说你这一点代码都没给我们,我们怎么用呀,实在不好意思,我写这篇文章的目的只是希望给没有思路的人一点提示,我相信只要你能耐

下心来按照我的步骤做下去,你的环境一定可以配置好,至于u3d怎么对接ios,谷歌地图具体如何开发,我给的网址链接也已经很详细了,我希望大家沉下心来去动手弄一弄,毕

竟谷歌地图具体开发是你们自己的工作嘛。

ps(这里给一个小提示,谷歌地图的显示跟一般的ios的view需要显示在u3d中是一样的,add一个subview即可,具体可以参考上文雨凇sama的博文)




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