One of DFGUI's cool features is the ability to inline-embed images in a dfLabel to avoid having separate sprites layered on top of the dfLabel.
To embed sprites in a dfLabel, you must first make sure that the Process Markup checkbox (Label Properties->Formatting) is ticked.
Then, embedding sprites is done using the sprite tag: Press [sprite "xbox_a"] to Select
The sprite that is specified in the sprite tag (in my case it's "xbox_a") is fetched from the Atlas that is specified on the dfLabel.
Friday, December 20, 2013
Embedding sprites in a dfLabel with DFGUI
Posted by
Andreas Grech
at
12:08 PM
Embedding sprites in a dfLabel with DFGUI
2013-12-20T12:08:00+01:00
Andreas Grech
DFGUI|Game Development|Unity 3D|
Comments
Labels:
DFGUI,
Game Development,
Unity 3D
Friday, December 13, 2013
A 2D Freeform Directional Blend Tree for locomotion in Unity 3D
This video demonstrates a root-motion driven, 2D Freeform Directional Blend Tree for locomotive states in Unity 3D.
Using such a blend tree, a character can aim and walk in different directions independently and simultaneously.
With a gamepad, I'm moving the character with the left stick and rotating with the right stick.
I am using a total of 9 animations for the blend tree. Four for each axis and the middle one for idle:
Here's a closer look at the blend tree and its motions:
This locomotive blend tree exists on an Animator Layer called LowerBody which has has an Avatar Mask applied with only the legs selected (including IK). By having layers representing different sections of the body, I can combine upper-body animations with lower-body animations. In my case, the character can walk/run and aim at the same time using a single animation for AIMING (which exists on the upper-body layer).
This is the Avatar Mask I use on the Lower-Body layer on which the locomotion blend tree exists:
I am controlling the blend tree with two parameters representing a direction vector: VelX and VelZ.
This direction vector determines the locomotive state of the character i.e. which direction his legs should be moving.
This is the gist of the code which both a) sets the (VelX, VelZ) direction vector [Left Stick] i.e. LOCOMOTION and b) rotates the model to aim [Right Stick] i.e ROTATION:
The soldier model and animations are from Mixamo.
Using such a blend tree, a character can aim and walk in different directions independently and simultaneously.
With a gamepad, I'm moving the character with the left stick and rotating with the right stick.
I am using a total of 9 animations for the blend tree. Four for each axis and the middle one for idle:
- Idle
- Forward Walk
- Backward Walk
- Left Strafe Walk
- Right Strafe Walk
- Forward Run
- Backward Run
- Left Strafe Run
- Right Strafe Run
Here's a closer look at the blend tree and its motions:
This locomotive blend tree exists on an Animator Layer called LowerBody which has has an Avatar Mask applied with only the legs selected (including IK). By having layers representing different sections of the body, I can combine upper-body animations with lower-body animations. In my case, the character can walk/run and aim at the same time using a single animation for AIMING (which exists on the upper-body layer).
This is the Avatar Mask I use on the Lower-Body layer on which the locomotion blend tree exists:
I am controlling the blend tree with two parameters representing a direction vector: VelX and VelZ.
This direction vector determines the locomotive state of the character i.e. which direction his legs should be moving.
- If (VelX, VelZ) is (0, 1), the character runs forward in a straight line.
- If (VelX, VelZ) is (-1, 0.5), the character walks forward while strafing to the left.
- If (VelX, VelZ) is (0.5, -1), the character runs backwards while slightly strafing to the right
- etc...
This is the gist of the code which both a) sets the (VelX, VelZ) direction vector [Left Stick] i.e. LOCOMOTION and b) rotates the model to aim [Right Stick] i.e ROTATION:
private Vector3 lastLeftStickInputAxis; // stores the axis input from the left stick between frames private void Update() { /* START LOCOMOTION */ // Get the axis from the left stick (a Vector2 with the left stick's direction) var leftStickInputAxis = inputManager.LeftAxis; // Get the angle between the the direction the model is facing and the input axis vector var a = SignedAngle(new Vector3(leftStickInputAxis.x, 0, leftStickInputAxis.y), model.transform.forward); // Normalize the angle if (a < 0) { a *= -1; } else { a = 360 - a; } // Take into consideration the angle of the camera a += Camera.main.transform.eulerAngles.y; var aRad = Mathf.Deg2Rad*a; // degrees to radians // If there is some form of input, calculate the new axis relative to the rotation of the model if (leftStickInputAxis.x != 0 || leftStickInputAxis.y != 0) { leftStickInputAxis = new Vector2(Mathf.Sin(aRad), Mathf.Cos(aRad)); } float xVelocity = 0f, yVelocity = 0f; float smoothTime = 0.05f; // Interpolate between the input axis from the last frame and the new input axis we calculated leftStickInputAxis = new Vector2(Mathf.SmoothDamp(lastLeftStickInputAxis.x, leftStickInputAxis.x, ref xVelocity, smoothTime), Mathf.SmoothDamp(lastLeftStickInputAxis.y, leftStickInputAxis.y, ref yVelocity, smoothTime)); // Update the Animator with our values so that the blend tree updates animator.SetFloat("VelX", leftStickInputAxis.x); animator.SetFloat("VelZ", leftStickInputAxis.y); lastLeftStickInputAxis = leftStickInputAxis; /* END LOCOMOTION */ /* START ROTATION */ // Get the axis from the right stick (a Vector2 with the right stick's direction) var rightStickInputAxis = inputManager.RightAxis; if (rightStickInputAxis.x != 0 || rightStickInputAxis.y != 0) { float angle2 = 0; if (rightStickInputAxis.x != 0 || rightStickInputAxis.y != 0) { angle2 = Mathf.Atan2(rightStickInputAxis.x, rightStickInputAxis.y)*Mathf.Rad2Deg; if (angle2 < 0) { angle2 = 360 + angle2; } } // Calculate the new rotation for the model and apply it var rotationTo = Quaternion.Euler(0, angle2 + Camera.main.transform.eulerAngles.y, 0); model.transform.rotation = Quaternion.Slerp(model.transform.rotation, rotationTo, Time.deltaTime*10); } /* END ROTATION */ } private float SignedAngle(Vector3 a, Vector3 b) { return Vector3.Angle(a, b) * Mathf.Sign(Vector3.Cross(a, b).y); }
The soldier model and animations are from Mixamo.
Posted by
Andreas Grech
at
5:12 PM
A 2D Freeform Directional Blend Tree for locomotion in Unity 3D
2013-12-13T17:12:00+01:00
Andreas Grech
C#|Game Development|Unity 3D|
Comments
Labels:
C#,
Game Development,
Unity 3D
Thursday, December 12, 2013
Keeping track of cooldowns with a helper class in Unity 3D
For my current project, I wrote a simple class to keep track of my cooldowns.
So for example, my character can fire every 2 seconds, jump every 4 seconds and sprint every 3.142 seconds; and this class takes care of the cooldown timers for me.
Here's how I use it:
And this here's the CooldownTimer class:
So for example, my character can fire every 2 seconds, jump every 4 seconds and sprint every 3.142 seconds; and this class takes care of the cooldown timers for me.
Here's how I use it:
public class Player : MonoBehaviour { private CooldownTimer firingCooldown; private CooldownTimer sprintCooldown; private void Awake() { firingCooldown = new CooldownTimer(2f); // the player can fire every 2 seconds sprintCooldown = new CooldownTimer(3.142f); // the player can sprint every 3.142 seconds } private void Update() { if (Input.GetButtonDown("Fire") && firingCooldown.CanWeDoAction()) { firingCooldown.UpdateActionTime(); // Do firing logic } if (Input.GetButtonDown("Sprint") && sprintCooldown.CanWeDoAction()) { sprintCooldown.UpdateActionTime(); // Do sprinting logic } } }
And this here's the CooldownTimer class:
using System; public class CooldownTimer { private float? LastActionDone { get; set; } private float IntervalSeconds { get; set; } public CooldownTimer(float intervalSeconds) { IntervalSeconds = intervalSeconds; } public void UpdateActionTime() { LastActionDone = Time.time; } public bool CanWeDoAction() { var canWeDoAction = true; if (LastActionDone.HasValue) { var secondsSinceLastAction = Time.time - LastActionDone; canWeDoAction = secondsSinceLastAction > IntervalSeconds; } return canWeDoAction; } }
Update 1
With a tip from Petr Kolda (Facebook), I've now modified the class to use Time.time instead of DateTime.Now.
Posted by
Andreas Grech
at
2:53 PM
Keeping track of cooldowns with a helper class in Unity 3D
2013-12-12T14:53:00+01:00
Andreas Grech
C#|Game Development|Unity 3D|
Comments
Labels:
C#,
Game Development,
Unity 3D
Wednesday, December 11, 2013
Opening multiple instances of Unity 3D
To open multiple instances of Unity 3D, go to Edit > Preferences, and from there tick the "Always Show Project Wizard" checkbox:
Pixel Perfect sprites in Unity 2D
In Unity 4.3, native 2D tools were introduced in Unity 3D. So, armed with a bunch of 1024x768 sprites from an old game I wrote, I decided to try out the new 2D tools by trying to port the old game to Unity 2D.
But the first issue I encountered when dragging in my first sprite to the scene was this:
Notice how even though my game resolution is set to 1024x768 (top corner) and my water image is 1024x768 and centered on the screen, the sprite (SpriteRenderer) doesn't fill the screen as it should.
The way to fix this is by changing the Size of your orthographic Camera.
To calculate the Size for your Camera, use this: Camera Size = (GameTargetHeight / 2) / PixelsToUnits
By default, Pixels To Units is set to 100.
So, since my game targets a resolution of 1024x768, my Camera Size would be: (768/2)/100 = 3.84
And as you can see, that fixes the problem beautifully:
But the first issue I encountered when dragging in my first sprite to the scene was this:
Notice how even though my game resolution is set to 1024x768 (top corner) and my water image is 1024x768 and centered on the screen, the sprite (SpriteRenderer) doesn't fill the screen as it should.
The way to fix this is by changing the Size of your orthographic Camera.
To calculate the Size for your Camera, use this: Camera Size = (GameTargetHeight / 2) / PixelsToUnits
By default, Pixels To Units is set to 100.
So, since my game targets a resolution of 1024x768, my Camera Size would be: (768/2)/100 = 3.84
And as you can see, that fixes the problem beautifully:
Posted by
Andreas Grech
at
1:07 PM
Pixel Perfect sprites in Unity 2D
2013-12-11T13:07:00+01:00
Andreas Grech
Game Development|Unity 3D|
Comments
Labels:
Game Development,
Unity 3D
Subscribe to:
Posts (Atom)