Layer or hierarchy problem for GameObject - unity3d

In my Unity project, I made a prefab to rendering images from web sources by URL. However, when testing the app, it displayed the images like this:
There are two image windows, but you can see, the image in the first opened window is floating over the second opened window, but under the second image.
The window (ImageHolder) is a prefab I made, and in this prefab, I made another prefab (ImageBox) to rendering image. Here is the prefab hierarchy below.
Here is my script to call to open the instances, the look up imageExtensions part is the part to call this image window. the else part is open web sources with browser, this part works fine.
void OpenLinks(string url, string name)
{
int l = 100; int m = -600;
// Find if the media in URL with type of media via extension
string extension = Path.GetExtension(url);
// Array of media extensions
string[] imageExtensions = { ".jpg", ".png", ".gif", "jpeg", "jfif", "svg", "webp" };
string[] videoExtensions = { ".mp4", ".avi", ".mov", "webm" };
string[] audioExtensions = { ".mp3", ".wav", ".aac" };
if (Array.Exists(imageExtensions, element => extension.Equals(element, StringComparison.OrdinalIgnoreCase)))
{
GameObject image = Instantiate(imageHolder, _nextWindowPosition, imageHolder.transform.rotation);
image.SetActive(true);
// Find the imageBox component and add a SpriteRenderer component
GameObject imageBox = image.transform.Find("ImageBackground/ImageBox").gameObject;
SpriteRenderer spriteRenderer = imageBox.GetComponent<SpriteRenderer>();
TextMeshProUGUI title = image.GetComponentInChildren<TextMeshProUGUI>();
image.transform.SetParent(Windows.transform, false);
image.name = name;
title.text = name;
_nextWindowPosition += new Vector2(50f, -50f);
if (_nextWindowPosition.x > 150)
_nextWindowPosition.x = 50f;
if (_nextWindowPosition.y < -600)
_nextWindowPosition.y = -50f;
GameObject imageBackground = image.transform.Find("ImageBackground").gameObject;
GameObject controlButtons = image.transform.Find("ControlButtons").gameObject;
StartCoroutine(LoadImage(url, spriteRenderer, imageBackground, controlButtons));
}
else if (Array.Exists(videoExtensions, element => extension.Equals(element, StringComparison.OrdinalIgnoreCase)))
{
}
else if (Array.Exists(audioExtensions, element => extension.Equals(element, StringComparison.OrdinalIgnoreCase)))
{
}
else
{
GameObject browser = Instantiate(browserWindow, _nextWindowPosition, browserWindow.transform.rotation);
browser.SetActive(true);
// Find the browser2D component
GameObject browser2D = browser.transform.Find("BrowserBackground/Browser2D").gameObject;
TextMeshProUGUI title = browser.GetComponentInChildren<TextMeshProUGUI>();
browser2D.GetComponent<SimpleWebBrowser.WebBrowser2D>().Navigate(url);
browser.transform.SetParent(Windows.transform, false);
browser.name = name;
title.text = name;
//RectTransform rectTransform = browser.GetComponent<RectTransform>();
//rectTransform.position = new Vector2(l, m);
_nextWindowPosition += new Vector2(50f, -50f);
if (_nextWindowPosition.x > 150)
_nextWindowPosition.x = 50f;
if (_nextWindowPosition.y < -600)
_nextWindowPosition.y = -50f;
}
}

Related

Unity struct fields overlapping with each other and other components

Image showing the problem:
https://i.stack.imgur.com/cmMYy.png
How can i fix this?
This is the struct code:
[Serializable] private struct SpawnableObject
{
public SpawnableObject(GameObject entity, float lowEndChance, float highEndChance)
{
chanceRange = new float[2];
if(lowEndChance > highEndChance)
{
float placeholder;
placeholder = lowEndChance;
lowEndChance = highEndChance;
highEndChance = placeholder;
Debug.LogWarning("lowEndChance is greater than highEndChance, swapping values.");
}
else if(lowEndChance == highEndChance)
{
highEndChance += 0.01f;
Debug.LogWarning("lowEndChance equals highEndChance");
}
this.entity = entity;
isDefault = false;
chanceRange[0] = lowEndChance;
chanceRange[1] = highEndChance;
}
public SpawnableObject(GameObject entity, float lowEndChance, float highEndChance, bool isDefault)
{
chanceRange = new float[2];
if(lowEndChance > highEndChance)
{
float placeholder;
placeholder = lowEndChance;
lowEndChance = highEndChance;
highEndChance = placeholder;
Debug.LogWarning("lowEndChance is greater than highEndChance, swapping values.");
}
else if(lowEndChance == highEndChance) Debug.LogWarning("lowEndChance equals highEndChance");
this.entity = entity;
this.isDefault = isDefault;
chanceRange[0] = lowEndChance;
chanceRange[1] = highEndChance;
}
[SerializeField] public GameObject entity;
[SerializeField] public float[] chanceRange;
[SerializeField] public bool isDefault;
}
Other details:
The problem persists after restarting unity.
The problem shows up when an array of the struct is shown in the
editor (It's ok for an individual one).
My editor version is 2021.3.3f1 LTS
Extra note for anyone experiencing this problem:
You can click on the 3 dots next to the script/component(when assigned to a GameObject) and click on "Properties...". This will open a menu where the UI is usable.
Not a good fix but at least allows you to use Unity.
Extra note again:
This only seems to happen with the element 0 of the array, so you can skip that buggy one and work starting from element 1, this time on the standard inspector.

how to cross out a certain text displayed on the screen?

In my game, there are certain objects that are tagged with "TargetObj", these objects have their names displayed on the screen like this:
GameObject[] targetObjects;
List<GameObject> targetObjectsList;
private TextMeshProUGUI mytext;
public TMP_FontAsset FontAssetA;
[SerializeField] GameObject TargetsCanvas;
void Start()
{
mainCamera = Camera.main;
targetObjects = GameObject.FindGameObjectsWithTag("TargetObj");
targetObjectsList = new List<GameObject>();
foreach (var obj in targetObjects)
{
mytext = CreateText(TargetsCanvas.transform);
mytext.text = "• " + obj.name;
mytext.font = FontAssetA;
}
}
static TextMeshProUGUI CreateText(Transform parent)
{
var go = new GameObject();
go.transform.parent = parent;
var text = go.AddComponent<TextMeshProUGUI>();
text.fontSize = 20;
return text;
}
They look like this:
The TargetsCanvas inspector:
Once the player picks up all tagged objects, he wins:
if (PickingUp)
{
if (currentlyPickedUpObject == null)
{
if (lookObject != null)
{
PickupObject();
if (lookObject.CompareTag("TargetObj") && !targetObjectsList.Contains(lookObject.gameObject))
{
if (aSource)
{
aSource.Play();
}
targetObjectsList.Add(lookObject.gameObject);
if (targetObjectsList.Count == targetObjects.Length)
{
winUI.SetActive(true);
Time.timeScale = 0f;
//SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
//Time.timeScale = 1f;
}
}
}
public void PickupObject()
{
physicsObject = lookObject.GetComponentInChildren<PhysicsObjects>();
currentlyPickedUpObject = lookObject;
pickupRB = currentlyPickedUpObject.GetComponent<Rigidbody>();
pickupRB.constraints = RigidbodyConstraints.FreezeRotation;
physicsObject.playerInteractions = this;
pickupRB.transform.parent = PickupParent.transform;
//StartCoroutine(physicsObject.PickUp());
}
I'm trying to cross out the name object on the screen once this object is picked up. I know that I can use this line to cross out a text:
mytext.fontStyle = FontStyles.Strikethrough;
but in my case, I don't know where exactly to use it to achieve what I want. any idea?
When using TextMeshPro Text, you can add a rich text tags to strikethrough any part of your string.
For example:
Make sure Rich Text is enabled under Extra Settings in your TMP Text Component
Use start tag <s> and end tag </s> to define where the strikethrough starts and ends
An example of setting this in code would be something like
public string textToStrike; //"Coffee Cup"
const string STRIKE_START = "<s>";
const string STRIKE_END = "</s>";
outputText = STRIKE_START + textToStrike + STRIKE_END;
Result outputText = Coffee Cup
You could even make a method that returns the inputted value as striked out if you wanted.
For example
private string StrikeText(string input)
{
string output = STRIKE_START + input + STRIKE_END;
return output;
}

Taking snapshots of a image in Unity

I am trying to take snapshots of materials I used in my application in Unity. I simply add a directional light and a camera and in a perspective mode. Then I render the result to a texture and save it as a .png file. The result is good but there is a strange gizmo like figure in the middle of image. Here it is :
Camera and light is far enough from the object. Also I disabled light to see if it is caused by directional light. But didn't solve. Anyone knows what cause this elliptic figure? Thanks in advance.
Edit. Here is the code
public static Texture2D CreateThumbnailFromMaterial(Material _material, string _name, string _path)
{
GameObject sphereObj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphereObj.name = _name;
sphereObj.GetComponent<Renderer>().material = _material;
Texture2D thumbnailTexture = CreateThumbnailFromModel(sphereObj, _path);
sphereObj.GetComponent<Renderer>().material = null;
Object.DestroyImmediate(sphereObj.gameObject);
return thumbnailTexture;
}
public static Texture2D CreateThumbnailFromModel(GameObject _gameObject, string _path)
{
Texture2D thumbnailTexture = new Texture2D(textureSize, textureSize);
thumbnailTexture.name = _gameObject.name.Simplify();
GameObject cameraObject = Object.Instantiate(Resources.Load("SceneComponent/SnapshotCamera") as GameObject);
Camera snapshotCamera = cameraObject.GetComponent<Camera>();
if (snapshotCamera)
{
GameObject sceneObject = GameObject.Instantiate(_gameObject) as GameObject;
sceneObject.transform.Reset();
sceneObject.transform.position = new Vector3(1000, 0, -1000);
sceneObject.hideFlags = HideFlags.HideAndDontSave;
// Create render texture
snapshotCamera.targetTexture = RenderTexture.GetTemporary(textureSize, textureSize, 24);
RenderTexture.active = snapshotCamera.targetTexture;
// Set layer
foreach (Transform child in sceneObject.GetComponentsInChildren<Transform>(true))
{
child.gameObject.layer = LayerMask.NameToLayer("ObjectSnapshot");
}
// Calculate bounding box
Bounds bounds = sceneObject.GetWorldSpaceAABB();
float maxBoundValue = 0f;
if (bounds.IsValid())
{
maxBoundValue = Mathf.Max(bounds.size.x, bounds.size.y, bounds.size.z);
}
double fov = Mathf.Deg2Rad * snapshotCamera.GetComponent<Camera>().fieldOfView;
float distanceToCenter = (maxBoundValue) / (float)System.Math.Tan(fov);
cameraObject.transform.LookAt(bounds.center);
cameraObject.transform.position = bounds.center - (snapshotCamera.transform.forward * distanceToCenter);
cameraObject.transform.SetParent(sceneObject.transform);
snapshotCamera.Render();
thumbnailTexture.ReadPixels(new Rect(0, 0, textureSize, textureSize), 0, 0);
thumbnailTexture.Apply();
sceneObject.transform.Reset();
snapshotCamera.transform.SetParent(null);
RenderTexture.active = null;
GameObject.DestroyImmediate(sceneObject);
GameObject.DestroyImmediate(cameraObject);
// Save as .png
IO.IOManager.Instance.SaveAsPNG(_path + thumbnailTexture.name, thumbnailTexture);
}
return thumbnailTexture;
}
And here is my camera properties

scaling issue on click event

I am developing a 2D game in Unity. I've created a character panel in that to let player select different character. In panel, there are thumbnails for different character. By tapping on a particular character thumbnail, the player can view that character. The original scale of thumbnail is 1, and when player taps on thumbnail, the scale get doubles. All is fine till this. but issue is that whenever player taps on thumbnail its scale gets double. But i want to limit it to once only. I've used flag to stop scaling, But still issue is there. After flag it stops scaling, but now player can click on multiple character simultaneously. I am copying snippet here.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class ViewCharacter : MonoBehaviour {
[SerializeField]
private GameObject TempCharacterHolder ,TempCharacter, TempCharacterText, TempCharacterPrice;
// Use this for initialization
void Start () {
for (int i = 0; i < ShoppingManager.instance.ShoppingList.Count; i++) {
if (i == TheGameController.instance.GetSelectedCharacter ()) {
PlayerPrefs.SetInt ("CharacterScaled" + i, 1);
} else {
PlayerPrefs.SetInt ("CharacterScaled" + i, 0);
}
}
}
public void ViewCharacterFunc()
{
int ClickedCharacter = int.Parse (TempCharacterText.GetComponent<Text> ().text);
foreach (var characters in ShoppingManager.instance.ShoppingList) {
if (string.Equals (characters.CharacterName, TempCharacterText.GetComponent<Text> ().text)) {
if (PlayerPrefs.GetInt("CharacterScaled"+characters.CharacterName)==0) {
ShoppingManager.instance.IncreaseScale (TempCharacter, TempCharacterHolder);
for (int i = 0; i < ShoppingManager.instance.ShoppingList.Count; i++) {
if (i == ClickedCharacter) {
PlayerPrefs.SetInt ("CharacterScaled" + i, 1);
} else {
PlayerPrefs.SetInt ("CharacterScaled" + i, 0);
}
}
}
} else {
Color clr = characters.Character_Holder.GetComponent<Image> ().color;
clr.a = 1;
characters.Character_Holder.GetComponent<Image> ().color = clr;
Vector3 TempVector = characters.CharaacterObject.GetComponent<RectTransform> ().localScale;
TempVector.x = 1f;
TempVector.y = 1f;
characters.CharaacterObject.GetComponent<RectTransform> ().localScale = TempVector;
}
}
}
}
If I understand your question correctly, your characters scale numerous times when you click on them instead of scaling once.
If that's the case, I'd suggest controlling that with a bool:
bool hasTouched = false;
void OnMouseDown()
{
ShoppingManager.instance.Message.SetActive (false);
foreach (var characters in ShoppingManager.instance.ShoppingList) {
Color clr = characters.Character_Holder.GetComponent<Image> ().color;
clr.a = 1;
characters.Character_Holder.GetComponent<Image> ().color = clr;
if (!hasTouched) //if we havent touched
{
Vector3 TempVector = characters.CharaacterObject.GetComponent<RectTransform> ().localScale*Time.deltaTime;
TempVector.x = 1.0f;
TempVector.y = 1.0f;
characters.CharaacterObject.GetComponent<RectTransform> ().localScale = TempVector;
hasTouched = true; //then we scale it, and we have touched it
}
}

Fit image on selection grid in unity

I want to scale and fit image to selection grid vertically and horizontally. I used an array texture2D to display images on selection grid.
This will be the result.
Code is here :
public Texture2D[] arr_texture2d_image;
private int sel_menu_int = 0;
void Start(){
arr_texture2d_image = new Texture2D[sel_menu_strs.Length];
for(int i = 0; i < sel_menu_strs.Length; i++){
WWW www = new WWW ("http://192.168.149.60/hmsx/api/" + sel_menu_strs[i]);
StartCoroutine (WaitForRequest(www,i));
}
IEnumerator WaitForRequest(WWW www,int i)
{
yield return www;
if (www.isDone == true) {
arr_texture2d_image[i] = www.texture as Texture2D;
www.Dispose();
}
}
}
void OnGUI(){
sel_menu_int = GUILayout.SelectionGrid (sel_menu_int, arr_texture2d_image, no_of_thumbs_x ,gui_skn.button);
}
I used this but nothing works.
Texture2D texTmp = new Texture2D(280, 160, TextureFormat.DXT1, false);
www.LoadImageIntoTexture(texTmp);
arr_texture2d_image[i] = texTmp;