A few weeks ago someone wrote a basic model viewing script for me, I am trying to convert it to work with the Unity 4.6 GUI to make things much easier to do, with little luck, I am hoping someone here can help me with this, I am intenting on releasing this so others can have an easy way to make interactive model viewers/showreel's for their work. Code (CSharp): using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Linq; public class ModelViewer : MonoBehaviour { [System.Serializable] public class ModelViewerInformation{ public GameObject Model; public List<AnimationClip> Animations; } public ModelViewerInformation[] Models; public int ModelIndex; void UpdateModelViewer(){ // Transform[] childs = GetComponentsInChildren<Transform>(); for(int i=0; i< transform.childCount; i++) { Destroy (transform.GetChild(i).gameObject); } GameObject SpawnedModel = Instantiate(Models[ModelIndex].Model, transform.position, transform.rotation) as GameObject; SpawnedModel.transform.parent = transform; } void Update(){ if (Input.GetKeyDown(KeyCode.LeftArrow)){ if (ModelIndex > 0) { ModelIndex -= 1; } else { ModelIndex = Models.Length; } UpdateModelViewer(); } if (Input.GetKeyDown(KeyCode.RightArrow)){ if (ModelIndex < Models.Length) { ModelIndex += 1; } else { ModelIndex = 0; } UpdateModelViewer(); } } }
Okay so I will jump in here. What is it you want to do? And what is LINQ used for in your declarations? If nothing ditch it. I'm booting up your code now. EDIT: First suggestion: Code (csharp): ModelIndex = Models.Length; should be Code (csharp): ModelIndex = Models.Length -1; as it is a zero index system and so it should also be Code (csharp): if (ModelIndex < Models.Length -1) { ModelIndex += 1; } that will stop the Array out of Range errors at least. Other than that I see no issues with this on 4.6 and a Code (csharp): void Start() { // will default to zero or the inspector value UpdateModelViewer(); } wouldn't hurt neither (tested on 4.6.1ish)
here it is with buttons, fancy rotation of model and lights with thrown-together limits system, shadow control, a moderately sane setup of positions and almost no error checking yay. Enjoy. Did I mention the almost illegible FPS counter? do I not give and give. (the public domain santa steve is available online... I do not claim ownership, the arguably similar UV design of said thing to a popular gamestyle likewise is not enforced as owned by Mojang (or now MS), And we all lived happily ever after, the end) Hint to next annoyed poster about shoddy demos, simply cache a starting offset to constrain the Absolute Y rotation relative to the starting position and compare that instead of the current Euler.
and here is a version that just elides the animations reference (for simplicity here) and runs through the embedded animations (with annotated caveats) This seems the most likely use-case so I have included it. Here it is in action http://kaycare.co.uk/games/ModelViewer/ Here is the updated code Code (csharp): using UnityEngine; using System.Collections; using System.Collections.Generic; public class ModelViewer : MonoBehaviour { [System.Serializable] public class ModelViewerInformation { public GameObject Model; } public ModelViewerInformation[] Models; public int ModelIndex; void UpdateModelViewer() { for (int i = 0; i < transform.childCount; i++) { Destroy(transform.GetChild(i).gameObject); } GameObject SpawnedModel = Instantiate(Models[ModelIndex].Model, transform.position, transform.rotation) as GameObject; SpawnedModel.transform.parent = transform; UpdateAnim(ref SpawnedModel); } public void LoadPrevious() { if (ModelIndex > 0) { ModelIndex -= 1; } else { ModelIndex = Models.Length - 1; } UpdateModelViewer(); } public void LoadNext() { if (ModelIndex < Models.Length - 1) { ModelIndex += 1; } else { ModelIndex = 0; } UpdateModelViewer(); } // I skip the cruft default zero one. This could be an option. private int currentAnimationIndex = 1; void Update() { if (anim) { if (!anim.isPlaying) { // we always just step over the index forwards. so, easy test. currentAnimationIndex ++; if (currentAnimationIndex >= animations.Count) { currentAnimationIndex = 1; } anim.Play(animations[currentAnimationIndex]); anim.wrapMode = WrapMode.Once; } } // Old stuff if (Input.GetKeyDown(KeyCode.LeftArrow)) { LoadPrevious(); } if (Input.GetKeyDown(KeyCode.RightArrow)) { LoadNext(); } } List<string> animations = new List<string>(); Animation anim; void UpdateAnim(ref GameObject model) { anim = model.GetComponent<Animation>(); animations.Clear(); // horrid foreach (AnimationState state in anim) { animations.Add(state.name); } // now we have a list we could create buttons "on the fly" with each name... // and call up the animation like anim.Play(animations[ValueWeAddedForThisButton]); // or just go for one and scroll through them... // often the first animation is junk so perhaps we should add a Skip Root Anim bool... if (animations.Count > 0) { // we reset the currentAnimationIndex to 1 currentAnimationIndex = 1; anim.Play(animations[currentAnimationIndex]); } anim.wrapMode = WrapMode.Once; } void Start() { // the model index played will default to zero or possibly the inspector value UpdateModelViewer(); } } Here are some screenies I made all the values to bind to to stop rotation. lights moving, blah blah nice and clear to be linked to GUI system via buttons. You can note the example in the buttons I used above. I was not even moderately careful with design considerations, frankly a small child could improve on it. Henjoy