You've already forked UniversalViewer
							
							DanMachi:
-compatibility improvements Core: -simplified object and keyframe serialization -complicated assetbundle loading
This commit is contained in:
		
							
								
								
									
										168
									
								
								Assets/KF3/Scripts/Containers/CharacterKeyframeData.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								Assets/KF3/Scripts/Containers/CharacterKeyframeData.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,168 @@ | ||||
| using SerializableTypes; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using UnityEngine; | ||||
| using static KF3CharacterContainerSerializable; | ||||
|  | ||||
| namespace KF3.Containers | ||||
| { | ||||
|     [System.Serializable] | ||||
|     public class CharacterKeyframeData : KeyframeData | ||||
|     { | ||||
|         public BoneList[] Bones = new BoneList[0]; | ||||
|         public MorphHelper[] Morphs = new MorphHelper[0]; | ||||
|         public MorphHelper[] Renderers = new MorphHelper[0]; | ||||
|         public bool | ||||
|             EyesLocked, | ||||
|             PhysicsEnabled, | ||||
|             IKEnabled; | ||||
|         public SVector3 LeftEyeRotation, RightEyeRotation; | ||||
|         public SVector3 EyeTarget; | ||||
|         public float LookAtStrength; | ||||
|         public string CurrentAnimation; | ||||
|  | ||||
|         public CharacterKeyframeData() { } | ||||
|  | ||||
|         public CharacterKeyframeData(KF3CharacterContainer container) | ||||
|         { | ||||
|             this.Root = new SerializableTransform(container.transform); | ||||
|             this.CurrentAnimation = container.CurrentAnimation; | ||||
|             this.IKEnabled = container.IKEnabled; | ||||
|             this.PhysicsEnabled = container.PhysicsEnabled; | ||||
|             if (container as KF3CeruleanContainer != null) | ||||
|             { | ||||
|                 var bones = new List<BoneList> | ||||
|             { | ||||
|                 new BoneList() | ||||
|                 { | ||||
|                     Name = "Body", | ||||
|                     Bones = container.Body.boneList.Select(b => new SerializableBone(b)).ToArray() | ||||
|                 } | ||||
|             }; | ||||
|                 this.Bones = bones.ToArray(); | ||||
|                 this.Renderers = container.Renderers.Select(r => new MorphHelper("", GetRendererName(container, r), 0, r.enabled)).ToArray(); | ||||
|             } | ||||
|             else if (container as KF3FriendContainer != null) | ||||
|             { | ||||
|                 var bones = new List<BoneList> | ||||
|             { | ||||
|                 new BoneList() | ||||
|                 { | ||||
|                     Name = "Body", | ||||
|                     Bones = container.Body != null ? container.Body.boneList.Select(b => new SerializableBone(b)).ToArray() : new SerializableBone[0] | ||||
|                 } | ||||
|             }; | ||||
|                 var container1 = (KF3FriendContainer)container; | ||||
|                 bones.Add(new BoneList() | ||||
|                 { | ||||
|                     Name = "Ears", | ||||
|                     Bones = container1.Ears != null ? container1.Ears.boneList.Select(b => new SerializableBone(b)).ToArray() : new SerializableBone[0] | ||||
|                 }); | ||||
|                 bones.Add(new BoneList() | ||||
|                 { | ||||
|                     Name = "EarsAlt", | ||||
|                     Bones = container1.EarsAlt != null ? container1.EarsAlt.boneList.Select(b => new SerializableBone(b)).ToArray() : new SerializableBone[0] | ||||
|                 }); | ||||
|                 bones.Add(new BoneList() | ||||
|                 { | ||||
|                     Name = "Tail", | ||||
|                     Bones = container1.Tail != null ? container1.Tail.boneList.Select(b => new SerializableBone(b)).ToArray() : new SerializableBone[0] | ||||
|                 }); | ||||
|                 bones.Add(new BoneList() | ||||
|                 { | ||||
|                     Name = "TailAlt", | ||||
|                     Bones = container1.TailAlt != null ? container1.TailAlt.boneList.Select(b => new SerializableBone(b)).ToArray() : new SerializableBone[0] | ||||
|                 }); | ||||
|                 var extraBones = new List<SerializableBone>(); | ||||
|                 foreach (var ik in container1.GetComponentsInChildren<InverseKinematics>()) | ||||
|                 { | ||||
|                     extraBones.Add(new SerializableBone(ik.target)); | ||||
|                     extraBones.Add(new SerializableBone(ik.elbow)); | ||||
|                 } | ||||
|                 bones.Add(new BoneList() | ||||
|                 { | ||||
|                     Name = "Extra", | ||||
|                     Bones = extraBones.ToArray() | ||||
|                 }); | ||||
|                 this.Bones = bones.ToArray(); | ||||
|                 this.EyesLocked = container1.EyesLocked; | ||||
|                 this.LeftEyeRotation = container1.LeftEyeRotation.eulerAngles; | ||||
|                 this.RightEyeRotation = container1.RightEyeRotation.eulerAngles; | ||||
|                 this.EyeTarget = container1.EyeTarget.transform.localPosition; | ||||
|                 this.LookAtStrength = container1.LookAtStrength; | ||||
|  | ||||
|                 var morphs = new List<MorphHelper>(); | ||||
|                 foreach (var mesh in container1.Morphs) | ||||
|                 { | ||||
|                     foreach (MorphHelper morph in mesh.Value) | ||||
|                     { | ||||
|                         morphs.Add(new MorphHelper(morph.ParentName, morph.Name, morph.Strength, morph.Value)); | ||||
|                     } | ||||
|                 } | ||||
|                 this.Morphs = morphs.ToArray(); | ||||
|                 this.Renderers = container1.Renderers.Select(r => new MorphHelper("", GetRendererName(container1, r), 0, r.enabled)).ToArray(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 Error.Log("Sum ting wong", UnityEngine.Color.red); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public override KeyframeData Clone() | ||||
|         { | ||||
|             var keyframe = new CharacterKeyframeData(); | ||||
|             keyframe.Root = new SerializableTransform(this.Root); | ||||
|             keyframe.Bones = this.Bones.Select(b => new BoneList() { Name = b.Name, Bones = b.Bones.Select(b1 => new SerializableBone(b1)).ToArray() }).ToArray(); | ||||
|             keyframe.EyesLocked = this.EyesLocked; | ||||
|             keyframe.IKEnabled = this.IKEnabled; | ||||
|             keyframe.PhysicsEnabled = this.PhysicsEnabled; | ||||
|             keyframe.LeftEyeRotation = this.LeftEyeRotation; | ||||
|             keyframe.RightEyeRotation = this.RightEyeRotation; | ||||
|             keyframe.EyeTarget = this.EyeTarget; | ||||
|             keyframe.LookAtStrength = this.LookAtStrength; | ||||
|             keyframe.CurrentAnimation = this.CurrentAnimation; | ||||
|             var morphs = new List<MorphHelper>(); | ||||
|             var renderers = new List<MorphHelper>(); | ||||
|             foreach (var morph in this.Morphs) | ||||
|             { | ||||
|                 morphs.Add(new MorphHelper(morph.ParentName, morph.Name, morph.Strength, morph.Value)); | ||||
|             } | ||||
|             foreach (var renderer in this.Renderers) | ||||
|             { | ||||
|                 renderers.Add(new MorphHelper(renderer.ParentName, renderer.Name, renderer.Strength, renderer.Value)); | ||||
|             } | ||||
|             keyframe.Morphs = morphs.ToArray(); | ||||
|             keyframe.Renderers = renderers.ToArray(); | ||||
|             return keyframe; | ||||
|         } | ||||
|  | ||||
|         public override KeyframeData Lerp(KeyframeData target, float amount) | ||||
|         { | ||||
|             var target1 = target as CharacterKeyframeData; | ||||
|             if (target1 == null) { Debug.LogError("Error, incompatible type"); return this; } | ||||
|  | ||||
|             var copy = this.Clone() as CharacterKeyframeData; | ||||
|             copy.Root = copy.Root.LerpWith(target1.Root, amount); | ||||
|             copy.EyeTarget = Vector3.Lerp(copy.EyeTarget, target1.EyeTarget, amount); | ||||
|             foreach (var bonelist in copy.Bones) | ||||
|             { | ||||
|                 for (int i = 0; i < bonelist.Bones.Length; i++) | ||||
|                 { | ||||
|                     var bone1 = target1.Bones.FirstOrDefault(b => b.Name == bonelist.Name)?.Bones.FirstOrDefault(b => b.Name == bonelist.Bones[i].Name); | ||||
|                     if (bone1 == null) continue; | ||||
|                     bonelist.Bones[i].Transform = bonelist.Bones[i].Transform.LerpWith(bone1.Transform, amount); | ||||
|                 } | ||||
|             } | ||||
|             if (copy.Morphs != null && target1.Morphs != null) | ||||
|             { | ||||
|                 foreach (var morph in copy.Morphs) | ||||
|                 { | ||||
|                     var targetMorph = target1.Morphs.FirstOrDefault(m => m.ParentName == morph.ParentName && m.Name == morph.Name); | ||||
|                     if (targetMorph == null) continue; | ||||
|                     morph.Strength = Mathf.Lerp(morph.Strength, targetMorph.Strength, amount); | ||||
|                 } | ||||
|             } | ||||
|             return copy; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										11
									
								
								Assets/KF3/Scripts/Containers/CharacterKeyframeData.cs.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/KF3/Scripts/Containers/CharacterKeyframeData.cs.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: 8923d4ac35f395b4cadc946757795475 | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
							
								
								
									
										162
									
								
								Assets/KF3/Scripts/Containers/KF3CeruleanContainer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								Assets/KF3/Scripts/Containers/KF3CeruleanContainer.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | ||||
| using KF3.Containers; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using UnityEngine; | ||||
|  | ||||
| public class KF3CeruleanContainer : KF3CharacterContainer | ||||
| { | ||||
|     public UIKF3CharacterPanel CharacterPanel; | ||||
|  | ||||
|     public static IEnumerator CreateAsync(string modelName, string animationSetName, System.Action<KF3CeruleanContainer> callback = null) | ||||
|     { | ||||
|         GameObject go = new GameObject(modelName); | ||||
|         var container = go.AddComponent<KF3CeruleanContainer>(); | ||||
|         yield return container.BuildGeneral(modelName, animationSetName); | ||||
|         UIHandleCerulean.CreateAsChild(container); | ||||
|         Main.SelectObject(container); | ||||
|         container.LoadInProgress = false; | ||||
|         callback?.Invoke(container); | ||||
|     } | ||||
|  | ||||
|     public override void SetAnimationReferences() | ||||
|     { | ||||
|         if (BodyAnimation) | ||||
|         { | ||||
|             BodySimpleAnimation = Body.GetComponentInChildren<SimpleAnimation>(); | ||||
|             if (Main.OverrideClip != null) | ||||
|             { | ||||
|                 foreach (var anim in BodyAnimation.prefabAnimeList) | ||||
|                 { | ||||
|                     anim.clip = Main.OverrideClip; | ||||
|                 } | ||||
|             } | ||||
|             Body.refAnimationObj = BodyAnimation.gameObject; | ||||
|             Body.JoinReferenceParam(); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             Error.Log(Color.blue, "Body Animations Missing"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public override void SetBones() | ||||
|     { | ||||
|         var bones = Body.boneList; | ||||
|         var extraBones = bones.Where(b => b.name.Contains("osg")).ToList(); | ||||
|  | ||||
|         foreach (var bone in bones) | ||||
|         { | ||||
|             if (!bone.gameObject.TryGetComponent(out UIHandle bone1)) | ||||
|             { | ||||
|                 if (bone.GetComponent<Osage>() != null) | ||||
|                 { | ||||
|                     bone1 = UIHandlePhysicsBone.CreateAsChild(this, bone, new List<SerializableBone.BoneTags>() { SerializableBone.BoneTags.Dynamic }).SetColor(Color.cyan).SetName(bone.name); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     bone1 = UIHandleBone.CreateAsChild(this, bone, new List<SerializableBone.BoneTags>()).SetColor(Color.gray).SetName(bone.name); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public override void DoStuff() | ||||
|     { | ||||
|         foreach (Renderer r in GetComponentsInChildren<Renderer>()) | ||||
|         { | ||||
|             Material[] overrideMaterials = new Material[r.materials.Length]; | ||||
|             for (int i = 0; i < r.materials.Length; i++) | ||||
|             { | ||||
|                 overrideMaterials[i] = new Material(Shader.Find("PRD/FriendsShaderV2")); | ||||
|                 if (ModelId >= 40400) | ||||
|                 { | ||||
|                     overrideMaterials[i].SetTexture("_BaseMap", r.materials[i].GetTexture("_BaseMap")); | ||||
|                     overrideMaterials[i].SetTexture("_1st_ShadeMap", r.materials[i].GetTexture("_1st_ShadeMap")); | ||||
|                 } | ||||
|                 else if (ModelId >= 40000) | ||||
|                 { | ||||
|                     overrideMaterials[i].SetTexture("_BaseMap", r.materials[i].mainTexture); | ||||
|                     overrideMaterials[i].SetTexture("_1st_ShadeMap", r.materials[i].mainTexture); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     overrideMaterials[i].SetTexture("_BaseMap", r.materials[i].GetTexture("_BaseMap") as Texture2D); | ||||
|                     overrideMaterials[i].SetTexture("_1st_ShadeMap", r.materials[i].GetTexture("_BaseMap") as Texture2D); | ||||
|                 } | ||||
|             } | ||||
|             r.materials = overrideMaterials; | ||||
|             Renderers.Add(r); | ||||
|         } | ||||
|  | ||||
|         var charaPanel = CharacterPanel = UIKF3CharacterPanel.Create(this); | ||||
|         InstantiatedObjects.Add(charaPanel.gameObject); | ||||
|     } | ||||
|  | ||||
|     public override void PastePose(KeyframeData frame, PoseLoadOptions pasteParams) | ||||
|     { | ||||
|         var bones = frame as CharacterKeyframeData; | ||||
|  | ||||
|         this.PlayBodyAnimation(""); | ||||
|         if (pasteParams.Root) | ||||
|         { | ||||
|             bones.Root.ApplyTo(transform); | ||||
|         } | ||||
|         if (pasteParams.Body) | ||||
|         { | ||||
|             foreach (var bone in this.Body.boneList) | ||||
|             { | ||||
|                 if (pasteParams.Other || bone.GetComponent<Osage>() == null) | ||||
|                     bones.Bones.FirstOrDefault(b => b.Name == "Body").Bones.FirstOrDefault(b => b.Name == bone.name)?.Transform.ApplyTo(bone, pasteParams); | ||||
|             } | ||||
|         } | ||||
|         if (bones.Renderers != null) | ||||
|         { | ||||
|             foreach (var renderer in bones.Renderers) | ||||
|             { | ||||
|                 var rend = this.Renderers.FirstOrDefault(r => KF3CharacterContainerSerializable.GetRendererName(this, r) == renderer.Name); | ||||
|                 if (rend != null) | ||||
|                 { | ||||
|                     rend.enabled = renderer.Value; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public override IEnumerator GetModel(string bodyIdLong, string costumeId) | ||||
|     { | ||||
|         KF3AssetLibrary lib = Main.Assets; | ||||
|         List<KF3AssetBundle> abList = lib.AssetBundles.Where(ab => ab.FileName.StartsWith($"ch_{bodyIdLong}_")).ToList(); | ||||
|         KF3AssetBundle bundle; | ||||
|  | ||||
|         //load body | ||||
|         bundle = abList.FirstOrDefault(ab => ab.FileName == $"ch_{bodyIdLong}_{costumeId}.prefab"); | ||||
|         yield return lib.LoadAsset(bundle, (ab) => | ||||
|         { | ||||
|             Body = spawnAndGetReferencer(ab); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public override IEnumerator GetAnimations(string idLong) | ||||
|     { | ||||
|         KF3AssetLibrary lib = Main.Assets; | ||||
|         KF3AssetBundle bundle; | ||||
|         List<KF3AssetBundle> abList = lib.AssetBundles.Where(ab => ab.FileName.StartsWith($"ch_{idLong}_")).ToList(); | ||||
|  | ||||
|         bundle = lib.CeruleanAnimationSets.FirstOrDefault(ab => ab.FileName == $"ch_{idLong}_a_mot.prefab"); | ||||
|         yield return lib.LoadAsset(bundle, (ab) => | ||||
|         { | ||||
|             BodyAnimation = spawnAndGetReferencer(ab); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public override void Select() | ||||
|     { | ||||
|         CharacterPanel.gameObject.SetActive(true); | ||||
|     } | ||||
|  | ||||
|     public override void Deselect() | ||||
|     { | ||||
|         CharacterPanel.gameObject.SetActive(false); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										11
									
								
								Assets/KF3/Scripts/Containers/KF3CeruleanContainer.cs.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/KF3/Scripts/Containers/KF3CeruleanContainer.cs.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: c1670e1c9f79d8340a9c745453d0f118 | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
							
								
								
									
										265
									
								
								Assets/KF3/Scripts/Containers/KF3CharacterContainer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										265
									
								
								Assets/KF3/Scripts/Containers/KF3CharacterContainer.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,265 @@ | ||||
| using KF3.Containers; | ||||
| using System.Collections; | ||||
| using System.Linq; | ||||
| using UnityEngine; | ||||
|  | ||||
| public class KF3CharacterContainer : KF3ObjectContainer | ||||
| { | ||||
|     protected override System.Type _serializeType => typeof(KF3CharacterContainerSerializable); | ||||
|     protected override System.Type _keyframeType => typeof(CharacterKeyframeData); | ||||
|  | ||||
|  | ||||
|     public bool | ||||
|         BonesVisible = true, | ||||
|         PhysicsEnabled = true, | ||||
|         IKEnabled = true; | ||||
|     public string | ||||
|         CostumeName, | ||||
|         AnimationName; | ||||
|     public CharaModelReferencer | ||||
|         Body, | ||||
|         BodyAnimation; | ||||
|     public SimpleAnimation | ||||
|         BodySimpleAnimation; | ||||
|  | ||||
|     public float AnimationSpeed = 0; | ||||
|     public string CurrentAnimation = ""; | ||||
|  | ||||
|     protected IEnumerator BuildGeneral(string modelName, string animSetName) | ||||
|     { | ||||
|         enabled = false; | ||||
|         string mIdLong = modelName.Split('_', '.')[1]; | ||||
|         string mCostume = modelName.Split('_', '.')[2]; | ||||
|         string aIdLong = animSetName.Split('_', '.')[1]; | ||||
|  | ||||
|         if (LoadInProgress) yield break; | ||||
|         LoadInProgress = true; | ||||
|         ModelId = int.Parse(mIdLong); | ||||
|         CostumeName = modelName; | ||||
|         AnimationName = animSetName; | ||||
|  | ||||
|         using(new KeyframeToggleContext(this)) | ||||
|         { | ||||
|             yield return GetModel(mIdLong, mCostume); | ||||
|             yield return GetAnimations(aIdLong); | ||||
|             SetAnimationReferences(); | ||||
|             SetBones(); | ||||
|             DoStuff(); | ||||
|         } | ||||
|         SetKeyframe(); | ||||
|         enabled = true; | ||||
|     } | ||||
|  | ||||
|     public virtual void SetAnimationReferences() {} | ||||
|  | ||||
|     public virtual void SetBones() {} | ||||
|  | ||||
|     public virtual void DoStuff() {} | ||||
|  | ||||
|     public virtual void ToggleBonesVisible(bool value) | ||||
|     { | ||||
|         BonesVisible = value; | ||||
|         foreach (var handle in Handles.Where(h => h as UIHandleBone != null)) | ||||
|         { | ||||
|             handle.ToggleActive(value); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void TogglePhysics() | ||||
|     { | ||||
|         TogglePhysics(!PhysicsEnabled); | ||||
|     } | ||||
|  | ||||
|     public void TogglePhysics(bool value = true) | ||||
|     { | ||||
|         PhysicsEnabled = value; | ||||
|         foreach (var handle in Handles.Where(h => h.GetType() == typeof(UIHandlePhysicsBone))) | ||||
|         { | ||||
|             handle.Target.GetComponent<Osage>().enabled = value; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void ResetBones() | ||||
|     { | ||||
|         foreach (var bone in Handles) | ||||
|         { | ||||
|             bone.TransformResetAll(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public string GetAnimationName() | ||||
|     { | ||||
|         if (BodySimpleAnimation.clip != null) | ||||
|         { | ||||
|             return BodySimpleAnimation.GetStates().FirstOrDefault(st => st.clip.name == BodySimpleAnimation.clip.name).name; | ||||
|         } | ||||
|         else return ""; | ||||
|     } | ||||
|  | ||||
|     public void PlayBodyAnimation(string clipName) | ||||
|     { | ||||
|         PlayAnimation(BodySimpleAnimation, clipName); | ||||
|     } | ||||
|  | ||||
|     public void PlayAnimation(SimpleAnimation anim, string clipName, float time = -1) | ||||
|     { | ||||
|         if (anim == null) return; | ||||
|         else if (string.IsNullOrEmpty(clipName)) | ||||
|         { | ||||
|             anim.Stop(); | ||||
|             anim.clip = null; | ||||
|             anim.enabled = false; | ||||
|             return; | ||||
|         } | ||||
|         anim.enabled = true; | ||||
|         anim.clip = anim.GetState(clipName).clip; | ||||
|         anim.Play(anim.GetStates().FirstOrDefault(state => state.clip == anim.clip).name); | ||||
|         anim.GetStates().FirstOrDefault(state => state.clip == anim.clip).speed = AnimationSpeed; | ||||
|         if(time != -1) | ||||
|         { | ||||
|             anim.GetStates().FirstOrDefault(state => state.clip == anim.clip).time = time; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void RewindAllAnimations() | ||||
|     { | ||||
|         if (BodySimpleAnimation && BodySimpleAnimation.clip != null) | ||||
|         { | ||||
|             BodySimpleAnimation.Rewind(); | ||||
|         } | ||||
|         if (this as KF3FriendContainer != null) | ||||
|         { | ||||
|             var EarsSimpleAnimation = ((KF3FriendContainer)this).EarsSimpleAnimation; | ||||
|             var TailSimpleAnimation = ((KF3FriendContainer)this).EarsSimpleAnimation; | ||||
|             if (EarsSimpleAnimation && EarsSimpleAnimation.clip != null) | ||||
|             { | ||||
|                 EarsSimpleAnimation.Rewind(); | ||||
|             } | ||||
|             if (TailSimpleAnimation && TailSimpleAnimation.clip != null) | ||||
|             { | ||||
|                 TailSimpleAnimation.Rewind(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void UnwindAllAnimations() | ||||
|     { | ||||
|         if (BodySimpleAnimation && BodySimpleAnimation.clip != null) | ||||
|         { | ||||
|             BodySimpleAnimation.Unwind(); | ||||
|         } | ||||
|         if (this as KF3FriendContainer != null) | ||||
|         { | ||||
|             var EarsSimpleAnimation = ((KF3FriendContainer)this).EarsSimpleAnimation; | ||||
|             var TailSimpleAnimation = ((KF3FriendContainer)this).EarsSimpleAnimation; | ||||
|             if (EarsSimpleAnimation && EarsSimpleAnimation.clip != null) | ||||
|             { | ||||
|                 EarsSimpleAnimation.Unwind(); | ||||
|             } | ||||
|             if (TailSimpleAnimation && TailSimpleAnimation.clip != null) | ||||
|             { | ||||
|                 TailSimpleAnimation.Unwind(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void SetAnimationTimeScale(float timeScale) | ||||
|     { | ||||
|         if (BodySimpleAnimation && BodySimpleAnimation.clip != null) | ||||
|         { | ||||
|             SimpleAnimation.State currentClip = BodySimpleAnimation.GetStates().FirstOrDefault(state => state.clip == BodySimpleAnimation.clip); | ||||
|             currentClip.speed = timeScale; | ||||
|         } | ||||
|         if (this as KF3FriendContainer != null) | ||||
|         { | ||||
|             var EarsSimpleAnimation = ((KF3FriendContainer)this).EarsSimpleAnimation; | ||||
|             var TailSimpleAnimation = ((KF3FriendContainer)this).EarsSimpleAnimation; | ||||
|             if (EarsSimpleAnimation && EarsSimpleAnimation.clip != null) | ||||
|             { | ||||
|                 SimpleAnimation.State currentClip = EarsSimpleAnimation.GetStates().FirstOrDefault(state => state.clip == EarsSimpleAnimation.clip); | ||||
|                 currentClip.speed = timeScale; | ||||
|             } | ||||
|             if (TailSimpleAnimation && TailSimpleAnimation.clip != null) | ||||
|             { | ||||
|                 SimpleAnimation.State currentClip = TailSimpleAnimation.GetStates().FirstOrDefault(state => state.clip == TailSimpleAnimation.clip); | ||||
|                 currentClip.speed = timeScale; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void ChangeAnimationTimeScale(int time) | ||||
|     { | ||||
|         if (BodySimpleAnimation && BodySimpleAnimation.clip != null) | ||||
|         { | ||||
|             SimpleAnimation.State currentClip = BodySimpleAnimation.GetStates().FirstOrDefault(state => state.clip == BodySimpleAnimation.clip); | ||||
|             currentClip.speed += 0.2f * time; | ||||
|         } | ||||
|         if (this as KF3FriendContainer != null) | ||||
|         { | ||||
|             var EarsSimpleAnimation = ((KF3FriendContainer)this).EarsSimpleAnimation; | ||||
|             var TailSimpleAnimation = ((KF3FriendContainer)this).EarsSimpleAnimation; | ||||
|             if (EarsSimpleAnimation && EarsSimpleAnimation.clip != null) | ||||
|             { | ||||
|                 SimpleAnimation.State currentClip = EarsSimpleAnimation.GetStates().FirstOrDefault(state => state.clip == EarsSimpleAnimation.clip); | ||||
|                 currentClip.speed += 0.2f * time; | ||||
|             } | ||||
|             if (TailSimpleAnimation && TailSimpleAnimation.clip != null) | ||||
|             { | ||||
|                 SimpleAnimation.State currentClip = TailSimpleAnimation.GetStates().FirstOrDefault(state => state.clip == TailSimpleAnimation.clip); | ||||
|                 currentClip.speed += 0.2f * time; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void ResetAnimationTimeScale() | ||||
|     { | ||||
|         if (BodySimpleAnimation && BodySimpleAnimation.clip != null) | ||||
|         { | ||||
|             SimpleAnimation.State currentClip = BodySimpleAnimation.GetStates().FirstOrDefault(state => state.clip == BodySimpleAnimation.clip); | ||||
|             currentClip.speed = currentClip.speed == 0 ? 1 : 0; | ||||
|         } | ||||
|         if (this as KF3FriendContainer != null) | ||||
|         { | ||||
|             var EarsSimpleAnimation = ((KF3FriendContainer)this).EarsSimpleAnimation; | ||||
|             var TailSimpleAnimation = ((KF3FriendContainer)this).EarsSimpleAnimation; | ||||
|             if (EarsSimpleAnimation && EarsSimpleAnimation.clip != null) | ||||
|             { | ||||
|                 SimpleAnimation.State currentClip = EarsSimpleAnimation.GetStates().FirstOrDefault(state => state.clip == EarsSimpleAnimation.clip); | ||||
|                 currentClip.speed = currentClip.speed == 0 ? 1 : 0; | ||||
|             } | ||||
|             if (TailSimpleAnimation && TailSimpleAnimation.clip != null) | ||||
|             { | ||||
|                 SimpleAnimation.State currentClip = TailSimpleAnimation.GetStates().FirstOrDefault(state => state.clip == TailSimpleAnimation.clip); | ||||
|                 currentClip.speed = currentClip.speed == 0 ? 1 : 0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public override void SetKeyframe(int frameNum = -1) | ||||
|     { | ||||
|         base.SetKeyframe(frameNum); | ||||
|     } | ||||
|  | ||||
|     protected CharaModelReferencer spawnAndGetReferencer(AssetBundle ab) | ||||
|     { | ||||
|         if (ab != null) | ||||
|         { | ||||
|             GameObject go = Instantiate(ab.LoadAsset(ab.GetAllAssetNames()[0]) as GameObject, transform); | ||||
|             ab.Unload(false); | ||||
|             return go.GetComponent<CharaModelReferencer>(); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /// <summary> Find and load all files related to selected model </summary> | ||||
|     public virtual IEnumerator GetModel(string bodyIdLong, string costumeId) | ||||
|     { | ||||
|         yield break; | ||||
|     } | ||||
|  | ||||
|     /// <summary> Find and load all files related to selected animation set </summary> | ||||
|     public virtual IEnumerator GetAnimations(string idLong) | ||||
|     { | ||||
|         yield break; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										11
									
								
								Assets/KF3/Scripts/Containers/KF3CharacterContainer.cs.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/KF3/Scripts/Containers/KF3CharacterContainer.cs.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: c13c0b3d8ec32244794be75bdce3fd14 | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
| @@ -0,0 +1,60 @@ | ||||
|  | ||||
| using System.Collections.Generic; | ||||
| using System.ComponentModel; | ||||
| using System.Linq; | ||||
| using UnityEngine; | ||||
|  | ||||
| [System.Serializable] | ||||
| public class KF3CharacterContainerSerializable : KF3ObjectContainerSerializable | ||||
| { | ||||
|     public bool IsCerulean; | ||||
|     public int ModelId; | ||||
|     public string CostumeName; | ||||
|     public string AnimationName; | ||||
|  | ||||
|     public KF3CharacterContainerSerializable() { } | ||||
|  | ||||
|     public KF3CharacterContainerSerializable(KF3CharacterContainer container) | ||||
|     { | ||||
|         this.GUID = container.GUID; | ||||
|         this.ModelId = container.ModelId; | ||||
|         this.CostumeName = container.CostumeName; | ||||
|         this.AnimationName = container.AnimationName; | ||||
|         this.IsCerulean = container as KF3CeruleanContainer != null; | ||||
|         this.Frames = container.Frames.Select(f => new FrameContent(f)).ToList(); | ||||
|     } | ||||
|  | ||||
|     public KF3CharacterContainerSerializable(KF3CharacterContainerSerializable source) | ||||
|     { | ||||
|         this.ModelId = source.ModelId; | ||||
|         this.CostumeName = source.CostumeName; | ||||
|         this.AnimationName = source.AnimationName; | ||||
|         this.IsCerulean = source.IsCerulean; | ||||
|         this.Filename = source.Filename; | ||||
|         this.GUID = source.GUID; | ||||
|         this.Frames = source.Frames.Select(f => new FrameContent(f)).ToList(); | ||||
|     } | ||||
|  | ||||
|     public static string GetRendererName(KF3ObjectContainer container1, Renderer r) | ||||
|     { | ||||
|         var container = container1 as KF3FriendContainer; | ||||
|         if (container == null) return r.gameObject.name; | ||||
|         else if (r.gameObject.name.ToLower() == "model") | ||||
|         { | ||||
|             if (r.transform.parent == container.Body.transform) | ||||
|                 return "hair"; | ||||
|             else if (container.Ears && r.transform.parent == container.Ears.transform) | ||||
|                 return "ears"; | ||||
|             else if (container.EarsAlt && r.transform.parent == container.EarsAlt.transform) | ||||
|                 return "ears (alt)"; | ||||
|             else if (container.Tail && r.transform.parent == container.Tail.transform) | ||||
|                 return "tail"; | ||||
|             else if (container.TailAlt && r.transform.parent == container.TailAlt.transform) | ||||
|                 return "tail (alt)"; | ||||
|             else | ||||
|                 return r.gameObject.name; | ||||
|         } | ||||
|         else | ||||
|             return r.gameObject.name; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: c2af1ff3ca27f394aaf69496edffa73a | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
							
								
								
									
										746
									
								
								Assets/KF3/Scripts/Containers/KF3FriendContainer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										746
									
								
								Assets/KF3/Scripts/Containers/KF3FriendContainer.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,746 @@ | ||||
| using KF3.Containers; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using UnityEngine; | ||||
| using UnityEngine.UI; | ||||
|  | ||||
| public class KF3FriendContainer : KF3CharacterContainer | ||||
| { | ||||
|     public bool | ||||
|         EyesLocked = false; | ||||
|     public float | ||||
|         LookAtStrength; | ||||
|     public Transform | ||||
|         LeftEye, | ||||
|         RightEye, | ||||
|         SubWeapon, | ||||
|         SubWeaponBone; | ||||
|     public UIHandleEyes | ||||
|         EyeTarget; | ||||
|     public Quaternion | ||||
|         LeftEyeRotation = Quaternion.identity, | ||||
|         RightEyeRotation = Quaternion.identity; | ||||
|     /// <summary> Original data </summary> | ||||
|     public CharaModelReferencer | ||||
|         Ears, | ||||
|         EarsAlt, | ||||
|         Tail, | ||||
|         TailAlt; | ||||
|     public CharaModelReferencer | ||||
|         EarsAnimation, | ||||
|         TailAnimation; | ||||
|     /// <summary> Custom Animator </summary> | ||||
|     public SimpleAnimation | ||||
|         EarsSimpleAnimation, | ||||
|         TailSimpleAnimation; | ||||
|  | ||||
|     public Dictionary<HumanBodyBones, Transform> HumanBones = new Dictionary<HumanBodyBones, Transform>(); | ||||
|     private Dictionary<Transform, UIHandle>     BoneHandles = new Dictionary<Transform, UIHandle>(); | ||||
|     //private Dictionary<Transform, HumanBodyBones> HumanBonesInverse = new Dictionary<Transform, HumanBodyBones>(); | ||||
|  | ||||
|     public UIKF3MorphPanel MorphPanel; | ||||
|     public UIKF3CharacterPanel CharacterPanel; | ||||
|  | ||||
|     private bool isFakeFriend = false; | ||||
|  | ||||
|     public static IEnumerator CreateAsync(string modelName, string animationSetName, bool fakeFriend = false, System.Action<KF3FriendContainer> callback = null) | ||||
|     { | ||||
|         GameObject go = new GameObject(modelName); | ||||
|         var container = go.AddComponent<KF3FriendContainer>(); | ||||
|         if (fakeFriend) container.DoNotSave = container.isFakeFriend = true; | ||||
|  | ||||
|         yield return container.BuildGeneral(modelName, animationSetName); | ||||
|         if (!container.isFakeFriend) UIHandleFriend.CreateAsChild(container); | ||||
|         container.LoadInProgress = false; | ||||
|         callback?.Invoke(container); | ||||
|     } | ||||
|  | ||||
|     protected override void Start() | ||||
|     { | ||||
|         if (isFakeFriend) return; | ||||
|  | ||||
|         LeftEyeRotation = LeftEye.localRotation; | ||||
|         RightEyeRotation = RightEye.localRotation; | ||||
|  | ||||
|         base.Start(); | ||||
|     } | ||||
|  | ||||
|     private void Update() | ||||
|     { | ||||
|         if (LoadInProgress || isFakeFriend) return; | ||||
|         if (BodySimpleAnimation && BodySimpleAnimation.clip != null) //check if simple animation component has been set | ||||
|         { | ||||
|             SimpleAnimation.State currentClip = BodySimpleAnimation.GetStates().FirstOrDefault(state => state.clip == BodySimpleAnimation.clip); | ||||
|             if (currentClip.normalizedTime == 1 && currentClip.speed > 0) //check if an animation is playing and if an animation was playing before | ||||
|             { | ||||
|                 RewindAllAnimations(); | ||||
|             } | ||||
|             else if (currentClip.normalizedTime <= 0 && currentClip.speed < 0) //check if an animation is playing and if an animation was playing before | ||||
|             { | ||||
|                 UnwindAllAnimations(); | ||||
|             } | ||||
|         } | ||||
|         if ((LeftEye && RightEye && EyeTarget) && !EyesLocked) | ||||
|         { | ||||
|             Vector3 target = Vector3.Lerp(EyeTarget.transform.position, KF3ModelViewerMain.Instance.GetCamera().transform.position, LookAtStrength); | ||||
|             LeftEye.LookAt(target, HumanBones[HumanBodyBones.Head].up); | ||||
|  | ||||
|             RightEye.LookAt(target, HumanBones[HumanBodyBones.Head].up); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #region Setup | ||||
|     public override void SetAnimationReferences() | ||||
|     { | ||||
|         if (BodyAnimation) | ||||
|         { | ||||
|             BodySimpleAnimation = Body.GetComponentInChildren<SimpleAnimation>(); | ||||
|             if (Main.OverrideClip != null) | ||||
|             { | ||||
|                 foreach (var anim in BodyAnimation.prefabAnimeList) | ||||
|                 { | ||||
|                     anim.clip = Main.OverrideClip; | ||||
|                 } | ||||
|             } | ||||
|             Body.refAnimationObj = BodyAnimation.gameObject; | ||||
|             Body.JoinReferenceParam(); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             Error.Log(Color.blue, "Body Animations Missing"); | ||||
|         } | ||||
|  | ||||
|         if (Ears && EarsAnimation) | ||||
|         { | ||||
|             EarsSimpleAnimation = Ears.GetComponentInChildren<SimpleAnimation>(); | ||||
|  | ||||
|             Ears.transform.SetParent(Body.boneList.FirstOrDefault(b => b.name == "j_head")); | ||||
|             Ears.transform.ResetTransform(); | ||||
|  | ||||
|             Ears.refAnimationObj = EarsAnimation.gameObject; | ||||
|             Ears.JoinReferenceParam(); | ||||
|  | ||||
|             if (EarsAlt) | ||||
|             { | ||||
|                 EarsAlt.transform.SetParent(Body.boneList.FirstOrDefault(b => b.name == "j_head")); | ||||
|                 EarsAlt.transform.ResetTransform(); | ||||
|                 EarsAlt.GetComponentInChildren<Renderer>().enabled = false; | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             Error.Log(Color.blue, "Ears Missing"); | ||||
|         } | ||||
|  | ||||
|         if (Tail && TailAnimation) | ||||
|         { | ||||
|             TailSimpleAnimation = Tail.GetComponentInChildren<SimpleAnimation>(); | ||||
|  | ||||
|             Tail.transform.SetParent(Body.boneList.FirstOrDefault(b => b.name == (string.IsNullOrEmpty(BodyAnimation.tailNodeName) ? "j_lowerbody" : BodyAnimation.tailNodeName))); | ||||
|             Tail.transform.ResetTransform(); | ||||
|  | ||||
|             Tail.refAnimationObj = TailAnimation.gameObject; | ||||
|             Tail.JoinReferenceParam(); | ||||
|  | ||||
|             if (TailAlt) | ||||
|             { | ||||
|                 TailAlt.transform.SetParent(Body.boneList.FirstOrDefault(b => b.name == (string.IsNullOrEmpty(BodyAnimation.tailNodeName) ? "j_lowerbody" : BodyAnimation.tailNodeName))); | ||||
|                 TailAlt.transform.ResetTransform(); | ||||
|                 TailAlt.GetComponentInChildren<Renderer>().enabled = false; | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             Error.Log(Color.blue, "Tail Missing"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public override void SetBones() | ||||
|     { | ||||
|         if (isFakeFriend) return; | ||||
|  | ||||
|         HumanBones = new Dictionary<HumanBodyBones, Transform>(); | ||||
|         var extraBones = Body.boneList.Where(b => b.name.Contains("osg")); | ||||
|         HumanBones.Add(HumanBodyBones.Spine,            Body.transform.Find("root/pelvis")); | ||||
|         HumanBones.Add(HumanBodyBones.Hips,             Body.transform.Find("root/pelvis/j_lowerbody")); | ||||
|         HumanBones.Add(HumanBodyBones.RightUpperLeg,    Body.transform.Find("root/pelvis/j_lowerbody/j_thigh_r")); | ||||
|         HumanBones.Add(HumanBodyBones.RightLowerLeg,    Body.transform.Find("root/pelvis/j_lowerbody/j_thigh_r/j_leg_r")); | ||||
|         HumanBones.Add(HumanBodyBones.RightFoot,        Body.transform.Find("root/pelvis/j_lowerbody/j_thigh_r/j_leg_r/j_foot_r")); | ||||
|         HumanBones.Add(HumanBodyBones.LeftUpperLeg,     Body.transform.Find("root/pelvis/j_lowerbody/j_thigh_l")); | ||||
|         HumanBones.Add(HumanBodyBones.LeftLowerLeg,     Body.transform.Find("root/pelvis/j_lowerbody/j_thigh_l/j_leg_l")); | ||||
|         HumanBones.Add(HumanBodyBones.LeftFoot,         Body.transform.Find("root/pelvis/j_lowerbody/j_thigh_l/j_leg_l/j_foot_l")); | ||||
|         HumanBones.Add(HumanBodyBones.Chest,            Body.transform.Find("root/pelvis/j_upperbody")); | ||||
|         HumanBones.Add(HumanBodyBones.UpperChest,       Body.transform.Find("root/pelvis/j_upperbody/j_chest")); | ||||
|         HumanBones.Add(HumanBodyBones.Neck,             Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_neck")); | ||||
|         HumanBones.Add(HumanBodyBones.Head,             Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_neck/j_head")); | ||||
|         HumanBones.Add(HumanBodyBones.RightShoulder,            Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_r")); | ||||
|         HumanBones.Add(HumanBodyBones.RightUpperArm,            Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_r/j_arm_r")); | ||||
|         HumanBones.Add(HumanBodyBones.RightLowerArm,            Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_r/j_arm_r/j_forearm_r")); | ||||
|         HumanBones.Add(HumanBodyBones.RightHand,                Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_r/j_arm_r/j_forearm_r/j_wrist_r")); | ||||
|         HumanBones.Add(HumanBodyBones.RightIndexProximal,       Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_r/j_arm_r/j_forearm_r/j_wrist_r/j_index_a_r")); | ||||
|         HumanBones.Add(HumanBodyBones.RightIndexIntermediate,   Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_r/j_arm_r/j_forearm_r/j_wrist_r/j_index_a_r/j_index_b_r")); | ||||
|         HumanBones.Add(HumanBodyBones.RightRingProximal,        Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_r/j_arm_r/j_forearm_r/j_wrist_r/j_ring_a_r")); | ||||
|         HumanBones.Add(HumanBodyBones.RightRingIntermediate,    Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_r/j_arm_r/j_forearm_r/j_wrist_r/j_ring_a_r/j_ring_b_r")); | ||||
|         HumanBones.Add(HumanBodyBones.RightThumbProximal,       Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_r/j_arm_r/j_forearm_r/j_wrist_r/j_thumb_a_r")); | ||||
|         HumanBones.Add(HumanBodyBones.RightThumbIntermediate,   Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_r/j_arm_r/j_forearm_r/j_wrist_r/j_thumb_a_r/j_thumb_b_r")); | ||||
|         HumanBones.Add(HumanBodyBones.LeftShoulder,             Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_l")); | ||||
|         HumanBones.Add(HumanBodyBones.LeftUpperArm,             Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_l/j_arm_l")); | ||||
|         HumanBones.Add(HumanBodyBones.LeftLowerArm,             Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_l/j_arm_l/j_forearm_l")); | ||||
|         HumanBones.Add(HumanBodyBones.LeftHand,                 Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_l/j_arm_l/j_forearm_l/j_wrist_l")); | ||||
|         HumanBones.Add(HumanBodyBones.LeftIndexProximal,        Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_l/j_arm_l/j_forearm_l/j_wrist_l/j_index_a_l")); | ||||
|         HumanBones.Add(HumanBodyBones.LeftIndexIntermediate,    Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_l/j_arm_l/j_forearm_l/j_wrist_l/j_index_a_l/j_index_b_l")); | ||||
|         HumanBones.Add(HumanBodyBones.LeftRingProximal,         Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_l/j_arm_l/j_forearm_l/j_wrist_l/j_ring_a_l")); | ||||
|         HumanBones.Add(HumanBodyBones.LeftRingIntermediate,     Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_l/j_arm_l/j_forearm_l/j_wrist_l/j_ring_a_l/j_ring_b_l")); | ||||
|         HumanBones.Add(HumanBodyBones.LeftThumbProximal,        Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_l/j_arm_l/j_forearm_l/j_wrist_l/j_thumb_a_l")); | ||||
|         HumanBones.Add(HumanBodyBones.LeftThumbIntermediate,    Body.transform.Find("root/pelvis/j_upperbody/j_chest/j_shoulder_l/j_arm_l/j_forearm_l/j_wrist_l/j_thumb_a_l/j_thumb_b_l")); | ||||
|         //HumanBonesInverse = HumanBones.Where(d=>d.Value != null).ToDictionary((i) => i.Value, (i) => i.Key); | ||||
|  | ||||
|         if (Tail) | ||||
|         { | ||||
|             extraBones = extraBones.Union(Tail.boneList.Where(b => b.name.Contains("osg"))); | ||||
|         } | ||||
|         if (TailAlt) | ||||
|         { | ||||
|             extraBones = extraBones.Union(TailAlt.boneList.Where(b => b.name.Contains("osg"))); | ||||
|         } | ||||
|         if (Ears) | ||||
|         { | ||||
|             extraBones = extraBones.Union(Ears.boneList.Where(b => b.name.Contains("osg"))); | ||||
|         } | ||||
|         if (EarsAlt) | ||||
|         { | ||||
|             extraBones = extraBones.Union(EarsAlt.boneList.Where(b => b.name.Contains("osg"))); | ||||
|         } | ||||
|  | ||||
|         var allBones = HumanBones.Where(b => b.Value != null).Select(b => b.Value).Union(Body.transform.Find("root")?.GetComponentsInChildren<Transform>().Where(t => t.name.Contains("weapon")).ToList()).Union(extraBones).Distinct(); | ||||
|  | ||||
|         foreach (var bone in allBones) | ||||
|         { | ||||
|             var tags = new List<SerializableBone.BoneTags>(); | ||||
|             UIHandle handle; | ||||
|  | ||||
|             if (HumanBones.ContainsValue(bone)) | ||||
|                 tags.Add(SerializableBone.BoneTags.Humanoid); | ||||
|             if (bone.name.EndsWith("_l")) | ||||
|                 tags.Add(SerializableBone.BoneTags.Left); | ||||
|             else if (bone.name.EndsWith("_r")) | ||||
|                 tags.Add(SerializableBone.BoneTags.Right); | ||||
|  | ||||
|             if (extraBones.Contains(bone)) | ||||
|             { | ||||
|                 if (bone.GetComponent<Osage>() != null) | ||||
|                 { | ||||
|                     tags.Add(SerializableBone.BoneTags.Dynamic); | ||||
|                     handle = UIHandlePhysicsBone.CreateAsChild(this, bone, tags).SetColor(Color.cyan); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     handle = UIHandleBone.CreateAsChild(this, bone, tags).SetColor(Color.cyan); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 handle = UIHandleBone.CreateAsChild(this, bone, tags); | ||||
|             } | ||||
|  | ||||
|             if (bone == HumanBones[HumanBodyBones.Hips]) | ||||
|                 handle.SetOffset(bone.up * -0.02f); | ||||
|             if (bone == HumanBones[HumanBodyBones.Chest]) | ||||
|                 handle.SetOffset(bone.up * -0.02f); | ||||
|  | ||||
|             BoneHandles.Add(bone, handle); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public override void DoStuff() | ||||
|     { | ||||
|         if (isFakeFriend) return; | ||||
|  | ||||
|         UIKF3MorphSlider eyeBase = null; | ||||
|  | ||||
|         foreach (Renderer r in GetComponentsInChildren<Renderer>()) | ||||
|         { | ||||
|             foreach (Material mat in r.materials) | ||||
|             { | ||||
| #if UNITY_ANDROID | ||||
|                     if(!mat.shader.name.EndsWith("V2")) | ||||
|                         mat.shader = Shader.Find(mat.shader.name + "V2"); | ||||
| #endif | ||||
|                 if (mat.shader.name == "PRD/Cheek") | ||||
|                 { | ||||
|                     Texture2D tex = mat.GetTexture("_BaseMap") as Texture2D; | ||||
|                     mat.shader = Shader.Find("Unlit/Transparent"); | ||||
|                     mat.mainTexture = tex; | ||||
|                 } | ||||
|             } | ||||
|             Renderers.Add(r); | ||||
|         } | ||||
|  | ||||
|         var morphPanel = MorphPanel = UIKF3MorphPanel.Create(this); | ||||
|         var charaPanel = CharacterPanel = UIKF3CharacterPanel.Create(this); | ||||
|         InstantiatedObjects.Add(morphPanel.gameObject); | ||||
|         InstantiatedObjects.Add(charaPanel.gameObject); | ||||
|  | ||||
|         foreach (Transform child in GetComponentsInChildren<Transform>()) | ||||
|         { | ||||
|             switch (child.name) | ||||
|             { | ||||
|                 case "md_eye_base": | ||||
|                     { | ||||
|                         UIKF3MorphSlider.CreateLookAt(this, morphPanel.EyesPanel); | ||||
|  | ||||
|                         SkinnedMeshRenderer meshRenderer = child.GetComponent<SkinnedMeshRenderer>(); | ||||
|                         if (meshRenderer == null || meshRenderer.sharedMesh == null) break; | ||||
|                         for (int i = 0; i < meshRenderer.sharedMesh.blendShapeCount; i++) | ||||
|                         { | ||||
|                             UIKF3MorphSlider.CreateMorph(this, meshRenderer, i, "BS_eye.eye_", morphPanel.EyesPanel); | ||||
|                         } | ||||
|  | ||||
|                         if (HumanBones.ContainsKey(HumanBodyBones.Head) && HumanBones[HumanBodyBones.Head] != null && !EyeTarget) | ||||
|                         { | ||||
|                             Transform head = HumanBones[HumanBodyBones.Head]; | ||||
|                             EyeTarget = UIHandleEyes.Create(this, head); | ||||
|                         } | ||||
|                         eyeBase = UIKF3MorphSlider.CreateEyeToggle(this, meshRenderer, morphPanel.EyesPanel, MorphPanel.EyesToggleGroup); | ||||
|                         break; | ||||
|                     } | ||||
|                 case "md_eye_special_a": | ||||
|                 case "md_eye_special_b": | ||||
|                     { | ||||
|                         SkinnedMeshRenderer meshRenderer = child.GetComponent<SkinnedMeshRenderer>(); | ||||
|                         var toggle = UIKF3MorphSlider.CreateEyeToggle(this, meshRenderer, morphPanel.EyesPanel, MorphPanel.EyesToggleGroup); | ||||
|                         break; | ||||
|                     } | ||||
|                 case "md_mouth_base": | ||||
|                     { | ||||
|                         SkinnedMeshRenderer meshRenderer = child.GetComponent<SkinnedMeshRenderer>(); | ||||
|                         if (meshRenderer == null || meshRenderer.sharedMesh == null) break; | ||||
|                         for (int i = 0; i < meshRenderer.sharedMesh.blendShapeCount; i++) | ||||
|                         { | ||||
|                             UIKF3MorphSlider.CreateMorph(this, meshRenderer, i, "BS_mouth.mouth_", morphPanel.MouthPanel); | ||||
|                         } | ||||
|                         break; | ||||
|                     } | ||||
|                 case "md_eye_l": LeftEye = child; break; | ||||
|                 case "md_eye_r": RightEye = child; break; | ||||
|                 case "md_brow_base": | ||||
|                     { | ||||
|                         SkinnedMeshRenderer meshRenderer = child.GetComponent<SkinnedMeshRenderer>(); | ||||
|                         if (meshRenderer == null || meshRenderer.sharedMesh == null) break; | ||||
|  | ||||
|                         for (int i = 0; i < meshRenderer.sharedMesh.blendShapeCount; i++) | ||||
|                         { | ||||
|                             UIKF3MorphSlider.CreateMorph(this, meshRenderer, i, "BS_brow.brow_", morphPanel.EyebrowsPanel); | ||||
|                         } | ||||
|                         break; | ||||
|                     } | ||||
|                 case "md_subweapon": | ||||
|                     { | ||||
|                         SubWeapon = child; | ||||
|                         if (SubWeaponBone == null) break; | ||||
|                         SubWeapon.SetParent(SubWeaponBone); | ||||
|                         SubWeapon.SetPositionAndRotation(Vector3.zero, Quaternion.identity); | ||||
|                         break; | ||||
|                     } | ||||
|                 case "subweapon": | ||||
|                     { | ||||
|                         SubWeaponBone = child; | ||||
|                         if (SubWeapon == null) break; | ||||
|                         SubWeapon.SetParent(SubWeaponBone); | ||||
|                         SubWeapon.SetPositionAndRotation(Vector3.zero, Quaternion.identity); | ||||
|                         break; | ||||
|                     } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if(eyeBase != null) | ||||
|         { | ||||
|             eyeBase.Toggle.isOn = true; | ||||
|         } | ||||
|  | ||||
|         SetIK(HumanBodyBones.LeftUpperArm); | ||||
|         SetIK(HumanBodyBones.RightUpperArm); | ||||
|         SetIK(HumanBodyBones.LeftUpperLeg); | ||||
|         SetIK(HumanBodyBones.RightUpperLeg); | ||||
|         ToggleIK(true); | ||||
|     } | ||||
|  | ||||
|     public void SetIK(HumanBodyBones bone) | ||||
|     { | ||||
|         var cTr = transform; | ||||
|         UIHandleIK ikHandle = null; | ||||
|         Color orange = new Color(1.0f, 0.64f, 0.0f); | ||||
|         switch (bone) | ||||
|         { | ||||
|             case HumanBodyBones.LeftUpperArm: | ||||
|                 { | ||||
|                     if (HumanBones[HumanBodyBones.LeftHand] == null) return; | ||||
|                     InverseKinematics IK = gameObject.AddComponent<InverseKinematics>(); | ||||
|                     IK.upperArm = HumanBones[HumanBodyBones.LeftUpperArm]; | ||||
|                     IK.forearm = HumanBones[HumanBodyBones.LeftLowerArm]; | ||||
|                     IK.hand = HumanBones[HumanBodyBones.LeftHand]; | ||||
|  | ||||
|                     IK.elbow = UIHandleIK.CreateTransform("Elbow_L", transform, IK.forearm.position + -cTr.forward * 0.1f); | ||||
|                     UIHandleIK.CreateAsChild(this, IK.elbow, orange, IK.name, 0.75f); | ||||
|  | ||||
|                     IK.target = UIHandleIK.CreateTransform("Hand_L", transform, IK.hand.position, IK.hand.eulerAngles); | ||||
|                     ikHandle = UIHandleIK.CreateAsChild(this, IK.target, Color.green, IK.name, 2f); | ||||
|                     ikHandle.HiddenHandles = new List<UIHandle> { | ||||
|                         BoneHandles[IK.upperArm], | ||||
|                         BoneHandles[IK.forearm], | ||||
|                         BoneHandles[IK.hand], | ||||
|                     }; | ||||
|  | ||||
|                     IK.uppperArm_OffsetRotation = new Vector3(0, 90, 0); | ||||
|                     IK.forearm_OffsetRotation = new Vector3(-90, 90, 0); | ||||
|                     IK.SpawnLines(Color.green); | ||||
|                     break; | ||||
|                 } | ||||
|             case HumanBodyBones.RightUpperArm: | ||||
|                 { | ||||
|                     if (HumanBones[HumanBodyBones.RightHand] == null) return; | ||||
|                     InverseKinematics IK = gameObject.AddComponent<InverseKinematics>(); | ||||
|                     IK.upperArm = HumanBones[HumanBodyBones.RightUpperArm]; | ||||
|                     IK.forearm = HumanBones[HumanBodyBones.RightLowerArm]; | ||||
|                     IK.hand = HumanBones[HumanBodyBones.RightHand]; | ||||
|  | ||||
|                     IK.elbow = UIHandleIK.CreateTransform("Elbow_R", transform, IK.forearm.position + -cTr.forward * 0.1f); | ||||
|                     UIHandleIK.CreateAsChild(this, IK.elbow, orange, IK.name, 0.75f); | ||||
|  | ||||
|                     IK.target = UIHandleIK.CreateTransform("Hand_R", transform, IK.hand.position, IK.hand.eulerAngles); | ||||
|                     ikHandle = UIHandleIK.CreateAsChild(this, IK.target, Color.blue, IK.name, 2f); | ||||
|                     ikHandle.HiddenHandles = new List<UIHandle> { | ||||
|                         BoneHandles[IK.upperArm], | ||||
|                         BoneHandles[IK.forearm], | ||||
|                         BoneHandles[IK.hand], | ||||
|                     }; | ||||
|  | ||||
|                     IK.uppperArm_OffsetRotation = new Vector3(0, 90, 0); | ||||
|                     IK.forearm_OffsetRotation = new Vector3(-90, 90, 0); | ||||
|                     IK.SpawnLines(Color.blue); | ||||
|                     break; | ||||
|                 } | ||||
|             case HumanBodyBones.LeftUpperLeg: | ||||
|                 { | ||||
|                     if (HumanBones[HumanBodyBones.LeftFoot] == null) return; | ||||
|                     InverseKinematics IK = gameObject.AddComponent<InverseKinematics>(); | ||||
|                     IK.upperArm = HumanBones[HumanBodyBones.LeftUpperLeg]; | ||||
|                     IK.forearm = HumanBones[HumanBodyBones.LeftLowerLeg]; | ||||
|                     IK.hand = HumanBones[HumanBodyBones.LeftFoot]; | ||||
|  | ||||
|                     IK.elbow = UIHandleIK.CreateTransform("Knee_L", transform, IK.forearm.position + cTr.forward * 0.2f); | ||||
|                     UIHandleIK.CreateAsChild(this, IK.elbow, orange, IK.name, 0.75f); | ||||
|  | ||||
|                     IK.target = UIHandleIK.CreateTransform("Foot_L", transform, IK.hand.position, IK.hand.eulerAngles + cTr.forward * 45); | ||||
|                     ikHandle = UIHandleIK.CreateAsChild(this, IK.target, Color.green, IK.name, 2f); | ||||
|                     ikHandle.HiddenHandles = new List<UIHandle> { | ||||
|                         BoneHandles[IK.upperArm], | ||||
|                         BoneHandles[IK.forearm], | ||||
|                         BoneHandles[IK.hand], | ||||
|                     }; | ||||
|  | ||||
|                     IK.uppperArm_OffsetRotation = new Vector3(0, 90, 0); | ||||
|                     IK.forearm_OffsetRotation = new Vector3(-90, 90, 0); | ||||
|                     IK.hand_OffsetRotation = new Vector3(0, 0, -45); | ||||
|                     IK.SpawnLines(Color.green); | ||||
|                     break; | ||||
|                 } | ||||
|             case HumanBodyBones.RightUpperLeg: | ||||
|                 { | ||||
|                     if (HumanBones[HumanBodyBones.RightFoot] == null) return; | ||||
|                     InverseKinematics IK = gameObject.AddComponent<InverseKinematics>(); | ||||
|                     IK.upperArm = HumanBones[HumanBodyBones.RightUpperLeg]; | ||||
|                     IK.forearm = HumanBones[HumanBodyBones.RightLowerLeg]; | ||||
|                     IK.hand = HumanBones[HumanBodyBones.RightFoot]; | ||||
|  | ||||
|                     IK.elbow = UIHandleIK.CreateTransform("Knee_R", transform, IK.forearm.position + cTr.forward * 0.2f); | ||||
|                     UIHandleIK.CreateAsChild(this, IK.elbow, orange, IK.name, 0.75f); | ||||
|  | ||||
|                     IK.target = UIHandleIK.CreateTransform("Foot_R", transform, IK.hand.position, IK.hand.eulerAngles + cTr.forward * 45); | ||||
|                     ikHandle = UIHandleIK.CreateAsChild(this, IK.target, Color.blue, IK.name, 2f); | ||||
|                     ikHandle.HiddenHandles = new List<UIHandle> { | ||||
|                         BoneHandles[IK.upperArm], | ||||
|                         BoneHandles[IK.forearm], | ||||
|                         BoneHandles[IK.hand], | ||||
|                     }; | ||||
|  | ||||
|                     IK.uppperArm_OffsetRotation = new Vector3(0, 90, 0); | ||||
|                     IK.forearm_OffsetRotation = new Vector3(-90, 90, 0); | ||||
|                     IK.hand_OffsetRotation = new Vector3(0, 0, -45); | ||||
|                     IK.SpawnLines(Color.blue); | ||||
|                     break; | ||||
|                 } | ||||
|         } | ||||
|     } | ||||
|     #endregion | ||||
|  | ||||
|     #region Animation | ||||
|  | ||||
|     public void PlayEarsAnimation(string clipName) | ||||
|     { | ||||
|         PlayAnimation(EarsSimpleAnimation, clipName); | ||||
|     } | ||||
|  | ||||
|     public void PlayTailAnimation(string clipName) | ||||
|     { | ||||
|         PlayAnimation(TailSimpleAnimation, clipName); | ||||
|     } | ||||
|  | ||||
|     #endregion | ||||
|  | ||||
|     #region Control | ||||
|     public void UpdateLookAtTarget(float value) | ||||
|     { | ||||
|         LookAtStrength = value; | ||||
|     } | ||||
|  | ||||
|     public void UpdateMorph(SkinnedMeshRenderer meshRenderer, int id, float value, Slider slider = null) | ||||
|     { | ||||
|         meshRenderer.SetBlendShapeWeight(id, value); | ||||
|         Morphs[meshRenderer].First(m => m.Name == meshRenderer.sharedMesh.GetBlendShapeName(id)).Strength = value; | ||||
|         if (slider) | ||||
|             slider.SetValueWithoutNotify(value); | ||||
|     } | ||||
|  | ||||
|     #endregion | ||||
|  | ||||
|     #region Toggles | ||||
|     public void ToggleIK(bool value) | ||||
|     { | ||||
|         foreach (var ik in GetComponents<InverseKinematics>()) | ||||
|         { | ||||
|             ik.SoftEnabled = value; | ||||
|             ik.linesVisible = value; | ||||
|         } | ||||
|         foreach (UIHandleIK ikHandle in Handles.Where(h=>h.GetType() == typeof(UIHandleIK))) | ||||
|         { | ||||
|             foreach(var handle in ikHandle.HiddenHandles) | ||||
|             { | ||||
|                 handle.ForceDisplayOff(value); | ||||
|             } | ||||
|         } | ||||
|         IKEnabled = value; | ||||
|     } | ||||
|  | ||||
|     public override void ToggleBonesVisible(bool value) | ||||
|     { | ||||
|         base.ToggleBonesVisible(value); | ||||
|         if (EyeTarget != null) | ||||
|         { | ||||
|             EyeTarget.ToggleActive(value); | ||||
|         } | ||||
|     } | ||||
|     #endregion | ||||
|  | ||||
|     public override void Select() | ||||
|     { | ||||
|         MorphPanel.gameObject.SetActive(true); | ||||
|         CharacterPanel.gameObject.SetActive(true); | ||||
|     } | ||||
|  | ||||
|     public override void Deselect() | ||||
|     { | ||||
|         MorphPanel.gameObject.SetActive(false); | ||||
|         CharacterPanel.gameObject.SetActive(false); | ||||
|     } | ||||
|  | ||||
|     public override void PastePose(KeyframeData keyframe1, PoseLoadOptions pasteParams) | ||||
|     { | ||||
|         var keyframe = keyframe1 as CharacterKeyframeData; | ||||
|  | ||||
|         this.CurrentAnimation = keyframe.CurrentAnimation; | ||||
|         if (keyframe.CurrentAnimation == "") | ||||
|         { | ||||
|             ToggleIK(keyframe.IKEnabled); | ||||
|             this.PlayAnimation(this.BodySimpleAnimation, ""); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             ToggleIK(false); | ||||
|             int currentFrame = TimelineController.Instance.CurrentFrame; | ||||
|             FrameContent startFrame = null; | ||||
|             foreach (var frame in Frames) | ||||
|             { | ||||
|                 if (frame.FrameNum <= currentFrame && (frame.ObjectData as CharacterKeyframeData).CurrentAnimation == keyframe.CurrentAnimation) | ||||
|                 { | ||||
|                     if (startFrame == null || frame.FrameNum > startFrame.FrameNum) | ||||
|                     { | ||||
|                         startFrame = frame; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             float diff = currentFrame - startFrame.FrameNum; | ||||
|             this.PlayAnimation(this.BodySimpleAnimation, keyframe.CurrentAnimation, diff * (TimelineController.Instance.FrameDelayMS/1000)); | ||||
|         } | ||||
|  | ||||
|         var body    = keyframe.Bones.FirstOrDefault(b => b.Name == "Body") ?? new BoneList(); | ||||
|         var ears    = keyframe.Bones.FirstOrDefault(b => b.Name == "Ears") ?? new BoneList(); | ||||
|         var tail    = keyframe.Bones.FirstOrDefault(b => b.Name == "Tail") ?? new BoneList(); | ||||
|         var earsAlt = keyframe.Bones.FirstOrDefault(b => b.Name == "EarsAlt") ?? new BoneList(); | ||||
|         var tailAlt = keyframe.Bones.FirstOrDefault(b => b.Name == "TailAlt") ?? new BoneList(); | ||||
|  | ||||
|         if (pasteParams.Root) | ||||
|         { | ||||
|             keyframe.Root.ApplyTo(transform); | ||||
|         } | ||||
|  | ||||
|         if (pasteParams.Body) | ||||
|         { | ||||
|             foreach (var bone in this.Body.boneList) | ||||
|             { | ||||
|                 if (pasteParams.Other || bone.GetComponent<Osage>() == null) | ||||
|                     body.Bones.FirstOrDefault(b => b.Name == bone.name)?.Transform.ApplyTo(bone, pasteParams); | ||||
|             } | ||||
|         } | ||||
|         if (pasteParams.Tail) | ||||
|         { | ||||
|             if (this.Tail != null) | ||||
|             { | ||||
|                 foreach (var bone in this.Tail.boneList) | ||||
|                 { | ||||
|                     tail.Bones.FirstOrDefault(b => b.Name == bone.name)?.Transform.ApplyTo(bone, pasteParams); | ||||
|                 } | ||||
|             } | ||||
|             if (this.TailAlt != null) | ||||
|             { | ||||
|                 foreach (var bone in this.TailAlt.boneList) | ||||
|                 { | ||||
|                     tailAlt.Bones.FirstOrDefault(b => b.Name == bone.name)?.Transform.ApplyTo(bone, pasteParams); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (pasteParams.Ears) | ||||
|         { | ||||
|             if (this.Ears != null) | ||||
|             { | ||||
|                 foreach (var bone in this.Ears.boneList) | ||||
|                 { | ||||
|                     ears.Bones.FirstOrDefault(b => b.Name == bone.name)?.Transform.ApplyTo(bone, pasteParams); | ||||
|                 } | ||||
|             } | ||||
|             if (this.EarsAlt != null && earsAlt != null) | ||||
|             { | ||||
|                 foreach (var bone in this.EarsAlt.boneList) | ||||
|                 { | ||||
|                     earsAlt.Bones.FirstOrDefault(b => b.Name == bone.name)?.Transform.ApplyTo(bone, pasteParams); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         foreach (var ik in GetComponentsInChildren<InverseKinematics>()) | ||||
|         { | ||||
|             var bones1 = keyframe.Bones.FirstOrDefault(b => b.Name == "Extra"); | ||||
|             if (bones1 != null) | ||||
|             { | ||||
|                 bones1.Bones.FirstOrDefault(b => b.Name == ik.target.name)?.Transform.ApplyTo(ik.target); | ||||
|                 bones1.Bones.FirstOrDefault(b => b.Name == ik.elbow.name)?.Transform.ApplyTo(ik.elbow); | ||||
|             } | ||||
|         } | ||||
|         if (pasteParams.Morphs) | ||||
|         { | ||||
|             //MorphPanel.PasteValues(keyframe.Renderers); | ||||
|             foreach (var morph in keyframe.Morphs) | ||||
|             { | ||||
|                 var rend = this.Morphs.Keys.FirstOrDefault(k => k.name == morph.ParentName); | ||||
|                 if (rend == null) continue; | ||||
|  | ||||
|                 MorphHelper h = this.Morphs[rend].FirstOrDefault(m => m.Name == morph.Name); | ||||
|                 if (h != null) this.UpdateMorph(rend, rend.sharedMesh.GetBlendShapeIndex(morph.Name), morph.Strength, h.Slider); | ||||
|             } | ||||
|         } | ||||
|         if (keyframe.Renderers != null) | ||||
|         { | ||||
|             foreach (var renderer in keyframe.Renderers) | ||||
|             { | ||||
|                 var rend = this.Renderers.FirstOrDefault(r => KF3CharacterContainerSerializable.GetRendererName(this, r) == renderer.Name); | ||||
|                 if (rend != null) | ||||
|                 { | ||||
|                     rend.enabled = renderer.Value; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         this.TogglePhysics(keyframe.PhysicsEnabled); | ||||
|         this.EyesLocked = keyframe.EyesLocked; | ||||
|         this.LeftEyeRotation = Quaternion.Euler(keyframe.LeftEyeRotation); | ||||
|         this.RightEyeRotation = Quaternion.Euler(keyframe.RightEyeRotation); | ||||
|         this.EyeTarget.transform.localPosition = keyframe.EyeTarget; | ||||
|         this.LookAtStrength = keyframe.LookAtStrength; | ||||
|         this.CharacterPanel.UpdateSelection(); | ||||
|     } | ||||
|  | ||||
|     public override IEnumerator GetModel(string bodyIdLong, string costumeId) | ||||
|     { | ||||
|         KF3AssetLibrary lib = Main.Assets; | ||||
|         List<KF3AssetBundle> abList = lib.AssetBundles.Where(ab => ab.FileName.StartsWith($"ch_{bodyIdLong}_")).ToList(); | ||||
|         KF3AssetBundle bundle; | ||||
|  | ||||
|         //load body | ||||
|         bundle = abList.FirstOrDefault(ab => ab.FileName == $"ch_{bodyIdLong}_{costumeId}.prefab"); | ||||
|         yield return lib.LoadAsset(bundle, (ab) => | ||||
|         { | ||||
|             Body = spawnAndGetReferencer(ab); | ||||
|         }); | ||||
|  | ||||
|         //load ears | ||||
|         bundle = abList.FirstOrDefault(ab => ab.FileName == $"ch_{bodyIdLong}_{costumeId}_ear.prefab"); | ||||
|         if (bundle == null) | ||||
|         { | ||||
|             bundle = abList.FirstOrDefault(ab => ab.FileName == $"ch_{bodyIdLong}_a_ear.prefab"); | ||||
|         } | ||||
|         yield return lib.LoadAsset(bundle, (ab) => | ||||
|         { | ||||
|             Ears = spawnAndGetReferencer(ab); | ||||
|         }); | ||||
|  | ||||
|         bundle = abList.FirstOrDefault(ab => ab.FileName == $"ch_{bodyIdLong}_z_ear.prefab"); | ||||
|         yield return lib.LoadAsset(bundle, (ab) => | ||||
|         { | ||||
|             EarsAlt = spawnAndGetReferencer(ab); | ||||
|         }); | ||||
|  | ||||
|         //load tail | ||||
|         bundle = abList.FirstOrDefault(ab => ab.FileName == $"ch_{bodyIdLong}_{costumeId}_tail.prefab"); | ||||
|         if (bundle == null) | ||||
|         { | ||||
|             bundle = abList.FirstOrDefault(ab => ab.FileName == $"ch_{bodyIdLong}_a_tail.prefab"); | ||||
|         } | ||||
|         yield return lib.LoadAsset(bundle, (ab) => | ||||
|         { | ||||
|             Tail = spawnAndGetReferencer(ab); | ||||
|         }); | ||||
|  | ||||
|         bundle = abList.FirstOrDefault(ab => ab.FileName == $"ch_{bodyIdLong}_z_tail.prefab"); | ||||
|         yield return lib.LoadAsset(bundle, (ab) => | ||||
|         { | ||||
|             TailAlt = spawnAndGetReferencer(ab); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public override IEnumerator GetAnimations(string idLong) | ||||
|     { | ||||
|         KF3AssetLibrary lib = Main.Assets; | ||||
|         KF3AssetBundle bundle; | ||||
|         List<KF3AssetBundle> abList = lib.AssetBundles.Where(ab => ab.FileName.StartsWith($"ch_{idLong}_")).ToList(); | ||||
|  | ||||
|         //load body motion | ||||
|         bundle = abList.FirstOrDefault(ab => ab.FileName == $"ch_{idLong}_a_mot.prefab"); | ||||
|         yield return lib.LoadAsset(bundle, (ab) => | ||||
|         { | ||||
|             BodyAnimation = spawnAndGetReferencer(ab); | ||||
|         }); | ||||
|  | ||||
|         //load ears motion | ||||
|         bundle = abList.FirstOrDefault(ab => ab.FileName == $"ch_{idLong}_a_ear_mot.prefab"); | ||||
|         yield return lib.LoadAsset(bundle, (ab) => | ||||
|         { | ||||
|             EarsAnimation = spawnAndGetReferencer(ab); | ||||
|         }); | ||||
|  | ||||
|         //load tail motion | ||||
|         bundle = abList.FirstOrDefault(ab => ab.FileName == $"ch_{idLong}_a_tail_mot.prefab"); | ||||
|         yield return lib.LoadAsset(bundle, (ab) => | ||||
|         { | ||||
|             TailAnimation = spawnAndGetReferencer(ab); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										11
									
								
								Assets/KF3/Scripts/Containers/KF3FriendContainer.cs.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/KF3/Scripts/Containers/KF3FriendContainer.cs.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: 65acd7afcc45d3142a3b712abcd41531 | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
							
								
								
									
										58
									
								
								Assets/KF3/Scripts/Containers/KF3ObjectContainer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								Assets/KF3/Scripts/Containers/KF3ObjectContainer.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| using KF3.Containers; | ||||
| using System; | ||||
| using UnityEngine; | ||||
|  | ||||
| public class KF3ObjectContainer : ObjectContainer | ||||
| { | ||||
|     protected override System.Type _serializeType => typeof(KF3ObjectContainerSerializable); | ||||
|  | ||||
|     public KF3CharacterContainer AsCharacter => this as KF3CharacterContainer; | ||||
|  | ||||
|     protected static KF3ModelViewerMain Main => KF3ModelViewerMain.Instance; | ||||
|  | ||||
|     protected override void Start() | ||||
|     { | ||||
|         if (DoNotSave) return; | ||||
|  | ||||
|         if(Frames.Count == 0) | ||||
|         { | ||||
|             SetKeyframe(); | ||||
|         } | ||||
|  | ||||
|         KF3ModelViewerMain.RegisterObject(this); | ||||
|         var selector = UITimelineObjectEntry.Create(this); | ||||
|         InstantiatedObjects.Add(selector.gameObject); | ||||
|  | ||||
|         KF3ModelViewerMain.Instance.SelectObject(this); | ||||
|     } | ||||
|  | ||||
|     protected override void OnDestroy() | ||||
|     { | ||||
|         if (Main.SelectedObject == this) | ||||
|         { | ||||
|             Main.SelectObject(null); | ||||
|         } | ||||
|  | ||||
|         KF3ModelViewerMain.UnregisterObject(this); | ||||
|  | ||||
|         base.OnDestroy(); | ||||
|     } | ||||
|  | ||||
|     #region Timeline | ||||
|     public override DataType GetDataType() | ||||
|     { | ||||
|         switch (this) | ||||
|         { | ||||
|             case KF3FriendContainer _: | ||||
|                 return DataType.Character; | ||||
|             case KF3CeruleanContainer _: | ||||
|                 return DataType.Character; | ||||
|             case KF3StaticContainer _: | ||||
|                 return DataType.Object; | ||||
|             default: | ||||
|                 Error.Log(Color.red, GetType().FullName); | ||||
|                 throw new NotImplementedException(); | ||||
|         } | ||||
|     } | ||||
|     #endregion | ||||
| } | ||||
							
								
								
									
										11
									
								
								Assets/KF3/Scripts/Containers/KF3ObjectContainer.cs.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/KF3/Scripts/Containers/KF3ObjectContainer.cs.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: d028abe563d1f8142859213a6513cc27 | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
| @@ -0,0 +1,12 @@ | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
|  | ||||
| [System.Serializable] | ||||
| public class KF3ObjectContainerSerializable : ObjectContainerSerializable | ||||
| { | ||||
|     public KF3ObjectContainerSerializable() : base() { } | ||||
|  | ||||
|     public KF3ObjectContainerSerializable(KF3ObjectContainer container) : base(container) { } | ||||
|  | ||||
|     public KF3ObjectContainerSerializable(KF3ObjectContainerSerializable source) : base(source) { } | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: a5a255f7822836f4f9cd74c5e12f5c9a | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
							
								
								
									
										185
									
								
								Assets/KF3/Scripts/Containers/KF3SceneContainer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								Assets/KF3/Scripts/Containers/KF3SceneContainer.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,185 @@ | ||||
|  | ||||
| using KF3.Containers; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using UnityEngine; | ||||
|  | ||||
| public class KF3SceneContainer : SceneContainer | ||||
| { | ||||
|     public string BackgroundName = ""; | ||||
|     public Dictionary<string, GameObject> Backgrounds = new Dictionary<string, GameObject>(); | ||||
|     public string StageName = ""; | ||||
|     public Dictionary<string, GameObject> Stages = new Dictionary<string, GameObject>(); | ||||
|     public List<GameObject> InstantiatedObjects = new List<GameObject>(); | ||||
|     public List<FrameContent> Frames = new List<FrameContent>(); | ||||
|  | ||||
|     public UIKF3SceneSettings Settings; | ||||
|  | ||||
|     protected KF3ModelViewerMain Main => KF3ModelViewerMain.Instance; | ||||
|  | ||||
|     public override void Init(ModelViewerMain main1) | ||||
|     { | ||||
|         var main = main1 as KF3ModelViewerMain; | ||||
|         base.Init(main); | ||||
|         Settings = UIKF3SceneSettings.Create(this); | ||||
|         InstantiatedObjects.Add(Settings.gameObject); | ||||
|  | ||||
|         if (main.UI != null) | ||||
|         { | ||||
|             KF3ModelViewerInterface.SetDropdownData(Settings.StageDropdown, KF3ModelViewerMain.Instance.Assets.Stages.Select(s => s.DisplayName).ToList(), true); | ||||
|             KF3ModelViewerInterface.SetDropdownData(Settings.BackgroundDropdown, KF3ModelViewerMain.Instance.Assets.Skies.Select(s => s.DisplayName).ToList(), true); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void SetBackground(string newBackground) | ||||
|     { | ||||
|         if (newBackground == BackgroundName) return; | ||||
|         var currentBackground = BackgroundName; | ||||
|  | ||||
|         if (newBackground != "") | ||||
|         { | ||||
|             if (!Backgrounds.ContainsKey(newBackground)) | ||||
|             { | ||||
|                 Backgrounds[newBackground] = null; | ||||
|                 KF3ModelViewerMain.Instance.StartCoroutine(Main.Builder.SpawnAsset(newBackground, bg => | ||||
|                 { | ||||
|                     Backgrounds[newBackground] = bg; | ||||
|                     InstantiatedObjects.Add(bg); | ||||
|                 })); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 Backgrounds[newBackground]?.SetActive(true); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (currentBackground != "") | ||||
|         { | ||||
|             Backgrounds[currentBackground]?.SetActive(false); | ||||
|  | ||||
|             var currentFrame = TimelineController.Instance.CurrentFrame; | ||||
|             bool containsCurrent = Frames.Where(f => (f.ObjectData as SceneKeyframe).Background == currentBackground && f.FrameNum != currentFrame).Any(); | ||||
|  | ||||
|             if (!containsCurrent) | ||||
|             { | ||||
|                 KF3ModelViewerMain.DisposeOf(Backgrounds[currentBackground]); | ||||
|                 Backgrounds.Remove(currentBackground); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         BackgroundName = newBackground; | ||||
|     } | ||||
|  | ||||
|     public void SetStage(string newStage) | ||||
|     { | ||||
|         if (newStage == StageName) return; | ||||
|         var currentStage = StageName; | ||||
|  | ||||
|         if (newStage != "") | ||||
|         { | ||||
|             if (!Stages.ContainsKey(newStage)) | ||||
|             { | ||||
|                 Stages[newStage] = null; | ||||
|                 KF3ModelViewerMain.Instance.StartCoroutine(Main.Builder.SpawnAsset(newStage, bg => | ||||
|                 { | ||||
|                     Stages[newStage] = bg; | ||||
|                     InstantiatedObjects.Add(bg); | ||||
|                 })); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 Stages[newStage]?.SetActive(true); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (currentStage != "") | ||||
|         { | ||||
|             Stages[currentStage]?.SetActive(false); | ||||
|  | ||||
|             var currentFrame = TimelineController.Instance.CurrentFrame; | ||||
|             bool containsCurrent = Frames.Where(f => (f.ObjectData as SceneKeyframe).Stage == currentStage && f.FrameNum != currentFrame).Any(); | ||||
|  | ||||
|             if (!containsCurrent) | ||||
|             { | ||||
|                 KF3ModelViewerMain.DisposeOf(Stages[currentStage]); | ||||
|                 Stages.Remove(currentStage); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         StageName = newStage; | ||||
|     } | ||||
|  | ||||
|     public KeyframeData SerializeFrame() | ||||
|     { | ||||
|         return new SceneKeyframe(this); | ||||
|     } | ||||
|  | ||||
|     public override SceneSerializable Serialize() | ||||
|     { | ||||
|         return new KF3SceneSerializable(this); | ||||
|     } | ||||
|  | ||||
|     public void Lerp(KeyframeData frame1, KeyframeData frame2, float amount) | ||||
|     { | ||||
|         var frame = (frame1 as SceneKeyframe).Lerp(frame2, amount) as SceneKeyframe; | ||||
|         SetBackground(frame.Background); | ||||
|         SetStage(frame.Stage); | ||||
|     } | ||||
|  | ||||
|     public void GetClosestFrames(int frame, out FrameContent previousFrame, out FrameContent nextFrame) | ||||
|     { | ||||
|         previousFrame = null; | ||||
|         nextFrame = null; | ||||
|  | ||||
|         var frames = Frames.OrderBy(f => f.FrameNum).ToArray(); | ||||
|  | ||||
|         for (int i = 0; i < Frames.Count; i++) | ||||
|         { | ||||
|             if (Frames[i].FrameNum < frame) | ||||
|             { | ||||
|                 previousFrame = nextFrame = frames[i]; | ||||
|             } | ||||
|             else if (Frames[i].FrameNum == frame) | ||||
|             { | ||||
|                 previousFrame = nextFrame = frames[i]; | ||||
|                 break; | ||||
|             } | ||||
|             else if (Frames[i].FrameNum > frame) | ||||
|             { | ||||
|                 if (previousFrame == null) previousFrame = frames[i]; | ||||
|                 nextFrame = frames[i]; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public virtual void SetKeyframe(int frameNum = -1) | ||||
|     { | ||||
|         if (frameNum == -1) frameNum = TimelineController.Instance.CurrentFrame; | ||||
|  | ||||
|         GetClosestFrames(frameNum, out var previousFrame, out var nextFrame); | ||||
|  | ||||
|         FrameContent currentFrame = null; | ||||
|         if (previousFrame == null || previousFrame.FrameNum != frameNum) | ||||
|         { | ||||
|             currentFrame = new FrameContent(frameNum); | ||||
|             Frames.Add(currentFrame); | ||||
|             Frames = Frames.OrderBy(f => f.FrameNum).ToList(); | ||||
|         } | ||||
|         else if (previousFrame.FrameNum == frameNum) currentFrame = previousFrame; | ||||
|         else if (nextFrame.FrameNum == frameNum) currentFrame = nextFrame; | ||||
|  | ||||
|         currentFrame.SetObjectData(SerializeFrame()); | ||||
|  | ||||
|         TimelineController.UpdateTimeline(); | ||||
|     } | ||||
|  | ||||
|     public void SetDefaultFrame() | ||||
|     { | ||||
|         Frames = new List<FrameContent>() | ||||
|         { | ||||
|             new FrameContent(0).SetObjectData(SerializeFrame()) | ||||
|         }; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										11
									
								
								Assets/KF3/Scripts/Containers/KF3SceneContainer.cs.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/KF3/Scripts/Containers/KF3SceneContainer.cs.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: 557b17c6118f1824f87ce6c5681d326a | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
							
								
								
									
										26
									
								
								Assets/KF3/Scripts/Containers/KF3SceneSerializable.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Assets/KF3/Scripts/Containers/KF3SceneSerializable.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Globalization; | ||||
| using System.Linq; | ||||
| using UnityEngine; | ||||
| using UnityEngine.Networking.Types; | ||||
|  | ||||
| [Serializable] | ||||
| public class KF3SceneSerializable : SceneSerializable | ||||
| { | ||||
|     public List<FrameContent> Frames = new List<FrameContent>(); | ||||
|  | ||||
|     public KF3SceneSerializable() { } | ||||
|  | ||||
|     public KF3SceneSerializable(KF3SceneContainer scene) | ||||
|     { | ||||
|         this.Version = Application.version; | ||||
|         this.Date = DateTime.Now.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture); ; | ||||
|         this.Timeline = new TimelineControllerSerializable(TimelineController.Instance); | ||||
|         this.Frames = scene.Frames.Select(f => new FrameContent(f)).ToList(); | ||||
|         foreach(var obj in scene.AllObjects) | ||||
|         { | ||||
|             Objects.Add(obj.Serialize() as KF3ObjectContainerSerializable); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										11
									
								
								Assets/KF3/Scripts/Containers/KF3SceneSerializable.cs.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/KF3/Scripts/Containers/KF3SceneSerializable.cs.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: 049dacceaae7adb468b3c151f7985fef | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
							
								
								
									
										286
									
								
								Assets/KF3/Scripts/Containers/KF3StaticContainer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								Assets/KF3/Scripts/Containers/KF3StaticContainer.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,286 @@ | ||||
| using System; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.ComponentModel; | ||||
| using System.Linq; | ||||
| using UnityEngine; | ||||
| using UnityEngine.UIElements; | ||||
|  | ||||
| public class KF3StaticContainer : KF3ObjectContainer | ||||
| { | ||||
|     public bool CanBeSaved = true; | ||||
|     private bool paused = false; | ||||
|     public int SelectedMaterialVariant = 0; | ||||
|     private Dictionary<Renderer, List<Material[]>> _materialVariants = new Dictionary<Renderer, List<Material[]>>(); | ||||
|     private Material lineMaterial; | ||||
|     public List<GameObject> DetachableObjects = new List<GameObject>(); | ||||
|     private Dictionary<GameObject, Transform[]> linePoints = new Dictionary<GameObject, Transform[]>(); | ||||
|  | ||||
|     public UIKF3StaticSettings SettingsPanel; | ||||
|  | ||||
|     //private void Start() | ||||
|     //{ | ||||
|     //    KF3ModelContainer mc = gameObject.AddComponent<KF3ModelContainer>(); | ||||
|     //    mc.Renderers = this.renderers; | ||||
|     //} | ||||
|     public static KF3StaticContainer Create(AssetBundle ab) | ||||
|     { | ||||
|         if(ab == null) return null; | ||||
|  | ||||
|         GameObject go = Instantiate(ab.LoadAsset(ab.GetAllAssetNames()[0]) as GameObject); | ||||
|         var container = go.AddComponent<KF3StaticContainer>(); | ||||
|         container.name = ab.name; | ||||
|         UIHandleProp.CreateAsChild(container, go.transform); | ||||
|         container.Init(); | ||||
|  | ||||
|         ab.Unload(false); | ||||
|  | ||||
|         return container; | ||||
|     } | ||||
|  | ||||
|     public void Init() | ||||
|     { | ||||
|         Renderer[] renderers = gameObject.GetComponentsInChildren<Renderer>(); | ||||
|  | ||||
|         foreach (Renderer renderer in renderers) | ||||
|         { | ||||
|             Material[] overrideMaterials = new Material[renderer.materials.Length]; | ||||
|             Material[] overrideMaterials2 = new Material[renderer.materials.Length]; | ||||
|             for (int i = 0; i < renderer.materials.Length; i++) | ||||
|             { | ||||
|                 if (renderer.materials[i].shader.name == "PRD/Stage") | ||||
|                 { | ||||
|                     overrideMaterials[i] = new Material(Shader.Find("PRD/FriendsShaderV2")); | ||||
|                     { | ||||
|                         overrideMaterials[i].SetTexture("_BaseMap", renderer.materials[i].mainTexture); | ||||
|                         overrideMaterials[i].SetTexture("_1st_ShadeMap", renderer.materials[i].mainTexture); | ||||
|                     } | ||||
|                     overrideMaterials2[i] = new Material(renderer.materials[i]); | ||||
|                     { | ||||
|                         overrideMaterials2[i].SetTexture("_ShadowTex", null); | ||||
|                     } | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     overrideMaterials[i] = overrideMaterials2[i] = renderer.materials[i]; | ||||
|                 } | ||||
|             } | ||||
|             AddMaterialVariant(renderer, renderer.materials); | ||||
|             AddMaterialVariant(renderer, overrideMaterials); | ||||
|             AddMaterialVariant(renderer, overrideMaterials2); | ||||
|         } | ||||
|  | ||||
|         SettingsPanel = UIKF3StaticSettings.Create(this); | ||||
|         InstantiatedObjects.Add(SettingsPanel.gameObject); | ||||
|     } | ||||
|  | ||||
|     public void PauseAll() | ||||
|     { | ||||
|         foreach (var par in transform.GetComponentsInChildren<ParticleSystem>()) | ||||
|         { | ||||
|             par.Pause(); | ||||
|         } | ||||
|         foreach (var anim in transform.GetComponentsInChildren<Animator>()) | ||||
|         { | ||||
|             anim.speed = 0; | ||||
|         } | ||||
|         paused = true; | ||||
|     } | ||||
|  | ||||
|     public void PlauseAll() | ||||
|     { | ||||
|         if (paused) | ||||
|             UnPauseAll(); | ||||
|         else | ||||
|             PauseAll(); | ||||
|     } | ||||
|  | ||||
|     public void UnPauseAll() | ||||
|     { | ||||
|         foreach (var par in transform.GetComponentsInChildren<ParticleSystem>()) | ||||
|         { | ||||
|             par.Play(); | ||||
|         } | ||||
|         foreach (var anim in transform.GetComponentsInChildren<Animator>()) | ||||
|         { | ||||
|             anim.speed = 1; | ||||
|         } | ||||
|         paused = false; | ||||
|     } | ||||
|  | ||||
|     public void ReStartAll() | ||||
|     { | ||||
|         foreach (var par in transform.GetComponentsInChildren<ParticleSystem>()) | ||||
|         { | ||||
|             par.time = 0; | ||||
|             par.Play(); | ||||
|         } | ||||
|         foreach (var anim in transform.GetComponentsInChildren<Animator>()) | ||||
|         { | ||||
|             anim.Play(anim.GetCurrentAnimatorStateInfo(0).shortNameHash, 0, 0); | ||||
|             anim.speed = 1; | ||||
|         } | ||||
|         paused = false; | ||||
|     } | ||||
|  | ||||
|     public void ToggleLines() | ||||
|     { | ||||
|         bool value = false; | ||||
|         foreach(var linePoint in linePoints) | ||||
|         { | ||||
|             value = !linePoint.Key.GetComponent<LineRenderer>().enabled; | ||||
|             break; | ||||
|         } | ||||
|         foreach (var linePoint in linePoints) | ||||
|         { | ||||
|             linePoint.Key.GetComponent<LineRenderer>().enabled = value; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     ////Set up UI knobs for every sub-objects of an animated effect | ||||
|     //public void BuildHierarchy() | ||||
|     //{ | ||||
|     //    foreach (var par in transform.GetComponentsInChildren<ParticleSystem>()) | ||||
|     //    { | ||||
|     //        if (par.transform.GetComponent<UIHandle>() == null) | ||||
|     //        { | ||||
|     //            par.gameObject.layer = 0; | ||||
|     //            par.gameObject.AddComponent<UIHandleParticle>() | ||||
|     //                .Init(par.gameObject).SetScale(1f).SetColor(Color.blue); | ||||
|     //            NewLine(par.transform.parent, par.transform, 0.01f, Color.blue); | ||||
|     //        } | ||||
|     //    } | ||||
|     //    foreach (var rend in transform.GetComponentsInChildren<Renderer>()) | ||||
|     //    { | ||||
|     //        if (rend.transform.parent.GetComponent<UIHandle>() == null) | ||||
|     //        { | ||||
|     //            Renderers.Add(rend); | ||||
|     //            rend.transform.parent.gameObject.layer = 0; | ||||
|     //            rend.transform.parent.gameObject.AddComponent<UIHandleDetachable>() | ||||
|     //                .Init(rend.transform.parent.gameObject).SetScale(1f).SetColor(Color.gray); | ||||
|     //            NewLine(transform, rend.transform.parent, 0.01f, Color.gray); | ||||
|     //            DetachableObjects.Add(rend.transform.gameObject); | ||||
|     //        } | ||||
|     //    } | ||||
|     //} | ||||
|  | ||||
|     //public GameObject DetachObject(int index) | ||||
|     //{ | ||||
|     //    return DetachObject(DetachableObjects[index]); | ||||
|     //} | ||||
|  | ||||
|     //public GameObject DetachObject(GameObject go) | ||||
|     //{ | ||||
|     //    var detached = Instantiate(go); | ||||
|     //    var knobs = detached.GetComponentsInChildren<UIHandle>(); | ||||
|     //    UIHandle knob = null; | ||||
|     //    for (int i = knobs.Length - 1; i >= 0; i--) | ||||
|     //    { | ||||
|     //        knob = knobs[i]; | ||||
|     //        if(knob.GetType() == typeof(UIHandleParticle)) | ||||
|     //        { | ||||
|     //            Destroy(knob.ClearForDeletion()); | ||||
|     //            DestroyImmediate(knob.gameObject); | ||||
|     //        } | ||||
|     //        else | ||||
|     //        { | ||||
|     //            Destroy(knob.ClearForDeletion()); | ||||
|     //        } | ||||
|     //    } | ||||
|     //    var container = detached.AddComponent<KF3StaticContainer>(); | ||||
|     //    detached.transform.position = go.transform.position; | ||||
|     //    detached.transform.rotation = go.transform.rotation; | ||||
|     //    detached.name = go.name + "_Detached"; | ||||
|     //    container.CanBeSaved = false; | ||||
|     //    Destroy(detached.GetComponent<UIHandle>().ClearForDeletion()); | ||||
|     //    knob = detached.AddComponent<UIHandleFurniture>() | ||||
|     //        .Init(detached).SetDefaults(Vector3.zero, Vector3.zero, Vector3.one); | ||||
|     //    var renderers = detached.GetComponentsInChildren<Renderer>().ToList(); | ||||
|     //    renderers.Remove(detached.GetComponent<Renderer>()); | ||||
|     //    foreach (var rend in renderers) | ||||
|     //    { | ||||
|     //        rend.gameObject.layer = 0; | ||||
|     //        rend.gameObject.AddComponent<UIHandleDetachable>() | ||||
|     //            .Init(rend.gameObject).SetColor(Color.gray).SetScale(1).SetName(detached.name + "_part"); | ||||
|     //        rend.enabled = true; | ||||
|     //        //var go2 = container.NewLine(rend.transform, rend.transform.parent, 0.01f, Color.gray); | ||||
|     //        //go2.name = rend.transform.name + " -> " + rend.transform.parent.name; | ||||
|     //    } | ||||
|     //    knob.ScaleReset(); | ||||
|     //    return detached; | ||||
|     //} | ||||
|  | ||||
|     public GameObject NewLine(Transform point1, Transform point2, float width, Color color) | ||||
|     { | ||||
|         if(lineMaterial == null) | ||||
|         { | ||||
|             lineMaterial = new Material(Shader.Find("Legacy Shaders/Particles/Alpha Blended Premultiply")); | ||||
|         } | ||||
|         GameObject go = new GameObject("line"); | ||||
|         go.layer = 5; | ||||
|         go.transform.SetParent(this.transform); | ||||
|         var lr = go.AddComponent<LineRenderer>(); | ||||
|         lr.startWidth = lr.endWidth = width; | ||||
|         lr.startColor = lr.endColor = color; | ||||
|         lr.sharedMaterial = lineMaterial; | ||||
|  | ||||
|         linePoints.Add(go, new Transform[] { point1, point2 }); | ||||
|         return go; | ||||
|     } | ||||
|  | ||||
|     private void Update() | ||||
|     { | ||||
|         foreach (var kv in linePoints) | ||||
|         { | ||||
|             var lr = kv.Key.GetComponent<LineRenderer>(); | ||||
|             for (int i = 0; i < kv.Value.Length; i++) | ||||
|             { | ||||
|                 lr.SetPosition(i, kv.Value[i].position); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void AddMaterialVariant(Renderer renderer, Material[] materialVariant) | ||||
|     { | ||||
|         if (!_materialVariants.ContainsKey(renderer)) | ||||
|         { | ||||
|             _materialVariants.Add(renderer, new List<Material[]>()); | ||||
|         } | ||||
|  | ||||
|         _materialVariants[renderer].Add(materialVariant); | ||||
|     } | ||||
|  | ||||
|     public void SetMaterialVariant(int index) | ||||
|     { | ||||
|         foreach (var keyValue in _materialVariants) | ||||
|         { | ||||
|             keyValue.Key.materials = keyValue.Value[index]; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     protected override void OnDestroy() | ||||
|     { | ||||
|         Destroy(lineMaterial); | ||||
|         foreach(var material in _materialVariants) | ||||
|         { | ||||
|             foreach(var material1 in material.Value) | ||||
|             { | ||||
|                 foreach (var material2 in material1) | ||||
|                 { | ||||
|                     Destroy(material2); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         base.OnDestroy(); | ||||
|     } | ||||
|  | ||||
|     public override void Select() | ||||
|     { | ||||
|         SettingsPanel.gameObject.SetActive(true); | ||||
|     } | ||||
|  | ||||
|     public override void Deselect() | ||||
|     { | ||||
|         SettingsPanel.gameObject.SetActive(false); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										11
									
								
								Assets/KF3/Scripts/Containers/KF3StaticContainer.cs.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/KF3/Scripts/Containers/KF3StaticContainer.cs.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: 85d6b154ae038604a99d1805754858d9 | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
							
								
								
									
										34
									
								
								Assets/KF3/Scripts/Containers/SceneKeyframe.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								Assets/KF3/Scripts/Containers/SceneKeyframe.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| namespace KF3.Containers | ||||
| { | ||||
|     [System.Serializable] | ||||
|     public class SceneKeyframe : KeyframeData | ||||
|     { | ||||
|         public string Stage; | ||||
|         public string Background; | ||||
|  | ||||
|         public SceneKeyframe() { } | ||||
|  | ||||
|         public SceneKeyframe(KF3SceneContainer main) | ||||
|         { | ||||
|             this.Root = null; | ||||
|             this.Stage = main.StageName; | ||||
|             this.Background = main.BackgroundName; | ||||
|         } | ||||
|  | ||||
|         public override KeyframeData Clone() | ||||
|         { | ||||
|             var keyframe = new SceneKeyframe(); | ||||
|             keyframe.Root = null; | ||||
|             keyframe.Stage = this.Stage; | ||||
|             keyframe.Background = this.Background; | ||||
|             return keyframe; | ||||
|         } | ||||
|  | ||||
|         public override KeyframeData Lerp(KeyframeData target1, float amount) | ||||
|         { | ||||
|             var target = target1 as SceneKeyframe; | ||||
|             var copy = this.Clone() as SceneKeyframe; | ||||
|             return copy; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										11
									
								
								Assets/KF3/Scripts/Containers/SceneKeyframe.cs.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/KF3/Scripts/Containers/SceneKeyframe.cs.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: d761685c6e163014f915b5afc1014541 | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
		Reference in New Issue
	
	Block a user