unity中用户注册与mysql数据库的连接方法
·
一.MySql
1.启动mysql

2.登陆自己的mysql
3.创建表

二.Node.js
1.打开node.js

2.在命令行(终端)执行以下步骤:

安装依赖包
运行以下命令来安装后端所需的依赖包:
npm install express body-parser mysql2 bcrypt jsonwebtoken cors
express:一个轻量级的 Web 框架,用于创建 API。body-parser:解析请求体数据。mysql2:用于连接和操作 MySQL 数据库。bcrypt:用于加密和验证用户密码。jsonwebtoken:用于生成和验证用户身份的 JWT。cors:解决跨域问题(Unity 客户端需要用到)。
由于 bcrypt 编译需要较多环境配置,可以使用更轻量化的模块,如 bcryptjs,它是纯 JavaScript 实现,不需要编译。

3.编写index.js
我这里用的是vscode

下面是index.js的代码,需要替换
// 引入 Express 框架,用于创建和管理 Web 服务器
const express = require("express");
// 引入 body-parser 中间件,用于解析请求体数据
const bodyParser = require("body-parser");
// 引入 mysql2/promise 模块,用于连接和操作 MySQL 数据库,支持 Promise
const mysql = require("mysql2/promise");
// 引入 bcryptjs 模块,用于对密码进行加密和校验
const bcrypt = require("bcryptjs");
// 引入 cors 模块,用于处理跨域请求
const cors = require("cors");
// 创建 Express 应用实例
const app = express();
// 定义服务器监听的端口号
const port = 3000;
// 使用中间件
app.use(cors());
app.use(bodyParser.json());
// 数据库连接配置
const dbConfig = {
host: "localhost",
user: "自己的用户名",
password: "自己的密码",
database: "自己创建的数据库的名",
};
let db;
// 初始化数据库连接
async function initializeDbConnection() {
try {
db = await mysql.createConnection(dbConfig);
console.log("已成功连接到数据库");
} catch (err) {
console.error("数据库连接失败:", err);
process.exit(1); // 如果连接失败,退出程序
}
}
// 注册接口
app.post("/register", async (req, res) => {
const { username, password } = req.body;
// 验证用户名和密码是否为空
if (!username || !password) {
return res.status(400).json({ error: "用户名和密码不能为空" });
}
try {
// 检查用户名是否已存在
const [rows] = await db.query("SELECT * FROM users WHERE username = ?", [username]);
if (rows.length > 0) {
return res.status(400).json({ error: "用户名已被注册" });
}
// 加密密码
const hashedPassword = await bcrypt.hash(password, 10);
// 插入用户数据
await db.query("INSERT INTO users (username, password_hash) VALUES (?, ?)", [username, hashedPassword]);
res.status(201).json({ message: "注册成功" });
} catch (error) {
console.error("注册错误:", error);
res.status(500).json({ error: "服务器内部错误" });
}
});
// 登录接口
app.post("/login", async (req, res) => {
const { username, password } = req.body;
// 验证用户名和密码是否为空
if (!username || !password) {
return res.status(400).json({ error: "用户名和密码不能为空" });
}
try {
// 检查用户名是否存在
const [rows] = await db.query("SELECT * FROM users WHERE username = ?", [username]);
if (rows.length === 0) {
return res.status(400).json({ error: "用户名或密码错误" });
}
const user = rows[0];
// 比较密码
const isMatch = await bcrypt.compare(password, user.password_hash);
if (!isMatch) {
return res.status(400).json({ error: "用户名或密码错误" });
}
res.status(200).json({ message: "登录成功" });
} catch (error) {
console.error("登录错误:", error);
res.status(500).json({ error: "服务器内部错误" });
}
});
// 启动服务器
(async () => {
await initializeDbConnection(); // 初始化数据库连接
app.listen(port, () => {
console.log(`服务器正在运行,地址:http://localhost:${port}`);
});
})();
然后在根目录的终端输入node index.js
就会看到成功连接

三.Postman


(昨天还有成功显示。。。)
四.Unity

写loginManager的脚本(在文章最后)

输入后成功显示注册成功,然后跳转场景
然后我们在数据库查询一下,果然保留了记录,还有创建时间

然后因为我昨天注册就是这个名字,所以可以看到控制台显示我今天注册失败,说明昨天保留到数据库了

然后今天换了一个用户名

可以看到console面板显示注册成功
注册成功后点登陆就能看到下一关场景了

using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class LoginManager : MonoBehaviour
{
public InputField nameInput; // 用户名输入框
public InputField passwordInput; // 密码输入框
public GameObject registerSuccessMessage; // 注册成功提示
public GameObject loginErrorMessage; // 登录失败提示
private string registerUrl = "http://localhost:3000/register"; // 注册 API 地址
private string loginUrl = "http://localhost:3000/login"; // 登录 API 地址
// 注册功能
public void Register()
{
string username = nameInput.text.Trim(); // 去除多余空格
string password = passwordInput.text.Trim();
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
{
Debug.LogError("用户名或密码不能为空!");
StartCoroutine(ShowMessage(loginErrorMessage)); // 显示错误提示
return;
}
// 调用协程进行注册
StartCoroutine(RegisterUser(username, password));
}
private IEnumerator RegisterUser(string username, string password)
{
// 创建 JSON 数据
string jsonData = $"{{\"username\":\"{username}\",\"password\":\"{password}\"}}";
// 创建请求
UnityWebRequest request = new UnityWebRequest(registerUrl, "POST");
byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(jsonData);
request.uploadHandler = new UploadHandlerRaw(bodyRaw);
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
Debug.Log($"发送注册请求到: {registerUrl}");
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
Debug.Log($"注册成功: {request.downloadHandler.text}");
StartCoroutine(ShowMessage(registerSuccessMessage)); // 显示注册成功提示
}
else
{
Debug.LogError($"注册失败: {request.error}\n响应: {request.downloadHandler.text}");
StartCoroutine(ShowMessage(loginErrorMessage)); // 显示错误提示
}
}
// 登录功能
public void Login()
{
string username = nameInput.text.Trim(); // 去除多余空格
string password = passwordInput.text.Trim();
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
{
Debug.LogError("用户名或密码不能为空!");
StartCoroutine(ShowMessage(loginErrorMessage)); // 显示错误提示
return;
}
// 调用协程进行登录
StartCoroutine(LoginUser(username, password));
}
private IEnumerator LoginUser(string username, string password)
{
// 创建 JSON 数据
string jsonData = $"{{\"username\":\"{username}\",\"password\":\"{password}\"}}";
// 创建请求
UnityWebRequest request = new UnityWebRequest(loginUrl, "POST");
byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(jsonData);
request.uploadHandler = new UploadHandlerRaw(bodyRaw);
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
Debug.Log($"发送登录请求到: {loginUrl}");
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
Debug.Log($"登录成功: {request.downloadHandler.text}");
SceneManager.LoadScene("GameScene1"); // 跳转到下一个场景
}
else
{
Debug.LogError($"登录失败: {request.error}\n响应: {request.downloadHandler.text}");
StartCoroutine(ShowMessage(loginErrorMessage)); // 显示登录失败提示
}
}
// 显示提示信息
private IEnumerator ShowMessage(GameObject messageObject)
{
messageObject.SetActive(true);
yield return new WaitForSeconds(2f);
messageObject.SetActive(false);
}
}
更多推荐
所有评论(0)