unity – Get and destroy gameobject component of same type

I want to destroy any graphic component on a gameobject , example is image,raw image, sprite , ect .But i don’t have the list of all graphic component so i don’t know how to loop through it . The reason is because i want to replace the component with the same type , for example i want to add Text component , but i can’t add it if there is already graphic component attached in the gameobject because there can only be one graphic component in a gameobject , so i need to destroy the graphic component first , how do i do it ?

I personally prefer the answer on c# but any programming language is accepted !

unity – Some submeshes of my gameobject dissapear when I set the bindposes

Well, I’m trying to animate some Source models imported into Unity3D using this Unity-Source-Tools library:

https://github.com/lewa-j/Unity-Source-Tools

To animate a Mesh generated by this tool I need to create a SkinnedMeshRenderer replacing the MeshRenderer and the MeshFilter components, so I created this method:

    private static void ReplaceRenderer(this GameObject obj, SourceStudioModelv2 model)
    {
        if (obj.GetComponent<SkinnedMeshRenderer>() != null)
            return;

        var mesh = Object.Instantiate(obj.GetComponent<MeshFilter>().sharedMesh);

        const bool debugPoses = true;
        const bool useNativePoses = true;

        var nativeBuilder = debugPoses ? new StringBuilder($"Native Matrixn{new string('=', 10)}n") : null;
        var unityBuilder = debugPoses ? new StringBuilder($"Unity Matrixn{new string('=', 10)}n") : null;

        var nativeMatrix = model.GetBindPosesFromModel(nativeBuilder).ToArray();
        var unityMatrix = obj.transform.GetBindPoses(model.Bones, unityBuilder).ToArray();

        if (debugPoses)
        {
            Debug.Log(nativeBuilder.ToString());
            Debug.Log(unityBuilder.ToString());
        }

        var matrix = useNativePoses
            ? nativeMatrix
            : unityMatrix;

        mesh.bindposes = matrix;

        Object.Destroy(obj.GetComponent<MeshFilter>());
        Object.Destroy(obj.GetComponent<MeshRenderer>());

        var skinned = obj.AddComponent<SkinnedMeshRenderer>();

        skinned.sharedMesh = mesh;
        skinned.rootBone = obj.transform;
        skinned.bones = model.Bones;
    }

As you can see, I’m creating two bind poses, because one of them is created from this part of the code: https://github.com/lewa-j/Unity-Source-Tools/blob/c5469deb1d630c1582c940ff3cdb0f69fc55eda3/Assets/Code/Read/SourceStudioModel.cs#L724-L728

And this is how I create the bindposes:

Native Poses

    private static IEnumerable<Matrix4x4> GetBindPosesFromModel(this SourceStudioModelv2 model, StringBuilder sb = null)
    {
        for (var i = 0; i < model.MdlBones.Length; i++)
        {
            var mdlBone = model.MdlBones(i);
            // From: https://stackoverflow.com/a/49268287/3286975
            var matrix = (new Matrix4x4(
                new Vector4(mdlBone.PoseToBone(0), mdlBone.PoseToBone(1), mdlBone.PoseToBone(2),
                    mdlBone.PoseToBone(3)),
                new Vector4(mdlBone.PoseToBone(4), mdlBone.PoseToBone(5), mdlBone.PoseToBone(6),
                    mdlBone.PoseToBone(7)),
                new Vector4(mdlBone.PoseToBone(8), mdlBone.PoseToBone(9), mdlBone.PoseToBone(10),
                    mdlBone.PoseToBone(11)),
                new Vector4(0, 0, 0, 1)
            )).transpose;
            sb?.AppendLine($"{i}: {matrix.ToString("F2")}");
            yield return matrix;
        }
    }

Unity Poses

    private static IEnumerable<Matrix4x4> GetBindPoses(this Transform transform, Transform() bones, StringBuilder sb = null)
    {
        for (var i = 0; i < bones.Length; i++)
        {
            var bone = bones(i);
            var matrix = bone.worldToLocalMatrix * transform.localToWorldMatrix;
            sb?.AppendLine($"{i}: {matrix.ToString("F2")}");
            yield return matrix;
        }
    }

And these are the values that each of them gives to me:

Unity Bindposes

https://pastebin.com/9tybGq7Z

And this is the result:

...

Native Bindposes

https://pastebin.com/YRZVq04y

But this one doesn’t show anything.


I saw this reference on internet: https://hg.alliedmods.net/hl2sdks/hl2sdk/file/4966093d3274/utils/studiomdl/simplify.cpp#l3745

But I’m not sure if I’ll be able to transcript this into Unity and if it will be useful…

If you would like to test this model out I created a *.unitypackage file for you to test:

https://mega.nz/file/xKpRSYwJ#j3ckM3GyFDFZKI6Y-OvN2cmcGC_GudGe2finLRQoA4U

...

So I don’t know how to proceed in this case, could anybody help me out with this?

c# – Unity TextMeshPro bounds.size is wrong when hovering first time over gameobject

I have this weird issue, which I am not able to fix. This is my third attempt and I need some help. Basically I have a hover element which spawns when I hover over a gameobject. The height of the element is determined by the amount of text (TextMeshProUGUI).

The issue happens only when I hover first time, also not always (I have no clue how to reliably to reproduce it).

Here is what happens (sec 10~):

I have tried to add these everywhere and different combinations:

LayoutRebuilder.ForceRebuildLayoutImmediate(hoverElementRect);
hoverElementRect.ForceUpdateRectTransforms();
Canvas.ForceUpdateCanvases();
txtMeshPro.ForceMeshUpdate();

They dont seem to help. I assume the problem is here:

float bgHeight = txtMeshPro.bounds.size.y + 25;

The bounds.size.y is wrong the first time I hover, but I have no clue why.

Here is the whole code for spawning the GUI element:

public static void SpawnGeneralHoverElement(string descText, RectTransform hoverOverRect, float guiWidth) {
    Canvas hoverCanvas = instance.hoverElementGeneral.GetComponent<Canvas>();
    EnableCanvas(hoverCanvas);

    TextMeshProUGUI txtMeshPro = hoverCanvas.GetComponentInChildren<TextMeshProUGUI>();
    RectTransform hoverElementRect = hoverCanvas.GetComponentsInChildren<RectTransform>()(1);

    float scale = hoverCanvas.GetComponent<RectTransform>().localScale.x;

    txtMeshPro.text = descText;

    // Need this to be dynamic, if I change hover element size, it will still work
    float hoverElementWidth = guiWidth;

    // Forces canvas update because of: stackoverflow.com/questions/55417905/why-is-textmeshpro-not-updating-textbounds-after-setting-text
    Canvas.ForceUpdateCanvases();
    LayoutRebuilder.ForceRebuildLayoutImmediate(hoverElementRect);
    hoverElementRect.ForceUpdateRectTransforms();
    txtMeshPro.ForceMeshUpdate();

    // Need this because otherwise the element spawns too far away on smaller resultions
    float spawnOffset = (txtMeshPro.bounds.size.y * hoverCanvas.GetComponent<RectTransform>().localScale.x) + (Screen.height * 0.022f);

    float bgHeight = txtMeshPro.bounds.size.y + 25;

    hoverElementRect.position = new Vector3(hoverOverRect.position.x, hoverOverRect.position.y + spawnOffset,
        hoverOverRect.position.z);

    hoverElementRect.sizeDelta = new Vector2(guiWidth, bgHeight);
    Debug.Log(hoverElementRect.sizeDelta);

    LayoutRebuilder.ForceRebuildLayoutImmediate(hoverElementRect);
    hoverElementRect.ForceUpdateRectTransforms();
    Canvas.ForceUpdateCanvases();
    txtMeshPro.ForceMeshUpdate();

    // Slide in form left to right if off bounds, need for traps for example
    float leftOffset = hoverElementRect.position.x - ((hoverElementRect.sizeDelta.x * scale) / 2);
    if (leftOffset < 0) {
        hoverElementRect.position = new Vector2(hoverElementRect.position.x + (leftOffset * -1) + 15, hoverElementRect.position.y);
    }

    // Slide in form right to left if off bounds, need for traps for example
    float rightOffset = Screen.width - (hoverElementRect.position.x + ((hoverElementRect.sizeDelta.x * scale) / 2));
    //Debug.Log("Screen width: " + Screen.width + "nrightOffset: " + rightOffset);
    if (rightOffset < 0) {
        hoverElementRect.position = new Vector2(hoverElementRect.position.x - (rightOffset * -1) - 15, hoverElementRect.position.y);
    }

    LayoutRebuilder.ForceRebuildLayoutImmediate(hoverElementRect);
    hoverElementRect.ForceUpdateRectTransforms();
    Canvas.ForceUpdateCanvases();
    txtMeshPro.ForceMeshUpdate();

}

How ot Iterate thru entire Dictionary of GameObject and setActive state [closed]

How can I iterate thru my entire Dictionary and set all the game objects to setActive(false)?

static Dictionary<string, GameObject> gameObjects;

Thanks!

unity – How can I access a GameObject variable in mono script from editor script?

In the mono script :

using UnityEngine;

public class TileTest : MonoBehaviour
{
    public GameObject prefabPathOnTerrain;

Then in the editor script at the top :

private SerializedProperty prefabPathOnTerrain;

Then inside OnEnable()

private void OnEnable()
    {
        prefabPathOnTerrain = serializedObject.FindProperty("prefabPathOnTerrain");
    }

And then inside a method I want to use it as a GameObject :
And instead using CreatePrimitive to use Instantiate :
But doing :

GameObject go = Instantiate(prefabPathOnTerrain);

Will not work.

public void TerrainObjects(GameObject gameobject)
    {
        Terrain terrain = Terrain.activeTerrain;
        var cube = GameObject.Find(string.Format("Terrain_{0}_{1}", gameobject.transform.localPosition.x, gameobject.transform.localPosition.y));
        if (cube != null)
            return;

        if (cube == null)
        {
              GameObject go = Instantiate(prefabPathOnTerrain);              

            //cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
        }

        cube.transform.localPosition = new Vector3(terrain.transform.localPosition.x + gameobject.transform.localPosition.x, 0, terrain.transform.localPosition.z + gameobject.transform.localPosition.y);
        cube.transform.localScale = new Vector3(gameobject.transform.localScale.x, gameobject.transform.localScale.y, 1);
        cube.transform.parent = GameObject.Find("Terrain Map").transform;

        cube.name = string.Format("Terrain_{0}_{1}", gameobject.transform.localPosition.x, gameobject.transform.localPosition.y);
        cube.tag = "Terrain Map";
    }

unity – How do I rotate a gameobject towards a point in world space?

I wanted to create a very simply turret.
This turret should aim at the point on the screen where the mouse pointer is currently located.

I have added a cube to serve as a very simple turret in my scene.
To visualize its aiming direction, I’m drawing a ray from it.

enter image description here

To rotate the “turret” to the mouse pointer position, I have created a script and added it to the “turret” gameobject:

void Update()
{
    var mousePos = Input.mousePosition;
    mousePos += Camera.main.transform.forward * 10f; // Make sure to add some "depth" to the screen point 
    var aim = Camera.main.ScreenToWorldPoint(mousePos);

    transform.LookAt(aim);

    RaycastHit hit;

    int layerMask = 1 << 8;
    layerMask = ~layerMask;

    Color color;
    if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity, layerMask))
    {
        color = Color.green;

    }
    else
    {
        color = Color.red;
    }

    Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * 10000, color);
}

However, there must be something wrong in my code.

In this screenshot, I have added a red arrow that points to the position of the mouse pointer:

enter image description here

The mouse pointer is over that orange tool. However, the turret is rotated towards the floor while it should be rotated upwards to the orange tool.

I do believe that my turret is well positioned (the blue arrow points forward):
enter image description here

How do I change my code so that it aims correctly, and what is my mistake?

I guess the problem is in these 2 lines, but I don’t see what’s wrong about it:

    mousePos += Camera.main.transform.forward * 10f; // Make sure to add some "depth" to the screen point 
    var aim = Camera.main.ScreenToWorldPoint(mousePos);

Thank you.

unity – GameObject LookAt not aligning properly

I have a celestial sphere with a plane in the centre and spheres (stars) aligned around the centre with a fixed radius.

Celestial Sphere Screenshot

In order to show the stars visible from a certain latitude and longitude from Earth, I need to rotate the plane accordingly.

To rotate the plane properly, I converted the latitude and longitude into 3D vectors, then utilised the LookAt() method to point the plane at this vector.

The following is the code which calculated the vectors from the coordinates, and utilises the LookAt() Method:

public void positionLand(double latitude, double longitude)
{
    Vector3 markerPositioning = new Vector3();
    markerPositioning.x = (float)-((math.cos(latitude)) * (math.cos(longitude)));
    markerPositioning.y = (float)((math.cos(latitude)) * (math.sin(longitude)));
    markerPositioning.z = (float)((math.sin(latitude)));

    groundPlane.transform.LookAt(markerPositioning);
}

To test if this would work, I used the coordinates of London, UK, latitude: 51.509865 and longitude: -0.118092. And this was the result:

London coordinates LookAt

As you can see, the plane is not properly rotating. Initially, I thought maybe the LookAt() method is using the incorrect forward vector of the plane gameobject, but this isn’t the case as there is no connection between the way the plane rotated and the coordinates of London.

What am I doing wrong and how can I fix this?

unity – How to check what part of an gameobject is seen by a camera?

Could anyone please give me a hint on how to determine how much of an object is seen by a camera. There have to be a threshold value (e.g. 30% of an object is seen). If value is below the threshold then I don’t cast rays otherwise I will do.
Now I am using WorldToViewPoint-function w.r.t. center of an object, but it doesn’t working properly in my view.

How to reset a gameobject to it’s prefab condition?

I have a GameObject with a ragdoll in it. Gameobject comes from a prefab which is pooled. So whenever the enemy is killed it’s disabled then enabled when spawn.

Problem is that the ragdoll settings and it’s condition cannot be reset by enabling. i.e. enemy stays dead even though respawned.
Is there a way to easily reset a GameObject to prefab state?

Solution online is to keep all the transforms and re-apply them by code. Is this the only way?

unit – Move gameObject in the opposite direction

I have the following four gameObjects objects, they have rotations, respectively: -90, 0, 90, 180. I want them to move as shown in the image below

enter description of image here


Here's what I've gotten so far:

public class Projecttile : MonoBehaviour
{
    public float speed;

    private void Update()
    {
        transform.Translate(transform.up * speed * Time.deltaTime);
    }
}

The result of my code is as follows: enter description of image here

Why does my code lead to this result, and how can I move each gameObject in the direction it faces?