Default Values for Components

I hope this isn’t a stupid question, but…

Is there a way to alter the default values of Components? For example: I want to alter to RigidBody component so that it is automatically set to have no Gravity.

If its not possible to change the defaults, is there a way to save the settings in any way? or is it possible to change the values of a component that is placed on multiple objects?

Thanks

You can use a script with the Reset function to set up defaults:

function Reset () {
	rigidbody.useGravity = false;
}

@script RequireComponent(Rigidbody);

When you add that script to an object that doesn’t have a rigidbody, one will be added, and the gravity is turned off at the same time. If an object already has a rigidbody, adding the script will turn gravity off. Also gravity is turned off if you choose the Reset context menu item.

You can’t do that exactly since the unity components are final and do not let you use inheritance and extend their capabilities.

You can do one of 2 things:

  1. Use a prefab

    • Create a game object.
    • Attach the rigidbody component to it.
    • Create a prefab in the Project window (right click mouse → Create → Prefab).
    • Drag the game object you’ve created on to the prefab you created.
    • Change the settings of the rigidbody on the prefab (not on the game object!).
    • Drag as many instances of this prefab to the hierarchy pane to create game objects that are copy of the prefab.
    • Now each time you change the prefab - the change effects all the instances of it which you have created.
    • Note: each setting you change on a game object which is connected to a prefab (was created from it), will not effect the other objects or the prefab (although in the GameObject menu you can select “Apply changes to prefab” when you have such a game object selected in order to… Apply those settings to the Master prefab.
  2. Create a script that requires the component you wish to have defaults for and change the settings of the component you need during run time, like this (give a meaningful name to the script e.g. “RigidBodyExtended”)

    @script RequireComponent(Rigidbody)

    // Duplicate any setting you wish to be able to change in run time
    public var useGravity = false;

    private var rigidBody : Rigidbody;

    function Awake()
    {
    // Grap the reference to the rigidbody
    rigidBody = GetComponent(Rigidbody);

     // Now you can use your own setting
     rigidBody.useGravity = useGravity;
    

    }

You can use the hierarchyWindowChanged callback to detect when something in the hierarchy has been added (which includes components), then change the values on a newly-added component. You have to be careful not to change things that already existed, and you have to be careful not to screw up prefabs, but it’s doable.

Because I’m too lazy to not provide example code, example code:

using UnityEditor;
using UnityEngine;
using System;

[InitializeOnLoad]
public class DefaultSetter {
    static string m_LastScene;
    static Rigidbody[] m_LastSeenRigidbody;

    static void Autorun()
    {
        EditorApplication.hierarchyWindowChanged += ExampleCallback;
    }

    static void ExampleCallback ()
    {
        if (m_LastScene != EditorApplication.currentScene)
        {
            m_LastSeenRigidbody = Resources.FindObjectsOfTypeAll(typeof(Rigidbody)) as Rigidbody[];
            m_LastScene = EditorApplication.currentScene;
        }
        else
        {
            Rigidbody[] newRigidbody = Resources.FindObjectsOfTypeAll(typeof(Rigidbody)) as Rigidbody[];
            foreach (Rigidbody rigidbody in newRigidbody)
            {
                if (!Array.Exists(m_LastSeenRigidbody, element => element == rigidbody))
                {
                    if (PrefabUtility.GetPrefabObject(rigidbody) == null)
                    {
                        Debug.LogFormat("Setting default rigidbody constraints on new rigidbody {0}", rigidbody);
                        rigidbody.constraints = RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY;
                    }
                }
            }
            m_LastSeenRigidbody = newRigidbody;
        }
    }
}

That’s probably imperfect but it seems to work, for now; report any bugs and I’ll fix 'em.