Unity联机的方法有很多,例如UNET、PUN、Mirror都是游戏开发中比较常见的联机方法,本章是关于Unity联机新的办法,本方法简单易懂但缺点是只是在一定程度上的联机。对于2D游戏来说此方法是比较合适的,但对于3D来说出现了一些问题,目前推测为数据小数位太多或者数据太大,后期修改完会做更新。
联机方法简介
在游戏操作时对各人物坐标与操作监视将数据实时传输到MySQL中,将A、B、C........等用户操作分别MySQL中,将数据交叉调取,在A游戏页面中对其他玩家的信息在数据库实时调取,因此,在A页面中也会有其他用户的操作,同样在B、C........等用户也是如此。
直接上代码(只有核心脚本文件,其它代码可根据需要去操作)
将操作数据传输存数据库
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class jiaohu : MonoBehaviour
{
private string phpURL = "http://localhost:80/unity/1.php";
private float sendInterval = 1f;
void Start()
{
StartCoroutine(SendPositionRepeatedly());
}
IEnumerator SendPositionRepeatedly()
{
while (true)
{
Vector3 rotation = transform.rotation.eulerAngles;
Vector3 position = transform.position;
WWWForm form = new WWWForm();
form.AddField("x", position.x.ToString());
form.AddField("y", position.y.ToString());
form.AddField("z", position.z.ToString());
form.AddField("y1", rotation.y.ToString());
// 发送POST请求
StartCoroutine(SendPosition(form));
yield return new WaitForSeconds(sendInterval);
}
}
IEnumerator SendPosition(WWWForm form)
{
using (UnityWebRequest www = UnityWebRequest.Post(phpURL, form))
{
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log("Error: " + www.error);
}
else
{
Debug.Log("Position sent successfully!");
}
}
}
}
调取对方数据库操作数据,实现A玩家操作画面可以看到其他玩家的操作输出
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class mu : MonoBehaviour
{
private const string phpURL = "http://localhost:80/unity/2.php";
public float updateInterval = 1f;
void Start()
{
StartCoroutine(GetDataPeriodically());
}
IEnumerator GetDataPeriodically()
{
while (true)
{
yield return new WaitForSeconds(updateInterval);
using (UnityWebRequest www = UnityWebRequest.Get(phpURL))
{
yield return www.SendWebRequest();
if (www.result == UnityWebRequest.Result.Success)
{
string jsonText = www.downloadHandler.text;
Wrapper wrapper = JsonUtility.FromJson<Wrapper>("{\"data\":" + jsonText + "}");
foreach (DataObject data in wrapper.data)
{
//Debug.Log("x: " + data.x + ", y: " + data.y + ", z: " + data.z);
Debug.Log(data.x);
Transform transform = GetComponent<Transform>();
Vector3 newPosition = new Vector3(data.x, transform.position.y, transform.position.z);
transform.position = newPosition;
}
}
else
{
Debug.Log("Error: " + www.error);
}
}
}
}
}
[System.Serializable]
public class Wrapper
{
public DataObject[] data;
}
[System.Serializable]
public class DataObject
{
public float x;
public float y;
public float z;
}
接受数据与存储数据
<?php
$servername = "localhost";
$username = "root";
$password = "128";
$dbname = "myw";
$x = $_POST['x'];
$y = $_POST['y'];
$z = $_POST['z'];
$y1= $_POST['y1'];
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "INSERT INTO unity1 (`x`, `y`, `z`,`y1`) VALUES ('$x', '$y', '$z','$y1')";
if ($conn->query($sql) === TRUE) {
echo "Position saved successfully!";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
?>
调取数据
<?php
$servername = "localhost";
$username = "root";
$password = "1286469031";
$dbname = "my";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("连接数据库失败: " . $conn->connect_error);
}
$sql = "SELECT x, y, z FROM unity2";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$data = array();
while ($row = $result->fetch_assoc()) {
$data[] = array(
'x' => (float)$row['x'],
'y' => (float)$row['y'],
'z' => (float)$row['z']
);
}
echo json_encode($data);
} else {
echo "未找到数据";
}
$conn->close();
?>
关于用此方法开发3D游戏联机时,出现的问题
在传输时x,y,z可能会出现科学计数法表示的数据,对方调取后可能出现无法解析数据的情况,但是2D游戏开发是不会出现这种情况的。