3D객체 마우스컨트롤 / HIT TEST
GameObject.cs
namespace Sample3D_1 { class GameObject { public Model model = null; public Vector3 position = Vector3.Zero; public Vector3 rotation = Vector3.Zero; public float scale = 1.0f; public bool clickme = false; public bool collision = true; } } |
Game.cs
GameObject[] obj = new GameObject[5]; Vector3 cameraPosition = new Vector3(0.0f, 60.0f, 160.0f); Vector3 cameraLookAt = new Vector3(0.0f, 0.0f, 0.0f); Matrix cameraProjectionMatrix; Matrix cameraViewMatrix; MouseState ms; MouseState prevMouse; Vector3 PrevPosition = Vector3.Zero; |
protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); cameraViewMatrix = Matrix.CreateLookAt(cameraPosition, cameraLookAt, Vector3.Up); cameraProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), graphics.GraphicsDevice.Viewport.AspectRatio, 1.0f, 10000.0f); for (int i = 0; i < 5; i++) { obj[i] = new GameObject(); obj[i].model = Content.Load<Model>("Models\\brownFire"); } obj[1].position.X = obj[0].position.X + 40.0f; obj[2].position.X = obj[0].position.X - 40.0f; obj[3].position.Y = obj[0].position.Y + 40.0f; obj[4].position.Y = obj[0].position.Y - 40.0f; } |
protected override void Update(GameTime gameTime) { if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); ms = Mouse.GetState(); for (int i = 0; i < 5; i++) { MouseCheck(obj[i]); //클릭한 곳에 3d객체가 존제하는지 체크 존재한다면 속성을 true로 KeyboardCheck(obj[i]); if (obj[i].clickme) { PrevPosition = obj[i].position; MouseControl(obj[i]); testcollision(obj[i]); } } prevMouse = ms; } |
private void testcollision(GameObject firefall) { BoundingSphere bs = firefall.model.Meshes[0].BoundingSphere; bs.Center = firefall.position; foreach (GameObject fire in obj) { if (!fire.clickme) { BoundingSphere bs2 = fire.model.Meshes[0].BoundingSphere; bs2.Center = fire.position; if (bs.Intersects(bs2)) { firefall.position = PrevPosition; } } } } |
private void MouseCheck(GameObject goods) { if (ms.LeftButton == ButtonState.Pressed) { Ray pickRay = GetPickRay(); BoundingSphere bs = goods.model.Meshes[0].BoundingSphere; bs.Center = goods.position; Nullable<float> result = pickRay.Intersects(bs); if (result.HasValue == true && prevMouse.LeftButton == ButtonState.Released) { goods.clickme = true; } } else if (ms.LeftButton == ButtonState.Released) { goods.clickme = false; } } |
private void MouseControl(GameObject goods) { float Xpos = SetMouseMove(goods); if (goods.clickme) { if (ms.X > prevMouse.X) { goods.position.X += (ms.X - prevMouse.X) / Xpos; } if (ms.X < prevMouse.X) { goods.position.X -= (prevMouse.X - ms.X) / Xpos; } if (ms.Y < prevMouse.Y) { goods.position.Y += (prevMouse.Y - ms.Y) / 3.5f; } if (ms.Y > prevMouse.Y) { goods.position.Y -= (ms.Y - prevMouse.Y) / 3.5f; } if (ms.ScrollWheelValue - prevMouse.ScrollWheelValue > 0) { goods.position.Z += 5.5f; } if (ms.ScrollWheelValue - prevMouse.ScrollWheelValue < 0) { goods.position.Z -= 5.5f; } } } |
private float SetMouseMove(GameObject goods) { if (goods.position.Z > 10.0f && goods.position.Z < 100.0f) { return 5.5f; } if (goods.position.Z < 10.0f && goods.position.Z > -10.0f) { return 4.5f; } if (goods.position.Z < -10.0f && goods.position.Z > -100.0f) { return 3.0f; } return 3.5f; } |
private Ray GetPickRay() { MouseState mouseState = Mouse.GetState(); int mouseX = mouseState.X; int mouseY = mouseState.Y; Vector3 nearsource = new Vector3((float)mouseX, (float)mouseY, 0f); Vector3 farsource = new Vector3((float)mouseX, (float)mouseY, 1f); Matrix world = Matrix.CreateTranslation(0, 0, 0); Vector3 nearPoint = GraphicsDevice.Viewport.Unproject(nearsource, cameraProjectionMatrix, cameraViewMatrix, world); Vector3 farPoint = GraphicsDevice.Viewport.Unproject(farsource, cameraProjectionMatrix, cameraViewMatrix, world); Vector3 direction = farPoint - nearPoint; direction.Normalize(); Ray pickRay = new Ray(nearPoint, direction); return pickRay; } |
private void KeyboardCheck(GameObject goods) { KeyboardState key = Keyboard.GetState(); if (key.IsKeyDown(Keys.Left)) { goods.rotation.Y += 0.05f; } if (key.IsKeyDown(Keys.Right)) { goods.rotation.Y -= 0.05f; } if (key.IsKeyDown(Keys.Up)) { goods.rotation.Z += 0.05f; } if (key.IsKeyDown(Keys.Down)) { goods.rotation.Z -= 0.05f; } if (key.IsKeyDown(Keys.D)) { goods.position.X += 5.5f; } if (key.IsKeyDown(Keys.A)) { goods.position.X -= 5.5f; } if (key.IsKeyDown(Keys.W)) { goods.position.Y += 5.5f; } if (key.IsKeyDown(Keys.S)) { goods.position.Y -= 5.5f; } if (key.IsKeyDown(Keys.PageDown)) { goods.position.Z += 5.5f; } if (key.IsKeyDown(Keys.PageUp)) { goods.position.Z -= 5.5f; } } |
rotected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); // Alpha값을 사용하겠다는 선언 GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add; GraphicsDevice.RenderState.AlphaBlendEnable = true; GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha; GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha; //**********************************// for (int i = 0; i < 5; i++) { DrawModel(obj[i]); } base.Draw(gameTime); } |
private void DrawModel(GameObject gameobj) { foreach (ModelMesh mesh in gameobj.model.Meshes) { foreach (BasicEffect effect in mesh.Effects) { effect.EnableDefaultLighting(); effect.PreferPerPixelLighting = true; effect.World = Matrix.CreateFromYawPitchRoll( gameobj.rotation.Y, gameobj.rotation.X, gameobj.rotation.Z) * Matrix.CreateScale(gameobj.scale) * Matrix.CreateTranslation(gameobj.position); effect.Projection = cameraProjectionMatrix; effect.View = cameraViewMatrix; if (gameobj.clickme) { effect.Alpha = 0.5f; } else { effect.Alpha = 1.0f; } } mesh.Draw(); } } |
마우스 컨트롤은 약간 조정했습니다.