using System; using System.Collections.Generic; using System.IO; using UnityEngine; [AddComponentMenu("Dynamic Bone/Dynamic Bone")] public class DynamicBone : MonoBehaviour { public bool SerializeWrite(BinaryWriter f_bw) { Func, bool> func = delegate(DynamicBone.PartialMode f_pmode, Dictionary f_dicValueFromBone) { f_bw.Write((int)f_pmode); if (f_pmode != DynamicBone.PartialMode.Partial) { return false; } if (this.m_Particles != null) { f_bw.Write(this.m_Particles.Count); for (int j = 0; j < this.m_Particles.Count; j++) { string text = this.m_Particles[j].m_Transform.name.ToLower(); f_bw.Write(text); f_bw.Write(f_dicValueFromBone[text]); } return true; } NDebug.MessageBox("エラー", "PartialMode.Partialの場合は実行中でないと各ボーン名が解らずボーン個別値指定が保存できません。"); return false; }; f_bw.Write("CM3D21_PHY"); f_bw.Write(1320); if (this.m_Root == null) { NDebug.MessageBox("エラー", "×物理ルートボーンが設定されていません。"); return false; } f_bw.Write(this.m_Root.name); func(this.m_EnablePartialDamping, this.m_dicPartialDamping); f_bw.Write(this.m_Damping); this.SerializeWriteAnimationCurve(f_bw, this.m_DampingDistrib); func(this.m_EnablePartialElasticity, this.m_dicPartialElasticity); f_bw.Write(this.m_Elasticity); this.SerializeWriteAnimationCurve(f_bw, this.m_ElasticityDistrib); func(this.m_EnablePartialStiffness, this.m_dicPartialStiffness); f_bw.Write(this.m_Stiffness); this.SerializeWriteAnimationCurve(f_bw, this.m_StiffnessDistrib); func(this.m_EnablePartialInert, this.m_dicPartialInert); f_bw.Write(this.m_Inert); this.SerializeWriteAnimationCurve(f_bw, this.m_InertDistrib); func(this.m_EnablePartialRadius, this.m_dicPartialRadius); f_bw.Write(this.m_Radius); this.SerializeWriteAnimationCurve(f_bw, this.m_RadiusDistrib); f_bw.Write(this.m_EndLength); f_bw.Write(this.m_EndOffset.x); f_bw.Write(this.m_EndOffset.y); f_bw.Write(this.m_EndOffset.z); f_bw.Write(this.m_Gravity.x); f_bw.Write(this.m_Gravity.y); f_bw.Write(this.m_Gravity.z); f_bw.Write(this.m_Force.x); f_bw.Write(this.m_Force.y); f_bw.Write(this.m_Force.z); f_bw.Write(Path.GetFileNameWithoutExtension(this.m_ColliderFileName).ToLower()); f_bw.Write((this.m_Colliders == null) ? 0 : this.m_Colliders.Count); if (this.m_Colliders != null) { } f_bw.Write((this.m_Exclusions == null) ? 0 : this.m_Exclusions.Count); if (this.m_Exclusions != null) { for (int i = 0; i < this.m_Exclusions.Count; i++) { } } f_bw.Write((int)this.m_FreezeAxis); return true; } private void SerializeWriteAnimationCurve(BinaryWriter f_bw, AnimationCurve f_ac) { Keyframe[] keys = f_ac.keys; f_bw.Write(keys.Length); for (int i = 0; i < keys.Length; i++) { f_bw.Write(keys[i].time); f_bw.Write(keys[i].value); f_bw.Write(keys[i].inTangent); f_bw.Write(keys[i].outTangent); } } public bool SerializeWriteCollider(BinaryWriter f_bw, string f_strFileName) { f_bw.Write("CM3D21_COL"); f_bw.Write(1320); if (this.m_Colliders == null || this.m_Colliders.Count == 0) { NDebug.MessageBox("エラー", "×物理Collidersは空です。"); return false; } f_bw.Write(this.m_Colliders.Count); for (int i = 0; i < this.m_Colliders.Count; i++) { if (this.m_Colliders[i] == null) { f_bw.Write("missing"); } else { f_bw.Write(this.m_Colliders[i].TypeName); this.m_Colliders[i].Serialize(f_bw, 1320); } } this.m_ColliderFileName = f_strFileName; this.m_strNowReadColliderFileName = f_strFileName; return true; } public void SerializeRead(BinaryReader f_br) { string a; Func, DynamicBone.PartialMode> func = delegate(Dictionary f_dicValueFromBone) { DynamicBone.PartialMode partialMode = (DynamicBone.PartialMode)f_br.ReadInt32(); if (partialMode != DynamicBone.PartialMode.Partial) { return partialMode; } int num4 = f_br.ReadInt32(); if (this.m_Particles != null && this.m_Particles.Count != 0) { if (num4 != this.m_Particles.Count) { NDebug.Assert("ボーン数が一致していません。", false); } for (int k = 0; k < num4; k++) { string strName = f_br.ReadString(); if (this.m_Particles.Find((DynamicBone.Particle a) => a.m_Transform.name.ToLower() == strName) == null) { NDebug.Assert("ボーンがありません。", false); } f_dicValueFromBone[strName] = f_br.ReadSingle(); } } else { for (int l = 0; l < num4; l++) { string key = f_br.ReadString(); f_dicValueFromBone[key] = f_br.ReadSingle(); } } return partialMode; }; if (this.m_Exclusions != null) { this.m_Exclusions.Clear(); } this.m_dicPartialStiffness.Clear(); a = f_br.ReadString(); if (a != "CM3D21_PHY") { NDebug.Assert("物理定義ヘッダー不正", false); } int num = f_br.ReadInt32(); string text = f_br.ReadString(); this.m_EnablePartialDamping = func(this.m_dicPartialDamping); this.m_Damping = f_br.ReadSingle(); this.SerializeReadAnimationCurve(f_br, out this.m_DampingDistrib); this.m_EnablePartialElasticity = func(this.m_dicPartialElasticity); this.m_Elasticity = f_br.ReadSingle(); this.SerializeReadAnimationCurve(f_br, out this.m_ElasticityDistrib); this.m_EnablePartialStiffness = func(this.m_dicPartialStiffness); this.m_Stiffness = f_br.ReadSingle(); this.SerializeReadAnimationCurve(f_br, out this.m_StiffnessDistrib); this.m_EnablePartialInert = func(this.m_dicPartialInert); this.m_Inert = f_br.ReadSingle(); this.SerializeReadAnimationCurve(f_br, out this.m_InertDistrib); this.m_EnablePartialRadius = func(this.m_dicPartialRadius); this.m_Radius = f_br.ReadSingle(); this.SerializeReadAnimationCurve(f_br, out this.m_RadiusDistrib); this.m_EndLength = f_br.ReadSingle(); this.m_EndOffset.Set(f_br.ReadSingle(), f_br.ReadSingle(), f_br.ReadSingle()); this.m_Gravity.Set(f_br.ReadSingle(), f_br.ReadSingle(), f_br.ReadSingle()); this.m_Force.Set(f_br.ReadSingle(), f_br.ReadSingle(), f_br.ReadSingle()); this.m_ColliderFileName = f_br.ReadString(); int num2 = f_br.ReadInt32(); for (int i = 0; i < num2; i++) { if (this.m_Colliders == null) { this.m_Colliders = new List(); } } int num3 = f_br.ReadInt32(); for (int j = 0; j < num3; j++) { if (this.m_Exclusions == null) { this.m_Exclusions = new List(); } } this.m_FreezeAxis = (DynamicBone.FreezeAxis)f_br.ReadInt32(); this.InitTransforms(); this.SetupParticles(); this.m_bSkipStartSetupParticles = true; } private void SerializeReadAnimationCurve(BinaryReader f_br, out AnimationCurve f_ac) { int num = f_br.ReadInt32(); f_ac = null; if (num != 0) { Keyframe[] array = new Keyframe[num]; for (int i = 0; i < num; i++) { array[i] = new Keyframe { time = f_br.ReadSingle(), value = f_br.ReadSingle(), inTangent = f_br.ReadSingle(), outTangent = f_br.ReadSingle() }; } f_ac = new AnimationCurve(array); } } public void SerializeReadCollider(BinaryReader f_br, Transform f_trBodyBoneRoot, string f_strFileName, Maid f_maid) { if (this.m_Colliders == null) { this.m_Colliders = new List(); } if (this.m_Colliders != null) { if (Application.isPlaying) { this.Uninit(); } this.m_Colliders.Clear(); } string a = f_br.ReadString(); if (a != "CM3D21_COL") { NDebug.Assert("物理Colliderヘッダー不正", false); } int f_nVersion = f_br.ReadInt32(); int num = f_br.ReadInt32(); for (int i = 0; i < num; i++) { GameObject gameObject = new GameObject(); string text = f_br.ReadString(); if (text == "dbc") { DynamicBoneCollider dynamicBoneCollider = gameObject.AddComponent(); dynamicBoneCollider.Deserialize(f_br, f_nVersion, f_trBodyBoneRoot); this.m_Colliders.Add(dynamicBoneCollider); } else if (text == "dpc") { DynamicBonePlaneCollider dynamicBonePlaneCollider = gameObject.AddComponent(); dynamicBonePlaneCollider.Deserialize(f_br, f_nVersion, f_trBodyBoneRoot); this.m_Colliders.Add(dynamicBonePlaneCollider); } else if (text == "dbm") { DynamicBoneMuneCollider dynamicBoneMuneCollider = gameObject.AddComponent(); dynamicBoneMuneCollider.m_maid = f_maid; dynamicBoneMuneCollider.Deserialize(f_br, f_nVersion, f_trBodyBoneRoot); this.m_Colliders.Add(dynamicBoneMuneCollider); } else if (!(text == "missing")) { NDebug.Assert("不正なColliderです。" + text, false); } } this.m_ColliderFileName = f_strFileName; this.m_strNowReadColliderFileName = f_strFileName; if (GameMain.Instance.CMSystem.SConfig.OvrHandHitToHair && GameMain.Instance.VRMode && GameMain.Instance.VRFamily != GameMain.VRFamilyType.NON) { Transform vrcontrollerTransform = GameMain.Instance.OvrMgr.GetVRControllerTransform(true); if (vrcontrollerTransform != null) { Transform transform = vrcontrollerTransform.Find(DynamicBone.m_vrHandHitObjName); if (transform == null) { GameObject gameObject2 = new GameObject(DynamicBone.m_vrHandHitObjName); transform = gameObject2.transform; transform.transform.SetParent(vrcontrollerTransform, false); transform.localPosition = new Vector3(0.03f, -0.03f, -0.03f); } DynamicBoneCollider orAddComponent = transform.GetOrAddComponent(); orAddComponent.m_Radius = 0.07f; this.m_Colliders.Add(orAddComponent); } Transform vrcontrollerTransform2 = GameMain.Instance.OvrMgr.GetVRControllerTransform(false); if (vrcontrollerTransform2 != null) { Transform transform2 = vrcontrollerTransform2.Find(DynamicBone.m_vrHandHitObjName); if (transform2 == null) { GameObject gameObject3 = new GameObject(DynamicBone.m_vrHandHitObjName); transform2 = gameObject3.transform; transform2.transform.SetParent(vrcontrollerTransform2, false); transform2.localPosition = new Vector3(-0.03f, -0.03f, -0.03f); } DynamicBoneCollider orAddComponent2 = transform2.GetOrAddComponent(); orAddComponent2.m_Radius = 0.07f; this.m_Colliders.Add(orAddComponent2); } } } public void Uninit() { if (this.m_Colliders != null) { for (int i = 0; i < this.m_Colliders.Count; i++) { if (this.m_Colliders[i] != null && this.m_Colliders[i].gameObject.name != DynamicBone.m_vrHandHitObjName) { UnityEngine.Object.DestroyImmediate(this.m_Colliders[i].gameObject); } } this.m_Colliders.Clear(); } } private void Start() { if (!this.m_bSkipStartSetupParticles) { this.SetupParticles(); } this.m_fRealTimeBefore = Time.realtimeSinceStartup; } private void FixedUpdate() { if (this.m_UpdateMode == DynamicBone.UpdateMode.AnimatePhysics) { this.PreUpdate(); } } private void Update() { if (this.m_UpdateMode != DynamicBone.UpdateMode.AnimatePhysics) { this.PreUpdate(); } } private void LateUpdate() { if (this.m_DistantDisable) { this.CheckDistance(); } if (this.m_Weight > 0f && (!this.m_DistantDisable || !this.m_DistantDisabled)) { float t; if (this.m_UpdateMode == DynamicBone.UpdateMode.UnscaledTime) { float realtimeSinceStartup = Time.realtimeSinceStartup; t = realtimeSinceStartup - this.m_fRealTimeBefore; this.m_fRealTimeBefore = realtimeSinceStartup; } else { t = Time.deltaTime; } this.UpdateDynamicBones(t); } } private void PreUpdate() { if (this.m_Weight > 0f && (!this.m_DistantDisable || !this.m_DistantDisabled)) { this.InitTransforms(); } } private void CheckDistance() { Transform transform = this.m_ReferenceObject; if (transform == null && Camera.main != null) { transform = Camera.main.transform; } if (transform != null) { float sqrMagnitude = (transform.position - base.transform.position).sqrMagnitude; bool flag = sqrMagnitude > this.m_DistanceToObject * this.m_DistanceToObject; if (flag != this.m_DistantDisabled) { if (!flag) { this.ResetParticlesPosition(); } this.m_DistantDisabled = flag; } } } private void OnEnable() { this.ResetParticlesPosition(); } private void OnDisable() { this.InitTransforms(); } private void OnValidate() { this.m_UpdateRate = Mathf.Max(this.m_UpdateRate, 0f); this.m_Damping = Mathf.Clamp01(this.m_Damping); this.m_Elasticity = Mathf.Clamp01(this.m_Elasticity); this.m_Stiffness = Mathf.Clamp01(this.m_Stiffness); this.m_Inert = Mathf.Clamp01(this.m_Inert); this.m_Radius = Mathf.Max(this.m_Radius, 0f); if (Application.isEditor && Application.isPlaying) { this.InitTransforms(); this.SetupParticles(); } } public void SetWeight(float w) { if (this.m_Weight != w) { if (w == 0f) { this.InitTransforms(); } else if (this.m_Weight == 0f) { this.ResetParticlesPosition(); } this.m_Weight = w; } } public float GetWeight() { return this.m_Weight; } private void UpdateDynamicBones(float t) { if (this.m_Root == null) { return; } this.m_ObjectScale = Mathf.Abs(base.transform.lossyScale.x); this.m_ObjectMove = base.transform.position - this.m_ObjectPrevPosition; this.m_ObjectPrevPosition = base.transform.position; int num = 1; if (this.m_UpdateRate > 0f) { float num2 = 1f / this.m_UpdateRate; this.m_Time += t; num = 0; while (this.m_Time >= num2) { this.m_Time -= num2; if (++num >= 3) { this.m_Time = 0f; break; } } } if (num > 0) { for (int i = 0; i < num; i++) { this.UpdateParticles1(); this.UpdateParticles2(); this.m_ObjectMove = Vector3.zero; } } else { this.SkipUpdateParticles(); } this.ApplyParticlesToTransforms(); } private void SetupParticles() { this.m_Particles.Clear(); if (this.m_Root == null) { return; } this.m_LocalGravity = this.m_Root.InverseTransformDirection(this.m_Gravity); this.m_ObjectScale = Mathf.Abs(base.transform.lossyScale.x); this.m_ObjectPrevPosition = base.transform.position; this.m_ObjectMove = Vector3.zero; this.m_BoneTotalLength = 0f; this.AppendParticles(this.m_Root, -1, 0f); this.UpdateParameters(); } private void AppendParticles(Transform b, int parentIndex, float boneLength) { DynamicBone.Particle particle = new DynamicBone.Particle(); particle.m_Transform = b; particle.m_ParentIndex = parentIndex; if (b != null) { particle.m_Position = (particle.m_PrevPosition = b.position); particle.m_InitLocalPosition = b.localPosition; particle.m_InitLocalRotation = b.localRotation; } else { Transform transform = this.m_Particles[parentIndex].m_Transform; if (this.m_EndLength > 0f) { Transform parent = transform.parent; if (parent != null) { particle.m_EndOffset = transform.InverseTransformPoint(transform.position * 2f - parent.position) * this.m_EndLength; } else { particle.m_EndOffset = new Vector3(this.m_EndLength, 0f, 0f); } } else { particle.m_EndOffset = transform.InverseTransformPoint(base.transform.TransformDirection(this.m_EndOffset) + transform.position); } particle.m_Position = (particle.m_PrevPosition = transform.TransformPoint(particle.m_EndOffset)); } if (parentIndex >= 0) { boneLength += (this.m_Particles[parentIndex].m_Transform.position - particle.m_Position).magnitude; particle.m_BoneLength = boneLength; this.m_BoneTotalLength = Mathf.Max(this.m_BoneTotalLength, boneLength); } int count = this.m_Particles.Count; this.m_Particles.Add(particle); if (b != null) { for (int i = 0; i < b.childCount; i++) { bool flag = false; if (this.m_Exclusions != null) { for (int j = 0; j < this.m_Exclusions.Count; j++) { Transform x = this.m_Exclusions[j]; if (x == b.GetChild(i)) { flag = true; break; } } } if (!flag) { this.AppendParticles(b.GetChild(i), count, boneLength); } else if (this.m_EndLength > 0f || this.m_EndOffset != Vector3.zero) { this.AppendParticles(null, count, boneLength); } } if (b.childCount == 0 && (this.m_EndLength > 0f || this.m_EndOffset != Vector3.zero)) { this.AppendParticles(null, count, boneLength); } } } private void TryGetValueFromBone(DynamicBone.PartialMode f_mode, Dictionary f_def, DynamicBone.SaveType f_type, string f_name, ref float f_value) { if (f_mode == DynamicBone.PartialMode.Partial) { if (!f_def.TryGetValue(f_name, out f_value)) { float num = 0f; f_def[f_name] = num; f_value = num; } } else if (f_mode == DynamicBone.PartialMode.FromBoneName) { if (f_name.Contains("_h_")) { f_value = this.m_ValueFromBone[(int)f_type, 0]; } else if (f_name.Contains("_h50_")) { f_value = this.m_ValueFromBone[(int)f_type, 1]; } else { f_value = this.m_ValueFromBone[(int)f_type, 2]; } } } public void UpdateParameters() { if (this.m_Root == null) { return; } this.m_LocalGravity = this.m_Root.InverseTransformDirection(this.m_Gravity); for (int i = 0; i < this.m_Particles.Count; i++) { DynamicBone.Particle particle = this.m_Particles[i]; particle.m_Damping = this.m_Damping; particle.m_Elasticity = this.m_Elasticity; particle.m_Stiffness = this.m_Stiffness; particle.m_Inert = this.m_Inert; particle.m_Radius = this.m_Radius; if (this.m_BoneTotalLength > 0f) { float time = particle.m_BoneLength / this.m_BoneTotalLength; if (this.m_EnablePartialDamping == DynamicBone.PartialMode.StaticOrCurve && this.m_DampingDistrib != null && this.m_DampingDistrib.keys.Length > 0) { particle.m_Damping *= this.m_DampingDistrib.Evaluate(time); } if (this.m_EnablePartialElasticity == DynamicBone.PartialMode.StaticOrCurve && this.m_ElasticityDistrib != null && this.m_ElasticityDistrib.keys.Length > 0) { particle.m_Elasticity *= this.m_ElasticityDistrib.Evaluate(time); } if (this.m_EnablePartialStiffness == DynamicBone.PartialMode.StaticOrCurve && this.m_StiffnessDistrib != null && this.m_StiffnessDistrib.keys.Length > 0) { particle.m_Stiffness *= this.m_StiffnessDistrib.Evaluate(time); } if (this.m_EnablePartialInert == DynamicBone.PartialMode.StaticOrCurve && this.m_InertDistrib != null && this.m_InertDistrib.keys.Length > 0) { particle.m_Inert *= this.m_InertDistrib.Evaluate(time); } if (this.m_EnablePartialRadius == DynamicBone.PartialMode.StaticOrCurve && this.m_RadiusDistrib != null && this.m_RadiusDistrib.keys.Length > 0) { particle.m_Radius *= this.m_RadiusDistrib.Evaluate(time); } } string f_name = particle.m_Transform.name.ToLower(); this.TryGetValueFromBone(this.m_EnablePartialDamping, this.m_dicPartialDamping, DynamicBone.SaveType.Damping, f_name, ref particle.m_Damping); this.TryGetValueFromBone(this.m_EnablePartialElasticity, this.m_dicPartialElasticity, DynamicBone.SaveType.Elasticity, f_name, ref particle.m_Elasticity); this.TryGetValueFromBone(this.m_EnablePartialStiffness, this.m_dicPartialStiffness, DynamicBone.SaveType.Stiffness, f_name, ref particle.m_Stiffness); this.TryGetValueFromBone(this.m_EnablePartialInert, this.m_dicPartialInert, DynamicBone.SaveType.Inert, f_name, ref particle.m_Inert); this.TryGetValueFromBone(this.m_EnablePartialRadius, this.m_dicPartialRadius, DynamicBone.SaveType.Radius, f_name, ref particle.m_Radius); particle.m_Damping = Mathf.Clamp01(particle.m_Damping); particle.m_Elasticity = Mathf.Clamp01(particle.m_Elasticity); particle.m_Stiffness = Mathf.Clamp01(particle.m_Stiffness); particle.m_Inert = Mathf.Clamp01(particle.m_Inert); particle.m_Radius = Mathf.Max(particle.m_Radius, 0f); } } private void InitTransforms() { for (int i = 0; i < this.m_Particles.Count; i++) { DynamicBone.Particle particle = this.m_Particles[i]; if (particle.m_Transform != null) { particle.m_Transform.localPosition = particle.m_InitLocalPosition; particle.m_Transform.localRotation = particle.m_InitLocalRotation; } } } private void ResetParticlesPosition() { for (int i = 0; i < this.m_Particles.Count; i++) { DynamicBone.Particle particle = this.m_Particles[i]; if (particle.m_Transform != null) { particle.m_Position = (particle.m_PrevPosition = particle.m_Transform.position); } else { Transform transform = this.m_Particles[particle.m_ParentIndex].m_Transform; particle.m_Position = (particle.m_PrevPosition = transform.TransformPoint(particle.m_EndOffset)); } } this.m_ObjectPrevPosition = base.transform.position; } private void UpdateParticles1() { Vector3 vector = this.m_Gravity; Vector3 normalized = this.m_Gravity.normalized; Vector3 lhs = this.m_Root.TransformDirection(this.m_LocalGravity); Vector3 b = normalized * Mathf.Max(Vector3.Dot(lhs, normalized), 0f); vector -= b; vector = (vector + this.m_Force) * this.m_ObjectScale; for (int i = 0; i < this.m_Particles.Count; i++) { DynamicBone.Particle particle = this.m_Particles[i]; if (particle.m_ParentIndex >= 0) { Vector3 a = particle.m_Position - particle.m_PrevPosition; Vector3 b2 = this.m_ObjectMove * particle.m_Inert; particle.m_PrevPosition = particle.m_Position + b2; particle.m_Position += a * (1f - particle.m_Damping) + vector + b2; } else { particle.m_PrevPosition = particle.m_Position; particle.m_Position = particle.m_Transform.position; } } } private void UpdateParticles2() { Plane plane = default(Plane); for (int i = 1; i < this.m_Particles.Count; i++) { DynamicBone.Particle particle = this.m_Particles[i]; DynamicBone.Particle particle2 = this.m_Particles[particle.m_ParentIndex]; float magnitude; if (particle.m_Transform != null) { magnitude = (particle2.m_Transform.position - particle.m_Transform.position).magnitude; } else { magnitude = particle2.m_Transform.localToWorldMatrix.MultiplyVector(particle.m_EndOffset).magnitude; } float num = Mathf.Lerp(1f, particle.m_Stiffness, this.m_Weight); if (num > 0f || particle.m_Elasticity > 0f) { Matrix4x4 localToWorldMatrix = particle2.m_Transform.localToWorldMatrix; localToWorldMatrix.SetColumn(3, particle2.m_Position); Vector3 a; if (particle.m_Transform != null) { a = localToWorldMatrix.MultiplyPoint3x4(particle.m_Transform.localPosition); } else { a = localToWorldMatrix.MultiplyPoint3x4(particle.m_EndOffset); } Vector3 a2 = a - particle.m_Position; particle.m_Position += a2 * particle.m_Elasticity; if (num > 0f) { a2 = a - particle.m_Position; float magnitude2 = a2.magnitude; float num2 = magnitude * (1f - num) * 2f; if (magnitude2 > num2) { particle.m_Position += a2 * ((magnitude2 - num2) / magnitude2); } } } if (this.m_Colliders != null) { float particleRadius = particle.m_Radius * this.m_ObjectScale; for (int j = 0; j < this.m_Colliders.Count; j++) { DynamicBoneColliderBase dynamicBoneColliderBase = this.m_Colliders[j]; if (dynamicBoneColliderBase != null && dynamicBoneColliderBase.enabled) { dynamicBoneColliderBase.Collide(ref particle.m_Position, particleRadius); } } if (this.m_hitFloorPlane != null) { this.m_hitFloorPlane.Collide(ref particle.m_Position, particleRadius); } } if (this.m_FreezeAxis != DynamicBone.FreezeAxis.None) { DynamicBone.FreezeAxis freezeAxis = this.m_FreezeAxis; if (freezeAxis != DynamicBone.FreezeAxis.X) { if (freezeAxis != DynamicBone.FreezeAxis.Y) { if (freezeAxis == DynamicBone.FreezeAxis.Z) { plane.SetNormalAndPosition(particle2.m_Transform.forward, particle2.m_Position); } } else { plane.SetNormalAndPosition(particle2.m_Transform.up, particle2.m_Position); } } else { plane.SetNormalAndPosition(particle2.m_Transform.right, particle2.m_Position); } particle.m_Position -= plane.normal * plane.GetDistanceToPoint(particle.m_Position); } Vector3 a3 = particle2.m_Position - particle.m_Position; float magnitude3 = a3.magnitude; if (magnitude3 > 0f) { particle.m_Position += a3 * ((magnitude3 - magnitude) / magnitude3); } } } private void SkipUpdateParticles() { for (int i = 0; i < this.m_Particles.Count; i++) { DynamicBone.Particle particle = this.m_Particles[i]; if (particle.m_ParentIndex >= 0) { particle.m_PrevPosition += this.m_ObjectMove; particle.m_Position += this.m_ObjectMove; DynamicBone.Particle particle2 = this.m_Particles[particle.m_ParentIndex]; float magnitude; if (particle.m_Transform != null) { magnitude = (particle2.m_Transform.position - particle.m_Transform.position).magnitude; } else { magnitude = particle2.m_Transform.localToWorldMatrix.MultiplyVector(particle.m_EndOffset).magnitude; } float num = Mathf.Lerp(1f, particle.m_Stiffness, this.m_Weight); if (num > 0f) { Matrix4x4 localToWorldMatrix = particle2.m_Transform.localToWorldMatrix; localToWorldMatrix.SetColumn(3, particle2.m_Position); Vector3 a; if (particle.m_Transform != null) { a = localToWorldMatrix.MultiplyPoint3x4(particle.m_Transform.localPosition); } else { a = localToWorldMatrix.MultiplyPoint3x4(particle.m_EndOffset); } Vector3 a2 = a - particle.m_Position; float magnitude2 = a2.magnitude; float num2 = magnitude * (1f - num) * 2f; if (magnitude2 > num2) { particle.m_Position += a2 * ((magnitude2 - num2) / magnitude2); } } Vector3 a3 = particle2.m_Position - particle.m_Position; float magnitude3 = a3.magnitude; if (magnitude3 > 0f) { particle.m_Position += a3 * ((magnitude3 - magnitude) / magnitude3); } } else { particle.m_PrevPosition = particle.m_Position; particle.m_Position = particle.m_Transform.position; } } } private static Vector3 MirrorVector(Vector3 v, Vector3 axis) { return v - axis * (Vector3.Dot(v, axis) * 2f); } private void ApplyParticlesToTransforms() { for (int i = 1; i < this.m_Particles.Count; i++) { DynamicBone.Particle particle = this.m_Particles[i]; DynamicBone.Particle particle2 = this.m_Particles[particle.m_ParentIndex]; if (particle2.m_Transform.childCount <= 1) { Vector3 direction; if (particle.m_Transform != null) { direction = particle.m_Transform.localPosition; } else { direction = particle.m_EndOffset; } Vector3 toDirection = particle.m_Position - particle2.m_Position; Quaternion lhs = Quaternion.FromToRotation(particle2.m_Transform.TransformDirection(direction), toDirection); particle2.m_Transform.rotation = lhs * particle2.m_Transform.rotation; } if (particle.m_Transform != null) { particle.m_Transform.position = particle.m_Position; } } } [ReadOnly] public string m_strNowReadPhysicsFileName; [Tooltip("The root of the transform hierarchy to apply physics.")] public Transform m_Root; [Tooltip("Internal physics simulation rate.")] public float m_UpdateRate; public DynamicBone.UpdateMode m_UpdateMode = DynamicBone.UpdateMode.UnscaledTime; [Header("■減衰率 設定タイプ")] [Tooltip("StaticOrCurve=下記の設定を使う。\nPartial=ボーン個別にToolで設定する。\nFromBoneName=旧仕様ボーン名から自動で設定する。")] public DynamicBone.PartialMode m_EnablePartialDamping; public Dictionary m_dicPartialDamping = new Dictionary(); [Header("減衰率")] [Tooltip("How much the bones slowed down.")] [Range(0f, 1f)] public float m_Damping = 0.5f; public AnimationCurve m_DampingDistrib; [Header("■復元率 設定タイプ")] [Tooltip("StaticOrCurve=下記の設定を使う。\nPartial=ボーン個別にToolで設定する。\nFromBoneName=旧仕様ボーン名から自動で設定する。")] public DynamicBone.PartialMode m_EnablePartialElasticity; public Dictionary m_dicPartialElasticity = new Dictionary(); [Header("復元率")] [Tooltip("How much the force applied to return each bone to original orientation.")] [Range(0f, 1f)] public float m_Elasticity = 0.1f; public AnimationCurve m_ElasticityDistrib; [Header("■元の向きの影響力 設定タイプ")] [Tooltip("StaticOrCurve=下記の設定を使う。\nPartial=ボーン個別にToolで設定する。\nFromBoneName=旧仕様ボーン名から自動で設定する。")] public DynamicBone.PartialMode m_EnablePartialStiffness; public Dictionary m_dicPartialStiffness = new Dictionary(); [Header("元の向きの影響力(StaticOrCurve)")] [Tooltip("How much bone's original orientation are preserved.")] [Range(0f, 1f)] public float m_Stiffness = 0.1f; public AnimationCurve m_StiffnessDistrib; [Header("■移動距離による物理無視率 設定タイプ")] [Tooltip("StaticOrCurve=下記の設定を使う。\nPartial=ボーン個別にToolで設定する。\nFromBoneName=旧仕様ボーン名から自動で設定する。")] public DynamicBone.PartialMode m_EnablePartialInert; public Dictionary m_dicPartialInert = new Dictionary(); [Header("移動距離による物理無視率")] [Tooltip("How much character's position change is ignored in physics simulation.")] [Range(0f, 1f)] public float m_Inert; public AnimationCurve m_InertDistrib; [Header("■各ノードの当たり判定半径 設定タイプ")] [Tooltip("StaticOrCurve=下記の設定を使う。\nPartial=ボーン個別にToolで設定する。\nFromBoneName=旧仕様ボーン名から自動で設定する。")] public DynamicBone.PartialMode m_EnablePartialRadius; [SerializeField] public Dictionary m_dicPartialRadius = new Dictionary(); [Header("各ノードの当たり判定半径")] [Tooltip("Each bone can be a sphere to collide with colliders. Radius describe sphere's size.")] public float m_Radius; public AnimationCurve m_RadiusDistrib; [Header("先端に余分ボーンの追加")] [Tooltip("If End Length is not zero, an extra bone is generated at the end of transform hierarchy.")] public float m_EndLength; [Tooltip("If End Offset is not zero, an extra bone is generated at the end of transform hierarchy.")] [Header("先端に余分ボーンのオフセット座標")] public Vector3 m_EndOffset = Vector3.zero; [Tooltip("力は骨に適用されます。キャラクターの初期ポーズに適用される部分的な力は相殺されます。The force apply to bones. Partial force apply to character's initial pose is cancelled out.")] public Vector3 m_Gravity = new Vector3(0f, 0f, 0f); [Header("力を加える")] [Tooltip("The force apply to bones.")] public Vector3 m_Force = new Vector3(0f, -0.01f, 0f); [Header("衝突相手ファイル")] public string m_ColliderFileName; [ReadOnly] public string m_strNowReadColliderFileName; public bool m_ViewColliderGizmo; [Header("各ノードが衝突する相手(実機では[衝突相手ファイル]により適用される)")] [Tooltip("Collider objects interact with the bones.")] public List m_Colliders; [Header("物理計算から特別に除外するノード(子供も動かなくなる)")] [Tooltip("Bones exclude from physics simulation.")] public List m_Exclusions; [Tooltip("Constrain bones to move on specified plane.")] public DynamicBone.FreezeAxis m_FreezeAxis; [Header("距離による物理自動無効化")] [Tooltip("キャラクターがカメラやプレーヤーから遠い場合、物理シミュレーションを自動的に無効にします。")] public bool m_DistantDisable; public Transform m_ReferenceObject; public float m_DistanceToObject = 20f; [HideInInspector] [NonSerialized] public DynamicBonePlaneCollider m_hitFloorPlane; private Vector3 m_LocalGravity = Vector3.zero; private Vector3 m_ObjectMove = Vector3.zero; private Vector3 m_ObjectPrevPosition = Vector3.zero; private float m_BoneTotalLength; private float m_ObjectScale = 1f; private float m_Time; private float m_Weight = 1f; private bool m_DistantDisabled; private float m_fRealTimeBefore; public float[,] m_ValueFromBone = new float[,] { { 0.5f, 0.5f, 0.5f }, { 0.03f, 0.03f, 0.03f }, { 0.95f, 0.8f, 0.5f }, { 0f, 0f, 0f }, { 0.3f, 0.3f, 0.3f } }; public List m_Particles = new List(); private bool m_bSkipStartSetupParticles; private static string m_vrHandHitObjName = "VR Hand Hair Hit"; private bool m_bHandHitEnableBefore; public enum UpdateMode { Normal, AnimatePhysics, UnscaledTime } public enum PartialMode { StaticOrCurve, Partial, FromBoneName } public enum FreezeAxis { None, X, Y, Z } public enum SaveType { Damping, Elasticity, Stiffness, Inert, Radius, MAX } public class Particle { public Transform m_Transform; public int m_ParentIndex = -1; public float m_Damping; public float m_Elasticity; public float m_Stiffness; public float m_Inert; public float m_Radius; public float m_BoneLength; public Vector3 m_Position = Vector3.zero; public Vector3 m_PrevPosition = Vector3.zero; public Vector3 m_EndOffset = Vector3.zero; public Vector3 m_InitLocalPosition = Vector3.zero; public Quaternion m_InitLocalRotation = Quaternion.identity; } }