using System; using System.Collections.Generic; using System.IO; using kt.Physics; using kt.Serialization; using kt.Utility; using UnityEngine; public class LimbColliderMgr : MonoBehaviour { public void Init(TBody body) { this.Body = body; this.DestroyCollider(); foreach (KeyValuePair keyValuePair in LimbColliderMgr.LimbTypeBoneNamePairDic) { LimbColliderMgr.LimbColliderData limbColliderData = new LimbColliderMgr.LimbColliderData(); limbColliderData.limbType = keyValuePair.Key; limbColliderData.parent = body.GetBone(keyValuePair.Value[0]); limbColliderData.child = body.GetBone(keyValuePair.Value[1]); GameObject gameObject = new GameObject(string.Format("{0} LimbCollider", keyValuePair.Key)); gameObject.transform.SetParent(limbColliderData.parent, false); limbColliderData.collider = gameObject.AddComponent(); limbColliderData.collider.capsuleStatus.direction = MathUtility.VectorType.X; limbColliderData.collider.capsuleStatus.isDirectionInverse = true; limbColliderData.collider.capsuleStatus.startRadius = (limbColliderData.collider.capsuleStatus.endRadius = 0.05f); limbColliderData.collider.SetChara(body.maid); limbColliderData.relatedMPNList.Add(MPN.sintyou); if (LimbColliderMgr.IsUpperBodyLimb(keyValuePair.Key)) { limbColliderData.relatedMPNList.Add(MPN.UdeScl); } else { limbColliderData.relatedMPNList.Add(MPN.DouPer); } this.LimbTypeColliderDataDic[keyValuePair.Key] = limbColliderData; limbColliderData.CalcCapsuleHeight(); } foreach (KeyValuePair keyValuePair2 in this.MaidPropMetaDic) { MPN key = keyValuePair2.Key; LimbColliderMgr.MaidPropInfo value = keyValuePair2.Value; MaidProp prop = body.maid.GetProp(key); if (prop != null) { value.Value = (float)prop.value; } } body.onBoneMorphApply.Add(new Action(this.SetPropValue), false); KasaiUtility.FileLoadGameData("limbconf.limbcol", new Action(this.Load), null); } private void OnDestroy() { this.DestroyCollider(); } private void DestroyCollider() { foreach (LimbColliderMgr.LimbColliderData limbColliderData in this.LimbTypeColliderDataDic.Values) { if (limbColliderData.collider) { UnityEngine.Object.Destroy(limbColliderData.collider); } } this.LimbTypeColliderDataDic.Clear(); } private void SetPropValue(string tag, float val) { foreach (KeyValuePair keyValuePair in this.MaidPropMetaDic) { MPN key = keyValuePair.Key; LimbColliderMgr.MaidPropInfo value = keyValuePair.Value; if (key.ToString() == tag) { value.isValChange = (value.Value != val); value.Value = val; break; } } } public void UpdateColliderTransform() { foreach (LimbColliderMgr.LimbColliderData limbColliderData in this.LimbTypeColliderDataDic.Values) { foreach (MPN key in limbColliderData.relatedMPNList) { if (this.MaidPropMetaDic[key].isValChange) { limbColliderData.CalcCapsuleHeight(); break; } } } foreach (LimbColliderMgr.MaidPropInfo maidPropInfo in this.MaidPropMetaDic.Values) { maidPropInfo.isValChange = false; } } public NativeMaidPropCollider GetCollider(LimbColliderMgr.LimbType limb_type) { if (this.LimbTypeColliderDataDic.ContainsKey(limb_type)) { return this.LimbTypeColliderDataDic[limb_type].collider; } return null; } public void Save(StreamWriter writer) { LimbColliderMgr.LimbColliderPackage limbColliderPackage = new LimbColliderMgr.LimbColliderPackage(); foreach (KeyValuePair keyValuePair in this.LimbTypeColliderDataDic) { LimbColliderMgr.LimbColliderData limbColliderData = new LimbColliderMgr.LimbColliderData(); limbColliderData.limbType = keyValuePair.Key; limbColliderData.colliderStatus = keyValuePair.Value.collider.maidPropStatus; limbColliderPackage.colliderDataList.Add(limbColliderData); } string value = JsonUtility.ToJson(limbColliderPackage, true); writer.Write(value); } public void Load(StreamReader reader) { string json = reader.ReadToEnd(); LimbColliderMgr.LimbColliderPackage limbColliderPackage = JsonUtility.FromJson(json); foreach (LimbColliderMgr.LimbColliderData limbColliderData in limbColliderPackage.colliderDataList) { if (this.LimbTypeColliderDataDic.ContainsKey(limbColliderData.limbType)) { this.LimbTypeColliderDataDic[limbColliderData.limbType].collider.SetStatus(limbColliderData.colliderStatus, this.Body); } } } private static bool IsUpperBodyLimb(LimbColliderMgr.LimbType limb_type) { return limb_type == LimbColliderMgr.LimbType.UpperArm_L || limb_type == LimbColliderMgr.LimbType.UpperArm_R || limb_type == LimbColliderMgr.LimbType.Forearm_L || limb_type == LimbColliderMgr.LimbType.Forearm_R; } public const string COLLIDER_FILE_NAME = "limbconf.limbcol"; private static Dictionary LimbTypeBoneNamePairDic = new Dictionary { { LimbColliderMgr.LimbType.UpperArm_L, new string[] { "Bip01 L UpperArm", "Bip01 L Forearm" } }, { LimbColliderMgr.LimbType.Forearm_L, new string[] { "Bip01 L Forearm", "Bip01 L Hand" } }, { LimbColliderMgr.LimbType.UpperArm_R, new string[] { "Bip01 R UpperArm", "Bip01 R Forearm" } }, { LimbColliderMgr.LimbType.Forearm_R, new string[] { "Bip01 R Forearm", "Bip01 R Hand" } }, { LimbColliderMgr.LimbType.Thigh_L, new string[] { "Bip01 L Thigh", "Bip01 L Calf" } }, { LimbColliderMgr.LimbType.Calf_L, new string[] { "Bip01 L Calf", "Bip01 L Foot" } }, { LimbColliderMgr.LimbType.Thigh_R, new string[] { "Bip01 R Thigh", "Bip01 R Calf" } }, { LimbColliderMgr.LimbType.Calf_R, new string[] { "Bip01 R Calf", "Bip01 R Foot" } } }; [SerializeField] [ReadOnly] private TBody Body; private Dictionary LimbTypeColliderDataDic = new Dictionary(); private readonly Dictionary MaidPropMetaDic = new Dictionary { { MPN.sintyou, new LimbColliderMgr.MaidPropInfo() }, { MPN.UdeScl, new LimbColliderMgr.MaidPropInfo() }, { MPN.DouPer, new LimbColliderMgr.MaidPropInfo() } }; public enum LimbType { UpperArm_L, Forearm_L, UpperArm_R, Forearm_R, Thigh_L, Calf_L, Thigh_R, Calf_R } [Serializable] public class LimbColliderPackage : ASerializationVersionControl { public override int FixVersion { get { return 1000; } } public List colliderDataList = new List(); } [Serializable] public class LimbColliderData : ASerializationVersionControl { public override int FixVersion { get { return 1000; } } public void CalcCapsuleHeight() { this.collider.capsuleStatus.height = Vector3.Distance(this.parent.position, this.child.position); this.collider.status.center = this.collider.localDirection * this.collider.capsuleStatus.height / 2f; } public override void OnBeforeSerialize() { base.OnBeforeSerialize(); if (this.collider) { this.colliderStatus = this.collider.maidPropStatus; } } public LimbColliderMgr.LimbType limbType; [HideInInspector] public NativeMaidPropColliderStatus colliderStatus = new NativeMaidPropColliderStatus(); [NonSerialized] public Transform parent; [NonSerialized] public Transform child; [NonSerialized] public NativeMaidPropCollider collider; [HideInInspector] [NonSerialized] public List relatedMPNList = new List(); } private class MaidPropInfo { public float Value; public bool isValChange; } }