Created
June 5, 2026 19:12
-
-
Save lucasteles/074730548267988c23b41655aa8ee8c1 to your computer and use it in GitHub Desktop.
Godot Billboard "2.5D" Node
This file contains hidden or 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
| public enum FacingSide : sbyte | |
| { | |
| None = 0, | |
| Left = -1, | |
| Right = 1, | |
| } |
This file contains hidden or 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
| using System.Runtime.CompilerServices; | |
| public partial class Node25D : Node3D | |
| { | |
| [Export] | |
| public Camera3D Camera; | |
| [Export] | |
| protected bool mirror = true; | |
| [Export] | |
| public FacingSide FacingSide { get; private set; } = FacingSide.Right; | |
| [ExportGroup("Billboard", "billboard")] | |
| [Export] | |
| bool billboardEnabled = true; | |
| [Export(PropertyHint.Range, "0,1")] | |
| float billboardWeight = 0.5f; | |
| bool lookUseModelFront = true; | |
| Vector3 lookModelUp = Vector3.Up; | |
| public void SetFacingSide(FacingSide side) | |
| { | |
| if (FacingSide == side) return; | |
| FacingSide = side; | |
| ApplyFacingSide(); | |
| } | |
| public override void _Ready() | |
| { | |
| if (!IsInstanceValid(Camera)) | |
| Camera = GetViewport().GetCamera3D(); | |
| ApplyFacingSide(); | |
| } | |
| public override void _PhysicsProcess(double delta) => LookAtCamera(); | |
| void ApplyFacingSide() | |
| { | |
| var basis = GetBasis(); | |
| if (FacingSide is FacingSide.Left) | |
| { | |
| basis.X = Vector3.Left; | |
| lookUseModelFront = false; | |
| lookModelUp = Vector3.Down; | |
| } | |
| else | |
| { | |
| basis.X = Vector3.Right; | |
| lookUseModelFront = true; | |
| lookModelUp = Vector3.Up; | |
| } | |
| SetBasis(basis); | |
| } | |
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |
| void LookAtCamera() | |
| { | |
| if (!billboardEnabled) return; | |
| var targetX = Mathf.Lerp(GlobalPosition.X, Camera.GlobalPosition.X, billboardWeight); | |
| Vector3 target = new(targetX, GlobalPosition.Y, Camera.GlobalPosition.Z); | |
| LookAt(target, lookModelUp, lookUseModelFront); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment