Вы находитесь на странице: 1из 45

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

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

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.

1.1 The game window

0-0
A C
Restart Application Quit Application

Time: 5:00
B

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.

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 "; // The score has 2-digits, so the amount of goals goes from 00 to 99. 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.

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 Goal

2 SoccerTeam

1 SoccerBall

4 FieldPlayer 1

1 StateMachine 1

1 GoalKeeper

Image 2 - Classes

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 Player Animations Running ( ok ), Kicking, Scoring, Waiting. none none none none Includes the pitch. Details

Ball Pitch Goal Stadium

Image 3 - Player

Image 4 - Player Modeling

Image 5 - Player Animation

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 prximo a bola var playerClosestToBall:Transform; // O jogador que ir receber o passe. var receivingPlayer:Transform; // O gol adversrio, deve ser um GameObject. var targetGoal:Transform; // O gol do prpio time, tambm um GameObject. var homeGoal:Transform;

16

// True para Time controlado pelo pc, false para time controlador pelo usurio. var isPC:boolean = true; // O time est com a bola? var hasTheBall:boolean; // Ponteiro para o GameObject do time adversrio. var opponentTeam:Transform; // Array de GameObjects vazios representando as posies 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 varivel soccerBall a ele.

17

soccerBall = GameObject.FindWithTag ("SoccerBall").transform; // Quando o jogo iniciado, o time est na posio de defesa. isAttacking = false; isDefending=true; // No inicio do jogo, os jogadores devem se posicionar para a sada de bola. prepareForKickOff = true; // Funo 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 prximo a bola e associa ele com a variavel playerClosestToBall findClosestToBall(); controllingPlayer = playerClosestToBall; // Se o time controlado pelo usurio, faz com que o controllingPlayer seja controlado pelo usurio. if (!isPC) switchController(controllingPlayer); // Jogadores assumem a posio 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 esto na sua posio 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(); if ( soccerBall.GetComponent(BallBehavior).myOwner != null ) { 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){ isDefending=false; isAttacking=true; attackingFormation(); } defendingFormation(); } else { //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; teamA.GetComponent(SoccerTeam).hasTheBall = true; teamB.GetComponent(SoccerTeam).hasTheBall = false; } else {

Camera.main.GetComponent(SGUI).teamAScore=Camera.main.Get Component(SGUI).teamAScore+1; teamA.GetComponent(SoccerTeam).hasTheBall = false; teamB.GetComponent(SoccerTeam).hasTheBall = true; }

soccerBall.GetComponent (BallBehavior).OnGoal();

teamA.GetComponent(SoccerTeam).prepareForKickOff = true; teamB.GetComponent(SoccerTeam).prepareForKickOff = true;


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 ){ 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();

27

teamA.GetComponent(SoccerTeam).prepareForKickOff = true; teamB.GetComponent(SoccerTeam).prepareForKickOff = true; } }


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(); if ( teamA.GetComponent(SoccerTeam).hasTheBall == true ){ teamA.GetComponent(SoccerTeam).hasTheBall = false; teamB.GetComponent(SoccerTeam).hasTheBall = true;
28

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; // 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; // allow player to control the character again. } 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 ){ if( Vector3.Angle (transform.forward, targetDir) <130 ){

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 ){ if( Vector3.Angle (transform.forward, targetDir) <130 ){

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; // allow player to control the character again. } 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) { // If we are really slow, just snap to the target direction 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

// Smooth the speed based on the current target direction 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 var targetSpeed = Mathf.Min(targetDirection.magnitude, 1.0); // Pick speed modifier if (Time.time - trotAfterSeconds > walkTimeStart) { targetSpeed *= trotSpeed; } else { targetSpeed *= walkSpeed; } moveSpeed = Mathf.Lerp(moveSpeed, targetSpeed, curSmooth); // Reset walk time start when we slow down if (moveSpeed < walkSpeed * 0.3) walkTimeStart = Time.time; } } function ApplyGravity () { 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 ){ if( Vector3.Angle (transform.forward, targetDir) <150 )

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

if( Vector3.Angle (transform.forward, targetDir) <130 ){

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

Вам также может понравиться