// Unity C# reference source // Copyright (c) Unity Technologies. For terms of use, see // https://unity3d.com/legal/licenses/Unity_Reference_Only_License using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Collections; using System.Collections.Generic; using UnityEngineInternal; using UnityEngine.SceneManagement; using UnityEngine.Bindings; using UnityEngine.Scripting; using uei = UnityEngine.Internal; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; namespace UnityEngine { [ExcludeFromPreset] [UsedByNativeCode] [global::UnityEngine.NativeClass("GameObject", PersistentTypeId = 1)] [NativeHeader("Runtime/Export/Scripting/GameObject.bindings.h")] public sealed partial class GameObject : Object { [FreeFunction("GameObjectBindings::CreatePrimitive")] public extern static GameObject CreatePrimitive(PrimitiveType type); [System.Security.SecuritySafeCritical] public unsafe T GetComponent() { var component = GetComponentFastPath(typeof(T)); // Because there is no constraint on T, a user could pass a value type that is larger than a reference // If so we need to ensure that the ref we pass to UnsafeUtility.As is larger enough so we don't read // random stack data. In that case we can assume that component will null, so we will return a zero'd T var tuple = (component, default(T)); return UnsafeUtility.As(ref tuple.component); } [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] [FreeFunction(Name = "GameObjectBindings::GetComponentFromType", HasExplicitThis = true, ThrowsException = true)] public extern Component GetComponent(Type type); [FreeFunction(Name = "GameObjectBindings::GetComponentFastPath", HasExplicitThis = true, ThrowsException = true)] internal extern Component GetComponentFastPath(Type type); [FreeFunction(Name = "Scripting::GetScriptingWrapperOfComponentOfGameObject", HasExplicitThis = true)] internal extern Component GetComponentByName(string type); [FreeFunction(Name = "Scripting::GetScriptingWrapperOfComponentOfGameObjectWithCase", HasExplicitThis = true)] internal extern Component GetComponentByNameWithCase(string type, bool caseSensitive); public Component GetComponent(string type) { return GetComponentByName(type); } [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] [FreeFunction(Name = "GameObjectBindings::GetComponentInChildren", HasExplicitThis = true, ThrowsException = true)] public extern Component GetComponentInChildren(Type type, bool includeInactive); [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] public Component GetComponentInChildren(Type type) { return GetComponentInChildren(type, false); } [uei.ExcludeFromDocs] public T GetComponentInChildren() { bool includeInactive = false; return GetComponentInChildren(includeInactive); } public T GetComponentInChildren([uei.DefaultValue("false")] bool includeInactive) { return (T)(object)GetComponentInChildren(typeof(T), includeInactive); } [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] [FreeFunction(Name = "GameObjectBindings::GetComponentInParent", HasExplicitThis = true, ThrowsException = true)] public extern Component GetComponentInParent(Type type, bool includeInactive); [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] public Component GetComponentInParent(Type type) { return GetComponentInParent(type, false); } [uei.ExcludeFromDocs] public T GetComponentInParent() { bool includeInactive = false; return GetComponentInParent(includeInactive); } public T GetComponentInParent([uei.DefaultValue("false")] bool includeInactive) { return (T)(object)GetComponentInParent(typeof(T), includeInactive); } [FreeFunction(Name = "GameObjectBindings::GetComponentsInternal", HasExplicitThis = true, ThrowsException = true)] private extern System.Array GetComponentsInternal(Type type, bool useSearchTypeAsArrayReturnType, bool recursive, bool includeInactive, bool reverse, object resultList); private System.Array GetComponentsInternal(bool useSearchTypeAsArrayReturnType, bool recursive, bool includeInactive, bool reverse, [Out] List resultList) { // Use UnsafeUtility.As to cast the list to the appropriate type // This could be a problem if native code provides us a type that does not match return GetComponentsInternal(typeof(T), useSearchTypeAsArrayReturnType, recursive, includeInactive, reverse, UnsafeUtility.As>(resultList)); } public Component[] GetComponents(Type type) { return (Component[])GetComponentsInternal(type, false, false, true, false, null); } public T[] GetComponents() { return (T[])GetComponentsInternal(true, false, true, false, null); } public void GetComponents(Type type, List results) { GetComponentsInternal(type, false, false, true, false, results); } public void GetComponents(List results) { GetComponentsInternal(true, false, true, false, results); } [uei.ExcludeFromDocs] public Component[] GetComponentsInChildren(Type type) { bool includeInactive = false; return GetComponentsInChildren(type, includeInactive); } public Component[] GetComponentsInChildren(Type type, [uei.DefaultValue("false")] bool includeInactive) { return (Component[])GetComponentsInternal(type, false, true, includeInactive, false, null); } public T[] GetComponentsInChildren(bool includeInactive) { return (T[])GetComponentsInternal(true, true, includeInactive, false, null); } public void GetComponentsInChildren(bool includeInactive, List results) { GetComponentsInternal(true, true, includeInactive, false, results); } public T[] GetComponentsInChildren() { return GetComponentsInChildren(false); } public void GetComponentsInChildren(List results) { GetComponentsInChildren(false, results); } [uei.ExcludeFromDocs] public Component[] GetComponentsInParent(Type type) { bool includeInactive = false; return GetComponentsInParent(type, includeInactive); } public Component[] GetComponentsInParent(Type type, [uei.DefaultValue("false")] bool includeInactive) { return (Component[])GetComponentsInternal(type, false, true, includeInactive, true, null); } public void GetComponentsInParent(bool includeInactive, List results) { GetComponentsInternal(true, true, includeInactive, true, results); } public T[] GetComponentsInParent(bool includeInactive) { return (T[])GetComponentsInternal(true, true, includeInactive, true, null); } public T[] GetComponentsInParent() { return GetComponentsInParent(false); } [System.Security.SecuritySafeCritical] public unsafe bool TryGetComponent(out T component) { var componentFound = TryGetComponentFastPath(typeof(T)); // Because there is no constraint on T, a user could pass a value type that is larger than a reference // If so we need to ensure that the ref we pass to UnsafeUtility.As is larger enough so we don't read // random stack data. In that case we can assume that component will null, so we will return a zero'd T var tuple = (componentFound, default(T)); component = UnsafeUtility.As(ref tuple.componentFound); return component != null; } public bool TryGetComponent(Type type, out Component component) { component = TryGetComponentInternal(type); return component != null; } [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] [FreeFunction(Name = "GameObjectBindings::TryGetComponentFromType", HasExplicitThis = true, ThrowsException = true)] internal extern Component TryGetComponentInternal(Type type); [FreeFunction(Name = "GameObjectBindings::TryGetComponentFastPath", HasExplicitThis = true, ThrowsException = true)] internal extern Component TryGetComponentFastPath(Type type); public static GameObject FindWithTag(string tag) { return FindGameObjectWithTag(tag); } [FreeFunction(Name = "GameObjectBindings::FindGameObjectsWithTagForListInternal", ThrowsException = true)] private static extern void FindGameObjectsWithTagForListInternal(string tag, [Out, NotNull] List results); public static void FindGameObjectsWithTag(string tag, List results) { FindGameObjectsWithTagForListInternal(tag, results); } public void SendMessageUpwards(string methodName, SendMessageOptions options) { SendMessageUpwards(methodName, null, options); } public void SendMessage(string methodName, SendMessageOptions options) { SendMessage(methodName, null, options); } public void BroadcastMessage(string methodName, SendMessageOptions options) { BroadcastMessage(methodName, null, options); } [FreeFunction(Name = "MonoAddComponent", HasExplicitThis = true)] internal extern Component AddComponentInternal(string className); [FreeFunction(Name = "MonoAddComponentWithType", HasExplicitThis = true)] private extern Component Internal_AddComponentWithType(Type componentType); [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] public Component AddComponent(Type componentType) { return Internal_AddComponentWithType(componentType); } public T AddComponent() where T : Component { return AddComponent(typeof(T)) as T; } public extern int GetComponentCount(); [NativeName("QueryComponentAtIndex")] internal extern Component QueryComponentAtIndex(int index); public Component GetComponentAtIndex(int index) { if (index < 0 || index >= GetComponentCount()) throw new ArgumentOutOfRangeException(nameof(index), "Valid range is 0 to GetComponentCount() - 1."); return QueryComponentAtIndex(index); } public T GetComponentAtIndex(int index) where T : Component { T component = (T)GetComponentAtIndex(index); if(component == null) throw new InvalidCastException(); return component; } public extern int GetComponentIndex(Component component); public extern Transform transform { [FreeFunction("GameObjectBindings::GetTransform", HasExplicitThis = true)] get; } public extern TransformHandle transformHandle { [FreeFunction("GameObjectBindings::GetTransformHandle", HasExplicitThis = true)] get; } public extern int layer { get; set; } [NativeMethod(Name = "SetSelfActive")] public extern void SetActive(bool value); public extern bool activeSelf { [NativeMethod(Name = "IsSelfActive")] get; } public extern bool activeInHierarchy { [NativeMethod(Name = "IsActive")] get; } public extern bool isStatic { [NativeMethod(Name = "GetIsStaticDeprecated")] get; [NativeMethod(Name = "SetIsStaticDeprecated")] set; } internal extern bool isStaticBatchable { [NativeMethod(Name = "IsStaticBatchable")] get; } public extern string tag { [FreeFunction("GameObjectBindings::GetTag", HasExplicitThis = true)] get; [FreeFunction("GameObjectBindings::SetTag", HasExplicitThis = true)] set; } public bool CompareTag(string tag) => CompareTag_Internal(tag); public bool CompareTag(TagHandle tag) => CompareTagHandle_Internal(tag); [FreeFunction(Name = "GameObjectBindings::CompareTag", HasExplicitThis = true)] private extern bool CompareTag_Internal(string tag); [FreeFunction(Name = "GameObjectBindings::CompareTagHandle", HasExplicitThis = true)] private extern bool CompareTagHandle_Internal(TagHandle tag); [FreeFunction(Name = "GameObjectBindings::FindGameObjectWithTag", ThrowsException = true)] public static extern GameObject FindGameObjectWithTag(string tag); [FreeFunction(Name = "GameObjectBindings::FindGameObjectsWithTag", ThrowsException = true)] public static extern GameObject[] FindGameObjectsWithTag(string tag); [FreeFunction(Name = "Scripting::SendScriptingMessageUpwards", HasExplicitThis = true)] extern public void SendMessageUpwards(string methodName, [uei.DefaultValue("null")] object value, [uei.DefaultValue("SendMessageOptions.RequireReceiver")] SendMessageOptions options); [uei.ExcludeFromDocs] public void SendMessageUpwards(string methodName, object value) { SendMessageOptions options = SendMessageOptions.RequireReceiver; SendMessageUpwards(methodName, value, options); } [uei.ExcludeFromDocs] public void SendMessageUpwards(string methodName) { SendMessageOptions options = SendMessageOptions.RequireReceiver; object value = null; SendMessageUpwards(methodName, value, options); } [FreeFunction(Name = "Scripting::SendScriptingMessage", HasExplicitThis = true)] extern public void SendMessage(string methodName, [uei.DefaultValue("null")] object value, [uei.DefaultValue("SendMessageOptions.RequireReceiver")] SendMessageOptions options); [uei.ExcludeFromDocs] public void SendMessage(string methodName, object value) { SendMessageOptions options = SendMessageOptions.RequireReceiver; SendMessage(methodName, value, options); } [uei.ExcludeFromDocs] public void SendMessage(string methodName) { SendMessageOptions options = SendMessageOptions.RequireReceiver; object value = null; SendMessage(methodName, value, options); } [FreeFunction(Name = "Scripting::BroadcastScriptingMessage", HasExplicitThis = true)] extern public void BroadcastMessage(string methodName, [uei.DefaultValue("null")] object parameter, [uei.DefaultValue("SendMessageOptions.RequireReceiver")] SendMessageOptions options); [uei.ExcludeFromDocs] public void BroadcastMessage(string methodName, object parameter) { SendMessageOptions options = SendMessageOptions.RequireReceiver; BroadcastMessage(methodName, parameter, options); } [uei.ExcludeFromDocs] public void BroadcastMessage(string methodName) { SendMessageOptions options = SendMessageOptions.RequireReceiver; object parameter = null; BroadcastMessage(methodName, parameter, options); } public GameObject(string name) { Internal_CreateGameObject(this, name); } public GameObject() { Internal_CreateGameObject(this, null); } public GameObject(string name, params Type[] components) { Internal_CreateGameObject(this, name); foreach (Type t in components) AddComponent(t); } [FreeFunction(Name = "GameObjectBindings::Internal_CreateGameObject")] static extern void Internal_CreateGameObject([Writable] GameObject self, string name); [FreeFunction(Name = "GameObjectBindings::Find")] public static extern GameObject Find(string name); [FreeFunction(Name = "GameObjectBindings::SetGameObjectsActiveByInstanceID")] extern private static void SetGameObjectsActive(IntPtr instanceIds, int instanceCount, bool active); [Obsolete("Obsolete. Please use GameObject.SetGameObjectsActive(NativeArray, bool) instead.", true)] public static unsafe void SetGameObjectsActive(NativeArray instanceIDs, bool active) => throw new NotImplementedException("Please use SetGameObjectsActive(NativeArray, bool) instead."); public static unsafe void SetGameObjectsActive(NativeArray entityIds, bool active) { if (!entityIds.IsCreated) throw new ArgumentException("NativeArray is uninitialized", nameof(entityIds)); if (entityIds.Length == 0) return; SetGameObjectsActive((IntPtr)entityIds.GetUnsafeReadOnlyPtr(), entityIds.Length, active); } [Obsolete("Obsolete. Please use GameObject.SetGameObjectsActive(ReadOnlySpan, bool) instead.", true)] public static unsafe void SetGameObjectsActive(ReadOnlySpan instanceIDs, bool active) => throw new NotImplementedException("Deprecated. Please use SetGameObjectsActive(ReadOnlySpan, bool) instead."); public static unsafe void SetGameObjectsActive(ReadOnlySpan entityIds, bool active) { if (entityIds.Length == 0) return; fixed (EntityId* instanceIDsPtr = entityIds) { SetGameObjectsActive((IntPtr)instanceIDsPtr, entityIds.Length, active); } } [FreeFunction("GameObjectBindings::InstantiateGameObjectsByInstanceID")] extern private static void InstantiateGameObjects(EntityId sourceInstanceID, IntPtr newInstanceIDs, IntPtr newTransformInstanceIDs, int count, Scene destinationScene); [Obsolete("Obsolete. Please use GameObject.InstantiateGameObjects(EntityId, int, NativeArray, NativeArray, Scene) instead.", true)] public static unsafe void InstantiateGameObjects(int sourceInstanceID, int count, NativeArray newInstanceIDs, NativeArray newTransformInstanceIDs, Scene destinationScene = default) => throw new NotImplementedException("Deprecated. Please use GameObject.InstantiateGameObjects(EntityId, int, NativeArray, NativeArray, Scene) instead."); public static unsafe void InstantiateGameObjects(EntityId sourceEntityId, int count, NativeArray newEntityIds, NativeArray newTransformEntityIds, Scene destinationScene = default) { if (!newEntityIds.IsCreated) throw new ArgumentException("NativeArray is uninitialized", nameof(newEntityIds)); if (!newTransformEntityIds.IsCreated) throw new ArgumentException("NativeArray is uninitialized", nameof(newTransformEntityIds)); if (count == 0) return; if ((count != newEntityIds.Length) || (count != newTransformEntityIds.Length)) throw new ArgumentException("Size mismatch! Both arrays must already be the size of count."); InstantiateGameObjects(sourceEntityId, (IntPtr)newEntityIds.GetUnsafeReadOnlyPtr(), (IntPtr)newTransformEntityIds.GetUnsafeReadOnlyPtr(), newEntityIds.Length, destinationScene); } [FreeFunction(Name = "GameObjectBindings::GetSceneByEntityId")] static extern Scene GetSceneInternal(EntityId entityId); public static Scene GetScene(EntityId entityId) => GetSceneInternal(entityId); public extern Scene scene { [FreeFunction("GameObjectBindings::GetScene", HasExplicitThis = true)] get; } public extern ulong sceneCullingMask { [FreeFunction(Name = "GameObjectBindings::GetSceneCullingMask", HasExplicitThis = true)] get; } [FreeFunction(Name = "GameObjectBindings::CalculateBounds", HasExplicitThis = true)] internal extern Bounds CalculateBounds(); internal extern int IsMarkedVisible(); public GameObject gameObject { get { return this; } } public extern bool IsDestroying(); } }