Added a RTS camera, and some assorted changes.
This commit is contained in:
168
RTSCamera.cs
Executable file
168
RTSCamera.cs
Executable file
@@ -0,0 +1,168 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using SJK.Math;
|
||||
|
||||
public partial class RTSCamera : Node3D
|
||||
{
|
||||
[Export]
|
||||
public Camera3D camera;
|
||||
Vector3 positionStartPos;
|
||||
Vector3 positionOffsetPos;
|
||||
Vector3 lastTransalation;
|
||||
|
||||
Vector3 cameraTargetOffset;
|
||||
Action Update_CurrentFunc;
|
||||
|
||||
//Generic bookkeeping variables;
|
||||
Vector2 LastMousePostition;
|
||||
//Camera Dragging Bookkeeping variables
|
||||
Vector3 LastMouseGroundPlanePositon;
|
||||
//Camera Rotating Bookkeeping variables
|
||||
float CameraRotateSpeed = .5f;
|
||||
bool isDraging;
|
||||
public override void _Ready()
|
||||
{
|
||||
Update_CurrentFunc = Update_DetectModeStart;
|
||||
}
|
||||
void Update_DetectModeStart()
|
||||
{
|
||||
if (Input.IsActionJustPressed("move_mouse"))
|
||||
{
|
||||
//Mouse Left went Down
|
||||
//Does nothing basicly
|
||||
}
|
||||
else if (Input.IsActionPressed("move_mouse") && GetViewport().GetMousePosition() != LastMousePostition)
|
||||
{
|
||||
LastMouseGroundPlanePositon = camera.MouseToGroundPlane() ?? Vector3.Zero;
|
||||
Update_CurrentFunc = Update_CameraDrag;
|
||||
Update_CurrentFunc();
|
||||
// GD.Print("1");
|
||||
}
|
||||
else if (Input.IsActionPressed("camera_rotate") && GetViewport().GetMousePosition() != LastMousePostition)
|
||||
{
|
||||
LastMouseGroundPlanePositon = camera.MouseToGroundPlane() ?? Vector3.Zero;
|
||||
Update_CurrentFunc = Update_RotateCamera;
|
||||
Update_CurrentFunc();
|
||||
// GD.Print("2");
|
||||
}
|
||||
|
||||
}
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (Input.IsActionJustPressed("ui_cancel"))
|
||||
{
|
||||
CancelUpdateFunc();
|
||||
}
|
||||
GD.PrintS(positionStartPos,positionOffsetPos,lastTransalation,LastMouseGroundPlanePositon,LastMousePostition,cameraTargetOffset,scrollAmount);
|
||||
Update_CurrentFunc();
|
||||
Update_CameraScroll((float)delta);
|
||||
LastMousePostition = GetViewport().GetMousePosition();
|
||||
camera.Fov = Mathf.Lerp(camera.Fov, Mathf.Lerp(90, 50, (camera.Position.Y - 5) / (80 - 5)), (float)delta * 10);
|
||||
}
|
||||
void CancelUpdateFunc()
|
||||
{
|
||||
Update_CurrentFunc = Update_DetectModeStart;
|
||||
}
|
||||
void Update_CameraDrag()
|
||||
{
|
||||
if (Input.IsActionJustReleased("move_mouse"))
|
||||
{
|
||||
CancelUpdateFunc();
|
||||
}
|
||||
|
||||
var hitpos = camera.MouseToGroundPlane() ?? Vector3.Zero;
|
||||
|
||||
|
||||
var diff = LastMouseGroundPlanePositon - hitpos;
|
||||
|
||||
GlobalTranslate(diff);
|
||||
LastMouseGroundPlanePositon = hitpos = camera.MouseToGroundPlane() ?? Vector3.Zero;
|
||||
|
||||
}
|
||||
float scrollAmount;
|
||||
public override void _UnhandledInput(InputEvent @event)
|
||||
{
|
||||
scrollAmount += Input.IsActionJustReleased("mouse_scroll_up") ? 1 : 0;
|
||||
scrollAmount += Input.IsActionJustReleased("mouse_scroll_down") ? -1 : 0;
|
||||
if (@event is InputEventKey eventKey && eventKey.Keycode == Key.F)
|
||||
{
|
||||
GlobalPosition = Vector3.Zero;
|
||||
camera.Position = Vector3.Zero;
|
||||
CancelUpdateFunc();
|
||||
}
|
||||
}
|
||||
void Update_CameraScroll(float delta)
|
||||
{
|
||||
|
||||
// Zoom to scrollwheel
|
||||
// float scrollAmount = Input.IsActionJustReleased("mouse_scroll_up")?1:0;
|
||||
// scrollAmount += Input.IsActionJustReleased( "mouse_scroll_down")?-1:0;
|
||||
// GD.Print(scrollAmount);
|
||||
float minHeight = 2;
|
||||
float maxHeight = 30;
|
||||
// Move camera towards hitPos
|
||||
// var hitPos = camera.MouseToGroundPlane();
|
||||
// Vector3 dir = hitPos - camera.Translation;
|
||||
var dir = -camera.GlobalTransform.Basis.Z * .5f;
|
||||
|
||||
var p = camera.Position;
|
||||
|
||||
// Stop zooming out at a certain distance.
|
||||
// TODO: Maybe you should still slide around at 20 zoom?
|
||||
if (scrollAmount > 0 || p.Y < (maxHeight - 0.1f))
|
||||
{
|
||||
cameraTargetOffset += dir * scrollAmount;
|
||||
}
|
||||
DebugDraw3D.DrawArrow(Vector3.Zero,cameraTargetOffset);
|
||||
Vector3 lastCameraPosition = camera.Position;
|
||||
camera.Position = camera.Position.Lerp(camera.Position + cameraTargetOffset, delta);
|
||||
cameraTargetOffset -= camera.Position - lastCameraPosition;
|
||||
|
||||
p = camera.Position;
|
||||
if (p.Y < minHeight)
|
||||
{
|
||||
p.Y = minHeight;
|
||||
}
|
||||
if (p.Y > maxHeight)
|
||||
{
|
||||
p.Y = maxHeight;
|
||||
}
|
||||
|
||||
camera.Position = p;
|
||||
// Change camera angle
|
||||
camera.RotationDegrees = new Vector3(
|
||||
Mathf.Lerp(-50, -75, camera.Position.Y / maxHeight),
|
||||
camera.RotationDegrees.Y,
|
||||
camera.RotationDegrees.Z
|
||||
);
|
||||
scrollAmount = 0;
|
||||
}
|
||||
void Update_RotateCamera()
|
||||
{
|
||||
if (!Input.IsActionPressed("move_mouse"))
|
||||
{
|
||||
CancelUpdateFunc();
|
||||
}
|
||||
Vector2 hitpos = GetViewport().GetMousePosition();
|
||||
|
||||
Vector2 diff = LastMousePostition - hitpos;
|
||||
camera.RotationDegrees = new Vector3(
|
||||
camera.RotationDegrees.X,
|
||||
camera.RotationDegrees.Y + (diff.X * CameraRotateSpeed),
|
||||
camera.RotationDegrees.Z
|
||||
);
|
||||
LastMousePostition = hitpos = GetViewport().GetMousePosition();
|
||||
}
|
||||
}
|
||||
|
||||
public static partial class SJKMath
|
||||
{
|
||||
public static Vector3? MouseToPlane(this Plane plane, Camera3D viewCamera, Vector2? mousePos = null)
|
||||
{
|
||||
var from = viewCamera.ProjectRayOrigin( mousePos ?? viewCamera.GetViewport().GetMousePosition());
|
||||
var normal = viewCamera.ProjectRayNormal(mousePos ?? viewCamera.GetViewport().GetMousePosition());
|
||||
return plane.IntersectsRay(from, normal);
|
||||
}
|
||||
public static Vector3? MouseToGroundPlane(this Camera3D viewCamera, Vector2? mousePos = null, float offset = 0) =>
|
||||
(Plane.PlaneXZ with { D = offset }).MouseToPlane(viewCamera, mousePos);
|
||||
}
|
||||
Reference in New Issue
Block a user