- Home /
C# from Unity to Unity iPhone
I'm trying to implement the code below. It's C# and works fine in Unity Basic. It's won't compile in Unity iPhone. I'm trying to understand the difference between C# in Unity vs Unity iPhone. I've included the script, original post link and errors. Thanks in advance for any insight you can provide.
http://forum.unity3d.com/viewtopic.php?t=45238&highlight=controller2d
Assets/Scripts/Controller2D.cs(140,56): error CS1002: Expecting
;' (Filename: Assets/Scripts/Controller2D.cs Line: 140) Assets/Scripts/Controller2D.cs(306,90): error CS1002: Expecting
;' (Filename: Assets/Scripts/Controller2D.cs Line: 306) Assets/Scripts/Controller2D.cs(313,10): error CS0116: A namespace can only contain types and namespace declarations (Filename: Assets/Scripts/Controller2D.cs Line: 313) Assets/Scripts/Controller2D.cs(395,10): error CS0116: A namespace can only contain types and namespace declarations (Filename: Assets/Scripts/Controller2D.cs Line: 395) Assets/Scripts/Controller2D.cs(409,11): error CS0116: A namespace can only contain types and namespace declarations (Filename: Assets/Scripts/Controller2D.cs Line: 409) Assets/Scripts/Controller2D.cs(415,13): error CS0116: A namespace can only contain types and namespace declarations (Filename: Assets/Scripts/Controller2D.cs Line: 415) Assets/Scripts/Controller2D.cs(421,10): error CS0116: A namespace can only contain types and namespace declarations (Filename: Assets/Scripts/Controller2D.cs Line: 421) Assets/Scripts/Controller2D.cs(426,10): error CS0116: A namespace can only contain types and namespace declarations (Filename: Assets/Scripts/Controller2D.cs Line: 426) Assets/Scripts/Controller2D.cs(431,10): error CS0116: A namespace can only contain types and namespace declarations (Filename: Assets/Scripts/Controller2D.cs Line: 431) Assets/Scripts/Controller2D.cs(436,10): error CS0116: A namespace can only contain types and namespace declarations (Filename: Assets/Scripts/Controller2D.cs Line: 436) Assets/Scripts/Controller2D.cs(441,10): error CS0116: A namespace can only contain types and namespace declarations (Filename: Assets/Scripts/Controller2D.cs Line: 441) Assets/Scripts/Controller2D.cs(446,13): error CS0116: A namespace can only contain types and namespace declarations (Filename: Assets/Scripts/Controller2D.cs Line: 446) Assets/Scripts/Controller2D.cs(451,11): error CS0116: A namespace can only contain types and namespace declarations (Filename: Assets/Scripts/Controller2D.cs Line: 451) Assets/Scripts/Controller2D.cs(456,10): error CS0116: A namespace can only contain types and namespace declarations (Filename: Assets/Scripts/Controller2D.cs Line: 456) Assets/Scripts/Controller2D.cs(460,10): error CS0116: A namespace can only contain types and namespace declarations (Filename: Assets/Scripts/Controller2D.cs Line: 460)
Controller2D.cs [code]using UnityEngine; [RequireComponent(typeof(CharacterController))] [AddComponentMenu("2D Platformer/Controller2D")]
public class Controller2D : MonoBehaviour {
// Require a character controller to be attached to the same game object [System.Serializable] public class PlatformerControllerMovement { // The speed when walking public float walkSpeed = 3.0f; // when pressing "Fire1" button (control) we start running public float runSpeed = 10.0f;
public float inAirControlAcceleration = 1.0f;
// The gravity for the character
public float gravity = 60.0f;
public float maxFallSpeed = 20.0f;
// How fast does the character change speeds? Higher is faster.
public float speedSmoothing = 20.0f;
// This controls how fast the graphics of the character "turn around" when the player turns around using the controls.
public float rotationSmoothing = 10.0f;
// The current move direction in x-y. This will always been (1,0,0) or (-1,0,0)
// The next line, @System.NonSerialized , tells Unity to not serialize the variable or show it in the inspector view. Very handy for organization!
[System.NonSerialized]
public Vector3 direction = Vector3.zero;
// The current vertical speed
[System.NonSerialized]
public float verticalSpeed = 0.0f;
// The current movement speed. This gets smoothed by speedSmoothing.
[System.NonSerialized]
public float speed = 0.0f;
// Is the user pressing the left or right movement keys?
[System.NonSerialized]
public bool isMoving = false;
// The last collision flags returned from controller.Move
[System.NonSerialized]
public CollisionFlags collisionFlags;
// We will keep track of an approximation of the character's current velocity, so that we return it from GetVelocity () for our camera to use for prediction.
[System.NonSerialized]
public Vector3 velocity;
// This keeps track of our current velocity while we're not grounded?
[System.NonSerialized]
public Vector3 inAirVelocity = Vector3.zero;
// This will keep track of how long we have we been in the air (not grounded)
[System.NonSerialized]
public float hangTime = 0.0f;
}
[System.Serializable]
// We will contain all the jumping related variables in one helper class for clarity.
public class PlatformerControllerJumping
{
// Can the character jump?
public bool enabled = true;
// How high do we jump when pressing jump and letting go immediately
public float height = 1.0f;
// We add extraHeight units (meters) on top when holding the button down longer while jumping
public float extraHeight = 4.1f;
public float doubleJumpHeight = 2.1f;
// This prevents inordinarily too quick jumping
// The next line, @System.NonSerialized , tells Unity to not serialize the variable or show it in the inspector view. Very handy for organization!
[System.NonSerialized]
public float repeatTime = 0.05f;
[System.NonSerialized]
public float timeout = 0.15f;
// Are we jumping? (Initiated with jump button and not grounded yet)
[System.NonSerialized]
public bool jumping = false;
// Are where double jumping? ( Initiated when jumping or falling after pressing the jump button )
[System.NonSerialized]
public bool doubleJumping = false;
// Can we make a double jump ( we can't make two double jump or more at the same jump )
[System.NonSerialized]
public bool canDoubleJump = false;
[System.NonSerialized]
public bool reachedApex = false;
// Last time the jump button was clicked down
[System.NonSerialized]
public float lastButtonTime = -10.0f;
// Last time we performed a jump
[System.NonSerialized]
public float lastTime = -1.0f;
// the height we jumped from (Used to determine for how long to apply extra jump power after jumping.)
[System.NonSerialized]
public float lastStartHeight = 0.0f;
}
// Does this script currently respond to Input?
public bool canControl = true;
// The character will spawn at spawnPoint's position when needed. This could be changed via a script at runtime to implement, e.g. waypoints/savepoints.
public Transform spawnPoint;
public PlatformerControllerMovement movement;
public PlatformerControllerJumping jump;
private CharacterController controller;
// Moving platform support.
private Transform activePlatform;
private Vector3 activeLocalPlatformPoint;
private Vector3 activeGlobalPlatformPoint;
private Vector3 lastPlatformVelocity;
// This is used to keep track of special effects in UpdateEffects ();
private bool areEmittersOn = false;
void Awake()
{
movement = new PlatformerControllerMovement();
jump = new PlatformerControllerJumping();
movement.direction = transform.TransformDirection(Vector3.forward);
controller = GetComponent<CharacterController>();
Spawn();
}
void Spawn()
{
// reset the character's speed
movement.verticalSpeed = 0.0f;
movement.speed = 0.0f;
// reset the character's position to the spawnPoint
transform.position = spawnPoint.position;
}
void OnDeath()
{
Spawn();
}
void UpdateSmoothedMovementDirection()
{
float h = Input.GetAxisRaw("Horizontal");
if (!canControl)
h = 0.0f;
movement.isMoving = Mathf.Abs(h) > 0.1;
if (movement.isMoving)
movement.direction = new Vector3(h, 0, 0);
// Grounded controls
//if (controller.isGrounded)
//{
// Smooth the speed based on the current target direction
float curSmooth = movement.speedSmoothing * Time.deltaTime;
// Choose target speed
float targetSpeed = Mathf.Min(Mathf.Abs(h), 1.0f);
// Pick speed modifier
/*
if (Input.GetButton ("Fire2") && canControl)
targetSpeed *= movement.runSpeed;
else
targetSpeed *= movement.walkSpeed;
*/
targetSpeed *= movement.runSpeed;
movement.speed = Mathf.Lerp(movement.speed, targetSpeed, curSmooth);
movement.hangTime = 0.0f;
//}
//else
//{
// // In air controls
// movement.hangTime += Time.deltaTime;
// if (movement.isMoving)
// movement.inAirVelocity += new Vector3(Mathf.Sign(h), 0, 0) * Time.deltaTime * movement.inAirControlAcceleration;
//}
}
void FixedUpdate()
{
// Make sure we are absolutely always in the 2D plane.
transform.position = new Vector3(transform.position.x, transform.position.y, 0.0f);
}
void ApplyJumping()
{
// Prevent jumping too fast after each other
if (jump.lastTime + jump.repeatTime > Time.time)
return;
if (controller.isGrounded)
{
// Jump
// - Only when pressing the button down
// - With a timeout so you can press the button slightly before landing
if (jump.enabled && Time.time < jump.lastButtonTime + jump.timeout)
{
movement.verticalSpeed = CalculateJumpVerticalSpeed(jump.height);
movement.inAirVelocity = lastPlatformVelocity;
SendMessage("DidJump", SendMessageOptions.DontRequireReceiver);
}
}
}
void ApplyGravity()
{
// Apply gravity
bool jumpButton = Input.GetButton("Jump");
if (!canControl)
jumpButton = false;
// When we reach the apex of the jump we send out a message
if (jump.jumping && !jump.reachedApex && movement.verticalSpeed <= 0.0)
{
jump.reachedApex = true;
SendMessage("DidJumpReachApex", SendMessageOptions.DontRequireReceiver);
}
// if we are jumping and we press jump button, we do a double jump or
// if we are falling, we can do a double jump to
if ((jump.jumping && Input.GetButtonUp("Jump") && !jump.doubleJumping) || (!controller.isGrounded && !jump.jumping && !jump.doubleJumping && movement.verticalSpeed < -12.0))
{
jump.canDoubleJump = true;
}
// if we can do a double jump, and we press the jump button, we do a double jump
if (jump.canDoubleJump && Input.GetButtonDown("Jump") && !IsTouchingCeiling())
{
jump.doubleJumping = true;
movement.verticalSpeed = CalculateJumpVerticalSpeed(jump.doubleJumpHeight);
jump.canDoubleJump = false;
}
// * When jumping up we don't apply gravity for some time when the user is holding the jump button
// This gives more control over jump height by pressing the button longer
bool extraPowerJump = jump.jumping && !jump.doubleJumping && movement.verticalSpeed > 0.0 && jumpButton && transform.position.y < jump.lastStartHeight + jump.extraHeight && !IsTouchingCeiling();
if (extraPowerJump)
return;
else if (controller.isGrounded)
{
movement.verticalSpeed = -movement.gravity * Time.deltaTime;
jump.canDoubleJump = false;
}
else
movement.verticalSpeed -= movement.gravity * Time.deltaTime;
// Make sure we don't fall any faster than maxFallSpeed. This gives our character a terminal velocity.
movement.verticalSpeed = Mathf.Max(movement.verticalSpeed, -movement.maxFallSpeed);
}
float CalculateJumpVerticalSpeed(float targetJumpHeight)
{
// From the jump height and gravity we deduce the upwards speed
// for the character to reach at the apex.
return Mathf.Sqrt(2 * targetJumpHeight * movement.gravity);
}
void DidJump()
{
jump.jumping = true;
jump.reachedApex = false;
jump.lastTime = Time.time;
jump.lastStartHeight = transform.position.y;
jump.lastButtonTime = -10;
}
void UpdateEffects()
{
bool wereEmittersOn = areEmittersOn;
areEmittersOn = jump.jumping && movement.verticalSpeed > 0.0;
// By comparing the previous value of areEmittersOn to the new one, we will only update the particle emitters when needed
if (wereEmittersOn != areEmittersOn)
{
foreach (ParticleEmitter emitter in GetComponentsInChildren<ParticleEmitter>())
{
emitter.emit = areEmittersOn;
}
}
}
void Update()
{
if (Input.GetButtonDown("Jump") && canControl)
{
jump.lastButtonTime = Time.time;
}
UpdateSmoothedMovementDirection();
// Apply gravity
// - extra power jump modifies gravity
ApplyGravity();
// Apply jumping logic
ApplyJumping();
// Moving platform support
if (activePlatform != null)
{
Vector3 newGlobalPlatformPoint = activePlatform.TransformPoint(activeLocalPlatformPoint);
Vector3 moveDistance = (newGlobalPlatformPoint - activeGlobalPlatformPoint);
transform.position = transform.position + moveDistance;
lastPlatformVelocity = (newGlobalPlatformPoint - activeGlobalPlatformPoint) / Time.deltaTime;
}
else
{
lastPlatformVelocity = Vector3.zero;
}
activePlatform = null;
// Save lastPosition for velocity calculation.
Vector3 lastPosition = transform.position;
// Calculate actual motion
Vector3 currentMovementOffset = movement.direction * movement.speed + new Vector3(0, movement.verticalSpeed, 0) + movement.inAirVelocity;
// We always want the movement to be framerate independent. Multiplying by Time.deltaTime does this.
currentMovementOffset *= Time.deltaTime;
// Move our character!
movement.collisionFlags = controller.Move(currentMovementOffset);
// Calculate the velocity based on the current and previous position.
// This means our velocity will only be the amount the character actually moved as a result of collisions.
movement.velocity = (transform.position - lastPosition) / Time.deltaTime;
// Moving platforms support
if (activePlatform != null)
{
activeGlobalPlatformPoint = transform.position;
activeLocalPlatformPoint = activePlatform.InverseTransformPoint(transform.position);
}
// Set rotation to the move direction
// if (movement.direction.sqrMagnitude > 0.01 && !Input.GetButton("Shoot")) // transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(movement.direction), Time.deltaTime movement.rotationSmoothing); // else transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(movement.direction), Time.deltaTime 100);
// We are in jump mode but just became grounded
if (controller.isGrounded)
{
movement.inAirVelocity = Vector3.zero;
if (jump.jumping || jump.doubleJumping)
{
jump.jumping = false;
jump.doubleJumping = false;
jump.canDoubleJump = false;
SendMessage("DidLand", SendMessageOptions.DontRequireReceiver);
Vector3 jumpMoveDirection = movement.direction * movement.speed + movement.inAirVelocity;
if (jumpMoveDirection.sqrMagnitude > 0.01)
movement.direction = jumpMoveDirection.normalized;
}
}
// Update special effects like rocket pack particle effects
UpdateEffects();
}
void OnControllerColliderHit(ControllerColliderHit hit)
{
if (hit.moveDirection.y > 0.01f)
return;
// Make sure we are really standing on a straight platform
// Not on the underside of one and not falling down from it either!
if (hit.moveDirection.y < -0.9f && hit.normal.y > 0.9f)
{
activePlatform = hit.collider.transform;
}
}
// Various helper functions below:
float GetSpeed()
{
return movement.speed;
}
Vector3 GetVelocity()
{
return movement.velocity;
}
bool IsMoving()
{
return movement.isMoving;
}
bool IsJumping()
{
return jump.jumping;
}
bool IsDoubleJumping()
{
return jump.doubleJumping;
}
bool canDoubleJump()
{
return jump.canDoubleJump;
}
bool IsTouchingCeiling()
{
return (movement.collisionFlags & CollisionFlags.CollidedAbove) != 0;
}
Vector3 GetDirection()
{
return movement.direction;
}
float GetHangTime()
{
return movement.hangTime;
}
void Reset()
{
gameObject.tag = "Player";
}
void SetControllable(bool controllable)
{
canControl = controllable;
}
}
Answer by Tetrad · Jun 22, 2010 at 09:35 PM
Unity iPhone doesn't implement the generic forms of GetComponent. So you have to do the old-fashioned GetComponent( "CharacterController" )
or GetComponent( typeof( CharacterController ) )
, and cast it back to the type you need (since they both return Component types).
To cast it back you can either use the as
syntax, so GetComponent( typeof( CharacterController ) ) as CharacterController;
or the other type that I like to call C-style casting but probably has a different name (CharacterController)GetComponent( typeof( CharacterController ) );
.
Also you can't use generics at all in Unity iPhone unless you enable .NET 2.1 support in the player preferences.
Answer by Jaap Kreijkamp · Jun 23, 2010 at 01:40 AM
You are compiling .NET2.0 code using .NET1.1, change this to .NET2.0 in Player Settings (Edit -> Project Settings -> Player Settings -> Api Compatibility Level).