彻底换一下
This commit is contained in:
256
Assets/Scripts/Character/AnimParserComponent.cs
Normal file
256
Assets/Scripts/Character/AnimParserComponent.cs
Normal file
@@ -0,0 +1,256 @@
|
||||
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("================================");
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Character/AnimParserComponent.cs.meta
Normal file
11
Assets/Scripts/Character/AnimParserComponent.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9048c68984c4c04ebb19b971ba86023
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user