Xenko C#开源游戏引擎入门
最近使有和 Three.js 开发三维页面,觉得很有趣。以前在做WP应用的时候使用过MonoGame做过一点东西,后来Windows 10上来,MonoGame好像不怎么支持了,也没用了。最近在看Windows 下的C# 3D绘图,发现了SharpDx,随藤摸瓜又爬到来了MonoGame 和发现Xenko.
MonoGame:当前又支持UWP应用,但提供的模板指定的是 14393的SDK。(下次再试试,这今试Xenko)
教程:https://docs.microsoft.com/zh-cn/xamarin/graphics-games/monogame/
Xenko:也是通过Xamarin进行跨平台,现在已是MIT开源。原生支持UWP,但用GameStudio 3.0.0.5生成的项目指定的是 10240的SDK,所以做UWP的话,用新SDK,则要改改。今天折腾一翻:
(为什么不用流行的Unity 3D呢?因为不懂,个人喜欢VS的编码方式,什么引用都看得见,何况Unity3D免费版有限制)
以下使用Xenko创建Windows/Uwp项目:
1.安装SDK:https://xenko.com/
2.启动Xenko 新建项目 MyGame2
3、创建的已是完整可运行的项目
切换UWP运行:
刷了一下,没有运行成功
使用VS 2017打开,提示没有安装 10240的SDK(然则我就是不想安装)
点击确定更新
VS不干了:
那就手动来,文本形式打开项目,修改成当前版本
重新加载项目:
出来了,此时重新生成项目。居然成功了。如果不成功,可以做以下尝试:
把nuget的Direct3D11的文件拷到UWP下:
其实不知道有没有用。因为我建第一个项目的时候是不行了,被我修改一翻后,第二个项目居然行了。
4、代码结构
甚是熟悉的UWP代码结构
MyGame2.UWP引用MyGame2.Game的游戏项目。UWP只是一个壳,实际游戏在MyGame2.Game中
看 BasicCameraController.cs 文件源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | using System; using Xenko.Core; using Xenko.Core.Mathematics; using Xenko.Engine; using Xenko.Input; namespace MyGame2 { /// <summary> /// A script that allows to move and rotate an entity through keyboard, mouse and touch input to provide basic camera navigation. /// </summary> /// <remarks> /// The entity can be moved using W, A, S, D, Q and E, arrow keys or dragging/scaling using multi-touch. /// Rotation is achieved using the Numpad, the mouse while holding the right mouse button, or dragging using single-touch. /// </remarks> public class BasicCameraController : SyncScript { private const float MaximumPitch = MathUtil.PiOverTwo * 0.99f; private Vector3 upVector; private Vector3 translation; private float yaw; private float pitch; public Vector3 KeyboardMovementSpeed { get ; set ; } = new Vector3(5.0f); public Vector3 TouchMovementSpeed { get ; set ; } = new Vector3(40, 40, 20); public float SpeedFactor { get ; set ; } = 5.0f; public Vector2 KeyboardRotationSpeed { get ; set ; } = new Vector2(3.0f); public Vector2 MouseRotationSpeed { get ; set ; } = new Vector2(90.0f, 60.0f); public Vector2 TouchRotationSpeed { get ; set ; } = new Vector2(60.0f, 40.0f); public override void Start() { base .Start(); // Default up-direction upVector = Vector3.UnitY; // Configure touch input if (!Platform.IsWindowsDesktop) { Input.Gestures.Add( new GestureConfigDrag()); Input.Gestures.Add( new GestureConfigComposite()); } } public override void Update() { ProcessInput(); UpdateTransform(); } private void ProcessInput() { translation = Vector3.Zero; yaw = 0; pitch = 0; // Move with keyboard if (Input.IsKeyDown(Keys.W) || Input.IsKeyDown(Keys.Up)) { translation.Z = -KeyboardMovementSpeed.Z; } else if (Input.IsKeyDown(Keys.S) || Input.IsKeyDown(Keys.Down)) { translation.Z = KeyboardMovementSpeed.Z; } if (Input.IsKeyDown(Keys.A) || Input.IsKeyDown(Keys.Left)) { translation.X = -KeyboardMovementSpeed.X; } else if (Input.IsKeyDown(Keys.D) || Input.IsKeyDown(Keys.Right)) { translation.X = KeyboardMovementSpeed.X; } if (Input.IsKeyDown(Keys.Q)) { translation.Y = -KeyboardMovementSpeed.Y; } else if (Input.IsKeyDown(Keys.E)) { translation.Y = KeyboardMovementSpeed.Y; } // Alternative translation speed if (Input.IsKeyDown(Keys.LeftShift) || Input.IsKeyDown(Keys.RightShift)) { translation *= SpeedFactor; } // Rotate with keyboard if (Input.IsKeyDown(Keys.NumPad2)) { pitch = KeyboardRotationSpeed.X; } else if (Input.IsKeyDown(Keys.NumPad8)) { pitch = -KeyboardRotationSpeed.X; } if (Input.IsKeyDown(Keys.NumPad4)) { yaw = KeyboardRotationSpeed.Y; } else if (Input.IsKeyDown(Keys.NumPad6)) { yaw = -KeyboardRotationSpeed.Y; } // Rotate with mouse if (Input.IsMouseButtonDown(MouseButton.Right)) { Input.LockMousePosition(); Game.IsMouseVisible = false ; yaw = -Input.MouseDelta.X * MouseRotationSpeed.X; pitch = -Input.MouseDelta.Y * MouseRotationSpeed.Y; } else { Input.UnlockMousePosition(); Game.IsMouseVisible = true ; } // Handle gestures foreach ( var gestureEvent in Input.GestureEvents) { switch (gestureEvent.Type) { // Rotate by dragging case GestureType.Drag: var drag = (GestureEventDrag)gestureEvent; var dragDistance = drag.DeltaTranslation; yaw = -dragDistance.X * TouchRotationSpeed.X; pitch = -dragDistance.Y * TouchRotationSpeed.Y; break ; // Move along z-axis by scaling and in xy-plane by multi-touch dragging case GestureType.Composite: var composite = (GestureEventComposite)gestureEvent; translation.X = -composite.DeltaTranslation.X * TouchMovementSpeed.X; translation.Y = -composite.DeltaTranslation.Y * TouchMovementSpeed.Y; translation.Z = -( float )Math.Log(composite.DeltaScale + 1) * TouchMovementSpeed.Z; break ; } } } private void UpdateTransform() { var elapsedTime = ( float )Game.UpdateTime.Elapsed.TotalSeconds; translation *= elapsedTime; yaw *= elapsedTime; pitch *= elapsedTime; // Get the local coordinate system var rotation = Matrix.RotationQuaternion(Entity.Transform.Rotation); // Enforce the global up-vector by adjusting the local x-axis var right = Vector3.Cross(rotation.Forward, upVector); var up = Vector3.Cross(right, rotation.Forward); // Stabilize right.Normalize(); up.Normalize(); // Adjust pitch. Prevent it from exceeding up and down facing. Stabilize edge cases. var currentPitch = MathUtil.PiOverTwo - ( float )Math.Acos(Vector3.Dot(rotation.Forward, upVector)); pitch = MathUtil.Clamp(currentPitch + pitch, -MaximumPitch, MaximumPitch) - currentPitch; // Move in local coordinates Entity.Transform.Position += Vector3.TransformCoordinate(translation, rotation); // Yaw around global up-vector, pitch and roll in local space Entity.Transform.Rotation *= Quaternion.RotationAxis(right, pitch) * Quaternion.RotationAxis(upVector, yaw); } } } |
5、运行看看
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步