- 引言。
该文章介绍了通过unity与mysql数据库连接,然后动态读取mysql数据库中的坐标信息,让场景中的人物模型按照坐标进行移动,从而实现人员的动态追踪。
- 与mysql数据库建立连接。
1建立数据源。
首先在mysql数据库中使用sql语句建立数据源,命名为points。
Sql语句如上图所示通过show databases查看可见points数据源已成功建立。
2与mysql数据库进行连接。
- 首先在unity中引入mysql.Data文件,并在脚本中引用相应的命名空间,这样便可以在unity脚本中调用mysql的相关类来对mysql数据库进行操作。
脚本中的第一行代码就是引入有关mysql的命名空间。
- 然后建立并打开连接。
注意在这里要填入您的电脑上mysql对应的主机id,登陆密码以及数据源的名称。
- 通过sql语句建立characterPoints数据表。
通过上诉sql语句建立数据表characterPoints,随后在mysql中查询发现创建成功。
- 通过sql语句在表中添加坐标。
Values一行的代码是第一行代码后面的补充部分,执行完后去数据库里面查询,结果如下。
(5)接下来是最重要的部分,即实现坐标的动态读取。具体思路是在update函数(该函数每帧执行)中读取点的坐标至PlayerPrefs(unity提供的字典)字典里。
以上代码中,首先在update中与数据库进行连接,随后将数据表中所有数据读到da中然后赋值给ds。
然后将表的行数存入字典中,最后通过循环将所有坐标读入字典中,因为updata是每帧执行故实现了坐标的动态读取。
- 控制人物按照字典坐标进行移动。
- 定义需要的变量。
Speed即人物移动的速度,ways数组用来存储坐标点,index是MoveTo()函数中的索引,index_Array是updateArray中的索引,随后对变量进行初始化。
在Update函数中,通过updateArray方法来实时更新坐标数组,用MoveTo方法来控制人物按照数组中的坐标进行移动。
2.updateArray函数。
首先用print函数输出字典中记录的坐标行数来进行测试,随后在for循环中创建空物体,
然后将坐标信息赋值给该空物体,最后将该空物体的transform组件放入数组中。
3.MoveTo函数。
首先解决索引越界问题,检测索引是否大于字典中存取的行数(一行对应一个点的坐标),如果大于说明索引自增后越界,执行return操作,不执行后续操作。然后通过lookat使物体朝向目标点,随后通过MoveTowards函数朝着目标点移动,然后检测人物当前坐标与目标点的距离,当小于0.2f时,可判断其抵达目标点,然后销毁该目标点,解决数据冗余问题,然后索引自增,最后判断索引如果是最后一个点,那么将最后一个点的坐标赋值给人物。
- 进行测试。
开始运行后我们发现数据库中的坐标跟unity中的空物体是一一对应的,并且人物确实按照坐标顺序进行移动,然后我们在数据库中临时插入数据,看unity中是否可以动态更新。
如图所示可实现动态更新。
- 源码。
using MySql.Data.MySqlClient;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using UnityEngine;
public class MySqllianjie : MonoBehaviour
{
void Update()
{
//建立连接语句
//charset=utf8这句要写,不然可能会报错
string constr = "server=localhost;User Id=root;password=123456;Database=points;charset=utf8";
//建立连接
MySqlConnection mycon = new MySqlConnection(constr);
//打开连接
mycon.Open();
//插入数据
// MySqlCommand mycmd = new MySqlCommand("insert into characterpoints(id,x,y,z) values (2,7,8,9)", mycon);
// if (mycmd.ExecuteNonQuery() > 0)
// {
// print("Insert success!");
// }
//查询数据
string selstr = "select * from characterpoints";
MySqlCommand myselect = new MySqlCommand(selstr, mycon);
DataSet ds = new DataSet();
try
{
MySqlDataAdapter da = new MySqlDataAdapter(selstr, mycon);
da.Fill(ds);
PlayerPrefs.SetInt("rows", ds.Tables[0].Rows.Count);
//在循环中,将数据库中的元素赋放到PlayerPrefs字典里
for (int i = 0; i < PlayerPrefs.GetInt("rows"); i++)
{
PlayerPrefs.SetFloat("x" + i, (float)ds.Tables[0].Rows[i][1]);
PlayerPrefs.SetFloat("y" + i, (float)ds.Tables[0].Rows[i][2]);
PlayerPrefs.SetFloat("z" + i, (float)ds.Tables[0].Rows[i][3]);
}
}
catch (Exception e)
{
throw new Exception("SQL:" + selstr + "n" + e.Message.ToString());
}
//关闭连接
mycon.Close();
}
}
using UnityEngine;
public class Move : MonoBehaviour
{
public float speed = 1;
public Transform[] ways;
private int index;
private int index_Array=0;
// Use this for initialization
void Start()
{
ways = new Transform[100];
index = 0;
}
void Update()
{
updateArray();
MoveTo();
}
void updateArray()
{
print(PlayerPrefs.GetInt("rows"));
for (; index_Array < PlayerPrefs.GetInt("rows"); index_Array++)
{
GameObject go = new GameObject("Empty");
go.transform.position =
new Vector3(PlayerPrefs.GetFloat("x" + index_Array), PlayerPrefs.GetFloat("y" + index_Array)
, PlayerPrefs.GetFloat("z" + index_Array));
ways[index_Array] = go.transform;
}
}
void MoveTo()
{
if (index > PlayerPrefs.GetInt("rows") - 1)
return;
transform.LookAt(ways[index].position);
transform.position = Vector3.MoveTowards(transform.position,
ways[index].position, Time.deltaTime * speed);
if (Vector3.Distance(ways[index].position, transform.position) < 0.2f)
{
//当物体到达该点后销毁该点
Destroy(ways[index].gameObject);
index++;
if (index == ways.Length)
{
transform.position = ways[index - 1].position;
}
}
}
}



