// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using System; namespace FlaxEngine { partial class Actor { /// /// Returns true if object is fully static on the scene, otherwise false. /// [Unmanaged] [Tooltip("Returns true if object is fully static on the scene, otherwise false.")] public bool IsStatic => StaticFlags == StaticFlags.FullyStatic; /// /// Returns true if object has static transform. /// [Unmanaged] [Tooltip("Returns true if object has static transform.")] public bool IsTransformStatic => (StaticFlags & StaticFlags.Transform) == StaticFlags.Transform; /// /// Adds the actor static flags. /// /// The flags to add. [Unmanaged] [Tooltip("Adds the actor static flags.")] public void AddStaticFlags(StaticFlags flags) { StaticFlags |= flags; } /// /// Removes the actor static flags. /// /// The flags to remove. [Unmanaged] [Tooltip("Removes the actor static flags.")] public void RemoveStaticFlags(StaticFlags flags) { StaticFlags &= ~flags; } /// /// Sets a single static flag to the desire value. /// /// The flag to change. /// The target value of the flag. [Unmanaged] [Tooltip("Sets a single static flag to the desire value.")] public void SetStaticFlag(StaticFlags flag, bool value) { StaticFlags = StaticFlags & ~flag | (value ? flag : StaticFlags.None); } /// /// Returns true if object has given flag(s) set. /// /// The flag(s) to check. /// True if has flag(s) set, otherwise false. [Unmanaged] [Tooltip("Returns true if object has given flag(s) set.")] public bool HasStaticFlag(StaticFlags flag) { return (StaticFlags & flag) == flag; } /// /// The rotation as Euler angles in degrees. /// /// /// The x, y, and z angles represent a rotation z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis (in that order). /// Angles order (xyz): pitch, yaw and roll. /// [HideInEditor, NoSerialize, NoAnimate] public Float3 EulerAngles { get => Orientation.EulerAngles; set { Quaternion.Euler(ref value, out var orientation); Internal_SetOrientation(__unmanagedPtr, ref orientation); } } /// /// The local rotation as Euler angles in degrees. /// /// /// The x, y, and z angles represent a rotation z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis (in that order). /// Angles order (xyz): pitch, yaw and roll. /// [HideInEditor, NoSerialize, NoAnimate] public Float3 LocalEulerAngles { get => LocalOrientation.EulerAngles; set { Quaternion.Euler(ref value, out var orientation); Internal_SetLocalOrientation(__unmanagedPtr, ref orientation); } } /// /// Returns true if actor has any children /// [HideInEditor, NoSerialize] public bool HasChildren => Internal_GetChildrenCount(__unmanagedPtr) != 0; /// /// Resets actor local transform. /// public void ResetLocalTransform() { LocalTransform = Transform.Identity; } /// /// Creates a new child actor of the given type. /// /// Type of the actor. /// The child actor. public Actor AddChild(Type type) { if (type.IsAbstract) return null; var result = (Actor)New(type); result.SetParent(this, false, false); return result; } /// /// Creates a new child actor of the given type. /// /// Type of the actor to search for. Includes any actors derived from the type. /// The child actor. public T AddChild() where T : Actor { if (typeof(T).IsAbstract) return null; var result = New(); result.SetParent(this, false, false); return result; } /// /// Finds the child actor of the given type. /// /// Type of the actor to search for. Includes any actors derived from the type. /// The child actor or null if failed to find. public T GetChild() where T : Actor { return GetChild(typeof(T)) as T; } /// /// Tries to the child actor of the given type. /// /// Type of the actor to search for. Includes any actors derived from the type. /// The returned actor, valid only if method returns true. /// True if found an child actor of that type or false if failed to find. public bool TryGetChild(out T actor) where T : Actor { actor = GetChild(typeof(T)) as T; return (object)actor != null; } /// /// Finds the child actor of the given type or creates a new one. /// /// Type of the actor to search for. Includes any actors derived from the type. /// The child actor. public T GetOrAddChild() where T : Actor { var result = GetChild(); if (result == null) { if (typeof(T).IsAbstract) return null; result = New(); result.SetParent(this, false, false); } return result; } /// /// Creates a new script of a specific type and adds it to the actor. /// /// Type of the script to create. /// The created script instance, null otherwise. public Script AddScript(Type type) { if (type.IsAbstract) return null; var script = (Script)New(type); script.Parent = this; return script; } /// /// Creates a new script of a specific type and adds it to the actor. /// /// Type of the script to search for. Includes any scripts derived from the type. /// The created script instance, null otherwise. public T AddScript() where T : Script { if (typeof(T).IsAbstract) return null; var script = New(); script.Parent = this; return script; } /// /// Finds the script of the given type from this actor. /// /// Type of the script to search for. Includes any scripts derived from the type. /// The script or null if failed to find. public T GetScript() where T : class { return GetScript(typeof(T)) as T; } /// /// Tries to find the script of the given type from this actor. /// /// Type of the script to search for. Includes any scripts derived from the type. /// The returned script, valid only if method returns true. /// True if found a script of that type or false if failed to find. public bool TryGetScript(out T script) where T : class { script = GetScript(typeof(T)) as T; return (object)script != null; } /// /// Tries to find the script of the given type in this actor hierarchy (checks this actor and all children hierarchy). /// /// Type of the object. /// Script instance if found, null otherwise. public T FindScript() where T : class { return FindScript(typeof(T)) as T; } /// /// Tries to find the actor of the given type in this actor hierarchy (checks this actor and all children hierarchy). /// /// Type of the object. /// Actor instance if found, null otherwise. public T FindActor() where T : Actor { return FindActor(typeof(T)) as T; } /// /// Tries to find the actor of the given type and name in this actor hierarchy (checks this actor and all children hierarchy). /// /// Name of the object. /// Type of the object. /// Actor instance if found, null otherwise. public T FindActor(string name) where T : Actor { return FindActor(typeof(T), name) as T; } /// /// Tries to find actor of the given type and tag in this actor hierarchy (checks this actor and all children hierarchy). /// /// A tag on the object. /// Type of the object. /// Actor instance if found, null otherwise. public T FindActor(Tag tag) where T : Actor { return FindActor(typeof(T), tag) as T; } /// /// Searches for all actors of a specific type in this actor children list. /// /// Type of the actor to search for. Includes any actors derived from the type. /// All actors matching the specified type public T[] GetChildren() where T : Actor { var count = ChildrenCount; var length = 0; for (int i = 0; i < count; i++) { if (GetChild(i) is T) length++; } if (length == 0) return Utils.GetEmptyArray(); var output = new T[length]; length = 0; for (int i = 0; i < count; i++) { if (GetChild(i) is T obj) output[length++] = obj; } return output; } /// /// Searches for all scripts of a specific type from this actor. /// /// Type of the scripts to search for. Includes any scripts derived from the type. /// All scripts matching the specified type. public T[] GetScripts() where T : class { var count = ScriptsCount; var length = 0; for (int i = 0; i < count; i++) { if (GetScript(i) is T) length++; } if (length == 0) return Utils.GetEmptyArray(); var output = new T[length]; length = 0; for (int i = 0; i < count; i++) { if (GetScript(i) is T obj) output[length++] = obj; } return output; } /// /// Gets the matrix that transforms a point from the world space to local space of the actor. /// public Matrix WorldToLocalMatrix { get { GetWorldToLocalMatrix(out var worldToLocal); return worldToLocal; } } /// /// Gets the matrix that transforms a point from the local space of the actor to world space. /// public Matrix LocalToWorldMatrix { get { GetLocalToWorldMatrix(out var localToWorld); return localToWorld; } } /// /// Rotates the actor around axis passing through point in world-space by angle (in degrees). /// /// Modifies both the position and the rotation of the actor (scale remains the same). /// The point (world-space). /// The axis (normalized). /// The angle (in degrees). public void RotateAround(Vector3 point, Vector3 axis, float angle) { var transform = Transform; var q = Quaternion.RotationAxis(axis, angle * Mathf.DegreesToRadians); var dif = (transform.Translation - point) * q; transform.Translation = point + dif; transform.Orientation = q; Transform = transform; } /// public override string ToString() { return $"{Name} ({GetType().Name})"; } } }