SoccerTutorial v2
SoccerTutorial v2
Part 1
Contents............................................................................................ 2
Image List
Image 3 - Player................................................................................. 9
Image 12 - The invisible boxes for the free kick trigger .......................... 29
2
Script List
3
Part 1: A Simple Soccer Game
Create the field, the goals and create the script that records the
occurrence of a goal, side kicks, and corner kicks.
Create the score field on the game window that will show the
goals on each side of the field.
4
1.1 The game window
In this game, the parts of the screen that will be shown are A and B.
Parts C, D, E and F will be coded in a future tutorial. The script to
display the score and the clock is:
// SGUI.js
// You can assign here an object of type GUISkin, which sets the GUI style.
// The variables responsible for storing the amount of goals from each
team.
var teamAScore:int= 0;
var teamBScore:int = 0;
var timer:float=0;
5
// Function to show the GUI of the game.
function OnGUI()
if(gSkin)
GUI.skin = gSkin;
// Draw the area that will show the team name and score.
// The score has 2-digits, so the amount of goals goes from 00 to 99.
if (teamAScore < 10 )
message+="0"+teamAScore;
// BRA 00 x ..
message+=" x ";
// BRA 00 x 00 ARG
if (teamBScore < 10 )
message+="0"+teamBScore+" ARG";
timer += Time.deltaTime;
6
GUI.Label ( Rect( Screen.width - 105, 20, 100, 35),
"0"+Mathf.Floor(timer/60)+":0"+Mathf.Floor((timer -
(Mathf.Floor(timer/60)*60))), "label");
else
SoccerPitch
2 2 1
4
1 1
Image 2 - Classes
In the game, there are two teams. Each team has four players
and a goalkeeper.
7
The field has two goals and one ball.
In the event of a goal, the ball goes into the midfield and the
players take their starting positions. The possession of the ball
goes to the team that conceded the goal.
In the event of a corner kick or goal kick, the ball goes into
the midfield. The ball possession goes to the team that was not
with the ball possession.
Player Running ( ok ),
Kicking,
Scoring,
Waiting.
Ball none
Pitch none
Goal none
8
Image 3 - Player
9
Image 6 - Unity3d
10
Image 7 - Unity3d and the soccer field
// BallBehavior.js
var myOwner:Transform;
var iniPosition:Vector3;
var teamA:Transform;
var teamB:Transform;
11
var canMove:boolean;
// Variable used in the function keepPosition, that keeps the ball in this
position.
var lastPosition:Vector3;
function Awake(){
// Start position is set as the position of the ball in the Unity editor.
iniPosition = transform.position;
canMove = true;
lastPosition = iniPosition;
// Update function
function Update () {
if ( !canMove ){
keepPosition();
return;
// If there is one player controlling the ball, the ball must remain in
front of him.
if(myOwner){
transform.position = Vector3(0,transform.position.y,0) +
Vector3(myOwner.position.x,0,myOwner.position.z) + myOwner.forward*2;
12
if(myOwner.GetComponent(CharacterController).velocity.sqrMagnitud
e > 10)
// Goal function.
function OnGoal(){
myOwner = null;
rigidbody.velocity = Vector3.zero;
rigidbody.angularVelocity= Vector3.zero;
// Ball should keep the position until the players take their positions.
canMove= false;
lastPosition = iniPosition;
function keepPosition(){
transform.position=lastPosition;
rigidbody.velocity = Vector3.zero;
rigidbody.angularVelocity= Vector3.zero;
13
// ThrowIn function
function OnThrowIn(){
myOwner = null;
rigidbody.velocity = Vector3.zero;
rigidbody.angularVelocity= Vector3.zero;
lastPosition = transform.position;
Script 1 - BallBehavior.js
14
Image 8 - Defending
15
Image 9 – Atacking
16
Image 10 - Setting up the points
17
// SoccerTeam.js
var controllingPlayer:Transform;
// The player that will give support for the player that is being
controlled.
var supportingPlayer:Transform;
var playerClosestToBall:Transform;
var receivingPlayer:Transform;
var targetGoal:Transform;
var homeGoal:Transform;
// True for Team controlled by the pc, false for controlling team for
the user.
var hasTheBall:boolean;
var opponentTeam:Transform;
var defendingTargets:Transform[];
var attackingTargets:Transform[];
var soccerBall:Transform;
18
// Is the team in attacking?
var isAttacking:boolean;
var isDefending:boolean;
var prepareForKickOff:boolean;
var players:Transform[];
function Awake(){
// it looks for the object with the tag " SoccerBall " and
associates the variable soccerBall to the returned object.
isAttacking = false;
isDefending=true;
prepareForKickOff = true;
setUpPlayers();
if(transform.tag == "RedTeam"){
19
opponentTeam = GameObject.FindWithTag
("BlueTeam").transform;
hasTheBall = true;
// find the closest player to the ball and associates him with the
variable playerClosestToBall
findClosestToBall();
controllingPlayer = playerClosestToBall;
if (!isPC) switchController(controllingPlayer);
defendingFormation();
function setUpPlayers(){
child.gameObject.AddComponent(PCThirdPersonController);
function defendingFormation(){
var x = 0;
20
if( child != controllingPlayer )
child.GetComponent(PCThirdPersonController).targetPoint =
defendingTargets[x];
else
child.GetComponent(PCThirdPersonController).targetPoint =
soccerBall;
x++;
function preparingFormation(){
var x = 0;
var script =
controllingPlayer.GetComponent(ThirdPersonController);
if ( script != null ){
controllingPlayer.Destroy(script);
controllingPlayer.GetComponent(PCThirdPersonController).canM
ove = true;
child.GetComponent(PCThirdPersonController).targetPoint
= defendingTargets[x];
x++;
function attackingFormation(){
var x = 0;
21
if( child != controllingPlayer)
child.GetComponent(PCThirdPersonController).targetPoint =
attackingTargets[x];
else if (
!controllingPlayer.GetComponent(PCThirdPersonController).playerHas
TheBall() )
child.GetComponent(PCThirdPersonController).targetPoint =
soccerBall;
else
child.GetComponent(PCThirdPersonController).targetPoint =
targetGoal;
x++;
function allPlayersAtHome():boolean{
var x = 0;
if ( ( child.position - defendingTargets[x].position
).sqrMagnitude > 3 ) return false;
x++;
return true;
function Update () {
findClosestToBall();
if (prepareForKickOff){
22
// If it is the kick off state, it executes the actions of the
state.
preparingFormation();
if ( allPlayersAtHome() )
if(
(opponentTeam.GetComponent(SoccerTeam).allPlayersAtHome() &&
hasTheBall ) || soccerBall.GetComponent(BallBehavior).myOwner !=
null )
prepareForKickOff = false;
controllingPlayer = playerClosestToBall;
if (!isPC) switchController(controllingPlayer);
soccerBall.GetComponent(BallBehavior).canMove = true;
else
return;
else
return;
23
// Verifies if it is in the throw in state
if(prepareForThrowIn){
preparingFormation();
if ( soccerBall.GetComponent(BallBehavior).myOwner !=
null )
prepareForThrowIn=false;
//findClosestToBall();
controllingPlayer = playerClosestToBall;
if (!isPC) switchController(controllingPlayer);
else
return;
if ( controllingPlayer != playerClosestToBall ){
switchControllingPlayer(playerClosestToBall);
24
if ( isDefending ){
//defending
if(hasTheBall){
isDefending=false;
isAttacking=true;
attackingFormation();
defendingFormation();
} else {
//atacking
if(!hasTheBall){
isDefending=true;
isAttacking=false;
defendingFormation();
attackingFormation();
if (isPC){
direction = targetGoal.position -
controllingPlayer.position;
25
}
function findClosestToBall(){
newDistance = (child.position -
soccerBall.position).sqrMagnitude;
playerClosestToBall = child;
ballSqrDistance = newDistance;
function switchControllingPlayer(newControllingPlayer:Transform){
if (!isPC){
switchController(controllingPlayer);
switchController(newControllingPlayer);
controllingPlayer = newControllingPlayer;
var newScript;
var oldScript;
if (!soccerPlayer.GetComponent(ThirdPersonController)){
newScript =
soccerPlayer.gameObject.AddComponent(ThirdPersonController);
26
soccerPlayer.GetComponent(PCThirdPersonController).canMove
= false;
else
soccerPlayer.GetComponent(PCThirdPersonController).canMove
= true;
oldScript =
soccerPlayer.GetComponent(ThirdPersonController);
soccerPlayer.Destroy(oldScript);
Script 2 - SoccerTeam.js
// goalTrigger.js
27
// The name of the team owning this goal, “TeamA” or “TeamB”, it
has to be defined in the Unity Editor inspector area
var goalTeam:String;
var soccerBall:Transform;
var teamA:Transform;
var teamB:Transform;
function Awake(){
if(other.gameObject.layer==9){
if ( goalTeam=="TeamA" ){
Camera.main.GetComponent(SGUI).teamBScore=Camera.main
.GetComponent(SGUI).teamBScore+1;
teamA.GetComponent(SoccerTeam).hasTheBall =
true;
teamB.GetComponent(SoccerTeam).hasTheBall =
false;
} else {
Camera.main.GetComponent(SGUI).teamAScore=Camera.main
.GetComponent(SGUI).teamAScore+1;
28
teamA.GetComponent(SoccerTeam).hasTheBall =
false;
teamB.GetComponent(SoccerTeam).hasTheBall =
true;
soccerBall.GetComponent (BallBehavior).OnGoal();
teamA.GetComponent(SoccerTeam).prepareForKickOff =
true;
teamB.GetComponent(SoccerTeam).prepareForKickOff =
true;
Script 3 - goalTrigger.js
// FreeKickTrigger.js
var soccerBall:Transform;
var teamA:Transform;
29
var teamB:Transform;
function Awake(){
if(other.gameObject.layer==9){
if ( !teamA.GetComponent(SoccerTeam).hasTheBall ){
teamA.GetComponent(SoccerTeam).hasTheBall =
true;
teamB.GetComponent(SoccerTeam).hasTheBall =
false;
} else {
teamA.GetComponent(SoccerTeam).hasTheBall =
false;
teamB.GetComponent(SoccerTeam).hasTheBall =
true;
soccerBall.GetComponent (BallBehavior).OnGoal();
teamA.GetComponent(SoccerTeam).prepareForKickOff =
true;
teamB.GetComponent(SoccerTeam).prepareForKickOff =
true;
Script 4 - FreeKickTrigger.js
30
Image 13 - The invisible box for the throw in trigger
// throwInTrigger.js
var soccerBall:Transform;
var teamA:Transform;
var teamB:Transform;
function Awake(){
if(other.gameObject.layer==9){
soccerBall.GetComponent (BallBehavior).OnThrowIn();
if ( teamA.GetComponent(SoccerTeam).hasTheBall ==
true ){
teamA.GetComponent(SoccerTeam).hasTheBall =
false;
31
teamB.GetComponent(SoccerTeam).hasTheBall =
true;
teamA.GetComponent(SoccerTeam).prepareForThrowIn= true;
} else {
teamA.GetComponent(SoccerTeam).hasTheBall =
true;
teamB.GetComponent(SoccerTeam).hasTheBall =
false;
teamB.GetComponent(SoccerTeam).prepareForThrowIn = true;
Script 5 - throwInTrigger.js
// PCThirdPersonController.js
var soccerBall:Transform;
var targetPoint:Transform;
32
var canMove:boolean = true;
function Awake ()
//targetPoint = soccerBall;
function HidePlayer()
GameObject.Find("rootJoint").GetComponent(SkinnedMeshRend
erer).enabled = false; // stop rendering the player.
function ShowPlayer()
GameObject.Find("rootJoint").GetComponent(SkinnedMeshRend
erer).enabled = true; // start rendering the player again.
33
isControllable = true; // allow player to control the character
again.
function Update() {
if (canMove){
direction.y = 0;
transform.rotation = Quaternion.Slerp
(transform.rotation, Quaternion.LookRotation(direction), rotateSpeed
* Time.deltaTime);
transform.eulerAngles = Vector3(0,
transform.eulerAngles.y, 0);
var forward =
transform.TransformDirection(Vector3.forward);
speedModifier = Mathf.Clamp01(speedModifier);
34
GetComponent
(CharacterController).SimpleMove(direction);
if (hit.rigidbody == soccerBall.rigidbody){
if (!playerHasTheBall() ||
soccerBall.rigidbody.GetComponent("BallBehavior").myOwner ==
null){
soccerBall.rigidbody.GetComponent("BallBehavior").myOwner =
transform;
transform.parent.GetComponent(SoccerTeam).hasTheBall =
true;
transform.parent.GetComponent(SoccerTeam).opponentTeam.
GetComponent(SoccerTeam).hasTheBall = false;
function playerHasTheBall():boolean{
return
(soccerBall.rigidbody.GetComponent("BallBehavior").myOwner ==
transform);
function Reset ()
35
{
gameObject.tag = "Player";
function kick(kickTarget:Transform){
if
(soccerBall.rigidbody.GetComponent("BallBehavior").myOwner ==
transform ){
soccerBall.rigidbody.GetComponent("BallBehavior").rigidbody.v
elocity =targetDir.normalized*kickSpeed;
soccerBall.rigidbody.GetComponent("BallBehavior").myOwner =
null;
function pass(receiver:Transform){
if
(soccerBall.rigidbody.GetComponent("BallBehavior").myOwner ==
transform ){
36
soccerBall.rigidbody.GetComponent("BallBehavior").rigidbody.v
elocity = targetDir.normalized*passSpeed;
soccerBall.rigidbody.GetComponent("BallBehavior").myOwner =
null;
else
soccerBall.rigidbody.GetComponent("BallBehavior").rigidbody.velocity
= transform.TransformDirection(Vector3(0,0,passSpeed));
soccerBall.rigidbody.GetComponent("BallBehavior").myOwner =
null;
function teamHasTheBall():boolean{
return
transform.parent.GetComponent(SoccerTeam).hasTheBall;
function isPC():boolean{
return transform.parent.GetComponent(SoccerTeam).isPC;
@script RequireComponent(CharacterController)
Script 6 - PCThirdPersonController.js
37
// ThirdPersonController.js
var soccerBall:Transform;
var targetGoal:Transform;
// The camera doesnt start following the target immediately but waits
for a split second to avoid too much waving around.
38
private var verticalSpeed = 0.0;
// When did the user start walking (Used for going into trot after a
while)
function Awake ()
moveDirection =
transform.TransformDirection(Vector3.forward);
targetGoal =
transform.parent.GetComponent(SoccerTeam).targetGoal;
39
// The message is also 'replied to' by identically-named functions in
the collision-handling scripts.
function HidePlayer()
GameObject.Find("rootJoint").GetComponent(SkinnedMeshRend
erer).enabled = false; // stop rendering the player.
function ShowPlayer()
GameObject.Find("rootJoint").GetComponent(SkinnedMeshRend
erer).enabled = true; // start rendering the player again.
function UpdateSmoothedMovementDirection ()
var forward =
cameraTransform.TransformDirection(Vector3.forward);
forward.y = 0;
40
forward = forward.normalized;
var v = Input.GetAxisRaw("Vertical");
var h = Input.GetAxisRaw("Horizontal");
if (v < -0.2)
movingBack = true;
else
movingBack = false;
// Grounded controls
if (grounded)
lockCameraTimer += Time.deltaTime;
if (isMoving != wasMoving)
lockCameraTimer = 0.0;
41
// We store speed and direction seperately,
if (targetDirection != Vector3.zero)
moveDirection = targetDirection.normalized;
else
moveDirection =
Vector3.RotateTowards(moveDirection, targetDirection, rotateSpeed
* Mathf.Deg2Rad * Time.deltaTime, 1000);
moveDirection = moveDirection.normalized;
42
//* We want to support analog input but make sure you
cant walk faster diagonally than just forward or sideways
targetSpeed *= trotSpeed;
else
targetSpeed *= walkSpeed;
walkTimeStart = Time.time;
function ApplyGravity ()
if (IsGrounded ())
verticalSpeed = 0.0;
else
43
verticalSpeed -= gravity * Time.deltaTime;
function Update() {
if (!isControllable)
Input.ResetInputAxes();
if (Input.GetButton ("Fire1"))
kick();
if (Input.GetButton ("Fire2"))
pass(targetGoal);
UpdateSmoothedMovementDirection();
// Apply gravity
ApplyGravity ();
44
movement *= Time.deltaTime;
collisionFlags = controller.Move(movement);
transform.rotation = Quaternion.LookRotation(moveDirection);
return;
wallJumpContactNormal = hit.normal;
if (hit.rigidbody == soccerBall.rigidbody){
if (!playerHasTheBall()){
soccerBall.rigidbody.GetComponent("BallBehavior").myOwner =
transform;
transform.parent.GetComponent(SoccerTeam).hasTheBall =
true;
transform.parent.GetComponent(SoccerTeam).opponentTeam.
GetComponent(SoccerTeam).hasTheBall = false;
function kick(){
45
if
(soccerBall.rigidbody.GetComponent("BallBehavior").myOwner ==
transform ){
soccerBall.rigidbody.GetComponent("BallBehavior").rigidbody.v
elocity = (targetGoal.position -
transform.position).normalized*kickSpeed;
else
soccerBall.rigidbody.GetComponent("BallBehavior").rigidbody.v
elocity = transform.TransformDirection(Vector3(0,0,kickSpeed));
soccerBall.rigidbody.GetComponent("BallBehavior").myOwner =
null;
function pass(receiver:Transform){
if
(soccerBall.rigidbody.GetComponent("BallBehavior").myOwner ==
transform ){
soccerBall.rigidbody.GetComponent("BallBehavior").rigidbody.v
elocity = targetDir.normalized*passSpeed;
46
soccerBall.rigidbody.GetComponent("BallBehavior").myOwner =
null;
else
soccerBall.rigidbody.GetComponent("BallBehavior").rigidbody.velocity
= transform.TransformDirection(Vector3(0,0,passSpeed));
soccerBall.rigidbody.GetComponent("BallBehavior").myOwner =
null;
function IsGrounded () {
function playerHasTheBall():boolean{
return
(soccerBall.rigidbody.GetComponent("BallBehavior").myOwner ==
transform);
function Reset ()
gameObject.tag = "Player";
@script RequireComponent(CharacterController)
Script 7 - ThirdPersonController.js
47
1.6 Next steps
As you noticed, it has a lot of things to do in this game, the
main is a script to control the goalkeeper.
48