Unity导出Android项目报错:Unable to list target platforms.

Unity导出Android项目报错:Unable to list target platforms.

由于sdk升级到26,所以在Unity5.3.6导出Android项目时,报错如下:

Error building Player: CommandInvokationFailure: Unable to list target platforms. Please make sure the android sdk path is correct. See the Console for more details.
/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java -Xmx2048M -Dcom.android.sdkmanager.toolsdir=”/Users/nestordu/Library/Android/sdk/tools” -Dfile.encoding=UTF8 -jar “/Applications/Unity5.3.6p2/PlaybackEngines/AndroidPlayer/Tools/sdktools.jar” –
stderr[
Error:Invalid command android
]
stdout[
]

导出项目时,调用了Android的SDK的tools下的命令,因为从25升级到26变化较大,所以命令不可用了“Invalid command android”。

解决方式如下:

方法1(直接删掉tools,下载25.2.5版本)

cd $ANDROID_HOME #切换到android sdk目录下
rm -rf tools #删除tools
wget http://dl.google.com/android/repository/tools_r25.2.5-ma‌​cosx.zip #下载
unzip tools_r25.2.5-macosx.zip #解压

方法2(通过sdkmanager的命令来降低版本,此方法未验证)

cd $ANDROID_HOME/sdk/tools/bin
sdkmanager --uninstall "tool;android-26"
sdkmanager --install "tool;android-25"
命令参考:https://developer.android.com/studio/command-line/sdkmanager.html

 

Mac下Android Library工程使用gradle生成jar包

Mac下Android Library工程使用gradle生成jar包

在开发sdk生成jar在eclipse里相对比较容易操作,只要导出class时指定哪里导出就可以,但在用AndroidStudio开发时要导出jar就没那么容易,需要写gradle脚本,但gradle脚本的入门成本还是比较高,网上也有打包jar的脚本参考,但大多是通过生成classes.jar重命名来生成,这样生成的jar是包含工程里所有类的,有时我们需要指定一些包和类来生成jar。
创建Android Library工程:菜单导航到 File -> New -> New Module … ,选择 Android Library,包名(com.sqstudio.test)。在gradle中加入以下脚本:
task clearJar(type: Delete) {
    delete 'libs/sdk.jar'
}
task makeJar(type:org.gradle.api.tasks.bundling.Jar) {
    //指定生成的jar名
    baseName 'sdk'
    //从哪里打包class文件
    from('build/intermediates/classes/debug/com/sqstudio/test')
    //打包到jar后的目录结构 
    into('com/sqstudio/test/')
    //去掉不需要打包的目录和文件
    exclude('BuildConfig.class', 'R.class')
    //去掉R$开头的文件 
    exclude{ it.name.startsWith('R$');}
}
makeJar.dependsOn(clearJar, build)

build.gradle写上后,只要在命令行执行gradle makeJar就可以在build/libs目录下找到这个jar包。

如果gradle执行失败,需检查环境配置(首次使用,会下载安装相关资源,需要等待)

vim ~/.bash_profile 然后加入:
GRADLE_HOME=/Applications/Android\ Studio.app/Contents/gradle/gradle-3.2;
export GRADLE_HOME
export PATH=$PATH:$GRADLE_HOME/bin

上面是个简单的例子,只能打包某个包下面的所有文件,如果要实现只打某个包下面的某些子包或者文件可参考如下示例:

task makeSdkJar(type:org.gradle.api.tasks.bundling.Jar) {
    baseName 'pluginsdk'
    //只打包org.cmdmac下的org.cmdmac.pluginsdk.impl和org.cmdmac.gamecenter,其他子包不会被打包进去
    from('build/intermediates/classes/debug/org/cmdmac/') {
        include 'pluginsdk/impl'
        include 'gamecenter'
    }
    into('org/cmdmac/')
//    exclude('R.class')
//    exclude{ it.name.startsWith('R$');}
}

 

参考资料:http://www.alloyteam.com/2015/03/shi-yong-gradle-da-bao-zhi-ding-bao-ming-he-lei-di-jar/

使LitJson支持Unity的类型

使LitJson支持Unity的类型

在使用LitJson时,会发现不支持Unity的Vector3等类型,更为奇怪的是在Unity的Editor模式下是正常的,在真机设备上不行了,今天查看源码终于找到原因了。

LitJson本身为支持Unity已经定义了一个类UnityTypeBindings,局部代码如下:

#if UNITY_EDITOR
[UnityEditor.InitializeOnLoad]
#endif
public static class UnityTypeBindings {

   static bool registerd;

   static UnityTypeBindings(){
      Register();
   }

就是因为在UNITY_EDITOR下加了标签[UnityEditor.InitializeOnLoad],所以在编辑器模式下支持Vector3等类型,因此只需要在项目加上如下代码即可:

UnityTypeBindings.Register()

参照以下注册方法,可实现自定义类型的Json序列化支持

Action<Vector2,JsonWriter> writeVector2 = (v,w) => {
   w.WriteObjectStart();
   w.WriteProperty("x",v.x);
   w.WriteProperty("y",v.y);
   w.WriteObjectEnd();
};

JsonMapper.RegisterExporter<Vector2>((v,w) => {
   writeVector2(v,w);
});

参考资料:
LitJson官网:http://lbv.github.io/litjson/
Unity之查找资源被哪里引用了

Unity之查找资源被哪里引用了

有时候要删除一个资源,就需要先查看下被哪里引用了,防止误删。Unity提供了一个方法 AssetDatabase.GetDependencies(),但是它只能查找这个资源引用了那些资源。 但是我想要的是查找某个资源被那些资源引用了,这是两种相反的查找公式。

网上找到一个查找脚本,速度很快,不过只能在Mac上用。右键选择一个资源,点击 Find References,会在Console面板上输出结果。

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

public class FindProject {

	#if UNITY_EDITOR_OSX

	[MenuItem("Assets/Find References In Project", false, 2000)]
	private static void FindProjectReferences()
	{
		string appDataPath = Application.dataPath;
		string output = "";
		string selectedAssetPath = AssetDatabase.GetAssetPath (Selection.activeObject);
		List<string> references = new List<string>();

		string guid = AssetDatabase.AssetPathToGUID (selectedAssetPath);

		var psi = new System.Diagnostics.ProcessStartInfo();
		psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Maximized;
		psi.FileName = "/usr/bin/mdfind";
		psi.Arguments = "-onlyin " + Application.dataPath + " " + guid;
		psi.UseShellExecute = false;
		psi.RedirectStandardOutput = true;
		psi.RedirectStandardError = true;

		System.Diagnostics.Process process = new System.Diagnostics.Process();
		process.StartInfo = psi;

		process.OutputDataReceived += (sender, e) => {
			if(string.IsNullOrEmpty(e.Data))
				return;

			string relativePath = "Assets" + e.Data.Replace(appDataPath, "");

			// skip the meta file of whatever we have selected
			if(relativePath == selectedAssetPath + ".meta")
				return;

			references.Add(relativePath);

		};
		process.ErrorDataReceived += (sender, e) => {
			if(string.IsNullOrEmpty(e.Data))
				return;

			output += "Error: " + e.Data + "\n";
		};
		process.Start();
		process.BeginOutputReadLine();
		process.BeginErrorReadLine();

		process.WaitForExit(2000);

		foreach(var file in references){
			output += file + "\n";
			Debug.Log(file, AssetDatabase.LoadMainAssetAtPath(file));
		}

		Debug.LogWarning(references.Count + " references found for object " + Selection.activeObject.name + "\n\n" + output);
	}

	#endif
}

 

Pip安装依赖于six的库失败的解决方法

Pip安装依赖于six的库失败的解决方法

今天在安装 google-api-python-client库时,six库一直报错升级不了

Installing collected packages: six
Found existing installation: six 1.4.1
DEPRECATION: Uninstalling a distutils installed project (six) has been deprecated and will be removed in a future version. This is due to the fact that uninstalling a distutils project will only partially uninstall the project.
Uninstalling six-1.4.1:
...

参考github上的解决办法:https://github.com/pypa/pip/issues/3165

将安装命令改成如下即可:

sudo pip install --upgrade google-api-python-client --ignore-installed six

即使用参数–ignore-installed来忽略本地安装的six。

原因可能是Apple预安装的这个six库出于安全原因被设置为sudo也不可以执行操作,所以需要依赖于高版本的库就需要更新six,但是没有six的权限,所以就回报错。

 

 

 

Unity之文本Text颜色渐变

Unity之文本Text颜色渐变

Unity的UGUI的Text只能设置单个颜色,由于项目需求,需要Text有渐变色,在网上找了几篇,发型都在用一个叫 TextVerticalGradientThreeColor的组件,不过这个组件虽然支持三种颜色,但是不能更改颜色数量和渐变位置,还是太方便,怎么办呢?那就花点时间自己造轮子吧。

TextGradientColor可配合自带的Outline和Shadow使用,上下顺序不同,渲染出来的效果也有差别,可以自己试试。

代码如下:

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

namespace UI.Extension
{
	//和文本的 Shadow 和 outline 效果配合 , 渲染顺序不一样,效果也不一样

	[AddComponentMenu ("UI/Effects/Text Gradient Color")]
	[RequireComponent (typeof(Text))]
	public class TextGradientColor : BaseMeshEffect
	{
		public Gradient gradientColor = new Gradient ();
		//是否垂直方向
		public bool isVertical = true;
		//是否叠加原有颜色
		public bool isMultiplyTextColor = false;
		protected TextGradientColor ()
		{
		}

		private void ModifyVertices (VertexHelper vh)
		{
			List<UIVertex> verts = new List<UIVertex> (vh.currentVertCount);
			vh.GetUIVertexStream (verts);
			vh.Clear ();

			//每个字母 分为两个三角形,6个顶点,如下图 0和5位置相同 2和3位置相同
			/**
			 *   5-0 ---- 1
			 *    | \    |
			 *    |  \   |
			 *    |   \  |
			 *    |    \ |
			 *    4-----3-2
			 **/

			int step = 6;
			for (int i = 0; i < verts.Count; i += step) {

				UIVertex start1, start2, end1, end2, current1, current2;
				if (isVertical) {
					start1 = verts [i + 0];
					start2 = verts [i + 1];
					end1 = verts [i + 4];
					end2 = verts [i + 3];
				} else {
					start1 = verts [i + 0];
					start2 = verts [i + 4];
					end1 = verts [i + 1];
					end2 = verts [i + 2];
				}

				for (int j = 0; j < gradientColor.colorKeys.Length; j++) {
					GradientColorKey colorKey = gradientColor.colorKeys [j];
					if (j == 0) {
						multiplyColor (start1,colorKey.color);
						multiplyColor (start2,colorKey.color);
					} else if (j == gradientColor.colorKeys.Length - 1) {
						multiplyColor (end1,colorKey.color);
						multiplyColor (end2,colorKey.color);

						//right
						vh.AddVert (start1);
						vh.AddVert (start2);
						vh.AddVert (end2);

						//left
						vh.AddVert (end2);
						vh.AddVert (end1);
						vh.AddVert (start1);

					} else {
						// create right
						current2 = CreateVertexByTime (start2, end2, colorKey.time);
						vh.AddVert (start1);
						vh.AddVert (start2);
						vh.AddVert (current2);

						// create left
						current1 = CreateVertexByTime (start1, end1, colorKey.time);
						vh.AddVert (current2);
						vh.AddVert (current1);
						vh.AddVert (start1);

						start1 = current1;
						start2 = current2;
					}
				}
			}

			//添加三角形

			//每个字母的顶点数量
			int stepVertCount = (gradientColor.colorKeys.Length - 1) * 2 * 3;
			for (int i = 0; i < vh.currentVertCount; i += stepVertCount) {
				for (int m = 0; m < stepVertCount; m += 3) {
					vh.AddTriangle (i + m + 0, i + m + 1, i + m + 2);
				}
			}
		}

		private UIVertex multiplyColor(UIVertex vertex, Color color)
		{
			if (isMultiplyTextColor)
				vertex.color = Multiply (vertex.color, color);
			else
				vertex.color = color;
			return vertex;
		}

		public static Color32 Multiply(Color32 a, Color32 b)
		{
			a.r = (byte)((a.r * b.r) >> 8);
			a.g = (byte)((a.g * b.g) >> 8);
			a.b = (byte)((a.b * b.b) >> 8);
			a.a = (byte)((a.a * b.a) >> 8);
			return a;
		}

		//根据比例创建顶点 (time这里是gradientColor里的比例)
		private UIVertex CreateVertexByTime (UIVertex start, UIVertex end, float time)
		{
			UIVertex center = new UIVertex ();
			center.normal = Vector3.Lerp (start.normal, end.normal, time);
			center.position = Vector3.Lerp (start.position, end.position, time);
			center.tangent = Vector4.Lerp (start.tangent, end.tangent, time);
			center.uv0 = Vector2.Lerp (start.uv0, end.uv0, time);
			center.uv1 = Vector2.Lerp (start.uv1, end.uv1, time);
			center.color =  gradientColor.Evaluate (time);

			if (isMultiplyTextColor) {
				//multiply color
				var color = Color.Lerp(start.color, end.color, time);
				center.color = Multiply (color, gradientColor.Evaluate (time));
			} else {
				center.color = gradientColor.Evaluate (time);
			}

			return center;
		}

		#region implemented abstract members of BaseMeshEffect

		public override void ModifyMesh (VertexHelper vh)
		{
			if (!this.IsActive ()) {
				return;
			}

			ModifyVertices (vh);
		}

		#endregion
	}
}  

 

WordPress提示“在裁剪您的图像时发生了错误”的解决方法

WordPress提示“在裁剪您的图像时发生了错误”的解决方法

问题:在WordPress中使用裁剪图片功能时,出现:”在裁剪您的图像时发生了错误。”或者”There has been an error cropping your image.”

原因:缺少PHP GD库。

Ubuntu下运行:

[c]sudo apt-get install php5-gd[/c]

CentOS下运行:

[csharp]yum install php-gd[/csharp]

安装PHP-GD库后重启服务器即可使用~

Mac下自启动SVN服务

Mac下自启动SVN服务

Mac本地svn服务,需要我们在终端执行相关的命令才能启动svnserve服务。

为了免去每次启动时都需要手动输入相关的启动服务的命令,那么就需要我们编写一个shell脚本命令。在每次电脑开机启动时就自动执行该脚本里的命令,那么我们的服务就会自动启动,免去了手动输入命令的麻烦。

#!/bin/bash

svnserve -d -r ~/Documents/svn

svnserve -d -r /你的SVN服务器路径   (建议使用相对路径,否则运行时会提示会找不该路径)

保存成可执行文件shell 也就是.sh脚本。(可以在一个没有格式的txt文本里编辑,然后再保存,修改后缀名为.sh)

然后更改该脚本权限为可执行。

chmod 711 localsvnserverstart.sh  (文件名可自定义)

是否可执行,可以验证一下。在终端中cd到该.sh所在的目录下,执行命令:./localsvnserverstart.sh

如果终端没有任何错误输出,可以到活动监视器里进行搜索:svnserve 查看是否有该服务已经启动了。

如何需要在开机时就启动该服务那么就需要进行以下操作了

进入系统偏好设置-用户与群组-登陆项

在管理员用户头像哪里有个登陆项,点击后会有一个列表框,点击添加,找到你你写的shell脚本,添加上去,并勾选这个选项(不需要勾选上,因为勾选的话,表示登录是隐藏应用程序),让其在开机启动是执行。


如果想在打开终端的时候,执行命令,可以在 ~/.bash_profile 文件里添加命令即可

 

Linux安装配置MySql

Linux安装配置MySql

1、安装客户端和服务器端

[codesyntax lang=”bash”]

#确认mysql是否已安装
yum list installed mysql*
rpm -qa | grep mysql*

#查看是否有安装包
yum list mysql*

#安装mysql客户端
yum install mysql

#安装mysql 服务器端
yum install mysql-server
yum install mysql-devel

[/codesyntax]

 

2、启动、停止设置

数据库字符集设置

mysql配置文件/etc/my.cnf中加入default-character-set=utf8

[codesyntax lang=”bash”]

#启动mysql服务:
service mysqld start
#或者
/etc/init.d/mysqld start

#设置开机启动:
chkconfig --add mysqld
chkconfig mysqld on

#查看开机启动设置是否成功
chkconfig --list | grep mysql*
mysqld 0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭

#停止mysql服务:
service mysqld stop

[/codesyntax]

 

 

3.创建或修改密码:

a.例如你的 root用户现在没有密码,你希望的密码修改为123456,那么命令是:

mysqladmin -u root password 123456

b.如果你的root现在有密码了(123456),那么修改密码为abcdef的命令是:

mysqladmin -u root -p password abcdef

注意,命令回车后会问你旧密码,输入旧密码123456之后命令完成,密码修改成功。

4.开启远程访问权限

 

4.1、登陆mysql

mysql -u root -p

4.2.修改mysql库的user表,将host项,从localhost改为%。%这里表示的是允许任意host访问,如果只允许某一个ip访问,则可改为相应的ip,比如可以将localhost改为192.168.1.123,这表示只允许局域网的192.168.1.123这个ip远程访问mysql。

mysql> use mysql;

mysql> update user set host = ‘%’ where user = ‘root’;

mysql> select host, user from user;

mysql> flush privileges;

5.防火墙开放3306端口

[codesyntax lang=”bash”]

#打开防火墙配置文件
vi  /etc/sysconfig/iptables

#增加下面一行
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT

#重启防火墙
service  iptables restart

[/codesyntax]

 

6. 查看mysql 状态

# ps -e | grep mysqld

13085 pts/1    00:00:00 mysqld_safe

13190 pts/1    00:00:00 mysqld

或者

service mysqld status

7.修改mysql端口

为了安全,不采用默认端口3306,改为3506

7.1. 登录mysql

[root@test /]# mysql -u root -p

Enter password:

7.2. 使用命令show global variables like ‘port’;查看端口号

mysql> show global variables like ‘port’;
+—————+——-+
| Variable_name | Value |
+—————+——-+
| port | 3306 |
+—————+——-+

7.3. 修改端口,编辑/etc/my.cnf文件,早期版本有可能是my.conf文件名,增加端口参数,并且设定端口,注意该端口未被使用,保存退出。

[root@test etc]# vi my.cnf
[mysqld]
port=3506
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

7.4.重启mysql

service mysqld restart

再次查看,端口已经变为3506

mysql> show global variables like ‘port’;
+—————+——-+
| Variable_name | Value |
+—————+——-+
| port | 3506 |
+—————+——-+

8、mysql的几个重要目录

8.1数据库目录

/var/lib/mysql/

8.2配置文件

/usr/share /mysql(mysql.server命令及配置文件)

8.3相关命令

/usr/bin(mysqladmin mysqldump等命令)

8.4启动脚本

/etc/rc.d/init.d/(启动脚本文件mysql的目录)

Linux下安装ShadowSocks

Linux下安装ShadowSocks

服务器环境:CentOS6.5 ,Python3.5,服务器pip可用。

1.安装和配置:

pip install shadowsocks

创建配置文件:

    vi /etc/shadowsocks.json
{
    "server":"0.0.0.0",
    "server_port":8989,
    "local_address": "127.0.0.1",
    "local_port":1080,
    "password":"yourpassword",
    "timeout":600,
    "method":"aes-256-cfb",
    "fast_open": false,
    "workers": 1
}

各字段的含义:

  • server:服务器 IP (IPv4/IPv6),注意这也将是服务端监听的 IP 地址
  • server_port:监听的服务器端口
  • local_address:本地监听的 IP 地址
  • local_port:本地端端口
  • password:用来加密的密码
  • timeout:超时时间(秒)
  • method:加密方法,可选择 “bf-cfb”, “aes-256-cfb”, “des-cfb”, “rc4”, 等等。默认是一种不安全的加密,推荐用 “aes-256-cfb”
  • works:works数量,默认为 1
  • fast_open:true 或 false。如果你的服务器 Linux 内核在3.7+,可以开启 fast_open 以降低延迟。开启方法:
echo 3 > /proc/sys/net/ipv4/tcp_fastopen

开启之后,将 fast_open 的配置设置为 true 即可。

 

2、 命令行参数(服务器端启动命令)

ssserver -c /etc/shadowsocks.json

如果想在后台一直运行Shadowsocks,启动命令如下:

nohup ssserver -c /etc/shadowsocks.json > /dev/null 2>&1 &

备注:关于nohup,是可以让程序在后台运行的命令。

同时可以用命令行参数覆盖 /etc/shadowsocks.json 里的设置:

sslocal -s 服务器地址 -p 服务器端口 -l 本地端端口 -k 密码 -m 加密方法

ssserver -p 服务器端口 -k 密码 -m 加密方法

备注:sslocal是客户端程序;ssserver是服务端程序。

 

5、 防火墙设置(如有)
编辑防火墙配置文件/etc/sysconfig/iptables,将服务器端口(server_port)放行。
新增一条防火墙规则:

-A INPUT -m state --state NEW -m tcp -p tcp --dport 8989 -j ACCEPT

如果找不到 文件/etc/sysconfig/iptables, 可以使用命令行:

iptables -A INPUT -m state –state NEW -m tcp -p tcp –dport 8989 -j ACCEPT

service iptables save

重启防火墙iptables:

service iptables restart

至此,服务器端的 Shadowsocks 安装和配置完毕。


等等…, 为什么能访问百度,访问不了facebook,啊? 服务器是国内的!!!吐血三升!