feat(scripting): add mono csharp runtime foundation

This commit is contained in:
2026-03-27 13:07:39 +08:00
parent 134a80b334
commit b06932724c
33 changed files with 4227 additions and 18 deletions

View File

@@ -0,0 +1,21 @@
namespace XCEngine
{
public class Behaviour : Component
{
internal ulong m_scriptComponentUUID = 0;
protected Behaviour()
{
}
public ulong ScriptComponentUUID => m_scriptComponentUUID;
public bool enabled
{
get => InternalCalls.Behaviour_GetEnabled(m_scriptComponentUUID);
set => InternalCalls.Behaviour_SetEnabled(m_scriptComponentUUID, value);
}
public bool isActiveAndEnabled => enabled && GameObject.activeInHierarchy;
}
}

View File

@@ -0,0 +1,70 @@
namespace XCEngine
{
public sealed class Camera : Component
{
internal Camera(ulong gameObjectUUID)
: base(gameObjectUUID)
{
}
public float FieldOfView
{
get => InternalCalls.Camera_GetFieldOfView(GameObjectUUID);
set => InternalCalls.Camera_SetFieldOfView(GameObjectUUID, value);
}
public float fieldOfView
{
get => FieldOfView;
set => FieldOfView = value;
}
public float NearClipPlane
{
get => InternalCalls.Camera_GetNearClipPlane(GameObjectUUID);
set => InternalCalls.Camera_SetNearClipPlane(GameObjectUUID, value);
}
public float nearClipPlane
{
get => NearClipPlane;
set => NearClipPlane = value;
}
public float FarClipPlane
{
get => InternalCalls.Camera_GetFarClipPlane(GameObjectUUID);
set => InternalCalls.Camera_SetFarClipPlane(GameObjectUUID, value);
}
public float farClipPlane
{
get => FarClipPlane;
set => FarClipPlane = value;
}
public float Depth
{
get => InternalCalls.Camera_GetDepth(GameObjectUUID);
set => InternalCalls.Camera_SetDepth(GameObjectUUID, value);
}
public float depth
{
get => Depth;
set => Depth = value;
}
public bool Primary
{
get => InternalCalls.Camera_GetPrimary(GameObjectUUID);
set => InternalCalls.Camera_SetPrimary(GameObjectUUID, value);
}
public bool primary
{
get => Primary;
set => Primary = value;
}
}
}

View File

@@ -0,0 +1,70 @@
using System;
using System.Reflection;
namespace XCEngine
{
public abstract class Component
{
internal ulong m_gameObjectUUID;
protected Component()
{
}
protected Component(ulong gameObjectUUID)
{
m_gameObjectUUID = gameObjectUUID;
}
public ulong GameObjectUUID => m_gameObjectUUID;
public GameObject GameObject => new GameObject(m_gameObjectUUID);
public GameObject gameObject => GameObject;
public Transform Transform => GameObject.Transform;
public Transform transform => Transform;
public bool HasComponent<T>() where T : Component
{
return GameObject.HasComponent<T>();
}
public T GetComponent<T>() where T : Component
{
return GameObject.GetComponent<T>();
}
public bool TryGetComponent<T>(out T component) where T : Component
{
component = GetComponent<T>();
return component != null;
}
internal static T Create<T>(ulong gameObjectUUID) where T : Component
{
return Create(typeof(T), gameObjectUUID) as T;
}
internal static Component Create(Type componentType, ulong gameObjectUUID)
{
if (componentType == null || gameObjectUUID == 0 || !typeof(Component).IsAssignableFrom(componentType))
{
return null;
}
try
{
return Activator.CreateInstance(
componentType,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
binder: null,
args: new object[] { gameObjectUUID },
culture: null) as Component;
}
catch
{
return null;
}
}
}
}

View File

@@ -0,0 +1,20 @@
namespace XCEngine
{
public static class Debug
{
public static void Log(string message)
{
InternalCalls.Debug_Log(message ?? string.Empty);
}
public static void LogWarning(string message)
{
InternalCalls.Debug_LogWarning(message ?? string.Empty);
}
public static void LogError(string message)
{
InternalCalls.Debug_LogError(message ?? string.Empty);
}
}
}

View File

@@ -0,0 +1,55 @@
namespace XCEngine
{
public sealed class GameObject
{
private readonly ulong m_uuid;
internal GameObject(ulong uuid)
{
m_uuid = uuid;
}
public ulong UUID => m_uuid;
public string Name
{
get => InternalCalls.GameObject_GetName(UUID) ?? string.Empty;
set => InternalCalls.GameObject_SetName(UUID, value ?? string.Empty);
}
public string name
{
get => Name;
set => Name = value;
}
public bool activeSelf => InternalCalls.GameObject_GetActiveSelf(UUID);
public bool activeInHierarchy => InternalCalls.GameObject_GetActiveInHierarchy(UUID);
public void SetActive(bool value)
{
InternalCalls.GameObject_SetActive(UUID, value);
}
public Transform Transform => GetComponent<Transform>();
public Transform transform => Transform;
public bool HasComponent<T>() where T : Component
{
return InternalCalls.GameObject_HasComponent(UUID, typeof(T));
}
public T GetComponent<T>() where T : Component
{
ulong componentOwnerUUID = InternalCalls.GameObject_GetComponent(UUID, typeof(T));
return Component.Create<T>(componentOwnerUUID);
}
public bool TryGetComponent<T>(out T component) where T : Component
{
component = GetComponent<T>();
return component != null;
}
}
}

View File

@@ -0,0 +1,185 @@
using System;
using System.Runtime.CompilerServices;
namespace XCEngine
{
internal static class InternalCalls
{
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Debug_Log(string message);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Debug_LogWarning(string message);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Debug_LogError(string message);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern float Time_GetDeltaTime();
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern string GameObject_GetName(ulong gameObjectUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void GameObject_SetName(ulong gameObjectUUID, string name);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool GameObject_GetActiveSelf(ulong gameObjectUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool GameObject_GetActiveInHierarchy(ulong gameObjectUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void GameObject_SetActive(ulong gameObjectUUID, bool active);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool GameObject_HasComponent(ulong gameObjectUUID, Type componentType);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern ulong GameObject_GetComponent(ulong gameObjectUUID, Type componentType);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool Behaviour_GetEnabled(ulong scriptComponentUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Behaviour_SetEnabled(ulong scriptComponentUUID, bool enabled);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_GetLocalPosition(ulong gameObjectUUID, out Vector3 position);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_SetLocalPosition(ulong gameObjectUUID, ref Vector3 position);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_GetLocalRotation(ulong gameObjectUUID, out Quaternion rotation);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_SetLocalRotation(ulong gameObjectUUID, ref Quaternion rotation);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_GetLocalScale(ulong gameObjectUUID, out Vector3 scale);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_SetLocalScale(ulong gameObjectUUID, ref Vector3 scale);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_GetLocalEulerAngles(ulong gameObjectUUID, out Vector3 eulerAngles);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_SetLocalEulerAngles(ulong gameObjectUUID, ref Vector3 eulerAngles);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_GetPosition(ulong gameObjectUUID, out Vector3 position);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_SetPosition(ulong gameObjectUUID, ref Vector3 position);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_GetRotation(ulong gameObjectUUID, out Quaternion rotation);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_SetRotation(ulong gameObjectUUID, ref Quaternion rotation);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_GetScale(ulong gameObjectUUID, out Vector3 scale);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_SetScale(ulong gameObjectUUID, ref Vector3 scale);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_GetForward(ulong gameObjectUUID, out Vector3 forward);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_GetRight(ulong gameObjectUUID, out Vector3 right);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_GetUp(ulong gameObjectUUID, out Vector3 up);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_Translate(ulong gameObjectUUID, ref Vector3 translation, int relativeTo);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_Rotate(ulong gameObjectUUID, ref Vector3 eulers, int relativeTo);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_LookAt(ulong gameObjectUUID, ref Vector3 target);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_TransformPoint(ulong gameObjectUUID, ref Vector3 point, out Vector3 transformedPoint);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_InverseTransformPoint(ulong gameObjectUUID, ref Vector3 point, out Vector3 transformedPoint);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_TransformDirection(ulong gameObjectUUID, ref Vector3 direction, out Vector3 transformedDirection);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_InverseTransformDirection(ulong gameObjectUUID, ref Vector3 direction, out Vector3 transformedDirection);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern ulong Transform_GetParent(ulong gameObjectUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Transform_SetParent(ulong gameObjectUUID, ulong parentGameObjectUUID, bool worldPositionStays);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern int Transform_GetChildCount(ulong gameObjectUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern ulong Transform_GetChild(ulong gameObjectUUID, int index);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern float Camera_GetFieldOfView(ulong gameObjectUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Camera_SetFieldOfView(ulong gameObjectUUID, float value);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern float Camera_GetNearClipPlane(ulong gameObjectUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Camera_SetNearClipPlane(ulong gameObjectUUID, float value);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern float Camera_GetFarClipPlane(ulong gameObjectUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Camera_SetFarClipPlane(ulong gameObjectUUID, float value);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern float Camera_GetDepth(ulong gameObjectUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Camera_SetDepth(ulong gameObjectUUID, float value);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool Camera_GetPrimary(ulong gameObjectUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Camera_SetPrimary(ulong gameObjectUUID, bool value);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern float Light_GetIntensity(ulong gameObjectUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Light_SetIntensity(ulong gameObjectUUID, float value);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern float Light_GetRange(ulong gameObjectUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Light_SetRange(ulong gameObjectUUID, float value);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern float Light_GetSpotAngle(ulong gameObjectUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Light_SetSpotAngle(ulong gameObjectUUID, float value);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool Light_GetCastsShadows(ulong gameObjectUUID);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Light_SetCastsShadows(ulong gameObjectUUID, bool value);
}
}

View File

@@ -0,0 +1,58 @@
namespace XCEngine
{
public sealed class Light : Component
{
internal Light(ulong gameObjectUUID)
: base(gameObjectUUID)
{
}
public float Intensity
{
get => InternalCalls.Light_GetIntensity(GameObjectUUID);
set => InternalCalls.Light_SetIntensity(GameObjectUUID, value);
}
public float intensity
{
get => Intensity;
set => Intensity = value;
}
public float Range
{
get => InternalCalls.Light_GetRange(GameObjectUUID);
set => InternalCalls.Light_SetRange(GameObjectUUID, value);
}
public float range
{
get => Range;
set => Range = value;
}
public float SpotAngle
{
get => InternalCalls.Light_GetSpotAngle(GameObjectUUID);
set => InternalCalls.Light_SetSpotAngle(GameObjectUUID, value);
}
public float spotAngle
{
get => SpotAngle;
set => SpotAngle = value;
}
public bool CastsShadows
{
get => InternalCalls.Light_GetCastsShadows(GameObjectUUID);
set => InternalCalls.Light_SetCastsShadows(GameObjectUUID, value);
}
public bool castsShadows
{
get => CastsShadows;
set => CastsShadows = value;
}
}
}

View File

@@ -1,8 +1,6 @@
namespace XCEngine
{
public class MonoBehaviour
public class MonoBehaviour : Behaviour
{
public ulong GameObjectUUID;
public ulong ScriptComponentUUID;
}
}

View File

@@ -0,0 +1,45 @@
using System.Runtime.InteropServices;
namespace XCEngine
{
[StructLayout(LayoutKind.Sequential)]
public struct Quaternion
{
public float X;
public float Y;
public float Z;
public float W;
public float x
{
get => X;
set => X = value;
}
public float y
{
get => Y;
set => Y = value;
}
public float z
{
get => Z;
set => Z = value;
}
public float w
{
get => W;
set => W = value;
}
public Quaternion(float x, float y, float z, float w)
{
X = x;
Y = y;
Z = z;
W = w;
}
}
}

View File

@@ -0,0 +1,8 @@
namespace XCEngine
{
public enum Space
{
Self = 0,
World = 1,
}
}

View File

@@ -0,0 +1,7 @@
namespace XCEngine
{
public static class Time
{
public static float deltaTime => InternalCalls.Time_GetDeltaTime();
}
}

View File

@@ -0,0 +1,263 @@
namespace XCEngine
{
public sealed class Transform : Component
{
internal Transform(ulong gameObjectUUID)
: base(gameObjectUUID)
{
}
public Vector3 LocalPosition
{
get
{
InternalCalls.Transform_GetLocalPosition(GameObjectUUID, out Vector3 position);
return position;
}
set
{
InternalCalls.Transform_SetLocalPosition(GameObjectUUID, ref value);
}
}
public Vector3 localPosition
{
get => LocalPosition;
set => LocalPosition = value;
}
public Quaternion LocalRotation
{
get
{
InternalCalls.Transform_GetLocalRotation(GameObjectUUID, out Quaternion rotation);
return rotation;
}
set
{
InternalCalls.Transform_SetLocalRotation(GameObjectUUID, ref value);
}
}
public Quaternion localRotation
{
get => LocalRotation;
set => LocalRotation = value;
}
public Vector3 LocalScale
{
get
{
InternalCalls.Transform_GetLocalScale(GameObjectUUID, out Vector3 scale);
return scale;
}
set
{
InternalCalls.Transform_SetLocalScale(GameObjectUUID, ref value);
}
}
public Vector3 localScale
{
get => LocalScale;
set => LocalScale = value;
}
public Vector3 LocalEulerAngles
{
get
{
InternalCalls.Transform_GetLocalEulerAngles(GameObjectUUID, out Vector3 eulerAngles);
return eulerAngles;
}
set
{
InternalCalls.Transform_SetLocalEulerAngles(GameObjectUUID, ref value);
}
}
public Vector3 localEulerAngles
{
get => LocalEulerAngles;
set => LocalEulerAngles = value;
}
public Vector3 Position
{
get
{
InternalCalls.Transform_GetPosition(GameObjectUUID, out Vector3 position);
return position;
}
set
{
InternalCalls.Transform_SetPosition(GameObjectUUID, ref value);
}
}
public Vector3 position
{
get => Position;
set => Position = value;
}
public Quaternion Rotation
{
get
{
InternalCalls.Transform_GetRotation(GameObjectUUID, out Quaternion rotation);
return rotation;
}
set
{
InternalCalls.Transform_SetRotation(GameObjectUUID, ref value);
}
}
public Quaternion rotation
{
get => Rotation;
set => Rotation = value;
}
public Vector3 Scale
{
get
{
InternalCalls.Transform_GetScale(GameObjectUUID, out Vector3 scale);
return scale;
}
set
{
InternalCalls.Transform_SetScale(GameObjectUUID, ref value);
}
}
public Vector3 scale
{
get => Scale;
set => Scale = value;
}
public Vector3 Forward
{
get
{
InternalCalls.Transform_GetForward(GameObjectUUID, out Vector3 forward);
return forward;
}
}
public Vector3 forward => Forward;
public Vector3 Right
{
get
{
InternalCalls.Transform_GetRight(GameObjectUUID, out Vector3 right);
return right;
}
}
public Vector3 right => Right;
public Vector3 Up
{
get
{
InternalCalls.Transform_GetUp(GameObjectUUID, out Vector3 up);
return up;
}
}
public Vector3 up => Up;
public Transform Parent
{
get
{
ulong parentUUID = InternalCalls.Transform_GetParent(GameObjectUUID);
return Create<Transform>(parentUUID);
}
set
{
InternalCalls.Transform_SetParent(GameObjectUUID, value?.GameObjectUUID ?? 0, true);
}
}
public Transform parent
{
get => Parent;
set => Parent = value;
}
public int ChildCount => InternalCalls.Transform_GetChildCount(GameObjectUUID);
public int childCount => ChildCount;
public Transform GetChild(int index)
{
ulong childUUID = InternalCalls.Transform_GetChild(GameObjectUUID, index);
return Create<Transform>(childUUID);
}
public void SetParent(Transform parent)
{
SetParent(parent, true);
}
public void SetParent(Transform parent, bool worldPositionStays)
{
InternalCalls.Transform_SetParent(GameObjectUUID, parent?.GameObjectUUID ?? 0, worldPositionStays);
}
public void Translate(Vector3 translation)
{
Translate(translation, Space.Self);
}
public void Translate(Vector3 translation, Space relativeTo)
{
InternalCalls.Transform_Translate(GameObjectUUID, ref translation, (int)relativeTo);
}
public void Rotate(Vector3 eulers)
{
Rotate(eulers, Space.Self);
}
public void Rotate(Vector3 eulers, Space relativeTo)
{
InternalCalls.Transform_Rotate(GameObjectUUID, ref eulers, (int)relativeTo);
}
public void LookAt(Vector3 worldPosition)
{
InternalCalls.Transform_LookAt(GameObjectUUID, ref worldPosition);
}
public Vector3 TransformPoint(Vector3 point)
{
InternalCalls.Transform_TransformPoint(GameObjectUUID, ref point, out Vector3 transformedPoint);
return transformedPoint;
}
public Vector3 InverseTransformPoint(Vector3 point)
{
InternalCalls.Transform_InverseTransformPoint(GameObjectUUID, ref point, out Vector3 transformedPoint);
return transformedPoint;
}
public Vector3 TransformDirection(Vector3 direction)
{
InternalCalls.Transform_TransformDirection(GameObjectUUID, ref direction, out Vector3 transformedDirection);
return transformedDirection;
}
public Vector3 InverseTransformDirection(Vector3 direction)
{
InternalCalls.Transform_InverseTransformDirection(GameObjectUUID, ref direction, out Vector3 transformedDirection);
return transformedDirection;
}
}
}

View File

@@ -0,0 +1,29 @@
using System.Runtime.InteropServices;
namespace XCEngine
{
[StructLayout(LayoutKind.Sequential)]
public struct Vector2
{
public float X;
public float Y;
public float x
{
get => X;
set => X = value;
}
public float y
{
get => Y;
set => Y = value;
}
public Vector2(float x, float y)
{
X = x;
Y = y;
}
}
}

View File

@@ -0,0 +1,37 @@
using System.Runtime.InteropServices;
namespace XCEngine
{
[StructLayout(LayoutKind.Sequential)]
public struct Vector3
{
public float X;
public float Y;
public float Z;
public float x
{
get => X;
set => X = value;
}
public float y
{
get => Y;
set => Y = value;
}
public float z
{
get => Z;
set => Z = value;
}
public Vector3(float x, float y, float z)
{
X = x;
Y = y;
Z = z;
}
}
}

View File

@@ -0,0 +1,45 @@
using System.Runtime.InteropServices;
namespace XCEngine
{
[StructLayout(LayoutKind.Sequential)]
public struct Vector4
{
public float X;
public float Y;
public float Z;
public float W;
public float x
{
get => X;
set => X = value;
}
public float y
{
get => Y;
set => Y = value;
}
public float z
{
get => Z;
set => Z = value;
}
public float w
{
get => W;
set => W = value;
}
public Vector4(float x, float y, float z, float w)
{
X = x;
Y = y;
Z = z;
W = w;
}
}
}