一、功能实现
1.日志记录:
- LogManager 脚本负责创建日志文件,并记录“时间”、“物体原本位置”、“物体移动后到达的位置”。
2.记录移动日志:
- 在 MoveObject 脚本中,当物体到达目标位置时,调用 LogManager 的 LogMovement 方法记录移动日志。
本篇文章依靠上面一篇文章的内容中搭建的场景,架构及功能,我们继续来实现本地日志存储的功能。在此附上上一篇文章地址:文章地址
二、实现原理:
利用unity的一些本地函数调用、文本读写、条件判定等实现日志存储的功能,较为简单。请大家批评指正。
三、代码模块
1.首先我们将原有的MoveObject.cs移动脚本做简单修改,以满足我们的数据的读取。
using UnityEngine;
public class MoveObject : MonoBehaviour
{
public GameObject squareObject; // 正方形物体
public float moveSpeed = 5f; // 移动速度
public float rotationSpeed = 720f; // 旋转速度(度/秒)
public Collider planeCollider; // 平面的碰撞体,用于边界检测
private Vector3 targetPosition; // 目标位置
private bool isMoving = false; // 是否正在移动
private Vector3 originalPosition; // 物体原本位置
private LogManager logManager; // 日志管理器
void Start()
{
// 初始化目标位置为物体的当前位置
targetPosition = squareObject.transform.position;
// 获取日志管理器
logManager = FindObjectOfType<LogManager>();
}
void Update()
{
// 检测鼠标点击
if (Input.GetMouseButtonDown(0))
{
// 创建一条从摄像机到鼠标点击位置的射线
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
// 检测射线是否与平面碰撞
if (Physics.Raycast(ray, out hit))
{
// 获取碰撞点的平面位置
Vector3 hitPoint = hit.point;
// 计算方块的半径(假设方块是正方形)
float halfSize = squareObject.transform.localScale.x / 2f;
// 获取平面边界
Bounds bounds = planeCollider.bounds;
// 限制目标位置在平面边界内
float clampedX = Mathf.Clamp(hitPoint.x, bounds.min.x + halfSize, bounds.max.x - halfSize);
float clampedZ = Mathf.Clamp(hitPoint.z, bounds.min.z + halfSize, bounds.max.z - halfSize);
// 设置目标位置,保持高度不变
targetPosition = new Vector3(clampedX, squareObject.transform.position.y, clampedZ);
// 记录物体原本位置
originalPosition = squareObject.transform.position;
// 开始移动
isMoving = true;
}
}
// 移动物体到目标位置
if (isMoving)
{
// 计算当前位置到目标位置的距离
float step = moveSpeed * Time.deltaTime;
squareObject.transform.position = Vector3.MoveTowards(squareObject.transform.position, targetPosition, step);
// 计算目标方向
Vector3 direction = (targetPosition - squareObject.transform.position).normalized;
// 计算目标旋转
Quaternion targetRotation = Quaternion.LookRotation(direction);
// 旋转物体朝向目标方向
squareObject.transform.rotation = Quaternion.RotateTowards(squareObject.transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
// 检查是否到达目标位置
if (Vector3.Distance(squareObject.transform.position, targetPosition) < 0.001f)
{
// 停止移动
isMoving = false;
// 记录移动日志
logManager.LogMovement(originalPosition, targetPosition);
}
}
}
}
2.创建一个3d空物体LogManager用来挂载LogManager.cs日志脚本,顺便我们也将之前挂载MoveObject.cs脚本的空物体文件名字也改为:MoveObject这样方便管理,项目到后期也容易区分。架构和LogManager.cs日志脚本代码如下所示:
using System;
using System.IO;
using UnityEngine;
public class LogManager : MonoBehaviour
{
private string logFilePath;
void Start()
{
// 设置日志文件存储路径
string logDirectory = Path.Combine(Application.dataPath, "log");
if (!Directory.Exists(logDirectory))
{
Directory.CreateDirectory(logDirectory);
}
// 生成日志文件名
string datePart = DateTime.Now.ToString("yyyy年MM月dd日");
int fileIndex = 1;
string fileName;
// 检查文件是否存在,如果存在则增加序号
do
{
fileName = $"{datePart}-{fileIndex:D3}.txt";
fileIndex++;
} while (File.Exists(Path.Combine(logDirectory, fileName)));
logFilePath = Path.Combine(logDirectory, fileName);
// 创建日志文件
using (StreamWriter writer = new StreamWriter(logFilePath, true))
{
writer.WriteLine("时间\t物体原本位置\t物体移动后到达的位置");
}
}
public void LogMovement(Vector3 originalPosition, Vector3 targetPosition)
{
string logEntry = $"{DateTime.Now:HH:mm:ss}\t{originalPosition}\t{targetPosition}";
using (StreamWriter writer = new StreamWriter(logFilePath, true))
{
writer.WriteLine(logEntry);
}
}
}