topical media & game development
lib-unity-tutorial-gameplay-Assets-Scripts-2D-Spaceship-Spaceship.js / js
//What is our forward direction? Our spaceship moves in the positive y direction.
var forwardDirection : Vector3 = Vector3 (0.0, 1.0, 0.0);
// Below we create two helper classes, MovementSettings and SpecialEffects
// Although the helper classes are not necessary, it makes for nice clean code and usage.
class MovementSettings {
// What is the maximum speed of this movement?
var maxSpeed : float;
// What's the acceleration in the positive and negative directions associated with this movement?
var positiveAcceleration : float;
var negativeAcceleration : float;
// How much drag should we apply when there isn't input for this movement?
var dragWhileCoasting : float;
// How much drag should we apply to slow down the movement for speeds above maxSpeed?
var dragWhileBeyondMaxSpeed : float;
// When neither of the above drag factors are in play, how much drag should there normally be? (Usually very small.)
var dragWhileAcceleratingNormally : float;
// This function determines which drag variable to use and returns one.
function ComputeDrag (input : float, velocity : Vector3) {
//Is the input not zero (the 0.01 allows for some error since we're working with floats and they aren't completely precise)
if (Mathf.Abs (input) > 0.01) {
// Are we greater or less than our max speed? Then return the appropriate drag.
if (velocity.magnitude > maxSpeed)
return dragWhileBeyondMaxSpeed;
else
return dragWhileAcceleratingNormally;
} else
//If the input is zero, use dragWhileCoasting
return dragWhileCoasting;
}
}
class SpecialEffects {
// There are four possible special effects that can be assigned.
var positiveThrustEffect : GameObject;
var negativeThrustEffect : GameObject;
var positiveTurnEffect : GameObject;
var negativeTurnEffect : GameObject;
// How loud should collision sounds be? This is used in the OnCollisionEnter () function.
var collisionVolume = 0.01;
}
// We create two instances using our MovementSettings helper class.
// One will be for translational (position) movement, the other for rotational.
var positionalMovement : MovementSettings;
var rotationalMovement : MovementSettings;
// We create an instance using our SpecialEffects helper class.
var specialEffects : SpecialEffects;
// Can the user control the spaceship currently? This will be toggled by another script that also toggles what the camera should track.
var canControl = true;
//FixedUpdate () is advantageous over Update () for working with rigidbody physics.
function FixedUpdate () {
// Retrieve input. Note the use of GetAxisRaw (), which in this case helps responsiveness of the controls.
// GetAxisRaw () bypasses Unity's builtin control smoothing.
thrust = Input.GetAxisRaw ("Vertical");
turn = Input.GetAxisRaw ("Horizontal");
if (!canControl) {
thrust = 0.0;
turn = 0.0;
}
//Use the MovementSettings class to determine which drag constant should be used for the positional movement.
//Remember the MovementSettings class is a helper class we defined ourselves. See the top of this script.
rigidbody.drag = positionalMovement.ComputeDrag (thrust, rigidbody.velocity);
//Then determine which drag constant should be used for the angular movement.
rigidbody.angularDrag = rotationalMovement.ComputeDrag (turn, rigidbody.angularVelocity);
//Determines which direction the positional and rotational motion is occurring, and then modifies thrust/turn with the given accelerations.
//If you are not familiar with the ?: conditional, it is basically shorthand for an "if..else" statement pair. See http://www.javascriptkit.com/jsref/conditionals.shtml
thrust *= (thrust > 0.0) ? positionalMovement.positiveAcceleration : positionalMovement.negativeAcceleration;
turn *= (turn > 0.0) ? rotationalMovement.positiveAcceleration : rotationalMovement.negativeAcceleration;
// Add torque and force to the rigidbody. Torque will rotate the body and force will move it.
// Always modify your forces by Time.deltaTime in FixedUpdate (), so if you ever need to change your Time.fixedTime setting,
// your setup won't break.
rigidbody.AddRelativeTorque (Vector3 (0.0, 0.0, -1.0) * turn * Time.deltaTime, ForceMode.VelocityChange);
rigidbody.AddRelativeForce (forwardDirection * thrust * Time.deltaTime, ForceMode.VelocityChange);
}
// This function allows us to SendMessage to an object to set whether or not the player can control it
function SetControllable (controllable : boolean) {
canControl = controllable;
}
// The Update () function only serves to provide special effects in this case.
function Update () {
//Collecting appropriate input.
thrust = Input.GetAxisRaw ("Vertical");
turn = Input.GetAxisRaw ("Horizontal");
if (!canControl) {
thrust = 0.0;
turn = 0.0;
}
// If the thrust effect slots aren't null in the inspector, send a message.
// The message will be received by the component SpecialEffectHandler
// If the boolean statement is true, (e.g. (thrust > 0.01)) then the special effects will be enabled.
if (specialEffects.positiveThrustEffect)
specialEffects.positiveThrustEffect.SendMessage ("SetSpecialEffectActive", (thrust > 0.01));
if (specialEffects.negativeThrustEffect)
specialEffects.negativeThrustEffect.SendMessage ("SetSpecialEffectActive", (thrust < -0.01));
if (specialEffects.positiveTurnEffect)
specialEffects.positiveTurnEffect.SendMessage ("SetSpecialEffectActive", (turn > 0.01));
if (specialEffects.negativeTurnEffect)
specialEffects.negativeTurnEffect.SendMessage ("SetSpecialEffectActive", (turn < -0.01));
}
// The OnCollisionEnter () function only serves to provide special effects in this case.
function OnCollisionEnter (collision : Collision) {
// Get the component "CollisionSoundEffect" of the object we collided with.
// The platforms in this tutorial have a CollisionSoundEffect component.
var collisionSoundEffect : CollisionSoundEffect = collision.gameObject.GetComponent (CollisionSoundEffect);
// If collisionSoundEffect isn't null, get the audio clip, set the volume, and play.
if (collisionSoundEffect) {
audio.clip = collisionSoundEffect.audioClip;
// By multiplying by collision.relativeVelocity.sqrMagnitude, the sound will be louder for faster impacts.
audio.volume = collisionSoundEffect.volumeModifier * collision.relativeVelocity.sqrMagnitude * specialEffects.collisionVolume;
audio.Play ();
}
}
// The Reset () function is called by Unity when you first add a script, and when you choose Reset on the
// gear popup menu for the script.
function Reset () {
// Set some nice default values for our MovementSettings.
// Of course, it is always best to tweak these for your specific game.
positionalMovement.maxSpeed = 3.0;
positionalMovement.dragWhileCoasting = 3.0;
positionalMovement.dragWhileBeyondMaxSpeed = 4.0;
positionalMovement.dragWhileAcceleratingNormally = 0.01;
positionalMovement.positiveAcceleration = 50.0;
// By default, we don't have reverse thrusters.
positionalMovement.negativeAcceleration = 0.0;
rotationalMovement.maxSpeed = 2.0;
rotationalMovement.dragWhileCoasting = 32.0;
rotationalMovement.dragWhileBeyondMaxSpeed = 16.0;
rotationalMovement.dragWhileAcceleratingNormally = 0.1;
// For rotation, acceleration is usually the same in both directions.
// It could make for interesting unique gameplay if it were significantly
// different, however!
rotationalMovement.positiveAcceleration = 50.0;
rotationalMovement.negativeAcceleration = 50.0;
}
// In order for this script to work, the object its applied to must have a Rigidbody and AudioSource component.
// This tells Unity to always have the components when this script is attached.
@script RequireComponent (Rigidbody, AudioSource)
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.