257 lines
9.2 KiB
C#
257 lines
9.2 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Linq;
|
|||
|
|
using UnityEngine;
|
|||
|
|
|
|||
|
|
namespace Game.HotFix
|
|||
|
|
{
|
|||
|
|
public enum AnimEnum
|
|||
|
|
{
|
|||
|
|
Anim_cloth,
|
|||
|
|
Anim_weapon,
|
|||
|
|
}
|
|||
|
|
// ֡<><D6A1><EFBFBD>ݽṹ
|
|||
|
|
public struct FrameData
|
|||
|
|
{
|
|||
|
|
public int frameID;
|
|||
|
|
public int startX;
|
|||
|
|
public int startY;
|
|||
|
|
public int width;
|
|||
|
|
public int height;
|
|||
|
|
public int offsetX;
|
|||
|
|
public int offsetY;
|
|||
|
|
public int sourceWidth;
|
|||
|
|
public int sourceHeight;
|
|||
|
|
|
|||
|
|
public override string ToString()
|
|||
|
|
{
|
|||
|
|
return $"Frame {frameID}: ({startX},{startY}) {width}x{height} offset:({offsetX},{offsetY})";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public class AnimParserComponent : MonoBehaviour
|
|||
|
|
{
|
|||
|
|
public static AnimParserComponent instance;
|
|||
|
|
// <20>洢<EFBFBD><E6B4A2><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: [<5B><><EFBFBD><EFBFBD>ID][<5B><><EFBFBD><EFBFBD>][֡]
|
|||
|
|
private Dictionary<string, Dictionary<int, List<FrameData>>> clothAnimData =
|
|||
|
|
new Dictionary<string, Dictionary<int, List<FrameData>>>();
|
|||
|
|
|
|||
|
|
private Dictionary<string, Dictionary<int, List<FrameData>>> weaponAnimData =
|
|||
|
|
new Dictionary<string, Dictionary<int, List<FrameData>>>();
|
|||
|
|
private void Awake()
|
|||
|
|
{
|
|||
|
|
instance = this;
|
|||
|
|
System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew();
|
|||
|
|
LoadAndParseCSV("cloth.biz.csv", clothAnimData);
|
|||
|
|
stopwatch.Stop();
|
|||
|
|
Debug.Log($"<22><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>CSV {clothAnimData.Count} <20><>ʱ {stopwatch.Elapsed.Milliseconds} ms");
|
|||
|
|
stopwatch.Start();
|
|||
|
|
LoadAndParseCSV("weapon.biz.csv", weaponAnimData);
|
|||
|
|
stopwatch.Stop();
|
|||
|
|
Debug.Log($"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CSV {weaponAnimData.Count} <20><>ʱ {stopwatch.Elapsed.Milliseconds} ms");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD><EFBFBD><EFBFBD>CSV<53>ļ<EFBFBD>
|
|||
|
|
public void LoadAndParseCSV(string file, Dictionary<string, Dictionary<int, List<FrameData>>> AnimData)
|
|||
|
|
{
|
|||
|
|
string filePath = Path.Combine(Application.dataPath, "GameAssets/CSV", file);
|
|||
|
|
if (!File.Exists(filePath))
|
|||
|
|
{
|
|||
|
|
Debug.LogError($"CSV file not found: {filePath}");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
string csvContent = File.ReadAllText(filePath);
|
|||
|
|
ParseCSVContent(csvContent, AnimData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>CSV<53>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
public void ParseCSVContent(string csvContent, Dictionary<string, Dictionary<int, List<FrameData>>> AnimData)
|
|||
|
|
{
|
|||
|
|
// <20><><EFBFBD>зָ<D0B7>
|
|||
|
|
var lines = csvContent.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
|||
|
|
int lineCount = 0;
|
|||
|
|
|
|||
|
|
foreach (var line in lines)
|
|||
|
|
{
|
|||
|
|
lineCount++;
|
|||
|
|
if (string.IsNullOrWhiteSpace(line) || line.StartsWith(","))
|
|||
|
|
continue;
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
// <20>ָ<EFBFBD><D6B8><EFBFBD>
|
|||
|
|
var parts = line.Trim().Split(',');
|
|||
|
|
if (parts.Length < 7)
|
|||
|
|
{
|
|||
|
|
Debug.LogWarning($"Skipping line {lineCount}: insufficient parts ({parts.Length})");
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
string partID = parts[0];
|
|||
|
|
int texWidth = ParseInt(parts[1]);
|
|||
|
|
int texHeight = ParseInt(parts[2]);
|
|||
|
|
int frameCount = ParseInt(parts[3]); //<2F>ܹ<EFBFBD>֡<EFBFBD><D6A1>
|
|||
|
|
int totalDirections = ParseInt(parts[4]); //<2F>ܹ<EFBFBD><DCB9><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
int framesPerDirection = ParseInt(parts[5]); //ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><D6A1>
|
|||
|
|
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD>б<EFBFBD>
|
|||
|
|
// <20><><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>
|
|||
|
|
for (int i = 6; i < 6 + frameCount; i++)
|
|||
|
|
{
|
|||
|
|
// <20><><EFBFBD>㵱ǰ<E3B5B1><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD><D1B4>ڵķ<DAB5><C4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
int directionIndex = (i - 6) / framesPerDirection;
|
|||
|
|
if (i >= parts.Length)
|
|||
|
|
{
|
|||
|
|
Debug.LogWarning($"Part {partID} direction {directionIndex}: expected {frameCount} frames, got {i - 6}");
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (string.IsNullOrWhiteSpace(parts[i]))
|
|||
|
|
continue;
|
|||
|
|
|
|||
|
|
var frameData = parts[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|||
|
|
if (frameData.Length < 10)
|
|||
|
|
{
|
|||
|
|
Debug.LogWarning($"Skipping frame data: insufficient values ({frameData.Length})");
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FrameData frame = new FrameData
|
|||
|
|
{
|
|||
|
|
frameID = ParseInt(frameData[0]),
|
|||
|
|
startX = ParseInt(frameData[1]),
|
|||
|
|
startY = ParseInt(frameData[2]),
|
|||
|
|
width = ParseInt(frameData[3]),
|
|||
|
|
height = ParseInt(frameData[4]),
|
|||
|
|
offsetX = ParseInt(frameData[5]),
|
|||
|
|
offsetY = ParseInt(frameData[6]),
|
|||
|
|
sourceWidth = ParseInt(frameData[7]),
|
|||
|
|
sourceHeight = ParseInt(frameData[8])
|
|||
|
|
};
|
|||
|
|
if (!AnimData.ContainsKey(partID))
|
|||
|
|
{
|
|||
|
|
AnimData[partID] = new Dictionary<int, List<FrameData>>();
|
|||
|
|
}
|
|||
|
|
if (!AnimData[partID].ContainsKey(directionIndex))
|
|||
|
|
{
|
|||
|
|
AnimData[partID][frame.frameID / 10000] = new List<FrameData>();
|
|||
|
|
}
|
|||
|
|
AnimData[partID][frame.frameID / 10000].Add(frame);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception e)
|
|||
|
|
{
|
|||
|
|
//Debug.LogError($"Error parsing line {lineCount}: {line}\n{e}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><>ȡָ<C8A1><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>
|
|||
|
|
public List<FrameData> GetFramesForPartAndDirection(Dictionary<string, Dictionary<int, List<FrameData>>> AnimData, string partID, int direction)
|
|||
|
|
{
|
|||
|
|
if (AnimData.TryGetValue(partID, out var directions) &&
|
|||
|
|
directions.TryGetValue(direction, out var frames))
|
|||
|
|
{
|
|||
|
|
return frames;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Debug.LogWarning($"No frames found for part {partID}, direction {direction}");
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
public List<FrameData> GetFramesForPartAndDirection(AnimEnum animEnum,string partId,int direction)
|
|||
|
|
{
|
|||
|
|
switch (animEnum)
|
|||
|
|
{
|
|||
|
|
case AnimEnum.Anim_cloth:
|
|||
|
|
return GetFramesForPartAndDirection(clothAnimData,partId,direction);
|
|||
|
|
case AnimEnum.Anim_weapon:
|
|||
|
|
return GetFramesForPartAndDirection(weaponAnimData, partId, direction);
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õķ<C3B5><C4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
public int GetDirectionCountForPart(string partID)
|
|||
|
|
{
|
|||
|
|
if (clothAnimData.TryGetValue(partID, out var directions))
|
|||
|
|
{
|
|||
|
|
return directions.Count;
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD>в<EFBFBD><D0B2><EFBFBD>ID
|
|||
|
|
public List<string> GetAllPartIDs()
|
|||
|
|
{
|
|||
|
|
return clothAnimData.Keys.ToList();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><>ȡ<EFBFBD>ض<EFBFBD><D8B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><D0B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
public Dictionary<int, List<FrameData>> GetPartData(string partID)
|
|||
|
|
{
|
|||
|
|
if (clothAnimData.TryGetValue(partID, out var directions))
|
|||
|
|
{
|
|||
|
|
return directions;
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
public void ClearAllData()
|
|||
|
|
{
|
|||
|
|
clothAnimData.Clear();
|
|||
|
|
Debug.Log("Cleared all animation data");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
private int ParseInt(string value)
|
|||
|
|
{
|
|||
|
|
if (int.TryParse(value, out int result))
|
|||
|
|
{
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
Debug.LogWarning($"Failed to parse integer: {value}");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
private int GetDirectionIndex(string partID)
|
|||
|
|
{
|
|||
|
|
if (clothAnimData.TryGetValue(partID, out var directions))
|
|||
|
|
{
|
|||
|
|
return directions.Count;
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
[ContextMenu("Print Animation Data")]
|
|||
|
|
public void PrintAnimationData()
|
|||
|
|
{
|
|||
|
|
Debug.Log("==== Animation Data Summary ====");
|
|||
|
|
Debug.Log($"Total parts: {clothAnimData.Count}");
|
|||
|
|
|
|||
|
|
foreach (var part in clothAnimData)
|
|||
|
|
{
|
|||
|
|
Debug.Log($"Part: {part.Key}");
|
|||
|
|
foreach (var direction in part.Value)
|
|||
|
|
{
|
|||
|
|
Debug.Log($" Direction {direction.Key}: {direction.Value.Count} frames");
|
|||
|
|
|
|||
|
|
// <20><>ӡǰ3֡<33><D6A1><EFBFBD><EFBFBD>
|
|||
|
|
for (int i = 0; i < Mathf.Min(3, direction.Value.Count); i++)
|
|||
|
|
{
|
|||
|
|
Debug.Log($" {direction.Value[i]}");
|
|||
|
|
}
|
|||
|
|
if (direction.Value.Count > 3)
|
|||
|
|
{
|
|||
|
|
Debug.Log($" ... and {direction.Value.Count - 3} more");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
Debug.Log("================================");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|