#if UNITY_5_3_OR_NEWER using System.Collections; using Mono.Cecil.Cil; using UnityEngine; using UnityEngine.Networking; namespace RoboidControl.Unity { /// /// The representation of a Thing in Unity /// public class Thing : MonoBehaviour { /// /// The core C# thing /// [field: SerializeField] public RoboidControl.Thing core { get; set; } private string modelUrl = null; // protected virtual void Awake() { // core.OnPoseChanged += PoseChanged; // } /// /// Set the core C# thing /// protected void SetCoreThing(RoboidControl.Thing thing) { core = thing; core.component = this; SiteServer siteServer = FindAnyObjectByType(); if (siteServer == null || siteServer.site == null) { Debug.LogWarning("No site server found"); return; } siteServer.site.Add(thing); core.OnPoseChanged += PoseChanged; } public static Thing Create(RoboidControl.Thing core) { // Debug.Log("Creating new Unity thing"); GameObject gameObj = string.IsNullOrEmpty(core.name) ? new("Thing") : new(core.name); Thing component = gameObj.AddComponent(); component.core = core; if (core.parent != null && core.parent.component != null) gameObj.transform.SetParent(core.parent.component.transform, false); if (core.position != null) gameObj.transform.localPosition = core.position.ToVector3(); if (core.orientation != null) gameObj.transform.localRotation = core.orientation.ToQuaternion(); core.OnPoseChanged += component.PoseChanged; return component; } /// /// Update the Unity representation /// protected virtual void Update() { if (core == null) return; if (core.linearVelocity != null && core.linearVelocity.distance != 0) { Vector3 direction = Quaternion.AngleAxis(core.linearVelocity.direction.horizontal, Vector3.up) * Vector3.forward; this.transform.Translate(core.linearVelocity.distance * Time.deltaTime * direction, Space.Self); } // else if (core.positionUpdated) // this.transform.localPosition = core.position.ToVector3(); if (core.angularVelocity != null && core.angularVelocity.distance != 0) { Vector3 angularVelocity = core.angularVelocity.ToVector3(); Vector3 axis = core.angularVelocity.direction.ToVector3(); this.transform.localRotation *= Quaternion.AngleAxis(core.angularVelocity.distance * Time.deltaTime, axis); //this.transform.localRotation *= Quaternion.Euler(angularVelocity * Time.deltaTime); } // else if (core.orientationUpdated) // this.transform.localRotation = core.orientation.ToQuaternion(); if (!string.IsNullOrEmpty(core.modelUrl) && this.modelUrl == null) { string extension = core.modelUrl.Substring(core.modelUrl.LastIndexOf(".")); if (extension == ".jpg" || extension == ".png") { StartCoroutine(LoadJPG()); } this.modelUrl = core.modelUrl; } } private void PoseChanged() { // Debug.Log($"{this} pose changed"); if (core.positionUpdated) this.transform.localPosition = core.position.ToVector3(); if (core.orientationUpdated) this.transform.localRotation = core.orientation.ToQuaternion(); } private IEnumerator LoadJPG() { UnityWebRequest request = UnityWebRequestTexture.GetTexture(core.modelUrl); yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { Texture2D texture = ((DownloadHandlerTexture)request.downloadHandler).texture; float aspectRatio = (float)texture.width / (float)texture.height; GameObject modelQuad = GameObject.CreatePrimitive(PrimitiveType.Quad); Collider c = modelQuad.GetComponent(); c.enabled = false; Destroy(c); modelQuad.transform.SetParent(this.transform, false); modelQuad.transform.localEulerAngles = new(90, -90, 0); modelQuad.transform.localScale = new Vector3(aspectRatio, 1, 1) / 5; if (this.name == "Ant") modelQuad.transform.localScale *= 2; Material quadMaterial = new(Shader.Find("Unlit/Transparent")) { mainTexture = texture }; modelQuad.GetComponent().material = quadMaterial; } else { Debug.LogError("Failed to load image: " + request.error); } } } } #endif