Rename a member in Unity without losing the assignments in the Inspector

This is pretty simple when you have the right tag.

public GameObject m_foo;

To rename m_foo to m_bar without losing the assignments that have been set in a Unity scene, add the following on the line before the m_foo declaration: –

[FormerlySerializedAs(“m_foo”)]

Now rename m_foo to m_bar and go have a look at the scene in Unity. The member name is changed but the assignments aren’t lost.

Once you’ve been in to Unity and the scene has updated, it’s safe to delete the “[FormerlySerializedAs(“m_foo”)]” line as it’s not needed anymore.

Hope it helps!

Advertisement

ADB Quick Commands

I keep looking these up, so dropping them here so I don’t have to: –

This will echo all output from a Unity project; adb logcat Unity:V *:S

This will echo all output from a Unity project to a file; adb logcat Unity:V *:S -d >> output.txt

This will clear the log; adb logcat -c

This will increase the buffer size so you have more than a few seconds before your logs start to disappear; adb logcat -G 16M

Unity Build Failure, unable to update SDK

So, building on Android, I get the error; “Unity Build Failure, unable to update SDK”. The project I’m working on has been updated to a new SDK but Unity doesn’t have that SDK version installed

I used the SDK manager to update to the correct API but Unity didn’t see the change as Unity is looking at it’s ‘local’ version.

To solve this, you need to install to the specific Unity version that you’re using. Simple process; Open a CommandLine (CMD) as Administrator and type: –

“C:\Program Files\Unity\Hub\Editor\2019.3.11f1\Editor\Data\PlaybackEngines\AndroidPlayer\SDK\tools\bin\sdkmanager.bat” “platforms;android-29”

Obviously, you’ll need to adjust the Unity version and the Android SDK to what you need, but this does an in-place update of the Unity installed SDK.

Once you run that, Unity is happy again

Unity: Unsupported type vector

I got this error from Unity (2018.3.3f1) while I was working with a large script and changing data that was serialized into a scene.

Unsupported type Vector” was the error but it had no call stack and no explanation of where it came from.

The solution was to delete the component from the scene, save the scene and then re-open it and re-add the component. Sounds weird but I have verified that it solves the problem.

This is all that was shown in the output window: –

UnsupportedTypeVector

 

C#: World Space to Pixels

Piece of code to convert from world space size to pixel size. Handy if you need to fit something to a pixel sized displayed area in a UI.

All you need is to supply the size of the object in world space and the distance from the camera to the object.

private Vector2 GetSizeAtDepth(Vector2 a_size, float a_depth, Camera a_camera)
{
    float fov2 = a_camera.fieldOfView * Mathf.PI / 360.0f;
    float height = Mathf.Tan(fov2) * a_depth * 2.0f;

    float pixelHeight = (a_size.y / height) * Screen.height;
    float pixelWidth = (a_size.x / (height * a_camera.aspect)) * Screen.width;

    return new Vector2(pixelWidth, pixelHeight);
}

 

Call it with something like the code below and it’ll return pixel sizes using the current screen res.

float depth = 8.0f;
Vector2 res = GetSizeAtDepth(new Vector2(10.0f, 10.0f), depth, m_renderCamera);

Debug.Log("pixelWidth: " + res.x);
Debug.Log("pixelHeight: " + res.y);

 

So, this is passing in a 10 x 10 x/y as the world space size (size of a standard Unity plane).

The ‘depth’ is the distance from the camera to the object. As the object is a plane that’s facing the camera, we don’t need to find a specific depth within the object. i.e. if it was a sphere then we’d have to decide if we wanted depth to the front, middle or back.

m_renderCamera is just a standard Unity camera.

Obviously, this can easily be adapted to work without Unity but I’m using it to get something up and running quickly.

Hope it helps!

 

 

Unity: Is this point inside a box?

See if a point is inside a box by doing a reverse transform on the point into box local space.

bool PointInBox(Vector3 a_point, BoxCollider a_box)
{
    // Transform the point into box local space
    a_point = a_box.transform.InverseTransformPoint(a_point) - a_box.center;

    // see if the point is inside the box local space
    Vector3 half = a_box.size * 0.5f;
    if (a_point.x < half.x && a_point.x > -half.x &&
    a_point.y < half.y && a_point.y > -half.y &&
    a_point.z < half.z && a_point.z > -half.z)
    {
        // Get a 0.0 to 1.0 range for each axis
        Vector3 current = a_point + half;
        m_last.x = current.x / a_box.size.x;
        m_last.y = current.y / a_box.size.y;
        m_last.z = current.z / a_box.size.z;

        m_lastPoint = a_point; // Set the last valid point inside the test area
        return true;
    }
    return false;
}

 

Unity: Make a programmatically generated button event show up in the Inspector

So, when you add an event to a button using AddListener, the event doesn’t show up in the inspector so you can’t see what’s going to be triggered by the button. When looking at the button in Play mode you see something like this : –

Bad.PNG

Events need to show in the Inspector so you know what’s going on when you’re trying to figure out how code is being triggered. Below is a very simple example of how to do this:-

using UnityEditor.Events;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

public class ButtonTest : MonoBehaviour
{
  public Button m_button;

  void Start()
  {
    // This will work and WILL show in the Inspector
    UnityAction<GameObject> action = new UnityAction<GameObject>(this.OnClickEvent);
    UnityEventTools.AddObjectPersistentListener<GameObject>(m_button.onClick, action, this.gameObject);
  }

  /// Handle the button click event
  public void OnClickEvent(GameObject a_gameObject)
  {
    Debug.Log("Button Pressed");
  }
}

…and the result is as follows…

Good.PNG

Hope it helps!