Added basic component access in Scripts

This commit is contained in:
Simon Lübeß
2023-03-29 16:32:46 +02:00
parent e60d74fccd
commit 4fd9a924a0
11 changed files with 332 additions and 33 deletions
+2 -2
View File
@@ -2,7 +2,7 @@ using GlitchyEngine.Core;
namespace GlitchyEngine;
public class Component : EngineObject
public abstract class Component
{
public Entity Entity { get; internal set; }
}
+30
View File
@@ -0,0 +1,30 @@
using GlitchyEngine.Math;
namespace GlitchyEngine;
public class RigidBody2D : Component
{
/// <summary>
/// Apply a force at a world point.
/// If the force is not applied at the center of mass, it will generate a torque and affect the angular velocity.
/// This wakes up the body.
/// </summary>
/// <param name="force">The world force vector, usually in Newtons (N).</param>
/// <param name="point">The world position of the point of application.</param>
/// <param name="wakeUp">Wake up the body</param>
public void ApplyForce(Vector2 force, Vector2 point, bool wakeUp = true)
{
ScriptGlue.RigidBody2D_ApplyForce(Entity._uuid, force, point, wakeUp);
}
/// <summary>
/// Apply a force to the center of mass.
/// This wakes up the body.
/// </summary>
/// <param name="force">The world force vector, usually in Newtons (N).</param>
/// <param name="wakeUp">Wake up the body</param>
public void ApplyForceToCenter(Vector2 force, bool wakeUp = true)
{
ScriptGlue.RigidBody2D_ApplyForceToCenter(Entity._uuid, force, wakeUp);
}
}
+14 -2
View File
@@ -1,8 +1,20 @@
using GlitchyEngine.Core;
using GlitchyEngine.Math;
namespace GlitchyEngine;
public class Transform : EngineObject
public class Transform : Component
{
public Vector3 Translation
{
get
{
ScriptGlue.Transform_GetTranslation(Entity.UUID, out Vector3 translation);
return translation;
}
set
{
ScriptGlue.Transform_SetTranslation(Entity.UUID, in value);
}
}
}
+100 -10
View File
@@ -1,4 +1,5 @@
using System;
using System.Runtime.CompilerServices;
using GlitchyEngine.Core;
using GlitchyEngine.Math;
@@ -27,24 +28,113 @@ public abstract class Entity : EngineObject
// _uuid = uuid;
//}
public T GetComponent<T>() where T : Component
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool HasComponent<T>() => HasComponent(typeof(T));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool HasComponent(Type type) => ScriptGlue.Entity_HasComponent(_uuid, type);
/// <summary>
/// Gets the component with the specified type.
/// </summary>
/// <typeparam name="T">The type of the component to get.</typeparam>
/// <returns>The component or null, if the entity doesn't have a component of the specified type.</returns>
public T GetComponent<T>() where T : Component, new()
{
Log.Info("Trying to get component");
if (HasComponent<T>())
{
return new T
{
Entity = this
};
}
return null;
}
/// <summary>
/// Gets the component with the given type.
/// </summary>
/// <param name="componentType">The type of the component to get.</param>
/// <returns>The component or null, if the entity doesn't have a component of the given type.</returns>
/// <remarks>For performance reasons it is recommended to use <see cref="GetComponent{T}"/> if possible.</remarks>
public Component GetComponent(Type componentType)
{
// TODO: probably throw!
if (!componentType.IsSubclassOf(typeof(Component))) return null;
if (HasComponent(componentType))
{
return Activator.CreateInstance(componentType) as Component;
}
//public Transform Transform => new (){_uuid = _uuid};
return null;
}
/// <summary>
/// Gets the component with the specified component type.
/// </summary>
/// <typeparam name="T">The type of the component to add.</typeparam>
/// <returns>The component.</returns>
public T AddComponent<T>() where T : Component, new()
{
ScriptGlue.Entity_AddComponent(_uuid, typeof(T));
return new T
{
Entity = this
};
}
/// <summary>
/// Gets the component with the given component type.
/// </summary>
/// <param name="componentType">The type of the component to add.</param>
/// <returns>The component or null, if the given type is not a valid component type.</returns>
/// <remarks>For performance reasons it is recommended to use <see cref="AddComponent{T}"/> if possible.</remarks>
public Component AddComponent(Type componentType)
{
// TODO: probably throw!
if (!componentType.IsSubclassOf(typeof(Component))) return null;
ScriptGlue.Entity_AddComponent(_uuid, componentType);
Component component = Activator.CreateInstance(componentType) as Component;
return component;
}
/// <summary>
/// Removes the component with the specified component type.
/// </summary>
/// <typeparam name="T">The type of the component to remove.</typeparam>
public void RemoveComponent<T>() where T : Component, new()
{
ScriptGlue.Entity_RemoveComponent(_uuid, typeof(T));
}
/// <summary>
/// Removes the component with the given component type.
/// </summary>
/// <param name="componentType">The type of the component to remove.</param>
/// <remarks>For performance reasons it is recommended to use <see cref="RemoveComponent{T}"/> if possible.</remarks>
public void RemoveComponent(Type componentType)
{
// TODO: probably throw!
if (!componentType.IsSubclassOf(typeof(Component))) return;
ScriptGlue.Entity_RemoveComponent(_uuid, componentType);
}
public Transform Transform => GetComponent<Transform>();
public Vector3 Translation
{
get
{
ScriptGlue.Entity_GetTranslation(_uuid, out Vector3 translation);
return translation;
}
set => ScriptGlue.Entity_SetTranslation(_uuid, value);
get => Transform.Translation;
set => Transform.Translation = value;
}
// Will be executed once after the entity as be created.
// void OnCreate();
+12 -1
View File
@@ -120,7 +120,18 @@ public struct Vector3
{
return !(a == b);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = X.GetHashCode();
hashCode = (hashCode * 397) ^ Y.GetHashCode();
hashCode = (hashCode * 397) ^ Z.GetHashCode();
return hashCode;
}
}
public override string ToString()
{
return $"X:{X}, Y:{Y}, Z:{Z}";
+17 -10
View File
@@ -5,7 +5,7 @@ namespace GlitchyEngine;
class MyTestEntity : Entity
{
//Rigidbody2D _rigidBody;
RigidBody2D _rigidBody;
/// <summary>
/// Called after the script component was created. (The entity might not be fully created yet)
@@ -14,7 +14,7 @@ class MyTestEntity : Entity
{
Log.Info($"Create! {UUID}");
//_rigidBody = GetComponent<Rigidbody2D>();
_rigidBody = GetComponent<RigidBody2D>();
}
///// <summary>
@@ -31,18 +31,25 @@ class MyTestEntity : Entity
/// <param name="deltaTime"></param>
void OnUpdate(float deltaTime)
{
Vector2 force = Vector2.Zero;
if (Input.IsKeyPressed(Key.A))
{
Log.Info($"HALLO!");
Vector3 translation = Translation;
translation.Y += 1.0f * deltaTime;
Translation = translation;
//_rigidBody.ApplyImpulse(new Vector2(0, 10));
force.X -= 1000 * deltaTime;
}
if (Input.IsKeyPressed(Key.D))
{
force.X += 1000 * deltaTime;
}
if (Input.IsKeyPressing(Key.Space))
{
force.Y += 2000;
}
_rigidBody.ApplyForceToCenter(force);
if (Input.IsMouseButtonReleasing(MouseButton.LeftButton))
{
Log.Info("Ouha!");
+1
View File
@@ -44,6 +44,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Components\Component.cs" />
<Compile Include="Components\RigidBody2D.cs" />
<Compile Include="Components\Transform.cs" />
<Compile Include="Core\EngineObject.cs" />
<Compile Include="Core\UUID.cs" />
+32 -2
View File
@@ -1,3 +1,4 @@
using System;
using System.Runtime.CompilerServices;
using GlitchyEngine.Core;
using GlitchyEngine.Math;
@@ -9,8 +10,37 @@ namespace GlitchyEngine;
/// </summary>
internal static class ScriptGlue
{
#region Entity
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Entity_GetTranslation(UUID entityId, out Vector3 translation);
internal static extern void Entity_AddComponent(UUID entityId, Type componentType);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Entity_SetTranslation(UUID entityId, in Vector3 translation);
internal static extern bool Entity_HasComponent(UUID entityId, Type componentType);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Entity_RemoveComponent(UUID entityId, Type componentType);
#endregion Entity
#region TransformComponent
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_GetTranslation(UUID entityId, out Vector3 translation);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_SetTranslation(UUID entityId, in Vector3 translation);
#endregion TransformComponent
#region RigidBody2D
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void RigidBody2D_ApplyForce(UUID entityId, in Vector2 force, Vector2 point, bool wakeUp);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void RigidBody2D_ApplyForceToCenter(UUID entityId, in Vector2 force, bool wakeUp);
#endregion RigidBody2D
}