forked from ramokz/phantom-camera
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP ramokz#286: more tests and re-organized
- fix several bugs from invalid getter/setters, properties, and types - added more tests - added LimitTarget query result type for working with TileMaps and CollisionShape2Ds - reorganized scripts since main script file had become quite large
- Loading branch information
1 parent
143d567
commit bcdf718
Showing
11 changed files
with
827 additions
and
626 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
34 changes: 34 additions & 0 deletions
34
addons/phantom_camera/scripts/managers/PhantomCameraManager.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
using System.Linq; | ||
using Godot; | ||
using PhantomCamera.Cameras; | ||
using PhantomCamera.Hosts; | ||
|
||
#nullable enable | ||
|
||
namespace PhantomCamera.Managers; | ||
|
||
public static class PhantomCameraManager | ||
{ | ||
private static GodotObject? _instance; | ||
|
||
public static GodotObject Instance => _instance ??= Engine.GetSingleton("PhantomCameraManager"); | ||
|
||
public static PhantomCamera2D[] PhantomCamera2Ds => | ||
Instance.Call(MethodName.GetPhantomCamera2Ds).AsGodotArray<Node2D>() | ||
.Select(node => new PhantomCamera2D(node)).ToArray(); | ||
|
||
public static PhantomCamera3D[] PhantomCamera3Ds => | ||
Instance.Call(MethodName.GetPhantomCamera3Ds).AsGodotArray<Node3D>() | ||
.Select(node => new PhantomCamera3D(node)).ToArray(); | ||
|
||
public static PhantomCameraHost[] PhantomCameraHosts => | ||
Instance.Call(MethodName.GetPhantomCameraHosts).AsGodotArray<Node>() | ||
.Select(node => new PhantomCameraHost(node)).ToArray(); | ||
|
||
public static class MethodName | ||
{ | ||
public const string GetPhantomCamera2Ds = "get_phantom_camera_2ds"; | ||
public const string GetPhantomCamera3Ds = "get_phantom_camera_3ds"; | ||
public const string GetPhantomCameraHosts = "get_phantom_camera_hosts"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
162 changes: 162 additions & 0 deletions
162
addons/phantom_camera/scripts/phantom_camera/PhantomCamera.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
using Godot; | ||
using PhantomCamera.Resources; | ||
|
||
// TODO: missing shared properties | ||
// - get/set pcam_host_owner | ||
// - get/set follow_target | ||
// - get/set follow_targets | ||
// - get/set follow_path | ||
// - get/set follow_offset | ||
// - get/set follow_damping | ||
// - get/set follow_damping_value | ||
// - dead_zone_width | ||
// - dead_zone_height | ||
|
||
#nullable enable | ||
|
||
namespace PhantomCamera.Cameras; | ||
|
||
public enum FollowMode | ||
{ | ||
None, | ||
Glued, | ||
Simple, | ||
Group, | ||
Path, | ||
Framed, | ||
ThirdPerson | ||
} | ||
|
||
public enum LookAtMode | ||
{ | ||
None, | ||
Mimic, | ||
Simple, | ||
Group | ||
} | ||
|
||
public enum InactiveUpdateMode | ||
{ | ||
Always, | ||
Never | ||
} | ||
|
||
public abstract class PhantomCamera // TODO: FollowTarget, LookAtTarget | ||
{ | ||
protected readonly GodotObject Node; | ||
|
||
public delegate void BecameActiveEventHandler(); | ||
public delegate void BecameInactiveEventHandler(); | ||
public delegate void FollowTargetChangedEventHandler(); | ||
public delegate void DeadZoneChangedEventHandler(); | ||
public delegate void TweenStartedEventHandler(); | ||
public delegate void IsTweeningEventHandler(); | ||
public delegate void TweenCompletedEventHandler(); | ||
|
||
public event BecameActiveEventHandler? BecameActive; | ||
public event BecameInactiveEventHandler? BecameInactive; | ||
public event FollowTargetChangedEventHandler? FollowTargetChanged; | ||
public event DeadZoneChangedEventHandler? DeadZoneChanged; | ||
public event TweenStartedEventHandler? TweenStarted; | ||
public event IsTweeningEventHandler? IsTweening; | ||
public event TweenCompletedEventHandler? TweenCompleted; | ||
|
||
private readonly Callable _callableBecameActive; | ||
private readonly Callable _callableBecameInactive; | ||
private readonly Callable _callableFollowTargetChanged; | ||
private readonly Callable _callableDeadZoneChanged; | ||
private readonly Callable _callableTweenStarted; | ||
private readonly Callable _callableIsTweening; | ||
private readonly Callable _callableTweenCompleted; | ||
|
||
public int Priority | ||
{ | ||
get => (int)Node.Call(MethodName.GetPriority); | ||
set => Node.Call(MethodName.SetPriority, value); | ||
} | ||
|
||
public FollowMode FollowMode => (FollowMode)(int)Node.Call(MethodName.GetFollowMode); | ||
|
||
public bool IsActive => (bool)Node.Call(MethodName.IsActive); | ||
|
||
public PhantomCameraTween TweenResource | ||
{ | ||
get => new((Resource)Node.Call(MethodName.GetTweenResource)); | ||
set => Node.Call(MethodName.SetTweenResource, (GodotObject)value.Resource); | ||
} | ||
|
||
public bool TweenOnLoad | ||
{ | ||
get => (bool)Node.Call(MethodName.GetTweenOnLoad); | ||
set => Node.Call(MethodName.SetTweenOnLoad, value); | ||
} | ||
|
||
public InactiveUpdateMode InactiveUpdateMode | ||
{ | ||
get => (InactiveUpdateMode)(int)Node.Call(MethodName.GetInactiveUpdateMode); | ||
set => Node.Call(MethodName.SetInactiveUpdateMode, (int)value); | ||
} | ||
|
||
protected PhantomCamera(GodotObject phantomCameraNode) | ||
{ | ||
Node = phantomCameraNode; | ||
|
||
_callableBecameActive = Callable.From(() => BecameActive?.Invoke()); | ||
_callableBecameInactive = Callable.From(() => BecameInactive?.Invoke()); | ||
_callableFollowTargetChanged = Callable.From(() => FollowTargetChanged?.Invoke()); | ||
_callableDeadZoneChanged = Callable.From(() => DeadZoneChanged?.Invoke()); | ||
_callableTweenStarted = Callable.From(() => TweenStarted?.Invoke()); | ||
_callableIsTweening = Callable.From(() => IsTweening?.Invoke()); | ||
_callableTweenCompleted = Callable.From(() => TweenCompleted?.Invoke()); | ||
|
||
Node.Connect(SignalName.BecameActive, _callableBecameActive); | ||
Node.Connect(SignalName.BecameInactive, _callableBecameInactive); | ||
Node.Connect(SignalName.FollowTargetChanged, _callableFollowTargetChanged); | ||
Node.Connect(SignalName.DeadZoneChanged, _callableDeadZoneChanged); | ||
Node.Connect(SignalName.TweenStarted, _callableTweenStarted); | ||
Node.Connect(SignalName.IsTweening, _callableIsTweening); | ||
Node.Connect(SignalName.TweenCompleted, _callableTweenCompleted); | ||
} | ||
|
||
~PhantomCamera() | ||
{ | ||
Node.Disconnect(SignalName.BecameActive, _callableBecameActive); | ||
Node.Disconnect(SignalName.BecameInactive, _callableBecameInactive); | ||
Node.Disconnect(SignalName.FollowTargetChanged, _callableFollowTargetChanged); | ||
Node.Disconnect(SignalName.DeadZoneChanged, _callableDeadZoneChanged); | ||
Node.Disconnect(SignalName.TweenStarted, _callableTweenStarted); | ||
Node.Disconnect(SignalName.IsTweening, _callableIsTweening); | ||
Node.Disconnect(SignalName.TweenCompleted, _callableTweenCompleted); | ||
} | ||
|
||
public static class MethodName | ||
{ | ||
public const string GetFollowMode = "get_follow_mode"; | ||
public const string IsActive = "is_active"; | ||
|
||
public const string GetPriority = "get_priority"; | ||
public const string SetPriority = "set_priority"; | ||
|
||
public const string GetTweenResource = "get_tween_resource"; | ||
public const string SetTweenResource = "set_tween_resource"; | ||
|
||
public const string GetTweenOnLoad = "get_tween_on_load"; | ||
public const string SetTweenOnLoad = "set_tween_on_load"; | ||
|
||
public const string GetInactiveUpdateMode = "get_inactive_update_mode"; | ||
public const string SetInactiveUpdateMode = "set_inactive_update_mode"; | ||
} | ||
|
||
public static class SignalName | ||
{ | ||
public const string BecameActive = "became_active"; | ||
public const string BecameInactive = "became_inactive"; | ||
public const string FollowTargetChanged = "follow_target_changed"; | ||
public const string LookAtTargetChanged = "look_at_target_changed"; | ||
public const string DeadZoneChanged = "dead_zone_changed"; | ||
public const string TweenStarted = "tween_started"; | ||
public const string IsTweening = "is_tweening"; | ||
public const string TweenCompleted = "tween_completed"; | ||
public const string TweenInterrupted = "tween_interrupted"; | ||
} | ||
} |
156 changes: 156 additions & 0 deletions
156
addons/phantom_camera/scripts/phantom_camera/PhantomCamera2D.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
using Godot; | ||
|
||
// TODO: missing 2d properties | ||
// - get/set auto_zoom (2d only) | ||
// - get/set auto_zoom_min (2d only) | ||
// - get/set auto_zoom_max (2d only) | ||
// - get/set auto_zoom_margin (2d only) | ||
// - draw_limits (2d only) | ||
|
||
#nullable enable | ||
|
||
namespace PhantomCamera.Cameras; | ||
|
||
public class PhantomCamera2D : PhantomCamera | ||
{ | ||
public Node2D Node2D => (Node2D)Node; | ||
|
||
public delegate void TweenInterruptedEventHandler(Node2D pCam); | ||
|
||
public event TweenInterruptedEventHandler? TweenInterrupted; | ||
|
||
private readonly Callable _callableTweenInterrupted; | ||
|
||
public Vector2 Zoom | ||
{ | ||
get => (Vector2)Node.Call(MethodName.GetZoom); | ||
set => Node.Call(MethodName.SetZoom, value); | ||
} | ||
|
||
public bool SnapToPixel | ||
{ | ||
get => (bool)Node.Call(MethodName.GetSnapToPixel); | ||
set => Node.Call(MethodName.SetSnapToPixel, value); | ||
} | ||
|
||
public int LimitLeft | ||
{ | ||
get => (int)Node.Call(MethodName.GetLimitLeft); | ||
set => Node.Call(MethodName.SetLimitLeft, value); | ||
} | ||
|
||
public int LimitTop | ||
{ | ||
get => (int)Node.Call(MethodName.GetLimitTop); | ||
set => Node.Call(MethodName.SetLimitTop, value); | ||
} | ||
|
||
public int LimitRight | ||
{ | ||
get => (int)Node.Call(MethodName.GetLimitRight); | ||
set => Node.Call(MethodName.SetLimitRight, value); | ||
} | ||
|
||
public int LimitBottom | ||
{ | ||
get => (int)Node.Call(MethodName.GetLimitBottom); | ||
set => Node.Call(MethodName.SetLimitBottom, value); | ||
} | ||
|
||
public Vector4I LimitMargin | ||
{ | ||
get => (Vector4I)Node.Call(MethodName.GetLimitMargin); | ||
set => Node.Call(MethodName.SetLimitMargin, value); | ||
} | ||
|
||
public static PhantomCamera2D FromScript(string path) => new(GD.Load<GDScript>(path).New().AsGodotObject()); | ||
public static PhantomCamera2D FromScript(GDScript script) => new(script.New().AsGodotObject()); | ||
|
||
public PhantomCamera2D(GodotObject phantomCameraNode) : base(phantomCameraNode) | ||
{ | ||
_callableTweenInterrupted = Callable.From<Node2D>(pCam => TweenInterrupted?.Invoke(pCam)); | ||
Node.Connect(SignalName.TweenInterrupted, _callableTweenInterrupted); | ||
} | ||
|
||
~PhantomCamera2D() | ||
{ | ||
Node.Disconnect(SignalName.TweenInterrupted, _callableTweenInterrupted); | ||
} | ||
|
||
public void SetLimitTarget(TileMap tileMap) | ||
{ | ||
Node.Call(MethodName.SetLimitTarget, tileMap.GetPath()); | ||
} | ||
|
||
public void SetLimitTarget(CollisionShape2D shape2D) | ||
{ | ||
Node.Call(MethodName.SetLimitTarget, shape2D.GetPath()); | ||
} | ||
|
||
public LimitTargetQueryResult? GetLimitTarget() | ||
{ | ||
var result = (NodePath)Node.Call(MethodName.GetLimitTarget); | ||
return result.IsEmpty ? null : new LimitTargetQueryResult(Node2D.GetNode(result)); | ||
} | ||
|
||
public void SetLimit(Side side, int value) | ||
{ | ||
Node.Call(MethodName.SetLimit, (int)side, value); | ||
} | ||
|
||
public int GetLimit(Side side) | ||
{ | ||
return (int)Node.Call(MethodName.GetLimit, (int)side); | ||
} | ||
|
||
public new static class MethodName | ||
{ | ||
public const string GetZoom = "get_zoom"; | ||
public const string SetZoom = "set_zoom"; | ||
|
||
public const string GetSnapToPixel = "get_snap_to_pixel"; | ||
public const string SetSnapToPixel = "set_snap_to_pixel"; | ||
|
||
public const string GetLimit = "get_limit"; | ||
public const string SetLimit = "set_limit"; | ||
|
||
public const string GetLimitLeft = "get_limit_left"; | ||
public const string SetLimitLeft = "set_limit_left"; | ||
|
||
public const string GetLimitTop = "get_limit_top"; | ||
public const string SetLimitTop = "set_limit_top"; | ||
|
||
public const string GetLimitRight = "get_limit_right"; | ||
public const string SetLimitRight = "set_limit_right"; | ||
|
||
public const string GetLimitBottom = "get_limit_bottom"; | ||
public const string SetLimitBottom = "set_limit_bottom"; | ||
|
||
public const string GetLimitTarget = "get_limit_target"; | ||
public const string SetLimitTarget = "set_limit_target"; | ||
|
||
public const string GetLimitMargin = "get_limit_margin"; | ||
public const string SetLimitMargin = "set_limit_margin"; | ||
} | ||
} | ||
|
||
public class LimitTargetQueryResult | ||
{ | ||
private readonly GodotObject _obj; | ||
|
||
public bool IsTileMap => _obj.IsClass("TileMap"); | ||
|
||
public bool IsCollisionShape2D => _obj.IsClass("CollisionShape2D"); | ||
|
||
public LimitTargetQueryResult(GodotObject godotObject) => _obj = godotObject; | ||
|
||
public TileMap? AsTileMap() | ||
{ | ||
return IsTileMap ? (TileMap)_obj : null; | ||
} | ||
|
||
public CollisionShape2D? AsCollisionShape2D() | ||
{ | ||
return IsCollisionShape2D ? (CollisionShape2D)_obj : null; | ||
} | ||
} |
Oops, something went wrong.