// Copyright (c) 2012-2024 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.
/// Finds only a active actor.
/// Actor instance if found, null otherwise.
public T FindActor(bool activeOnly = false) where T : Actor
{
return FindActor(typeof(T), activeOnly) 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.
/// Finds only an active actor.
/// Actor instance if found, null otherwise.
public T FindActor(Tag tag, bool activeOnly = false) where T : Actor
{
return FindActor(typeof(T), tag, activeOnly) 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).
/// /// Whether to orient the actor the same amount as rotation.
public void RotateAround(Vector3 point, Vector3 axis, float angle, bool orientActor = true)
{
var transform = Transform;
var q = Quaternion.RotationAxis(axis, angle * Mathf.DegreesToRadians);
if (Vector3.NearEqual(point, transform.Translation) && orientActor)
transform.Orientation *= q;
else
{
var dif = (transform.Translation - point) * q;
transform.Translation = point + dif;
if (orientActor)
transform.Orientation *= q;
}
Transform = transform;
}
///
public override string ToString()
{
return $"{Name} ({GetType().Name})";
}
#if FLAX_EDITOR
private bool ShowTransform => !(this is UIControl);
#endif
}
}