Creating a Soccer Game. Part 1. Author: Thiago Campos Viana



Similar documents
Introduction to scripting with Unity

Making Android Motion Applications Using the Unity 3D Engine

Unity game examples By Mike Hergaarden from M2H (

Blender Notes. Introduction to Digital Modelling and Animation in Design Blender Tutorial - week 9 The Game Engine

Scripting in Unity3D (vers. 4.2)

How To Create A 3D Game In Unity 2.5.3D (Unity)

Movement Animset Pro v.1.5

How to Build a Simple Pac-Man Game

1.0-Scratch Interface 1.1. Valuable Information

Rifle Animset Pro for UE4

3. Add an Event: Alarm Alarm 0 a. Add an Action: Set Variable i. Applies to: Self ii. Variable: time_left iii. Value: +1 iv. Check the Relative box

Team Selection. Team Selection. Advanced Game. Positions. Advanced Game

The Car Tutorial Part 1 Creating a Racing Game for Unity

The Progression from 4v4 to 11v11

Law 6 The Assistant Referee

ACL Soccer 4 v 4 Small Sided Games (SSG s)

REFERENCE GUIDE 1. INTRODUCTION

COACHING GOALS FOR U7 TO U10 PLAYERS

Soccer Control and Trapping Small Sided Game, Soccer Control, Soccer Trapping

Use fireworks and Bonfire night as a stimulus for programming

Board Game Making in Unity

Coaching TOPSoccer. Training Session Activities. 1 US Youth Soccer

by Przemysław Króliszewski & Sebastian Korczak. itechnologie Sp. z o. o. p.kroliszewski@itechnologie.com.pl, s.korczak@itechnologie.com.

17 Laws of Soccer. LAW 5 The Referee The referee enforces the 17 laws.

Module 3 Crowd Animation Using Points, Particles and PFX Linker for creating crowd simulations in LightWave 8.3

Creating Animated Apps

17 Basic Rules of Soccer

The referee acts on the advice of assistant referees regarding incidents that he has not seen

SPECTATORS GUIDE TO RUGBY (Borrowed from a USA RUGBY brochure)

Andover Soccer Association U7 Boys / Girls High-Level Playing Rules

Law 3 The Number of Players

Scratch Primary Lesson 4

mouse (or the option key on Macintosh) and move the mouse. You should see that you are able to zoom into and out of the scene.

FIFA Laws of the Game U10-18

50 COACHING DRILLS. 50 FineSoccer Coaching Drills

YMCA Basketball Games and Skill Drills for 3 5 Year Olds

Tutorial: Creating Platform Games

2015 FFA Laws Of The Game Certificate Help File

Peoria Park District Youth Soccer Practice Drills

Football Learning Guide for Parents and Educators. Overview

Fantastic Fours. Field Layout

Principles of Soccer

Rugby The Basics

Copyright AC Ramskill (AcademyCoach83) October 2007

Socci Sport Alternative Games

R e f e r e e s G u i d e l i n e s Issued by Director of Refereeing

PDF Created with deskpdf PDF Writer - Trial ::

CS 378: Computer Game Technology

Introduction. Below is a list of benefits for the 4v4 method

Project 2: Character Animation Due Date: Friday, March 10th, 11:59 PM

TouchDevelop Curriculum

INTERNSHIP REPORT CSC410. Shantanu Chaudhary 2010CS50295

CREATE A 3D MOVIE IN DIRECTOR

The first step is to upload the Helicopter images from a strip. 1) Click on Resources > Create Sprite 2) Name it spr_helicopter 3) Click Edit Sprite

Review Vocabulary force: a push or a pull. Vocabulary Newton s third law of motion

Summary of FUTSAL Laws of the Gamel. A summary of FIFA's Futsal Laws of the Game

Creating Maze Games. Game Maker Tutorial. The Game Idea. A Simple Start. Written by Mark Overmars

Experience Design Assignment 2 : Shoot-em-up

Welcome, today we will be making this cute little fish come alive. Put the UltimaFish.bmp texture into your Morrowind/Data Files/Textures directory.

CATIA V5 Tutorials. Mechanism Design & Animation. Release 18. Nader G. Zamani. University of Windsor. Jonathan M. Weaver. University of Detroit Mercy

Silent Walk FPS Creator 2 User s Manual

FUTSAL BASIC PRINCIPLES MANUAL

Team Handball Study Guide

Playing in a (Diamond Midfield)

Dashboard Skin Tutorial. For ETS2 HTML5 Mobile Dashboard v3.0.2

Beginner Youth Basketball Plays

Castleknock GAA Coaching the Tackle. GPO Dáire O Neill

MEMORANDUM. Stefanie Sparks Smith Secretary-Rules Editor, NCAA Women s Lacrosse Rules Committee.

Whack-a-Witch. Level. Activity Checklist Follow these INSTRUCTIONS one by one. Test Your Project Click on the green flag to TEST your code

Character Bodypart Tutorial

Rules for the IEEE Very Small Competition Version 1.0

SIMPLE CROSSING - FUNCTIONAL PRACTICE

Classe AGI - PHP 5.x

READ AND REACT OFFENSE

How To Run A Factory I/O On A Microsoft Gpu 2.5 (Sdk) On A Computer Or Microsoft Powerbook 2.3 (Powerpoint) On An Android Computer Or Macbook 2 (Powerstation) On

Tutorial: Biped Character in 3D Studio Max 7, Easy Animation

FUTSAL RULES Below are additions and/or highlights to FIFA Futsal Rules For details on FIFA Rules, see Rules PDF.

Topics. Elements of the Law Offside Position Involvement in Active Play. Infringements Recommendations

SOCCER FUN GAMES (1) RELAY RACE.

Updated: Jan. 24, 2016

Contents.

Crickets and Bugs. Bodies Bingo. Make bingo cards with activities or jokes in the spaces. Each person goes up to another one and tells the joke or

Basic Lesson Plans for Football

secondary Intra-school/Level 1 Resource football - 9 v 9

The Fundamental Principles of Animation

RULE 7 Ball in Play, Dead Ball, Scrimmage

The Football Association Laws for 9v9 Football Law 1 Playing Area

SCHOOL NETBALL LEAGUE RULES FORMAT AND LOGISTICS

Balls, Hoops and Odds & Ends

Chapter 9- Animation Basics

Solar Tracking Controller

Elements and the Teaching of Creative and Deceptive Play F. Trovato Alaska Youth Soccer Association

CHAPTER 14 Understanding an App s Architecture

HARDWIRED CONTROL PANELS

Fish Chomp. Level. Activity Checklist Follow these INSTRUCTIONS one by one. Test Your Project Click on the green flag to TEST your code

Topic: Passing and Receiving for Possession

Themes. Best wishes. Michael Beale Youth Development Officer

Physics: Principles and Applications, 6e Giancoli Chapter 4 Dynamics: Newton's Laws of Motion

Transcription:

Creating a Soccer Game Part 1 Author: Thiago Campos Viana

Contents Contents...2 Image List...2 Script List...3 Part 1: A Simple Soccer Game...4 1.1 The game window...5 1.2 The rules...7 1.3 The assets...8 1.4 The ball...11 1.5 The player positions...14 Image List Image 1 - Game Window...5 Image 2 - Classes...7 Image 3 - Player...9 Image 4 - Player Modeling...9 Image 5 - Player Animation...9 Image 6 - Unity3d...10 Image 7 - Unity3d and the soccer field...11 Image 8 - Defending...15 Image 9 - Atacking...16 2

Script List Script 1 - BallBehavior.js...14 Script 2 - SoccerTeam.js...25 Script 3 - goaltrigger.js...27 Script 4 - FreeKickTrigger.js...28 Script 5 - throwintrigger.js...29 Script 6 - PCThirdPersonController.js...35 Script 7 - ThirdPersonController.js...45 3

Part 1: A Simple Soccer Game This series of tutorials will detail the development of a socer game, starting with a simple soccer. The first part of the project is based on Simple Soccer writed by Mat Buckland in his book Programming Game AI by Example. The first part of the tutorials has the following objectives: Provide an overview of the game to be developed. Create the field, the goals and create the script that records the occurrence of a goal, side kicks, and corner kicks. Develop the camera control script. Create the score field on the game window that will show the goals on each side of the field. Create the game timer. Start the development of scripts responsible for controlling the ball and players. 4

1.1 The game window A 0-0 Time: 5:00 B C Restart Application Quit Application D PlayerName GK/DF/MF/FW 4 (n) E MiniMap F PlayerName GK/DF/MF/FW 4 (n) Image 1 - 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. var gskin : GUISkin; private var isloading = false; // The variables responsible for storing the amount of goals from each team. var teamascore:int= 0; var teambscore:int = 0; // A float which controls the elapsed time of the match. 5

var timer:float=0; // Function to show the GUI of the game. function OnGUI() // If gskin variable is not null, change the style of GUI. if(gskin) GUI.skin = gskin; // Draw the area that will show the team name and score. GUI.Button( Rect( 15, 20, 220, 30), "", "button"); // Name of the first team, "BRA" - Brazil var message = "BRA "; 99. // The score has 2-digits, so the amount of goals goes from 00 to if (teamascore < 10 ) message+="0"+teamascore; else message+= teamascore; // BRA 00 x.. message+=" x "; // BRA 00 x 00 ARG if (teambscore < 10 ) message+="0"+teambscore+" ARG"; else message+= teambscore+" ARG"; // Draw the timer area. GUI.Label ( Rect( 20, 20, 210, 35),message, "label"); timer += Time.deltaTime; GUI.Button( Rect( Screen.width - 110, 20, 80, 30), "", "button"); // Shows the timer. 6

if( Mathf.Floor((timer - (Mathf.Floor(timer/60)*60))) < 10) 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 GUI.Label ( Rect( Screen.width - 105, 20, 100, 35), "0"+Mathf.Floor(timer/60)+":"+Mathf.Floor((timer - (Mathf.Floor(timer/60)*60))), "label"); This script should be assigned to the MainCamera object. 1.2 The rules SoccerPitch 2 2 1 Goal SoccerTeam SoccerBall 4 1 1 FieldPlayer StateMachine GoalKeeper 1 1 Image 2 - Classes 7

In the game, there are two teams. Each team has four players and a goalkeeper. The field has two goals and one ball. There are no faults. 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. In the event of a throw-in. The team that was not in possession of the ball, has a time to catch the ball and put it back in play. 1.3 The assets The models were made with "Blender": Name Animations Details Player Running ( ok ), Kicking, Scoring, Waiting. Ball Pitch Goal none none none Stadium none Includes the pitch. 8

Image 3 - Player Image 4 - Player Modeling Image 5 - Player Animation 9

Image 6 - Unity3d 10

Image 7 - Unity3d and the soccer field 1.4 The ball The ball is a GameObject with a rigidbody and a script called BallBehavior.js. // BallBehavior.js // Pointer to the player with the ball. var myowner:transform; // Store the starting position of the ball. var iniposition:vector3; // Pointer to the teams. 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 executed when initializing the object. function Awake() // Start position is set as the position of the ball in the Unity editor. iniposition = transform.position; // The ball can move. canmove = true; // Find the team objects. teama = GameObject.FindWithTag ("BlueTeam").transform; teamb = GameObject.FindWithTag ("RedTeam").transform; lastposition = iniposition; // Update function function Update () // Check if the ball can move. 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.sqrmagnitude > 10) transform.rotatearound (transform.position, myowner.right, 5*Time.deltaTime * myowner.getcomponent(charactercontroller).velocity.sqrmagnitude); // Goal function. function OnGoal() // No player has control of the ball. myowner = null; // Sets the linear velocity of the ball to zero. rigidbody.velocity = Vector3.zero; // Sets the angular velocity of the ball to zero. rigidbody.angularvelocity= Vector3.zero; // Ball should keep the position until the players take their positions. canmove= false; // LastPosition is used in the function keepposition, keeping the ball in one point lastposition = iniposition; // Keeps the ball in the lastposition point. 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 1.5 The player positions In this tutorial, each team has four players and a goalkeeper, players assumes two formations, attack and defense, each represented by a set of empty GameObjects, which are arranged on the map following a certain pattern. Image 8 shows how these objects should be placed into the position of defense and Image 9 the attack. 14

Image 8 - Defending 15

Image 9 - Atacking // SoccerTeam.js // O jogador que está sendo controlado no momnento. var controllingplayer:transform; // O jogador que dará suporte para o jogador que está sendo controlado. var supportingplayer:transform; // O jogador mais próximo a bola var playerclosesttoball:transform; // O jogador que irá receber o passe. var receivingplayer:transform; // O gol adversário, deve ser um GameObject. var targetgoal:transform; // O gol do própio time, também um GameObject. var homegoal:transform; 16

// True para Time controlado pelo pc, false para time controlador pelo usuário. var ispc:boolean = true; // O time está com a bola? var hastheball:boolean; // Ponteiro para o GameObject do time adversário. var opponentteam:transform; // Array de GameObjects vazios representando as posições de ataque e defesa. var defendingtargets:transform[]; var attackingtargets:transform[]; // Ponteiro para a bola. var soccerball:transform; // O time está no atacando? var isattacking:boolean; // O time está defendendo? var isdefending:boolean; // A bola deve sair do meio de campo? var prepareforkickoff:boolean; // A bola deve sair da lateral. var prepareforthrowin:boolean = false; // Ponteiro para os jogadores do time. var players:transform[]; function Awake() // busca o objeto com a tag SoccerBall e associa a variável soccerball a ele. 17

soccerball = GameObject.FindWithTag ("SoccerBall").transform; // Quando o jogo é iniciado, o time está na posição de defesa. isattacking = false; isdefending=true; // No inicio do jogo, os jogadores devem se posicionar para a saída de bola. prepareforkickoff = true; // Função que adiciona o script PCThirdPersonController para todos jogadores. setupplayers(); // O jogo inicia com o RedTeam com a posse de bola. if(transform.tag == "RedTeam") opponentteam = GameObject.FindWithTag ("BlueTeam").transform; hastheball = true; else opponentteam = GameObject.FindWithTag ("RedTeam").transform; // Encontro o jogador mais próximo a bola e associa ele com a variavel playerclosesttoball findclosesttoball(); controllingplayer = playerclosesttoball; // Se o time é controlado pelo usuário, faz com que o controllingplayer seja controlado pelo usuário. if (!ispc) switchcontroller(controllingplayer); // Jogadores assumem a posição de defesa. defendingformation(); 18

function setupplayers() for (var child : Transform in players) child.gameobject.addcomponent(pcthirdpersoncontroller); function defendingformation() var x = 0; for (var child : Transform in players) 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).canmove = true; 19

for (var child : Transform in players) child.getcomponent(pcthirdpersoncontroller).targetpoint = defendingtargets[x]; x++; function attackingformation() var x = 0; for (var child : Transform in players) if( child!= controllingplayer) child.getcomponent(pcthirdpersoncontroller).targetpoint = attackingtargets[x]; else if (! controllingplayer.getcomponent(pcthirdpersoncontroller).playerha stheball() ) child.getcomponent(pcthirdpersoncontroller).targetpoint = soccerball; else child.getcomponent(pcthirdpersoncontroller).targetpoint = targetgoal; x++; // Todos os jogadores estão na sua posição inicial? function allplayersathome():boolean var x = 0; 20

for (var child : Transform in players) if ( ( child.position - defendingtargets[x].position ).sqrmagnitude > 3 ) return false; x++; return true; function Update () findclosesttoball(); if (prepareforkickoff) preparingformation(); if ( allplayersathome() ) if( (opponentteam.getcomponent(soccerteam).allplayersathome() && hastheball ) soccerball.getcomponent(ballbehavior).myowner!= null ) prepareforkickoff = false; //findclosesttoball(); controllingplayer = playerclosesttoball; if (!ispc) switchcontroller(controllingplayer); soccerball.getcomponent(ballbehavior).canmove = true; else 21

return; else return; if(prepareforthrowin) preparingformation(); null ) if ( soccerball.getcomponent(ballbehavior).myowner!= prepareforthrowin=false; //findclosesttoball(); controllingplayer = playerclosesttoball; if (!ispc) switchcontroller(controllingplayer); else return; if ( controllingplayer!= playerclosesttoball ) var newdistance = (playerclosesttoball.position - soccerball.position).sqrmagnitude; var olddistance = (controllingplayer.position - soccerball.position).sqrmagnitude; if (ispc newdistance < olddistance*0.7) switchcontrollingplayer(playerclosesttoball); 22

if ( isdefending ) //defendendo //se está no estado de defesa e pega a bola, sai da defesa e inicia o estado de ataque if(hastheball) else isdefending=false; isattacking=true; attackingformation(); defendingformation(); //atacando //se está no estado de ataque e perde a bola, sai do ataque e inicia a defesa if(!hastheball) isdefending=true; isattacking=false; defendingformation(); attackingformation(); if (ispc) direction = targetgoal.position - controllingplayer.position; if (direction.sqrmagnitude < 400) controllingplayer.getcomponent(pcthirdpersoncontroller).kick(targ etgoal); 23

function findclosesttoball() var ballsqrdistance= Mathf.Infinity; for (var child : Transform in players) newdistance = (child.position - soccerball.position).sqrmagnitude; if (newdistance < ballsqrdistance) playerclosesttoball = child; ballsqrdistance = newdistance; function switchcontrollingplayer(newcontrollingplayer:transform) if (!ispc) switchcontroller(controllingplayer); switchcontroller(newcontrollingplayer); controllingplayer = newcontrollingplayer; function switchcontroller( soccerplayer:transform ) var newscript; var oldscript; if (!soccerplayer.getcomponent(thirdpersoncontroller)) newscript = soccerplayer.gameobject.addcomponent(thirdpersoncontroller); 24

soccerplayer.getcomponent(pcthirdpersoncontroller).canmove = false; else soccerplayer.getcomponent(pcthirdpersoncontroller).canmove = true; oldscript = soccerplayer.getcomponent(thirdpersoncontroller); soccerplayer.destroy(oldscript); Script 2 - SoccerTeam.js // goaltrigger.js var goalteam:string; var soccerball:transform; var teama:transform; var teamb:transform; function Awake() soccerball = GameObject.FindWithTag ("SoccerBall").transform; teama = GameObject.FindWithTag ("BlueTeam").transform; teamb = GameObject.FindWithTag ("RedTeam").transform; 25

function OnTriggerEnter (other : Collider) if(other.gameobject.layer==9) if ( goalteam=="teama" ) Camera.main.GetComponent(SGUI).teamBScore=Camera.main.Get Component(SGUI).teamBScore+1; true; false; teama.getcomponent(soccerteam).hastheball = teamb.getcomponent(soccerteam).hastheball = else Camera.main.GetComponent(SGUI).teamAScore=Camera.main.Get Component(SGUI).teamAScore+1; false; true; teama.getcomponent(soccerteam).hastheball = teamb.getcomponent(soccerteam).hastheball = soccerball.getcomponent (BallBehavior).OnGoal(); true; true; teama.getcomponent(soccerteam).prepareforkickoff = teamb.getcomponent(soccerteam).prepareforkickoff = 26

Script 3 - goaltrigger.js // FreeKickTrigger.js var soccerball:transform; var teama:transform; var teamb:transform; function Awake() soccerball = GameObject.FindWithTag ("SoccerBall").transform; teama = GameObject.FindWithTag ("BlueTeam").transform; teamb = GameObject.FindWithTag ("RedTeam").transform; function OnTriggerEnter (other : Collider) if(other.gameobject.layer==9) if (!teama.getcomponent(soccerteam).hastheball ) true; false; teama.getcomponent(soccerteam).hastheball = teamb.getcomponent(soccerteam).hastheball = else false; true; teama.getcomponent(soccerteam).hastheball = teamb.getcomponent(soccerteam).hastheball = soccerball.getcomponent (BallBehavior).OnGoal(); 27

true; true; teama.getcomponent(soccerteam).prepareforkickoff = teamb.getcomponent(soccerteam).prepareforkickoff = Script 4 - FreeKickTrigger.js // throwintrigger.js var soccerball:transform; var teama:transform; var teamb:transform; function Awake() soccerball = GameObject.FindWithTag ("SoccerBall").transform; teama = GameObject.FindWithTag ("BlueTeam").transform; teamb = GameObject.FindWithTag ("RedTeam").transform; function OnTriggerEnter (other : Collider) if(other.gameobject.layer==9) soccerball.getcomponent (BallBehavior).OnThrowIn(); true ) false; true; if ( teama.getcomponent(soccerteam).hastheball == teama.getcomponent(soccerteam).hastheball = teamb.getcomponent(soccerteam).hastheball = 28

teama.getcomponent(soccerteam).prepareforthrowin= true; else true; false; teama.getcomponent(soccerteam).hastheball = teamb.getcomponent(soccerteam).hastheball = teamb.getcomponent(soccerteam).prepareforthrowin = true; Script 5 - throwintrigger.js // PCThirdPersonController.js var soccerball:transform; // The speed when walking var walkspeed = 3.0; // when pressing "Fire3" button (cmd) we start running var runspeed = 6.0; var kickspeed = 40; var passspeed = 20; var rotatespeed = 500.0; var targetpoint:transform; 29

var canmove:boolean = true; // The last collision flags returned from controller.move private var collisionflags : CollisionFlags; private var iscontrollable = true; function Awake () soccerball = GameObject.FindWithTag ("SoccerBall").transform; //targetpoint = soccerball; // This next function responds to the "HidePlayer" message by hiding the player. // The message is also 'replied to' by identically-named functions in the collision-handling scripts. // - Used by the LevelStatus script when the level completed animation is triggered. function HidePlayer() GameObject.Find("rootJoint").GetComponent(SkinnedMeshRenderer ).enabled = false; // stop rendering the player. iscontrollable = false; // disable player controls. // This is a complementary function to the above. We don't use it in the tutorial, but it's included for // the sake of completeness. (I like orthogonal APIs; so sue me!) function ShowPlayer() 30

GameObject.Find("rootJoint").GetComponent(SkinnedMeshRenderer ).enabled = true; // start rendering the player again. iscontrollable = true; again. // allow player to control the character function Update() if (canmove) direction = targetpoint.position - transform.position; direction.y = 0; if (direction.sqrmagnitude > 2) // Rotate towards the target transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotatespeed * Time.deltaTime); transform.eulerangles = Vector3(0, transform.eulerangles.y, 0); // Modify speed so we slow down when we are not facing the target var forward = transform.transformdirection(vector3.forward); var speedmodifier = Vector3.Dot(forward, direction.normalized); speedmodifier = Mathf.Clamp01(speedModifier); // Move the character 31

direction = forward * runspeed * speedmodifier; GetComponent (CharacterController).SimpleMove(direction); function OnControllerColliderHit (hit : ControllerColliderHit ) 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.getc omponent(soccerteam).hastheball = false; function playerhastheball():boolean return (soccerball.rigidbody.getcomponent("ballbehavior").myowner == transform); 32

function Reset () gameobject.tag = "Player"; function kick(kicktarget:transform) var targetdir = kicktarget.position - transform.position; if (soccerball.rigidbody.getcomponent("ballbehavior").myowner == transform ) <130 ) if( Vector3.Angle (transform.forward, targetdir) soccerball.rigidbody.getcomponent("ballbehavior").rigidbody.velocit y =targetdir.normalized*kickspeed; soccerball.rigidbody.getcomponent("ballbehavior").myowner = null; function pass(receiver:transform) var targetdir = receiver.position - transform.position; if (soccerball.rigidbody.getcomponent("ballbehavior").myowner == transform ) targetdir) <130 ) if( Vector3.Angle (transform.forward, 33

soccerball.rigidbody.getcomponent("ballbehavior").rigidbody.velocit y = targetdir.normalized*passspeed; soccerball.rigidbody.getcomponent("ballbehavior").myowner = null; else soccerball.rigidbody.getcomponent("ballbehavior").rigidbody.velocit y = 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; // Require a character controller to be attached to the same game object @script RequireComponent(CharacterController) @script AddComponentMenu("Third Person Player/PCThird Person Controller") 34

Script 6 - PCThirdPersonController.js // ThirdPersonController.js var soccerball:transform; var targetgoal:transform; // The speed when walking var walkspeed = 9.0; // after trotafterseconds of walking we trot with trotspeed var trotspeed = 10.0; var kickspeed = 40; var passspeed = 20; // The gravity for the character var gravity = 20.0; var speedsmoothing = 10.0; var rotatespeed = 500.0; var trotafterseconds = 3.0; // The camera doesnt start following the target immediately but waits for a split second to avoid too much waving around. private var lockcameratimer = 0.0; // The current move direction in x-z 35

private var movedirection = Vector3.zero; // The current vertical speed private var verticalspeed = 0.0; // The current x-z move speed private var movespeed = 0.0; // The last collision flags returned from controller.move private var collisionflags : CollisionFlags; // Is the user pressing any keys? private var ismoving = false; // When did the user start walking (Used for going into trot after a while) private var walktimestart = 0.0; private var iscontrollable = true; function Awake () movedirection = transform.transformdirection(vector3.forward); targetgoal = transform.parent.getcomponent(soccerteam).targetgoal; soccerball = GameObject.FindWithTag ("SoccerBall").transform; 36

// This next function responds to the "HidePlayer" message by hiding the player. // The message is also 'replied to' by identically-named functions in the collision-handling scripts. // - Used by the LevelStatus script when the level completed animation is triggered. function HidePlayer() GameObject.Find("rootJoint").GetComponent(SkinnedMeshRenderer ).enabled = false; // stop rendering the player. iscontrollable = false; // disable player controls. // This is a complementary function to the above. We don't use it in the tutorial, but it's included for // the sake of completeness. (I like orthogonal APIs; so sue me!) function ShowPlayer() GameObject.Find("rootJoint").GetComponent(SkinnedMeshRenderer ).enabled = true; // start rendering the player again. iscontrollable = true; again. // allow player to control the character function UpdateSmoothedMovementDirection () var cameratransform = Camera.main.transform; var grounded = IsGrounded(); 37

// Forward vector relative to the camera along the x-z plane var forward = cameratransform.transformdirection(vector3.forward); forward.y = 0; forward = forward.normalized; // Right vector relative to the camera // Always orthogonal to the forward vector var right = Vector3(forward.z, 0, -forward.x); var v = Input.GetAxisRaw("Vertical"); var h = Input.GetAxisRaw("Horizontal"); // Are we moving backwards or looking backwards if (v < -0.2) movingback = true; else movingback = false; var wasmoving = ismoving; ismoving = Mathf.Abs (h) > 0.1 Mathf.Abs (v) > 0.1; // Target direction relative to the camera var targetdirection = h * right + v * forward; // Grounded controls if (grounded) // Lock camera for short period when transitioning moving & standing still 38

lockcameratimer += Time.deltaTime; if (ismoving!= wasmoving) lockcameratimer = 0.0; // We store speed and direction seperately, // so that when the character stands still we still have a valid forward direction // movedirection is always normalized, and we only update it if there is user input. if (targetdirection!= Vector3.zero) direction // If we are really slow, just snap to the target if (movespeed < walkspeed * 0.9 && grounded) movedirection = targetdirection.normalized; // Otherwise smoothly turn towards it else movedirection = Vector3.RotateTowards(moveDirection, targetdirection, rotatespeed * Mathf.Deg2Rad * Time.deltaTime, 1000); movedirection = movedirection.normalized; 39

direction // Smooth the speed based on the current target var cursmooth = speedsmoothing * Time.deltaTime; // Choose target speed //* We want to support analog input but make sure you cant walk faster diagonally than just forward or sideways 1.0); var targetspeed = Mathf.Min(targetDirection.magnitude, // Pick speed modifier if (Time.time - trotafterseconds > walktimestart) else targetspeed *= trotspeed; targetspeed *= walkspeed; movespeed = Mathf.Lerp(moveSpeed, targetspeed, cursmooth); // Reset walk time start when we slow down if (movespeed < walkspeed * 0.3) function ApplyGravity () walktimestart = Time.time; if (iscontrollable) // don't move player at all if not controllable. 40

if (IsGrounded ()) verticalspeed = 0.0; else verticalspeed -= gravity * Time.deltaTime; function Update() if (!iscontrollable) // kill all inputs if not controllable. Input.ResetInputAxes(); if (Input.GetButton ("Fire1")) kick(); if (Input.GetButton ("Fire2")) pass(targetgoal); UpdateSmoothedMovementDirection(); // Apply gravity // - extra power jump modifies gravity // - controlleddescent mode modifies gravity ApplyGravity (); 41

// Calculate actual motion var movement = movedirection * movespeed + Vector3 (0, verticalspeed, 0); movement *= Time.deltaTime; // Move the controller var controller : CharacterController = GetComponent(CharacterController); collisionflags = controller.move(movement); transform.rotation = Quaternion.LookRotation(moveDirection); function OnControllerColliderHit (hit : ControllerColliderHit ) if (hit.movedirection.y > 0.01) 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.getc omponent(soccerteam).hastheball = false; 42

function kick() var targetdir = targetgoal.position - transform.position; if (soccerball.rigidbody.getcomponent("ballbehavior").myowner == transform ) <150 ) if( Vector3.Angle (transform.forward, targetdir) soccerball.rigidbody.getcomponent("ballbehavior").rigidbody.velocit y = (targetgoal.position - transform.position).normalized*kickspeed; else soccerball.rigidbody.getcomponent("ballbehavior").rigidbody.velocit y = transform.transformdirection(vector3(0,0,kickspeed)); soccerball.rigidbody.getcomponent("ballbehavior").myowner = null; function pass(receiver:transform) var targetdir = receiver.position - transform.position; if (soccerball.rigidbody.getcomponent("ballbehavior").myowner == transform ) 43

targetdir) <130 ) if( Vector3.Angle (transform.forward, soccerball.rigidbody.getcomponent("ballbehavior").rigidbody.velocit y = targetdir.normalized*passspeed; soccerball.rigidbody.getcomponent("ballbehavior").myowner = null; else soccerball.rigidbody.getcomponent("ballbehavior").rigidbody.velocit y = transform.transformdirection(vector3(0,0,passspeed)); soccerball.rigidbody.getcomponent("ballbehavior").myowner = null; function IsGrounded () return (collisionflags & CollisionFlags.CollidedBelow)!= 0; function playerhastheball():boolean return (soccerball.rigidbody.getcomponent("ballbehavior").myowner == transform); function Reset () gameobject.tag = "Player"; 44

// Require a character controller to be attached to the same game object @script RequireComponent(CharacterController) @script AddComponentMenu("Third Person Player/Third Person Controller") Script 7 - ThirdPersonController.js 45