using System; using System.Collections.Generic; using System.Linq; using System.Text; using TMPro; using Unity.VisualScripting; using UnityEngine; using UnityEngine.UI; public class ActiveScoppedElements : MonoBehaviour { [Serializable] public struct ObjectToInstantiate { public List elements; public GameObject obj; } public enum AnimationState { IDLE, GORIGHT, GOLEFT } public TextAsset jsonFile; public TextAsset atomJsonFile; public HashSet actives = new HashSet(); public HashSet InstantiatesObject = new HashSet(); public HashSet AtomInstantiatesObjects = new HashSet(); public TextMeshProUGUI textToUpdate; public TextMeshProUGUI objectInstantiateText; public HashSet DisableGameObjects = new HashSet(); public GameObject[] InformationObjs; public GameObject[] DebugObjs; private AnimationState _animationState = AnimationState.IDLE; private float _animationSpeed = 1.0f; public GameObject atomPrefabToInstantiate; private bool IsLock = false; private AtomeFactory _atomFactory; void Start() { _atomFactory = new AtomeFactory(this.atomJsonFile); Debug.Log("AtomFactory created !"); /*if (button != null) { button.onClick.AddListener(this.Center); }*/ if (this.textToUpdate != null) { textToUpdate.text = "Scanner des Markers..."; } } public void AddScoppedElement(String name) { Debug.Log("Added " + name); if (!actives.Contains(name)) { actives.Add(name); RefreshText(); RefreshAtom(name, true); } } public void Center() { Debug.Log("Center called !"); foreach (var obj in InstantiatesObject) { if (Camera.main == null) { throw new Exception("NO MAIN CAMERA DEFINED "); } Vector3 cameraPosition = Camera.main.transform.position; // Obtenez la rotation de la caméra sans inclure la rotation autour de l'axe Y Quaternion cameraRotation = Quaternion.Euler(0, Camera.main.transform.rotation.eulerAngles.y, 0); // Calculez la position finale en ajoutant la direction vers l'avant multipliée par la distance désirée Vector3 position = cameraPosition + cameraRotation * Vector3.forward * 0.35f; //var instantiatedObj = Instantiate(objt.obj, position, cameraRotation); obj.transform.position = position; obj.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f); obj.transform.rotation = cameraRotation; } } public void onClickStopAnimation() { Quaternion cameraRotation = Quaternion.Euler(0, Camera.main.transform.rotation.eulerAngles.y, 0); this._animationState = AnimationState.IDLE; foreach (var obj in InstantiatesObject) { obj.transform.rotation = cameraRotation; } } public void onClickPauseAnimation() { this._animationState = AnimationState.IDLE; } public void onClickStartAnimation() { this._animationState = AnimationState.GORIGHT; } public void onClickRightAnimation() { this._animationState = AnimationState.GORIGHT; } public void onClickGoLeftAnimation() { this._animationState = AnimationState.GOLEFT; } public void onClickSpeedUp() { this._animationSpeed += 0.5f; } public void onClickSpeedDown() { this._animationSpeed -= 0.5f; } public void onClickToggleLockMode() { this.IsLock = !this.IsLock; } void Update() { if (this._animationState == AnimationState.GORIGHT) { foreach (var obj in InstantiatesObject) { obj.transform.Rotate(0, this._animationSpeed, 0, Space.Self); /*Vector3 position = obj.GetComponent().bounds.center; obj.transform.RotateAround(position, new Vector3(0, 0.1f, 0), 30 * Time.deltaTime);*/ } } } private void RefreshText() { if (this.textToUpdate != null) { this.textToUpdate.text = String.Join(", ", this.actives); } } static IEnumerable GetPermutations(List list) { if (list.Count == 1) { // Cas de base : une seule chaîne yield return list[0]; } else { // Récursion pour obtenir les permutations du reste de la liste foreach (var item in list) { var remaining = new List(list); remaining.Remove(item); foreach (var subPermutation in GetPermutations(remaining)) { // Concaténer l'élément actuel avec les permutations du reste yield return item + subPermutation; } } } } private void DisableAllMarkerModel() { foreach (var o in GameObject.FindGameObjectsWithTag("OBJ")) { o.SetActive(false); DisableGameObjects.Add(o); } } private void EnableAllMarkerModel() { foreach (var o in DisableGameObjects) { o.SetActive(true); } DisableGameObjects.Clear(); } private GameObject FindGameObjectWithFormula() { var factory = MoleculeFactory.getInstrance(this.jsonFile); factory.setAtomFactory(this._atomFactory); Debug.Log("ACTIVES ELEMENTS:"); Debug.Log(this.actives); foreach (var formula in GetPermutations(this.actives.ToList())) { Debug.Log("FORMULA: " + String.Join("", formula)); if (factory.hasMolecule(String.Join("", formula))) { return factory.createMolecule(String.Join("", formula)); } } return null; } private String GetFormula() { var factory = MoleculeFactory.getInstrance(this.jsonFile); factory.setAtomFactory(this._atomFactory); foreach (var formula in GetPermutations(this.actives.ToList())) { Debug.Log("FORMULA: " + String.Join("", formula)); if (factory.hasMolecule(String.Join("", formula))) { return String.Join("", formula); } } return null; } private void RenderAtom(String elementName, bool toAdd) { var cleanedElement = CleanStringOfDigits(elementName); if (!toAdd) { try { var a = AtomInstantiatesObjects.First(t => t.name == ("ATOM_" + cleanedElement)); if (a != null) { AtomInstantiatesObjects.Remove(a); Destroy(a); Debug.Log("AtomInstantiatesObjects.Remove(a) called !"); return; } } catch (Exception ex) { Debug.Log("pas trouvé"); return; } } var atomObject = GameObject.Find(elementName); if (atomObject == null) { Debug.Log("atomObject=null"); return; } if (atomObject.transform.childCount >= 1) { //atomObject.transform.GetChild(0).GetComponent().SetActive(true); Debug.Log("Object already created !"); return; } var factory = MoleculeFactory.getInstrance(this.jsonFile); factory.setAtomFactory(this._atomFactory); if (!factory.GetAtomFactory().hasAtome(cleanedElement)) { Debug.Log("No atom found with this formula '" + cleanedElement + "'"); return; } var obj = this._atomFactory.createAnimatedAtome(cleanedElement); obj.name = "ATOM_" + cleanedElement; obj.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f); Quaternion cameraRotation = Quaternion.Euler(0, Camera.main.transform.rotation.eulerAngles.y, 0); obj.transform.localPosition = new Vector3(0, 0, 0); obj.transform.SetParent(atomObject.transform, false); obj.transform.rotation = cameraRotation; AtomInstantiatesObjects.Add(obj); //var obj = Instantiate(atomPrefabToInstantiate, new Vector3(0, 0, 0), Quaternion.identity); //AtomPrefab objPrefab = obj.GetComponent(); //AtomeInformation info = factory.GetAtomFactory().createAtome(cleanedElement); //objPrefab.Render(info); } private void RefreshAtom(String elementName, bool toAdd) { var objToFind = FindGameObjectWithFormula(); if (objToFind != null) { Debug.Log("Object to instantiate found !"); if (Camera.main == null) { throw new Exception("NO MAIN CAMERA DEFINED "); } foreach (var atomInstantiatesObject in AtomInstantiatesObjects) { Destroy(atomInstantiatesObject); } AtomInstantiatesObjects.Clear(); Vector3 cameraPosition = Camera.main.transform.position; Quaternion cameraRotation = Quaternion.Euler(0, Camera.main.transform.rotation.eulerAngles.y, 0); Vector3 position = cameraPosition + cameraRotation * Vector3.forward * 0.35f; objToFind.transform.position = position; objToFind.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f); objToFind.transform.rotation = cameraRotation; MeshRenderer meshRenderer = objToFind.GetComponent(); if (meshRenderer != null) { float sizeInDirection = meshRenderer.bounds.size.x; // Pour la hauteur, ajustez selon votre besoin Debug.Log("SizeInDirection: " + sizeInDirection); objToFind.transform.position -= objToFind.transform.right * sizeInDirection * 0.175f; } Debug.Log("RefreshAtom(): Created " + objToFind.name); objToFind.name = "[N] " + objToFind.name; InstantiatesObject.Add(objToFind); this.OnInstantiateObject(objToFind); Debug.Log("Instantiate " + objToFind.name); DisableAllMarkerModel(); } else { foreach (var o in InstantiatesObject) { Destroy(o); OnDestroyObject(o); } InstantiatesObject.Clear(); EnableAllMarkerModel(); RenderAtom(elementName, toAdd); } if (InstantiatesObject.Count > 0 && objectInstantiateText != null) { objectInstantiateText.text = String.Join(", ", InstantiatesObject.Select((s) => s.name)); } else if (objectInstantiateText != null) { objectInstantiateText.text = "En attente..."; } } private void SetMoleculeInfo(String formula) { if (formula == null) { return; } var factory = MoleculeFactory.getInstrance(this.jsonFile); factory.setAtomFactory(this._atomFactory); Molecule mol = factory.GetMoleculeByFormula(formula); var descriptionGO = GameObject.Find("TXT_DESC").GetComponent(); var atomNbGO = GameObject.Find("TXT_ATOM_NB").GetComponent(); var symGO = GameObject.Find("TXT_SYM").GetComponent(); var nameGO = GameObject.Find("TXT_NAME").GetComponent(); nameGO.text = mol.name; symGO.text = mol.formula; descriptionGO.text = "Masse moleculaire: "; atomNbGO.text = mol.atoms.Length + " Atomes"; } private void OnInstantiateObject(GameObject obj) { foreach (var informationObj in InformationObjs) { informationObj.SetActive(true); } SetMoleculeInfo(GetFormula()); foreach (var debugObj in DebugObjs) { debugObj.SetActive(false); } } private void OnDestroyObject(GameObject obj) { foreach (var informationObj in InformationObjs) { informationObj.SetActive(false); } foreach (var debugObj in DebugObjs) { debugObj.SetActive(true); } } private string CleanStringOfNonDigits( string s ) { if (string.IsNullOrEmpty(s)) return s; StringBuilder sb = new StringBuilder(s.Length) ; for (int i = 0; i < s.Length; ++i) { char c = s[i]; if ( c < '0' ) continue ; if ( c > '9' ) continue ; sb.Append(s[i]); } string cleaned = sb.ToString(); return cleaned; } private string CleanStringOfDigits(string s) { return new String(s.Where(Char.IsLetter).ToArray()); } public void RemoveUnscoppedElement(String elementName) { if (this.IsLock) { return; } Debug.Log("Removed " + elementName); actives.Remove(elementName); RefreshText(); RefreshAtom(elementName, false); } }