Tip of the day

From Unify Community Wiki
Revision as of 09:50, 3 April 2015 by Createdbyx (Talk | contribs)

Jump to: navigation, search

Contents

April 2015

  • Tip #81 – Per-Camera Fog

The fallowing script allows you to control fog settings on a per camera basis, allowing you to use say green fog for one camera but red fog for another camera.

Unity 5 package demo is available here
CameraFog.unitypackage (46.66 kb)
File:CameraFog.zip
See related page CameraFog

CameraFogScreenShot.png

CameraFog.cs script code

 
    using UnityEngine;
 
    /// <summary>
    /// Modifies a camera to allows you to control the fog settings for that camera separately from the global scene fog or other cameras. 
    /// </summary>
    [RequireComponent(typeof(Camera))]
    [ExecuteInEditMode]
    public class CameraFog : MonoBehaviour
    {
        /// <summary>
        /// The enabled state weather or not fog will be visible.
        /// </summary>
        public bool Enabled;
 
        /// <summary>
        /// The start distance from the camera where the fog will be drawn.
        /// </summary>
        public float StartDistance;
 
        /// <summary>
        /// The end distance from the camera where the fog will be drawn.
        /// </summary>
        public float EndDistance;
 
        /// <summary>
        /// The fog mode that controls how the fog is rendered.
        /// </summary>
        public FogMode Mode;
 
        /// <summary>
        /// The density of the fog that is rendered.
        /// </summary>
        public float Density;
 
        /// <summary>
        /// The fog color.
        /// </summary>
        public Color Color;
 
        /// <summary>
        /// Stores the pre-render state of the start distance.
        /// </summary>
        private float _startDistance;
 
        /// <summary>
        /// Stores the pre-render state of the end  distance.
        /// </summary>
        private float _endDistance;
 
        /// <summary>
        /// Stores the pre-render state of the fog mode.
        /// </summary>
        private FogMode _mode;
 
        /// <summary>
        /// Stores the pre-render state of the density.
        /// </summary>
        private float _density;
 
        /// <summary>
        /// Stores the pre-render state of the fog color.
        /// </summary>
        private Color _color;
 
        /// <summary>
        /// Stores the pre-render state wheather or not the fog is enabled.
        /// </summary>
        private bool _enabled;
 
        /// <summary>
        /// Event that is fired before any camera starts rendering.
        /// </summary>
        private void OnPreRender()
        {
            this._startDistance = RenderSettings.fogStartDistance;
            this._endDistance = RenderSettings.fogEndDistance;
            this._mode = RenderSettings.fogMode;
            this._density = RenderSettings.fogDensity;
            this._color = RenderSettings.fogColor;
            this._enabled = RenderSettings.fog;
 
            RenderSettings.fog = this.Enabled;
            RenderSettings.fogStartDistance = this.StartDistance;
            RenderSettings.fogEndDistance = this.EndDistance;
            RenderSettings.fogMode = this.Mode;
            RenderSettings.fogDensity = this.Density;
            RenderSettings.fogColor = this.Color;
        }
 
        /// <summary>
        /// Event that is fired after any camera finishes rendering.
        /// </summary>
        private void OnPostRender()
        {
            RenderSettings.fog = this._enabled;
            RenderSettings.fogStartDistance = this._startDistance;
            RenderSettings.fogEndDistance = this._endDistance;
            RenderSettings.fogMode = this._mode;
            RenderSettings.fogDensity = this._density;
            RenderSettings.fogColor = this._color;
        }
    }
  • Tip #80 – Unity5 Material Reference Charts

The unity 5 documentation has a couple of handy reference charts/Info Graphics for when you need to help determining what material values to set to get a particular look and feel.

http://docs.unity3d.com/Manual/StandardShaderMaterialCharts.html

StandardShaderCalibrationChartMetallic.png StandardShaderCalibrationChartSpecular.png

March 2015

  • Tip #79 – Unity 5 Transform performance

With the introduction to Unity 5 there comes some api changes. Specifically this foot note was interesting “[2] in Unity5 we also cache the transform component on the c# side, so there should no longer be a performance reason to cache the transform component yourself.”

I decided to test it out by writing a few performance test scripts and comparing performance numbers. Below is a screen shot of my results along with the scripts used.

As you can see caching a reference to the transform component in the Start method then using that reference is still faster then calling “this.transform” directly albeit only slightly by about 10-20 ticks. And calling “this.GetComponent<Transform>()” is almost twice as slow.

Unity5GetComponentPerformanceTests.png

The code for the PerformanceTesting class is available here.

TransformCachedGetComponentPerformance script

 
    using UnityEngine;
 
    public class TransformCachedGetComponentPerformance : MonoBehaviour
    {
        private Transform reference;
 
        /// <summary>
        /// Awake is called when the script instance is being loaded.
        /// </summary>
        public void Awake()
        {
#if PERFORMANCE
            var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
            perf.Create("UnityTesting/TransformCachedGetComponentPerformance/Update");
#endif
        }
 
        /// <summary>
        /// Start is called just before any of the Update methods is called the first time.
        /// </summary>
        public void Start()
        {
            this.reference = this.GetComponent<Transform>();
        }
 
        /// <summary>
        /// Update is called every frame, if the MonoBehaviour is enabled.
        /// </summary>
        public void Update()
        {
#if PERFORMANCE
            var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
            perf.Start("UnityTesting/TransformCachedGetComponentPerformance/Update");     
#endif
 
            var rnd = new System.Random();
            this.reference.localPosition = new Vector3(rnd.Next(-3, 3), rnd.Next(-3, 3), rnd.Next(-3, 3));
 
#if PERFORMANCE
            perf.Stop("UnityTesting/TransformCachedGetComponentPerformance/Update");
#endif
        }
    }

TransformGetComponentPerformance script

 
    using UnityEngine;
 
    public class TransformGetComponentPerformance : MonoBehaviour
    {
        /// <summary>
        /// Awake is called when the script instance is being loaded.
        /// </summary>
        public void Awake()
        {
#if PERFORMANCE
            var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
            perf.Create("UnityTesting/TransformGetComponentPerformance/Update");
#endif
        }
 
        /// <summary>
        /// Update is called every frame, if the MonoBehaviour is enabled.
        /// </summary>
        public void Update()
        {
#if PERFORMANCE
            var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
            perf.Start("UnityTesting/TransformGetComponentPerformance/Update");
#endif
 
            var rnd = new System.Random();
            this.GetComponent<Transform>().localPosition = new Vector3(rnd.Next(-3, 3), rnd.Next(-3, 3), rnd.Next(-3, 3));
 
#if PERFORMANCE
            perf.Stop("UnityTesting/TransformGetComponentPerformance/Update");
#endif
        }
    }

TransformFieldPerformance script

 
    using UnityEngine;
 
    public class TransformFieldPerformance : MonoBehaviour
    {
        /// <summary>
        /// Awake is called when the script instance is being loaded.
        /// </summary>
        public void Awake()
        {
#if PERFORMANCE
            var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
            perf.Create("UnityTesting/TransformFieldPerformance/Update");
#endif
        }
 
        /// <summary>
        /// Update is called every frame, if the MonoBehaviour is enabled.
        /// </summary>
        public void Update()
        {
#if PERFORMANCE
            var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
            perf.Start("UnityTesting/TransformFieldPerformance/Update");
#endif
 
            var rnd = new System.Random();
            this.transform.localPosition = new Vector3(rnd.Next(-3, 3), rnd.Next(-3, 3), rnd.Next(-3, 3));
 
#if PERFORMANCE
            perf.Stop("UnityTesting/TransformFieldPerformance/Update");
#endif
        }
    }

December 2014

  • Tip #78 – Lock the mouse cursor to the screen

There are some instances when you may need to lock the mouse cursor to the screen. For example rotating the camera where you would press down on the right mouse button then drag the mouse to rotate the camera. If you wish to hide the mouse cursor and lock it to the screen while dragging you can use Screen.lockCursor.

 
using UnityEngine;
 
public class lockCursorExample : MonoBehaviour
{
    void DidLockCursor()
    {
        Debug.Log("Locking cursor");
    }
 
    void DidUnlockCursor()
    {
        Debug.Log("Unlocking cursor");
    }
 
    private bool wasLocked;
 
    void Update()
    {
        if (!Screen.lockCursor && this.wasLocked)
        {
            this.wasLocked = false;
            this.DidUnlockCursor();
        }
        else if (Screen.lockCursor && !this.wasLocked)
        {
            this.wasLocked = true;
            this.DidLockCursor();
        }
 
        if (Input.GetMouseButtonDown(1))
        {
            Screen.lockCursor = true;
        }
 
        if (Input.GetMouseButtonUp(1))
        {
            Screen.lockCursor = false;
        }
    }
}
  • Tip #77 – ToolTip Attribute for MonoBehaviour fields

Ever wish you could have a tool tip appear when hovering your mouse over a control in the inspector? Well look no further then Unity’s ToolTip attribute that you can apply to your MonoBehaviour’s fields!

 
using UnityEngine;
using System.Collections;
 
public class ExampleClass : MonoBehaviour {
    [Tooltip("Health value between 0 and 100.")]
    public int health = 0;
}

November 2014

  • Tip #76 – Don’t Destroy On Scene Load

Sometimes it is handy to keep a game object alive for as long as your game is running. In order to prevent your object from being destroyed when loading a new scene use GameObject.DontDestroyOnLoad and your game object will persist between scene changes.

  • Tip #75 – Get default Arial font at runtime using code

If you need to retrieve the default Arial font via code at run time you can do so using the Resources.GetBuiltInResource method.

 
var font = Resources.GetBuiltinResource(typeof(Font), "Arial.ttf") as Font;
  • Tip #74 – Change text field properties with GUISettings

If you need to stylize your gui you can use the GUISettings class to change, the cursor color, flash speed, the selection color for text fields, as well as double click behavior.

 
public class GuiSettingsExample : MonoBehaviour
{
    public Color cursorColor;    
    public float flashSpeed;     
    public bool doubleClickSelectWord;      
    public Color selectionColor;            
    public bool tripleCLickLine;            
    private string text = "test string";    
    private Vector2 scroll;                 
    public GUISkin skin;                    
 
    public void OnGUI()
    {
        GUI.skin = this.skin;
        var settings = GUI.skin.settings;
        settings.cursorColor = this.cursorColor;
        settings.cursorFlashSpeed = this.flashSpeed;
        settings.doubleClickSelectsWord = this.doubleClickSelectWord;
        settings.selectionColor = this.selectionColor;
        settings.tripleClickSelectsLine = this.tripleCLickLine;
 
 
        this.scroll = GUILayout.BeginScrollView(this.scroll, false, false, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
        this.text = GUILayout.TextArea(this.text);
        GUILayout.EndScrollView();
    }
}

May 2014

  • Tip #73 – GUI Matrix

Did you know that the GUI class has a matrix property that you can use to rotate and scale your gui elements.

The sample behaviour that is provided below will scale and rotate a gui label in the center of the screen.

 
public class GuiMatrixDemo : MonoBehaviour
{
    private float rotation;
 
    /// <summary>
    /// OnGUI is called for rendering and handling GUI events.
    /// </summary>
    public void OnGUI()
    {
        var matrix = GUI.matrix;
 
        GUI.Label(new Rect(5, 5, 100, 20), "before matrix");
 
        this.rotation += 15f * Time.deltaTime;
        var scale = Mathf.Clamp((float)Math.Sin(Time.time) + 1 * 2, 1, 3);
        GUI.matrix = Matrix4x4.TRS(new Vector3(Screen.width / 2, Screen.height / 2, 0), Quaternion.Euler(0, 0, this.rotation), Vector3.one * scale);
        var size = GUI.skin.label.CalcSize(new GUIContent("test string"));
        var rect = new Rect((-size.x / 2f), (-size.y / 2f), size.x, size.y);
        GUI.Label(rect, "test string");
        GUI.matrix = matrix;
        GUI.Label(new Rect(5, 25, 100, 20), "after matrix");
    }
}

Archived Years

Older Tips

  • When move a GameObject, hold the Key V,will fast align.
  • A skinned character updates its vertices every frame, even when not animating. To freeze a skinned character in place without making it disappear or revert to a T-pose, set its SkinnedMeshRenderer.bones field to null.
  • There are two really nice hotkeys to insert or delete array elements in the inspector. SHIFT + DEL will delete the selected element and CTRL + D will duplicate it. SHIFT is only needed for reference types like GameObject[].
  • When you're using Debug.Log or related methods, provide the instance of the script so you can click the log output and have the relevant object selected in editor! Debug.Log("Test", this);
  • If you're placing objects in the screen and want them to "snap" into place (great for placing items on the ground) you can hold the Command key (Control on Windows) while dragging the object's axis (snap increments are defined in Edit->Snap Settings)
  • Importing classes in JavaScript. Tired of writing Debug.Log and SendMessageOptions.DontRequireReceiver? Did you know that static members of classess and enums can be imported just like importing namespaces. Simply add import UnityEngine.Debug; and import UnityEngine.SendMessageOptions and then you can write Log("my log string") and SendMessage("ApplyDamage",2.0,DontRequireReceiver);.
  • Deleting objects. Use Command + Backspace in the Scene, Hierarchy and Project views to remove objects. In the Scene and Hierarchy views this will just remove the selected instance of the object. In the Project view this will remove the selected object file and put it in your system Trash.
  • If you need some textures, like font textures, to not be affected by Texture.masterTextureLimit, disable Generate Mip Maps in the texture's import settings. On the down side, this can adversely affect clarity of rendering at smaller scales.
  • Boo has some handy built-in functions like shell(), join() and reversed(). And the cool part? They are available from JavaScript as well.
  • Every built-in component in the inspector has a small question mark in the right of it's heading. That's the quickest way to open the context-help for that component. It's your friend.
  • To remember which color means what on an axis in Unity, just remember the mnemonic: RGB = XYZ.
  • You can use keyboard shortcuts for Edit->Load Selection and Edit->Save Selection to speed up the selection of commonly used parts in your scene.
  • If you option-click an object in your hierarchy, the entire hierarchy within it will expand and unexpand.
  • You can write Editor scripts to greatly reduce project-specific tedium when making something with Unity. These are just as easy to write as regular scripts, and can save you a lot of hassle. See the Wizard Archive for some examples.
  • If you have the problem when importing models that Vector3.up points in the wrong direction (or for any of the other directions), make the game model in question the child of a blank game object, and orient it correctly in local space.
  • When assigning properties of components in the Inspector, you can click on the triangle to pop up a menu of choices. Type in the name of the thing you want and press enter to assign it. This can be a speedy alternative to using drag-and-drop.
  • When entering text in the Inspector view, you can press option-return to get a new line. This is useful for writing multiline things with GUIText objects.
  • If you only have one editor view and no game views in the Unity pane set up, the editor view will be automatically replaced with a game view when you enter play mode and back again when you press stop. This is a nice feature when you are working on a small monitor.
  • Use Tags to assign your own categories and attributes to game objects. Then scripts can refer to the tags. Example: if (contact.otherCollider.tag == "Enemy") or GameObject.FindWithTag ("Enemy")
  • If you want to move a file inside of a project use Unity's project view to move it and not the Finder. This way all references and import settings of the file will be maintained.

Note: Place your new tip at the top of the list, not at the bottom.

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox