I like to get familiar with Unity3d v3, mobile device development, and c#.
MonoDevelop is a great tool for developing Unity 3. It has excellent code completion and line by line debugging. Unfortunately it doesn’t support UnityScript/JavaScript for code completion, so I decided to suck it up and just force myself to go with C#.
Being unfamiliar with Unity development as a whole, I found the Penelope Tutorial fantastic. It is written using the old unity api and with UnityScript. I figured, since I’m going to be going though the tutorial and converting everything to C# and the Unity 3 API I might as make the coding snippets though out the tutorial available as well.
http://unity3d.com/support/resources/tutorials/penelope.html
Here is the first part: pages 19 – 33 of the Penelope PDF converted to c# and using the latest Unity 3 API
So read and follow the text (there are also some coding bits ‘hidden’ in the text not as coding snippets) and when you get to a coding piece just refer to these snippets below.
Complete source from pages 19-33.
Page 19
public void Start ()
{
gui = (GUITexture)GetComponent( typeof(GUITexture) );
}
.
.
Pages 19-20
Since Android is a new platform, looks like unity 3 updated their API to be less specific, so iPhoneInput has turned into Input, these changes are littered though out, so keep an eye out.
{
int count = Input.touchCount;
int i;
for( i = 0; i < count; i++)
{
Touch touch = Input.GetTouch(i);
if( gui.HitTest( touch.position ) )
{
// error is thrown when setting gui.pixelInset directly in c#
Rect tempRect = gui.pixelInset;
tempRect.x = touch.position.x;
tempRect.y = touch.position.y;
gui.pixelInset = tempRect;
}
}
}
.
.
Page 21
private Rect defaultRect;
private Vector2 guiTouchOffset;
public void Start ()
{
gui = (GUITexture)GetComponent( typeof(GUITexture) );
// get where the gui texture was originally placed
defaultRect = gui.pixelInset;
// get our offset for center instead of corner;
guiTouchOffset.x = defaultRect.width * 0.5f;
guiTouchOffset.y = defaultRect.height * 0.5f;
}
public void Update ()
{
int count = Input.touchCount;
int i;
for( i = 0; i < count; i++)
{
Touch touch = Input.GetTouch(i);
Vector2 guiTouchPos = touch.position - guiTouchOffset;
if( gui.HitTest( touch.position ) )
{
Rect tempRect = gui.pixelInset;
tempRect.x = guiTouchPos.x;
tempRect.y = guiTouchPos.y;
gui.pixelInset = tempRect;
}
}
}
.
.
Pages 22-24
private Rect defaultRect;
private Vector2 guiTouchOffset;
public void Start ()
{
gui = (GUITexture)GetComponent( typeof(GUITexture) );
// get where the gui texture was originally placed
defaultRect = gui.pixelInset;
// get our offset for center instead of corner;
guiTouchOffset.x = defaultRect.width * 0.5f;
guiTouchOffset.y = defaultRect.height * 0.5f;
}
public void Reset()
{
gui.pixelInset = defaultRect;
}
public void Update ()
{
int count = Input.touchCount;
// no fingers are touching, so we reset the position
if( count == 0 )
{
Reset();
}
else
{
int i;
for( i = 0; i < count; i++)
{
Touch touch = Input.GetTouch(i);
Vector2 guiTouchPos = touch.position - guiTouchOffset;
if( gui.HitTest( touch.position ) )
{
Rect tempRect = gui.pixelInset;
tempRect.x = guiTouchPos.x;
tempRect.y = guiTouchPos.y;
gui.pixelInset = tempRect;
// another check to see if fingers are touching
if( touch.phase == TouchPhase.Ended
|| touch.phase == TouchPhase.Canceled )
{
Reset();
}
}
}
}
}
.
.
Page 24
{
public Vector2 min = Vector2.zero;
public Vector2 max = Vector2.zero;
}
.
.
Pages 24-25
public void Start()
{
// ...
guiBoundary.min.x = defaultRect.x - guiTouchOffset.x;
guiBoundary.max.x = defaultRect.x + guiTouchOffset.x;
guiBoundary.min.y = defaultRect.y - guiTouchOffset.y;
guiBoundary.max.y = defaultRect.y + guiTouchOffset.y;
}
public void Update()
{
// ...
tempRect.x = Mathf.Clamp( guiTouchPos.x,
guiBoundary.min.x,
guiBoundary.max.x );
tempRect.y = Mathf.Clamp( guiTouchPos.y,
guiBoundary.min.y,
guiBoundary.max.y );
// ...
}
.
.
Page 25 (bottom) Page 26(top) no change
.
.
Page 26:
public void Update ()
{
float absoluteX = (float)Mathf.Abs( position.x );
float absoluteY = (float)Mathf.Abs( position.y );
if( absoluteX < deadZone.x )
{
position.x = 0.0f;
}
if( absoluteY < deadZone.y )
{
position.y = 0.0f;
}
// ...
}
.
.
Page 27
////////
static private float tapTimeDelta = 0.3f;
private float tapTimeWindow;
Page 27 (bottom) and 28 no change
.
.
Page 28-31 And if you noticed, I brace all if statements. This little section here, personally, was very confusing to follow. Put some things out of scope my first go at it.
{
int count = Input.touchCount;
if( tapTimeWindow > 0 )
{
tapTimeWindow -= Time.deltaTime;
}
else
{
tapCount = 0;
}
// no fingers are touching, so we reset the position
if( count == 0 )
{
Reset();
}
else
{
int i;
for( i = 0; i < count; i++)
{
Touch touch = Input.GetTouch(i);
Vector2 guiTouchPos = touch.position - guiTouchOffset;
/////
///// Tutorial cuts in here: When we get to our hit test...
/////
if( gui.HitTest( touch.position ) &&
( (lastFingerId == -1) ||
(lastFingerId != touch.fingerId) ) )
{
lastFingerId = touch.fingerId;
if( tapTimeWindow > 0 )
{
tapCount++;
}
else
{
tapCount = 1;
tapTimeWindow = tapTimeDelta;
}
}
///
/// Tutorial cuts in here as well: We can then use a second check...
///
if( lastFingerId == touch.fingerId )
{
if( touch.tapCount > tapCount )
{
tapCount = touch.tapCount;
}
Rect tempRect = gui.pixelInset;
tempRect.x = Mathf.Clamp( guiTouchPos.x,
guiBoundary.min.x,
guiBoundary.max.x );
tempRect.y = Mathf.Clamp( guiTouchPos.y,
guiBoundary.min.y,
guiBoundary.max.y );
gui.pixelInset = tempRect;
// another check to see if fingers are touching
if( touch.phase == TouchPhase.Ended
|| touch.phase == TouchPhase.Canceled )
{
Reset();
}
}
}
}
////
//// Tutorial cuts in for the last time: Update function...
////
position.x = ( gui.pixelInset.x + guiTouchOffset.x - guiCenter.x ) / guiTouchOffset.x;
position.y = ( gui.pixelInset.y + guiTouchOffset.y - guiCenter.y ) / guiTouchOffset.y;
float absoluteX = (float)Mathf.Abs( position.x );
float absoluteY = (float)Mathf.Abs( position.y );
if( absoluteX < deadZone.x )
{
position.x = 0.0f;
}
if( absoluteY < deadZone.y )
{
position.y = 0.0f;
}
}
.
.
Page 31 – 32
static private bool enumeratedJoysticks = false;
public void Update ()
{
if( !enumeratedJoysticks )
{
joysticks = (Joystick[]) FindObjectsOfType( typeof(Joystick) );
enumeratedJoysticks = true;
}
//...
.
.
Page 32
{
if( lastFingerId == fingerId )
{
Reset();
}
}
.
.
Page 32 – again
{
if( j != this )
{
j.LatchedFinger( touch.fingerId );
}
}
.
.
Page 33
{
gameObject.active = false;
enumeratedJoysticks = false;
}
.
.
Page 33 – Bottom. Included the whole deadzone part to make it a touch less confusing:
float absoluteY = (float)Mathf.Abs( position.y );
if( absoluteX < deadZone.x )
{
position.x = 0.0f;
}
else if( normalize )
{
position.x = Mathf.Sign( position.x ) * ( absoluteX - deadZone.x ) / (1 - deadZone.x );
}
if( absoluteY < deadZone.y )
{
position.y = 0.0f;
}
else if( normalize )
{
position.y = Mathf.Sign( position.y ) * ( absoluteY - deadZone.y ) / ( 1 - deadZone.y);
}
Here is the whole Joystick.cs source from this point in the tutorial.